From 1adec4dfb27961790f949acf0225aae11f7e84b2 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 24 Nov 2022 03:16:58 +0100 Subject: [PATCH 1/4] Fix overflow in SPI memory when writing default key dictionnaries. Boundaries were defined in the memory layout but weren't enforced by the client, causing an overflow when trying to load a dictionnary that was too big. It's too hard to enforce it on the ARM side as the command is a generic write. Now that limits are defined, also outputs them as part of the `hw status` command. --- armsrc/flashmem.c | 6 +++--- client/src/cmdflashmem.c | 27 ++++++++++++++++++--------- include/pmflash.h | 12 +++++++++--- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 426540143..ba882eaa7 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -594,7 +594,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" Mifare.................. "_YELLOW_("%d")" keys", num); + Dbprintf(" Mifare.................. "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_MF_KEYS_MAX); } Flash_CheckBusy(BUSY_TIMEOUT); @@ -602,7 +602,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" T55x7................... "_YELLOW_("%d")" keys", num); + Dbprintf(" T55x7................... "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_T55XX_KEYS_MAX); } Flash_CheckBusy(BUSY_TIMEOUT); @@ -610,7 +610,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" iClass.................. "_YELLOW_("%d")" keys", num); + Dbprintf(" iClass.................. "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_ICLASS_KEYS_MAX); } FlashStop(); diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index 97126ad9b..f01531d55 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -204,19 +204,23 @@ static int CmdFlashMemLoad(const char *Cmd) { size_t datalen = 0; uint32_t keycount = 0; int res = 0; + uint8_t keylen = 0; uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); switch (d) { case DICTIONARY_MIFARE: offset = DEFAULT_MF_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, data + 2, &datalen, 6, &keycount); + keylen = 6; + res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; } // limited space on flash mem - if (keycount > 0xFFFF) - keycount &= 0xFFFF; + if (keycount > DEFAULT_MF_KEYS_MAX) { + keycount = DEFAULT_MF_KEYS_MAX; + datalen = keycount * keylen; + } data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; @@ -224,14 +228,17 @@ static int CmdFlashMemLoad(const char *Cmd) { break; case DICTIONARY_T55XX: offset = DEFAULT_T55XX_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, data + 2, &datalen, 4, &keycount); + keylen = 4; + res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; } // limited space on flash mem - if (keycount > 0xFFFF) - keycount &= 0xFFFF; + if (keycount > DEFAULT_T55XX_KEYS_MAX) { + keycount = DEFAULT_T55XX_KEYS_MAX; + datalen = keycount * keylen; + } data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; @@ -239,14 +246,16 @@ static int CmdFlashMemLoad(const char *Cmd) { break; case DICTIONARY_ICLASS: offset = DEFAULT_ICLASS_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, data + 2, &datalen, 8, &keycount); + res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; } // limited space on flash mem - if (keycount > 0xFFFF) - keycount &= 0xFFFF; + if (keycount > DEFAULT_ICLASS_KEYS_MAX) { + keycount = DEFAULT_ICLASS_KEYS_MAX; + datalen = keycount * keylen; + } data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; diff --git a/include/pmflash.h b/include/pmflash.h index 58bf2eb46..78e402ade 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -65,17 +65,23 @@ // Reserved space for T55XX PWD = 4 kb #ifndef DEFAULT_T55XX_KEYS_OFFSET -# define DEFAULT_T55XX_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x3000) +# define DEFAULT_T55XX_KEYS_LEN (0x1000) +# define DEFAULT_T55XX_KEYS_OFFSET (T55XX_CONFIG_OFFSET - DEFAULT_T55XX_KEYS_LEN) +# define DEFAULT_T55XX_KEYS_MAX ((DEFAULT_T55XX_KEYS_LEN - 2) / 4) #endif // Reserved space for iClass keys = 4 kb #ifndef DEFAULT_ICLASS_KEYS_OFFSET -# define DEFAULT_ICLASS_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x4000) +# define DEFAULT_ICLASS_KEYS_LEN (0x1000) +# define DEFAULT_ICLASS_KEYS_OFFSET (DEFAULT_T55XX_KEYS_OFFSET - DEFAULT_ICLASS_KEYS_LEN) +# define DEFAULT_ICLASS_KEYS_MAX ((DEFAULT_ICLASS_KEYS_LEN - 2) / 8) #endif // Reserved space for MIFARE Keys = 8 kb #ifndef DEFAULT_MF_KEYS_OFFSET -# define DEFAULT_MF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x6000) +# define DEFAULT_MF_KEYS_LEN (0x2000) +# define DEFAULT_MF_KEYS_OFFSET (DEFAULT_ICLASS_KEYS_OFFSET - DEFAULT_MF_KEYS_LEN) +# define DEFAULT_MF_KEYS_MAX ((DEFAULT_MF_KEYS_LEN - 2) / 6) #endif // RDV40, validation structure to help identifying that client/firmware is talking with RDV40 From ba83c26c1eab8ba311ef43ade88bb36e1f4e4af7 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 24 Nov 2022 09:35:22 +0100 Subject: [PATCH 2/4] Add one more sector for Mifare keys on SPI flash. This is a breaking change and after firmware upgrade, dictionnaries should be loaded into flash again to ensure they're valid. --- include/pmflash.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pmflash.h b/include/pmflash.h index 78e402ade..c3d00594a 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -28,7 +28,7 @@ // 0x3E000 - 1 4kb sector = settings // 0x3D000 - 1 4kb sector = default T55XX keys dictionary // 0x3B000 - 1 4kb sector = default ICLASS keys dictionary -// 0x39000 - 2 4kb sectors = default MFC keys dictionary +// 0x38000 - 3 4kb sectors = default MFC keys dictionary // #ifndef FLASH_MEM_BLOCK_SIZE # define FLASH_MEM_BLOCK_SIZE 256 @@ -79,7 +79,7 @@ // Reserved space for MIFARE Keys = 8 kb #ifndef DEFAULT_MF_KEYS_OFFSET -# define DEFAULT_MF_KEYS_LEN (0x2000) +# define DEFAULT_MF_KEYS_LEN (0x3000) # define DEFAULT_MF_KEYS_OFFSET (DEFAULT_ICLASS_KEYS_OFFSET - DEFAULT_MF_KEYS_LEN) # define DEFAULT_MF_KEYS_MAX ((DEFAULT_MF_KEYS_LEN - 2) / 6) #endif From 5bf0200b0260501de3cb1bfccbc8487f03a72f07 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 24 Nov 2022 09:37:02 +0100 Subject: [PATCH 3/4] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d06091bab..bc52d4c85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) + - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) From 8da4da6aa53bf11a017d40e2774223549540512c Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 24 Nov 2022 09:40:34 +0100 Subject: [PATCH 4/4] Also update comment about total size for Mifare keys storage. --- include/pmflash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pmflash.h b/include/pmflash.h index c3d00594a..f0deac507 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -77,7 +77,7 @@ # define DEFAULT_ICLASS_KEYS_MAX ((DEFAULT_ICLASS_KEYS_LEN - 2) / 8) #endif -// Reserved space for MIFARE Keys = 8 kb +// Reserved space for MIFARE Keys = 12 kb #ifndef DEFAULT_MF_KEYS_OFFSET # define DEFAULT_MF_KEYS_LEN (0x3000) # define DEFAULT_MF_KEYS_OFFSET (DEFAULT_ICLASS_KEYS_OFFSET - DEFAULT_MF_KEYS_LEN)