From 67ad6298cd4f7d4e34a40cb43c2302c710df5e1b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 15:54:22 +0300 Subject: [PATCH 01/20] added 14a send/receive arm timeout --- armsrc/iso14443a.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b5e612ec9..6851ef85a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1578,6 +1578,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing volatile uint8_t b; uint16_t c = 0; + uint32_t sendtimer = GetTickCount(); while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c++]; @@ -1587,6 +1588,8 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; } + if (GetTickCount() - sendtimer > 100) + break; } NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); @@ -1937,6 +1940,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive (void)b; uint32_t timeout = iso14a_get_timeout(); + uint32_t receive_timer = GetTickCount(); for (;;) { WDT_HIT(); @@ -1949,7 +1953,12 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive return false; } } + + // timeout already in ms + 100ms guard time + if (GetTickCount() - receive_timer > timeout + 100) + break; } + return false; } void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing) { From 81fa3f20df702815602e922e52380f0994965ac2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 16:22:14 +0300 Subject: [PATCH 02/20] speed optimization --- armsrc/iso14443a.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 6851ef85a..8543cdfa5 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1579,17 +1579,23 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing volatile uint8_t b; uint16_t c = 0; uint32_t sendtimer = GetTickCount(); + uint32_t cntr = 0; while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c++]; + } else { + if (cntr++ > 1000) { + cntr = 0; + if (GetTickCount() - sendtimer > 100) + break; + } } + //iceman test if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; } - if (GetTickCount() - sendtimer > 100) - break; } NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); From 87e183e664140662c3bfbba2de6270195a37de79 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 16:26:10 +0300 Subject: [PATCH 03/20] small fix --- armsrc/iso14443a.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 8543cdfa5..032766cb6 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1583,6 +1583,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c++]; + cntr = 0; } else { if (cntr++ > 1000) { cntr = 0; From f748c217b6013e2af335d66a03aea2d9fa2981a3 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 18 Jul 2019 15:27:12 +0200 Subject: [PATCH 04/20] Update README.md appveyor RRG/Iceman link. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e3be68472..46dc5f785 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. Note that it also supports other Proxmark3 platforms as well! -[![Build status](https://ci.appveyor.com/api/projects/status/ct5blik2wa96bv0x/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-ji4wj/branch/master) +[![Build status](https://ci.appveyor.com/api/projects/status/uvk6cexs6xxwonn4/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-isfoh/branch/master) [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) --- From 29f8bfb80c08bc506ca85cf554912b2a1592f3a3 Mon Sep 17 00:00:00 2001 From: Julien Piat Date: Thu, 18 Jul 2019 15:54:21 +0200 Subject: [PATCH 05/20] Update default_keys.dic with new keys from Scan Badge APK --- client/default_keys.dic | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index c8d96bd44..4df09cb1c 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -944,5 +944,9 @@ A23456789123 A00003000084 675A32413770 395244733978 +A0004A000036 +2C9F3D45BA13 +4243414F5250 +DFE73BE48AC6 # B069D0D03D17 From 5a5b3db92ee618b435c202b1946723b98f1b5b85 Mon Sep 17 00:00:00 2001 From: Julien Piat Date: Thu, 18 Jul 2019 16:11:03 +0200 Subject: [PATCH 06/20] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c78d813db..89a4d7ec8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change: new keys for Vigik badges in default_keys.dict (@luminouw) - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) - Add to 'hf 14a apdu' print apdu and compose apdu (@merlokk) - Change: buggy 'mem read' removed, 'mem save' renamed 'mem dump', can now display too (@doegox) From 1e0433c1d79002cce7e67e54d247673ce3a29403 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 19:02:01 +0300 Subject: [PATCH 07/20] now code can't use uninitialized fpga link and encoders/decoders --- armsrc/iso14443a.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b5e612ec9..db20481c8 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -13,6 +13,7 @@ #define MAX_ISO14A_TIMEOUT 524288 static uint32_t iso14a_timeout; +static bool iso14443a_active = false; uint8_t colpos = 0; int rsamples = 0; @@ -1551,6 +1552,9 @@ void PrepareDelayedTransfer(uint16_t delay) { //------------------------------------------------------------------------------------- static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) { + if (!iso14443a_active) + return; + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); if (timing) { @@ -1922,6 +1926,9 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start //----------------------------------------------------------------------------- static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c = 0; + + if (!iso14443a_active) + return false; // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). @@ -2354,6 +2361,14 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { UartReset(); NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; iso14a_set_timeout(1060); // 106 * 10ms default + + iso14443a_active = true; +} + +void iso14443a_off() { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + iso14443a_active = false; } /* Peter Fillmore 2015 @@ -2558,7 +2573,7 @@ void ReaderIso14443a(PacketCommandNG *c) { return; OUT: - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + iso14443a_off(); set_tracing(false); LEDsoff(); } @@ -2854,7 +2869,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf)); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + iso14443a_off(); LEDsoff(); set_tracing(false); } @@ -3094,7 +3109,7 @@ void DetectNACKbug() { //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0); BigBuf_free(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + iso14443a_off(); LEDsoff(); set_tracing(false); } From e87abc9681ecae0cac02adc52984bbd92c1511e5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 18 Jul 2019 17:32:56 +0300 Subject: [PATCH 08/20] small fix apdu leds --- armsrc/iso14443a.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index db20481c8..11f2ca66b 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -13,6 +13,7 @@ #define MAX_ISO14A_TIMEOUT 524288 static uint32_t iso14a_timeout; +// if iso14443a not active - transmit/receive dont try to execute static bool iso14443a_active = false; uint8_t colpos = 0; @@ -2367,7 +2368,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { void iso14443a_off() { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); + LEDsoff(); iso14443a_active = false; } @@ -2575,7 +2576,6 @@ void ReaderIso14443a(PacketCommandNG *c) { OUT: iso14443a_off(); set_tracing(false); - LEDsoff(); } // Determine the distance between two nonces. @@ -2870,7 +2870,6 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf)); iso14443a_off(); - LEDsoff(); set_tracing(false); } @@ -3110,6 +3109,5 @@ void DetectNACKbug() { //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0); BigBuf_free(); iso14443a_off(); - LEDsoff(); set_tracing(false); } From 9cd80406e210830d04e4fb3f7f24e7c32f2c01e9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 18 Jul 2019 16:39:48 +0200 Subject: [PATCH 09/20] Add Travis badge --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 46dc5f785..331edb337 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,9 @@ This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. Note that it also supports other Proxmark3 platforms as well! -[![Build status](https://ci.appveyor.com/api/projects/status/uvk6cexs6xxwonn4/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-isfoh/branch/master) -[![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) +| Releases | Linux & OSX CI | Windows CI | +| ------------------- |:-------------------:| -------------------:| +| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/uvk6cexs6xxwonn4/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-isfoh/branch/master) | --- From fdada47325d3c0622c179d7c095fa2a0d1ae0106 Mon Sep 17 00:00:00 2001 From: RFID Research Group Date: Thu, 18 Jul 2019 20:45:08 +0200 Subject: [PATCH 10/20] Update README.md swapped to RRG account for Appveyor --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 331edb337..50813868e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Note that it also supports other Proxmark3 platforms as well! | Releases | Linux & OSX CI | Windows CI | | ------------------- |:-------------------:| -------------------:| -| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/uvk6cexs6xxwonn4/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-isfoh/branch/master) | +| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | --- From 01e6db5c2e05f4dfde50c5b8823f2b5fa8d447e1 Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 18 Jul 2019 22:26:01 +0200 Subject: [PATCH 11/20] Add a simple tool to analyze elf files --- CHANGELOG.md | 1 + tools/analyzesize.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100755 tools/analyzesize.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 89a4d7ec8..bedc1dc04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add a simple python tool to check the elf sizes (@slurdge) - Change: new keys for Vigik badges in default_keys.dict (@luminouw) - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) - Add to 'hf 14a apdu' print apdu and compose apdu (@merlokk) diff --git a/tools/analyzesize.py b/tools/analyzesize.py new file mode 100755 index 000000000..ef14e2879 --- /dev/null +++ b/tools/analyzesize.py @@ -0,0 +1,31 @@ +#! /usr/bin/python3 + +import json +import subprocess +import sys + +def print_increase(x, y, name): + if x > y: + print("{} increase by: {} (0x{:08X}) bytes ({}%)".format(name, x-y, x-y, (x-y)*100/y)) + else: + print("{} decrease by: {} (0x{:08X}) bytes ({}%)".format(name, y-x, y-x, (y-x)*100/x)) +dbname = "tools/data.json" +db = json.load(open(dbname,"r")) + +if len(sys.argv) < 3: + print("Usage: analazysize.py ") + exit(-1) +action, name = sys.argv[1:3] +currentdata = subprocess.run(["arm-none-eabi-size","armsrc/obj/fullimage.stage1.elf"], stdout=subprocess.PIPE).stdout +currentdata = currentdata.split(b"\n")[1].strip() +text,data,bss = [int(x) for x in currentdata.split(b"\t")[:3]] +if action.lower() == "add": + db[name] = [text, data, bss] + json.dump(db, open(dbname, "w")) +elif action.lower() == "diff": + text_ref, data_ref, bss_ref = db[name] + flash_ref = text_ref+data_ref + flash = text+data + print_increase(flash, flash_ref, "Flash") + print_increase(bss, bss_ref, "RAM") + \ No newline at end of file From 32382ace3be9efd3e99e6f8e5b0903360d9f29ca Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 18 Jul 2019 22:28:07 +0200 Subject: [PATCH 12/20] Ignore local openocd configuration --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e37ce9534..f5ee135e6 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ client/traces/* armsrc/TEMP EMV/* tools/mf_nonce_brute/* tools/andrew/* +tools/jtag_openocd/openocd_configuration ppls patches/* *- Copy.* @@ -73,3 +74,4 @@ client/lualibs/mf_default_keys.lua client/lualibs/pm3_cmd.lua # recompiled fpga_version_info.c + From 41731ea0849c4d5bca0e46236292e06570b01f0d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 18 Jul 2019 23:42:58 +0200 Subject: [PATCH 13/20] analyzesize: create db on first use --- tools/analyzesize.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/analyzesize.py b/tools/analyzesize.py index ef14e2879..70c35de26 100755 --- a/tools/analyzesize.py +++ b/tools/analyzesize.py @@ -10,7 +10,10 @@ def print_increase(x, y, name): else: print("{} decrease by: {} (0x{:08X}) bytes ({}%)".format(name, y-x, y-x, (y-x)*100/x)) dbname = "tools/data.json" -db = json.load(open(dbname,"r")) +try: + db = json.load(open(dbname,"r")) +except FileNotFoundError: + db = dict() if len(sys.argv) < 3: print("Usage: analazysize.py ") From 4e9e7d6da004140c7c4a2ed2c3f560ac9a4d6763 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 18 Jul 2019 23:50:45 +0200 Subject: [PATCH 14/20] temporary fix to get Appveyor happy. Will need more tuning later. --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a62924787..e75224cd2 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3591,7 +3591,7 @@ static command_t CommandTable[] = { {"list", CmdHF14AMfList, AlwaysAvailable, "List Mifare history"}, {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack. read parity error messages."}, {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack. Test nested authentication"}, - {"hardnested", CmdHF14AMfNestedHard, IfPm3Iso14443a, "Nested attack for hardened Mifare cards"}, + {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened Mifare cards"}, {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for Mifare NACK bug"}, {"chk", CmdHF14AMfChk, IfPm3Iso14443a, "Check keys"}, From 7bf3255a6cd6f901a8cc01306c5dd4794ed974cc Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 18 Jul 2019 21:18:52 +0200 Subject: [PATCH 15/20] Flasher support for 512K flash A better way would be to cut the connecting function and flashing function and to move the whole mem computation to flash.c Working flasher --- CHANGELOG.md | 1 + bootrom/bootrom.c | 29 ++++++++++++++++++----------- client/flash.c | 35 ++++++++++++++++++----------------- client/flash.h | 2 +- client/flasher.c | 20 ++++++++++++++------ 5 files changed, 52 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bedc1dc04..cfa26a2b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add support for flashing 512K units (@slurdge) - Add a simple python tool to check the elf sizes (@slurdge) - Change: new keys for Vigik badges in default_keys.dict (@luminouw) - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 4e92bc95b..bda7de2c6 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -153,28 +153,35 @@ void UsbPacketReceived(uint8_t *packet, int len) { case CMD_FINISH_WRITE: { uint32_t *flash_mem = (uint32_t *)(&_flash_start); for (int j = 0; j < 2; j++) { - for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { - flash_mem[i] = c->d.asDwords[i]; - } - uint32_t flash_address = arg0 + (0x100 * j); - + AT91PS_EFC efc_bank = AT91C_BASE_EFC0; + int offset = 0; + uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE; + if (page_n >= AT91C_IFLASH_NB_OF_PAGES / 2) { + page_n -= AT91C_IFLASH_NB_OF_PAGES / 2; + efc_bank = AT91C_BASE_EFC1; + // We need to offset the writes or it will not fill the correct bank write buffer. + offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t); + } + for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { + flash_mem[offset+i] = c->d.asDwords[i]; + } + /* Check that the address that we are supposed to write to is within our allowed region */ if (((flash_address + AT91C_IFLASH_PAGE_SIZE - 1) >= end_addr) || (flash_address < start_addr)) { /* Disallow write */ dont_ack = 1; reply_old(CMD_NACK, 0, 0, 0, 0, 0); } else { - uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE; - /* Translate address to flash page and do flash, update here for the 512k part */ - AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY | - MC_FLASH_COMMAND_PAGEN(page_n) | - AT91C_MC_FCMD_START_PROG; + + efc_bank->EFC_FCR = MC_FLASH_COMMAND_KEY | + MC_FLASH_COMMAND_PAGEN(page_n) | + AT91C_MC_FCMD_START_PROG; } // Wait until flashing of page finishes uint32_t sr; - while (!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY)); + while (!((sr = efc_bank->EFC_FSR) & AT91C_MC_FRDY)); if (sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) { dont_ack = 1; reply_old(CMD_NACK, sr, 0, 0, 0, 0); diff --git a/client/flash.c b/client/flash.c index e41b47fb0..a29d8d7b0 100644 --- a/client/flash.c +++ b/client/flash.c @@ -12,13 +12,6 @@ #define FLASH_START 0x100000 -#ifdef HAS_512_FLASH -# define FLASH_SIZE (512*1024) -#else -# define FLASH_SIZE (256*1024) -#endif - -#define FLASH_END (FLASH_START + FLASH_SIZE) #define BOOTLOADER_SIZE 0x2000 #define BOOTLOADER_END (FLASH_START + BOOTLOADER_SIZE) @@ -33,7 +26,7 @@ static const uint8_t elf_ident[] = { // Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent // unaligned segments if needed -static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint16_t num_phdrs) { +static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint16_t num_phdrs, uint32_t flash_end) { Elf32_Phdr *phdr = phdrs; flash_seg_t *seg; uint32_t last_end = 0; @@ -77,11 +70,11 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap"); return -1; } - if (paddr < FLASH_START || (paddr + filesz) > FLASH_END) { + if (paddr < FLASH_START || (paddr + filesz) > flash_end) { PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash"); return -1; } - if (vaddr >= FLASH_START && vaddr < FLASH_END && (flags & PF_W)) { + if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) { PrintAndLogEx(ERR, "Error: Flash VMA segment is writable"); return -1; } @@ -153,7 +146,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, } // Sanity check segments and check for bootloader writes -static int check_segs(flash_file_t *ctx, int can_write_bl) { +static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) { for (int i = 0; i < ctx->num_segs; i++) { flash_seg_t *seg = &ctx->segments[i]; @@ -165,7 +158,7 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) { PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds"); return -1; } - if (seg->start + seg->length > FLASH_END) { + if (seg->start + seg->length > flash_end) { PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds"); return -1; } @@ -182,11 +175,12 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) { } // Load an ELF file and prepare it for flashing -int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) { +int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size) { FILE *fd; Elf32_Ehdr ehdr; Elf32_Phdr *phdrs = NULL; uint16_t num_phdrs; + uint32_t flash_end = FLASH_START + flash_size; int res; fd = fopen(name, "rb"); @@ -239,10 +233,10 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) { goto fail; } - res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs); + res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end); if (res < 0) goto fail; - res = check_segs(ctx, can_write_bl); + res = check_segs(ctx, can_write_bl, flash_end); if (res < 0) goto fail; @@ -362,15 +356,22 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipinfo = resp.oldarg[0]; } + uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES / 2; + if (((*chipinfo & 0xF00) >> 8) > 9) { + flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES; + } + + PrintAndLogEx(INFO, "End of flahs: 0x%08x", flash_end); + if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { // This command is stupid. Why the heck does it care which area we're // flashing, as long as it's not the bootloader area? The mind boggles. PacketResponseNG resp; if (enable_bl_writes) { - SendCommandBL(CMD_START_FLASH, FLASH_START, FLASH_END, START_FLASH_MAGIC, NULL, 0); + SendCommandBL(CMD_START_FLASH, FLASH_START, flash_end, START_FLASH_MAGIC, NULL, 0); } else { - SendCommandBL(CMD_START_FLASH, BOOTLOADER_END, FLASH_END, 0, NULL, 0); + SendCommandBL(CMD_START_FLASH, BOOTLOADER_END, flash_end, 0, NULL, 0); } return wait_for_ack(&resp); } else { diff --git a/client/flash.h b/client/flash.h index 7140de673..cc0387bf3 100644 --- a/client/flash.h +++ b/client/flash.h @@ -37,7 +37,7 @@ typedef struct { flash_seg_t *segments; } flash_file_t; -int flash_load(flash_file_t *ctx, const char *name, int can_write_bl); +int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size); int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipid); int flash_write(flash_file_t *ctx); void flash_free(flash_file_t *ctx); diff --git a/client/flasher.c b/client/flasher.c index 94e2ef6ba..8b6a87bf8 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -21,6 +21,7 @@ #include "ui.h" #define MAX_FILES 4 +#define ONE_KB 1024 static void usage(char *argv0) { PrintAndLogEx(NORMAL, "Usage: %s [-b] image.elf [image.elf...]\n", argv0); @@ -76,6 +77,7 @@ int main(int argc, char **argv) { int num_files = 0; int res; flash_file_t files[MAX_FILES]; + char * filenames[MAX_FILES]; memset(files, 0, sizeof(files)); @@ -102,11 +104,7 @@ int main(int argc, char **argv) { return -1; } } else { - res = flash_load(&files[num_files], argv[i], can_write_bl); - if (res < 0) - return -1; - - PrintAndLogEx(NORMAL, ""); + filenames[num_files] = argv[i]; num_files++; } } @@ -132,9 +130,19 @@ int main(int argc, char **argv) { PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n"); PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command")); PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); + mem_avail = 256; //we default to a low value } + + for (int i = 0 ; i < num_files; ++i){ + res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); + if (res < 0) + return -1; + + PrintAndLogEx(NORMAL, ""); + } + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); -// TODO check if enough space on Pm3 mem to write the given files + for (int i = 0; i < num_files; i++) { res = flash_write(&files[i]); if (res < 0) From 44278272a41e9140ba459e87845de1c9196920c2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 12:39:23 +0200 Subject: [PATCH 16/20] typo --- client/flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/flash.c b/client/flash.c index a29d8d7b0..abd81a9de 100644 --- a/client/flash.c +++ b/client/flash.c @@ -361,7 +361,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES; } - PrintAndLogEx(INFO, "End of flahs: 0x%08x", flash_end); + PrintAndLogEx(INFO, "End of flash: 0x%08x", flash_end); if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { // This command is stupid. Why the heck does it care which area we're From f6f14f82d48d7306492e356f5dd8d36db6ab2c83 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 13:02:12 +0200 Subject: [PATCH 17/20] Add option -i to flasher to query Pm3 for its memory size, and some doc tuning --- CHANGELOG.md | 1 + client/flasher.c | 58 +++++++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfa26a2b3..45c2074b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add option -i to flasher to query Pm3 for its memory size (@doegox) - Add support for flashing 512K units (@slurdge) - Add a simple python tool to check the elf sizes (@slurdge) - Change: new keys for Vigik badges in default_keys.dict (@luminouw) diff --git a/client/flasher.c b/client/flasher.c index 8b6a87bf8..4caeab63b 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -24,15 +24,20 @@ #define ONE_KB 1024 static void usage(char *argv0) { - PrintAndLogEx(NORMAL, "Usage: %s [-b] image.elf [image.elf...]\n", argv0); - PrintAndLogEx(NORMAL, "\t-b\tEnable flashing of bootloader area (DANGEROUS)\n"); - PrintAndLogEx(NORMAL, "\nExample:\n\n\t %s "SERIAL_PORT_EXAMPLE_H" armsrc/obj/fullimage.elf", argv0); + PrintAndLogEx(NORMAL, "Usage: %s [-b] image.elf [image.elf...]", argv0); + PrintAndLogEx(NORMAL, " %s -i\n", argv0); + PrintAndLogEx(NORMAL, "\t-b\tEnable flashing of bootloader area (DANGEROUS)"); + PrintAndLogEx(NORMAL, "\t-i\tProbe the connected Proxmark3 to retrieve its memory size"); + PrintAndLogEx(NORMAL, "\nExamples:\n\t %s "SERIAL_PORT_EXAMPLE_H" -i", argv0); + PrintAndLogEx(NORMAL, "\t %s "SERIAL_PORT_EXAMPLE_H" armsrc/obj/fullimage.elf", argv0); #ifdef __linux__ - PrintAndLogEx(NORMAL, "\nNote (Linux): if the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); - PrintAndLogEx(NORMAL, " you need to blacklist Proxmark3 for modem-manager - see wiki for more details:\n"); - PrintAndLogEx(NORMAL, " https://github.com/Proxmark/proxmark3/wiki/Gentoo Linux\n"); - PrintAndLogEx(NORMAL, " https://github.com/Proxmark/proxmark3/wiki/Ubuntu Linux\n"); - PrintAndLogEx(NORMAL, " https://github.com/Proxmark/proxmark3/wiki/OSX\n"); + PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); + PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:"); + PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md"); + PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n"); #endif } @@ -78,7 +83,7 @@ int main(int argc, char **argv) { int res; flash_file_t files[MAX_FILES]; char * filenames[MAX_FILES]; - + bool info = false; memset(files, 0, sizeof(files)); session.supports_colors = false; @@ -99,6 +104,8 @@ int main(int argc, char **argv) { if (argv[i][0] == '-') { if (!strcmp(argv[i], "-b")) { can_write_bl = 1; + } else if (!strcmp(argv[i], "-i")) { + info = true; } else { usage(argv[0]); return -1; @@ -133,24 +140,25 @@ int main(int argc, char **argv) { mem_avail = 256; //we default to a low value } - for (int i = 0 ; i < num_files; ++i){ - res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); - if (res < 0) - return -1; + if (! info) { + for (int i = 0 ; i < num_files; ++i){ + res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); + if (res < 0) + return -1; - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, ""); + } + + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); + + for (int i = 0; i < num_files; i++) { + res = flash_write(&files[i]); + if (res < 0) + return -1; + flash_free(&files[i]); + PrintAndLogEx(NORMAL, "\n"); + } } - - PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); - - for (int i = 0; i < num_files; i++) { - res = flash_write(&files[i]); - if (res < 0) - return -1; - flash_free(&files[i]); - PrintAndLogEx(NORMAL, "\n"); - } - res = flash_stop_flashing(); if (res < 0) return -1; From 33f2cb09817936a7bcf8ae8311bc3d46fdb83792 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 13:15:32 +0200 Subject: [PATCH 18/20] Rework flasher exit on error --- client/flasher.c | 56 +++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/client/flasher.c b/client/flasher.c index 4caeab63b..0db87cb94 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -81,6 +81,7 @@ int main(int argc, char **argv) { int can_write_bl = 0; int num_files = 0; int res; + int ret = 0; flash_file_t files[MAX_FILES]; char * filenames[MAX_FILES]; bool info = false; @@ -127,8 +128,10 @@ int main(int argc, char **argv) { uint32_t chipid = 0; res = flash_start_flashing(can_write_bl, serial_port_name, &chipid); - if (res < 0) - return -1; + if (res < 0) { + ret = -1; + goto finish; + } int mem_avail = chipid_to_mem_avail(chipid); if (mem_avail != 0) { @@ -140,32 +143,41 @@ int main(int argc, char **argv) { mem_avail = 256; //we default to a low value } - if (! info) { - for (int i = 0 ; i < num_files; ++i){ - res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); - if (res < 0) - return -1; + if (info) + goto finish; - PrintAndLogEx(NORMAL, ""); - } - - PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); - - for (int i = 0; i < num_files; i++) { - res = flash_write(&files[i]); - if (res < 0) - return -1; - flash_free(&files[i]); - PrintAndLogEx(NORMAL, "\n"); + for (int i = 0 ; i < num_files; ++i){ + res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); + if (res < 0) { + ret = -1; + goto finish; } + PrintAndLogEx(NORMAL, ""); } + + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); + + for (int i = 0; i < num_files; i++) { + res = flash_write(&files[i]); + if (res < 0) { + ret = -1; + goto finish; + } + flash_free(&files[i]); + PrintAndLogEx(NORMAL, "\n"); + } + +finish: res = flash_stop_flashing(); if (res < 0) - return -1; + ret = -1; CloseProxmark(); - PrintAndLogEx(SUCCESS, _BLUE_("All done.")); - PrintAndLogEx(SUCCESS, "\nHave a nice day!"); - return 0; + if (ret==0) + PrintAndLogEx(SUCCESS, _BLUE_("All done.")); + else + PrintAndLogEx(ERR, "Aborted on error."); + PrintAndLogEx(NORMAL, "\nHave a nice day!"); + return ret; } From 8e6258936caea0fda3c6b82d2038cfae66acac66 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 13:18:35 +0200 Subject: [PATCH 19/20] make style --- armsrc/iso14443a.c | 8 ++++---- bootrom/bootrom.c | 8 ++++---- client/emv/emvcore.c | 2 +- client/flasher.c | 8 ++++---- tools/analyzesize.py | 1 - 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index bcd898c89..9c76a476d 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1596,7 +1596,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing break; } } - + //iceman test if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); @@ -1937,7 +1937,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start //----------------------------------------------------------------------------- static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c = 0; - + if (!iso14443a_active) return false; @@ -1968,7 +1968,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive return false; } } - + // timeout already in ms + 100ms guard time if (GetTickCount() - receive_timer > timeout + 100) break; @@ -2378,7 +2378,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { UartReset(); NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; iso14a_set_timeout(1060); // 106 * 10ms default - + iso14443a_active = true; } diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index bda7de2c6..0726f332d 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -164,9 +164,9 @@ void UsbPacketReceived(uint8_t *packet, int len) { offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t); } for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { - flash_mem[offset+i] = c->d.asDwords[i]; + flash_mem[offset + i] = c->d.asDwords[i]; } - + /* Check that the address that we are supposed to write to is within our allowed region */ if (((flash_address + AT91C_IFLASH_PAGE_SIZE - 1) >= end_addr) || (flash_address < start_addr)) { /* Disallow write */ @@ -175,8 +175,8 @@ void UsbPacketReceived(uint8_t *packet, int len) { } else { efc_bank->EFC_FCR = MC_FLASH_COMMAND_KEY | - MC_FLASH_COMMAND_PAGEN(page_n) | - AT91C_MC_FCMD_START_PROG; + MC_FLASH_COMMAND_PAGEN(page_n) | + AT91C_MC_FCMD_START_PROG; } // Wait until flashing of page finishes diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 6657f2ce3..c814eb11e 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -539,7 +539,7 @@ int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, i--; } else { // (1) - card select error, (4) reply timeout, (200) - result length = 0 - if (res == 1 || res == 4 ||res == 200) { + if (res == 1 || res == 4 || res == 200) { if (!LeaveFieldON) DropFieldEx(channel); diff --git a/client/flasher.c b/client/flasher.c index 0db87cb94..25585e7cd 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -83,7 +83,7 @@ int main(int argc, char **argv) { int res; int ret = 0; flash_file_t files[MAX_FILES]; - char * filenames[MAX_FILES]; + char *filenames[MAX_FILES]; bool info = false; memset(files, 0, sizeof(files)); @@ -146,8 +146,8 @@ int main(int argc, char **argv) { if (info) goto finish; - for (int i = 0 ; i < num_files; ++i){ - res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); + for (int i = 0 ; i < num_files; ++i) { + res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail * ONE_KB); if (res < 0) { ret = -1; goto finish; @@ -174,7 +174,7 @@ finish: CloseProxmark(); - if (ret==0) + if (ret == 0) PrintAndLogEx(SUCCESS, _BLUE_("All done.")); else PrintAndLogEx(ERR, "Aborted on error."); diff --git a/tools/analyzesize.py b/tools/analyzesize.py index 70c35de26..4a5211c67 100755 --- a/tools/analyzesize.py +++ b/tools/analyzesize.py @@ -31,4 +31,3 @@ elif action.lower() == "diff": flash = text+data print_increase(flash, flash_ref, "Flash") print_increase(bss, bss_ref, "RAM") - \ No newline at end of file From f4ffa005c9783549192f04fcc0d5d6a77207e6f3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 14:00:26 +0200 Subject: [PATCH 20/20] Travis on osx: testing xcode9.2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b81af3d97..723d1c1a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ compiler: gcc matrix: include: - os: osx - osx_image: xcode9.1 # OS X 10.13.1 + osx_image: xcode9.2 # OS X 10.13 - os: linux dist: xenial sudo: required