diff --git a/armsrc/sam_common.c b/armsrc/sam_common.c index d104148ff..38c2f3c1f 100644 --- a/armsrc/sam_common.c +++ b/armsrc/sam_common.c @@ -218,7 +218,7 @@ out: * * @return Status code indicating success or failure of the operation. */ -int sam_get_version(void) { +int sam_get_version(bool info) { int res = PM3_SUCCESS; if (g_dbglevel >= DBG_DEBUG) { @@ -268,18 +268,18 @@ int sam_get_version(void) { } uint8_t *sam_version_an = sam_find_asn1_node(sam_response_an, 0x80); if (sam_version_an == NULL) { - if (g_dbglevel >= DBG_ERROR) DbpString("SAM get version failed"); + if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get version failed")); goto error; } uint8_t *sam_build_an = sam_find_asn1_node(sam_response_an, 0x81); if (sam_build_an == NULL) { - if (g_dbglevel >= DBG_ERROR) DbpString("SAM get firmware ID failed"); + if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get firmware ID failed")); goto error; } - if (g_dbglevel >= DBG_INFO) { - DbpString("SAM get version successful"); - Dbprintf("Firmware version: %X.%X", sam_version_an[2], sam_version_an[3]); - Dbprintf("Firmware ID: "); + if (g_dbglevel >= DBG_INFO || info) { + DbpString(_BLUE_("-- SAM Information --")); + Dbprintf(_YELLOW_("Firmware version: ")"%X.%X", sam_version_an[2], sam_version_an[3]); + Dbprintf(_YELLOW_("Firmware ID : ")); Dbhexdump(sam_build_an[1], sam_build_an + 2, false); } goto out; @@ -298,6 +298,75 @@ out: return res; } +int sam_get_serial_number(void) { + int res = PM3_SUCCESS; + + if (g_dbglevel >= DBG_DEBUG) { + DbpString("start sam_get_serial_number"); + } + + uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME); + uint16_t response_len = ISO7816_MAX_FRAME; + + uint8_t payload[] = { + 0xa0, 0x02, // <- SAM command + 0x96, 0x00 // <- get serial number + }; + uint16_t payload_len = sizeof(payload); + + sam_send_payload( + 0x44, 0x0a, 0x44, + payload, + &payload_len, + response, + &response_len + ); + + //resp: + //c1 64 00 00 00 + // bd 0e <- SAM response + // 8a 0c <- get serial number response + // 61 01 13 51 22 66 6e 15 3e 1b ff ff + //90 00 + + if (g_dbglevel >= DBG_DEBUG) { + DbpString("end sam_get_serial_number"); + } + + if (response[5] != 0xbd) { + Dbprintf("Invalid SAM response"); + goto error; + } else { + uint8_t *sam_response_an = sam_find_asn1_node(response + 5, 0x8a); + if (sam_response_an == NULL) { + if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get response failed")); + goto error; + } + uint8_t *sam_serial_an = sam_response_an + 2; + if (sam_serial_an == NULL) { + if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM get serial number failed")); + goto error; + } + + Dbprintf(_YELLOW_("Sam Serial Number: ")); + Dbhexdump(sam_response_an[1],sam_serial_an, false); + + goto out; + } + +error: + res = PM3_ESOFT; + +out: + BigBuf_free(); + + if (g_dbglevel >= DBG_DEBUG) { + DbpString("end sam_get_serial_number"); + } + + return res; +} + /** diff --git a/armsrc/sam_common.h b/armsrc/sam_common.h index 1c3a88e88..4cc6e364f 100644 --- a/armsrc/sam_common.h +++ b/armsrc/sam_common.h @@ -39,7 +39,8 @@ int sam_send_payload( uint16_t *response_len ); -int sam_get_version(void); +int sam_get_version(bool info); +int sam_get_serial_number(void); uint8_t *sam_find_asn1_node(const uint8_t *root, const uint8_t type); void sam_append_asn1_node(const uint8_t *root, const uint8_t *node, uint8_t type, const uint8_t *const data, uint8_t len); diff --git a/armsrc/sam_picopass.c b/armsrc/sam_picopass.c index d22985e49..29fd1797b 100644 --- a/armsrc/sam_picopass.c +++ b/armsrc/sam_picopass.c @@ -338,11 +338,14 @@ int sam_picopass_get_pacs(PacketCommandNG *c) { const bool breakOnNrMac = !!(flags & BITMASK(2)); const bool preventEpurseUpdate = !!(flags & BITMASK(3)); const bool shallow_mod = !!(flags & BITMASK(4)); + const bool info = !!(flags & BITMASK(5)); uint8_t *cmd = c->data.asBytes + 1; uint16_t cmd_len = c->length - 1; int res = PM3_EFAILED; + uint8_t sam_response[ISO7816_MAX_FRAME] = { 0x00 }; + uint8_t sam_response_len = 0; clear_trace(); I2C_Reset_EnterMainProgram(); @@ -351,7 +354,12 @@ int sam_picopass_get_pacs(PacketCommandNG *c) { StartTicks(); // step 1: ping SAM - sam_get_version(); + sam_get_version(info); + + if(info){ + sam_get_serial_number(); + goto out; + } if (!skipDetect) { // step 2: get card information @@ -371,8 +379,6 @@ int sam_picopass_get_pacs(PacketCommandNG *c) { } // step 3: SamCommand RequestPACS, relay NFC communication - uint8_t sam_response[ISO7816_MAX_FRAME] = { 0x00 }; - uint8_t sam_response_len = 0; res = sam_send_request_iso15(cmd, cmd_len, sam_response, &sam_response_len, shallow_mod, breakOnNrMac, preventEpurseUpdate); if (res != PM3_SUCCESS) { goto err; diff --git a/armsrc/sam_seos.c b/armsrc/sam_seos.c index 04bc128a2..3f8c806e9 100644 --- a/armsrc/sam_seos.c +++ b/armsrc/sam_seos.c @@ -282,7 +282,7 @@ int sam_seos_get_pacs(PacketCommandNG *c) { StartTicks(); // step 1: ping SAM - sam_get_version(); + sam_get_version(false); if (skipDetect == false) { // step 2: get card information diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 16899893e..a21d9c3ee 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -5904,6 +5904,7 @@ static int CmdHFiClassSAM(const char *Cmd) { arg_lit0("p", "prevent", "fake epurse update"), arg_lit0(NULL, "shallow", "shallow mod"), arg_strx0("d", "data", "", "DER encoded command to send to SAM"), + arg_lit0(NULL, "info", "get SAM infos (version, serial number)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -5915,6 +5916,7 @@ static int CmdHFiClassSAM(const char *Cmd) { bool break_nrmac = arg_get_lit(ctx, 5); bool prevent = arg_get_lit(ctx, 6); bool shallow_mod = arg_get_lit(ctx, 7); + bool info = arg_get_lit(ctx, 9); uint8_t flags = 0; if (disconnect_after) { @@ -5937,6 +5939,10 @@ static int CmdHFiClassSAM(const char *Cmd) { flags |= BITMASK(4); } + if (info) { + flags |= BITMASK(5); + } + uint8_t data[PM3_CMD_DATA_SIZE] = {0}; data[0] = flags;