From ce45b3b2424e52fe5167e530c6631aeef2ad1cf6 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Tue, 17 Oct 2023 17:47:54 +0200 Subject: [PATCH] Fix potential stack overflow while making it easier to support more ATRs --- common/cardhelper.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/common/cardhelper.c b/common/cardhelper.c index 7103769c9..8c5fd8c22 100644 --- a/common/cardhelper.c +++ b/common/cardhelper.c @@ -73,27 +73,35 @@ bool IsHIDSamPresent(bool verbose) { } // SAM identification - uint8_t sam_atr[] = {0x3B, 0x95, 0x96, 0x80, 0xB1, 0xFE, 0x55, 0x1F, 0xC7, 0x47, 0x72, 0x61, 0x63, 0x65, 0x13}; - if (memcmp(card.atr, sam_atr, card.atr_len) < 0) { - - uint8_t sam_atr2[] = {0x3b, 0x90, 0x96, 0x91, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0xc7, 0xd4}; - if (memcmp(card.atr, sam_atr2, card.atr_len) < 0) { - if (verbose) { - PrintAndLogEx(SUCCESS, "Not detecting a SAM"); - } - return false; + smart_card_atr_t supported[] = { + {15, {0x3B, 0x95, 0x96, 0x80, 0xB1, 0xFE, 0x55, 0x1F, 0xC7, 0x47, 0x72, 0x61, 0x63, 0x65, 0x13}}, + {11, {0x3b, 0x90, 0x96, 0x91, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0xc7, 0xd4}}, + }; + bool found = false; + for (int i = 0; i < sizeof(supported) / sizeof(supported[0]); i++) { + if ((card.atr_len == supported[i].atr_len) && + (memcmp(card.atr, supported[i].atr, supported[i].atr_len) == 0)) { + found = true; + break; } } - - // Suspect some SAMs has version name in their ATR - uint8_t T0 = card.atr[1]; - uint8_t K = T0 & 0x0F; - if (K > 4 && verbose) { - if (byte_strstr(card.atr, card.atr_len, (const uint8_t *)"Grace", 5) > -1) { - PrintAndLogEx(SUCCESS, "SAM (Grace) detected"); - } else if (byte_strstr(card.atr, card.atr_len, (const uint8_t *)"Hopper", 6) > -1) { - PrintAndLogEx(SUCCESS, "SAM (Hopper) detected"); + if (found == false) { + if (verbose) { + PrintAndLogEx(SUCCESS, "Not detecting a SAM"); } + return false; + } + + // Suspect some SAMs has version name in the historical bytes + uint8_t T0 = card.atr[1]; + uint8_t K = T0 & 0x0F; // Number of historical bytes + if (K > 0 && (K < (card.atr_len - 3)) && verbose) { + // Last byte of ATR is CRC and before that we have K bytes of + // "historical bytes". + // By construction K can't go above 15 + char sam_name[16] = {0}; + memcpy(sam_name, &card.atr[card.atr_len - 1 - K], K); + PrintAndLogEx(SUCCESS, "SAM (%s) detected", sam_name); } return true; }