diff --git a/armsrc/sam_seos.c b/armsrc/sam_seos.c index 866f62a63..37a2da259 100644 --- a/armsrc/sam_seos.c +++ b/armsrc/sam_seos.c @@ -226,7 +226,7 @@ static int sam_send_request_iso14a(const uint8_t * const request, const uint8_t // send get pacs static const uint8_t payload[] = { 0xa0, 19, // <- SAM command - 0xA1, 17, // <- SamCommandGetContentElement + 0xBE, 17, // <- samCommandGetContentElement2 0x80, 1, 0x04, // <- implicitFormatPhysicalAccessBits 0x84, 12, @@ -290,29 +290,43 @@ static int sam_send_request_iso14a(const uint8_t * const request, const uint8_t ); } - // resp: + // resp for SamCommandGetContentElement: // c1 64 00 00 00 // bd 09 // 8a 07 // 03 05 <- include tag for pm3 client // 06 85 80 6d c0 <- decoded PACS data // 90 00 + + // resp for samCommandGetContentElement2: + // c1 64 00 00 00 + // bd 1e + // b3 1c + // a0 1a + // 80 05 + // 06 85 80 6d c0 + // 81 0e + // 2b 06 01 04 01 81 e4 38 01 01 02 04 3c ff + // 82 01 + // 07 + // 90 00 if(request_len == 0){ - if(sam_rx_buf[5] != 0xbd && sam_rx_buf[5+2] != 0x8a && sam_rx_buf[5+4] != 0x03){ + if( + !(sam_rx_buf[5] == 0xbd && sam_rx_buf[5+2] == 0x8a && sam_rx_buf[5+4] == 0x03) + && + !(sam_rx_buf[5] == 0xbd && sam_rx_buf[5+2] == 0xb3 && sam_rx_buf[5+4] == 0xa0) + ){ if (g_dbglevel >= DBG_ERROR) - Dbprintf("Invalid SAM response"); - goto err; + Dbprintf("No PACS data in SAM response"); + res=PM3_ESOFT; } } *response_len = sam_rx_buf[5+1] +2; memcpy(response, sam_rx_buf+5, *response_len); - res=PM3_SUCCESS; goto out; - err: - res=PM3_ESOFT; out: return res; } diff --git a/client/src/cmdhfseos.c b/client/src/cmdhfseos.c index 6ef6a2a60..bc96ad7d4 100644 --- a/client/src/cmdhfseos.c +++ b/client/src/cmdhfseos.c @@ -100,6 +100,17 @@ static const known_algo_t known_algorithm_map[] = { {9, "AES-128_CBC_MODE"}, }; +static const sioMediaTypeName_t sioMediaTypeMapping[] = { + { 0x00, "Unknown"}, + { 0x01, "DESFire"}, + { 0x02, "MIFARE"}, + { 0x03, "iCLASS (PicoPass)"}, + { 0x04, "ISO14443AL4"}, + { 0x06, "MIFARE Plus"}, + { 0x07, "Seos"}, + { 0xFF, "INVALID VALUE"} +}; + static int create_cmac (uint8_t* key, uint8_t* input, uint8_t* out, int input_len, int encryption_algorithm) { uint8_t iv[16] = {0x00}; @@ -1707,6 +1718,23 @@ static int dump_PACS_bits(const uint8_t * const data, const uint8_t length, bool return PM3_SUCCESS; } + +// get a SIO media type based on the UID +// uid[8] tag uid +// returns description of the best match +static const char *getSioMediaTypeInfo(uint8_t uid) { + + for (int i = 0; i < ARRAYLEN(sioMediaTypeMapping); ++i) { + if (uid == sioMediaTypeMapping[i].uid) { + return sioMediaTypeMapping[i].desc; + } + } + + //No match, return default + return sioMediaTypeMapping[ARRAYLEN(sioMediaTypeMapping) - 1].desc; +} + + static int CmdHfSeosSAM(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf seos sam", @@ -1756,9 +1784,7 @@ static int CmdHfSeosSAM(const char *Cmd) { } clearCommandBuffer(); - // void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len) { SendCommandMIX(CMD_HF_SAM_SEOS, disconnectAfter, skipDetect, datalen, data, datalen); - // SendCommandNG(CMD_HF_SAM_SEOS, NULL, 0); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_SAM_SEOS, &resp, 4000) == false) { PrintAndLogEx(WARNING, "SAM timeout"); @@ -1789,6 +1815,34 @@ static int CmdHfSeosSAM(const char *Cmd) { if(res != PM3_SUCCESS){ return res; } + // check for standard samCommandGetContentElement2: + // bd 1e + // b3 1c + // a0 1a + // 80 05 + // 06 85 80 6d c0 + // 81 0e + // 2b 06 01 04 01 81 e4 38 01 01 02 04 3c ff + // 82 01 + // 07 + } else if(d[0]==0xbd && d[2]==0xb3 && d[4]==0xa0){ + const uint8_t * pacs = d + 6; + const uint8_t pacs_length = pacs[1]; + const uint8_t * pacs_data = pacs + 2; + int res = dump_PACS_bits(pacs_data, pacs_length, verbose); + if(res != PM3_SUCCESS){ + return res; + } + + const uint8_t * oid = pacs + 2 + pacs_length; + const uint8_t oid_length = oid[1]; + const uint8_t * oid_data = oid + 2; + PrintAndLogEx(SUCCESS, "SIO OID.......: " _GREEN_("%s"), sprint_hex_inrow(oid_data, oid_length)); + + const uint8_t * mediaType = oid + 2 + oid_length; + const uint8_t mediaType_data = mediaType[2]; + PrintAndLogEx(SUCCESS, "SIO Media Type: " _GREEN_("%s"), getSioMediaTypeInfo(mediaType_data)); + } else { print_hex(d, resp.length); } diff --git a/client/src/cmdhfseos.h b/client/src/cmdhfseos.h index 33e6d45f5..950346c04 100644 --- a/client/src/cmdhfseos.h +++ b/client/src/cmdhfseos.h @@ -21,6 +21,12 @@ #include "common.h" +// structure and database for uid -> tagtype lookups +typedef struct { + uint8_t uid; + const char *desc; +} sioMediaTypeName_t; + int infoSeos(bool verbose); int CmdHFSeos(const char *Cmd); int seos_kdf(bool encryption, uint8_t* masterKey, uint8_t keyslot,