diff --git a/client/src/cmdhfseos.c b/client/src/cmdhfseos.c index 259f22f415..3cb89f5db3 100644 --- a/client/src/cmdhfseos.c +++ b/client/src/cmdhfseos.c @@ -47,7 +47,7 @@ static uint8_t zeros[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 static int CmdHelp(const char *Cmd); typedef struct { - uint8_t nonce[8]; + uint8_t keyslot; uint8_t privEncKey[16]; uint8_t privMacKey[16]; uint8_t readKey[16]; @@ -57,7 +57,7 @@ typedef struct { keyset_t keys[] = { { - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce + 0x01, // Keyslot { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privEncKey { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privMacKey { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // readKey @@ -65,7 +65,7 @@ keyset_t keys[] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // adminKey }, { - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce + 0x01, // Keyslot { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privEncKey { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privMacKey { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // readKey @@ -73,7 +73,7 @@ keyset_t keys[] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // adminKey }, { - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce + 0x02, // Keyslot { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privEncKey { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privMacKey { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // readKey @@ -81,7 +81,7 @@ keyset_t keys[] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // adminKey }, { - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce + 0x09, // Keyslot { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privEncKey { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privMacKey { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // readKey @@ -469,7 +469,7 @@ static int seos_challenge_get(uint8_t *RNDICC, uint8_t RNDICC_len, uint8_t keysl // const char keyslot_str[3] = "01"; //strcat(getChallengePre, keyslot_str); - snprintf(getChallengePre + strlen(getChallengePre), 3, "%02u", keyslot); + snprintf(getChallengePre + strlen(getChallengePre), 3, "%02X", keyslot); strcat(getChallengePre, "047c02810000"); uint8_t aGET_CHALLENGE[12]; @@ -1091,7 +1091,7 @@ static int seos_pacs_adf_select(char *oid, int oid_len, uint8_t *data_tag, int d resplen -= 2; - uint8_t keyslot = 0x01; + uint8_t keyslot = keys[key_index].keyslot; seos_challenge_get(RNDICC, sizeof(RNDICC), keyslot); select_df_decode(response, resplen, &ALGORITHM_INFO_value1, &ALGORITHM_INFO_value2, CRYPTOGRAM_encrypted_data, MAC_value); res = select_DF_verify(response, resplen, MAC_value, sizeof(MAC_value), ALGORITHM_INFO_value1, key_index); @@ -1201,7 +1201,7 @@ static int seos_adf_select(char *oid, int oid_len, int key_index) { resplen -= 2; - seos_challenge_get(RNDICC, sizeof(RNDICC), 0x01); + seos_challenge_get(RNDICC, sizeof(RNDICC), keys[key_index].keyslot); select_df_decode(response, resplen, &ALGORITHM_INFO_value1, &ALGORITHM_INFO_value2, CRYPTOGRAM_encrypted_data, MAC_value); select_DF_verify(response, resplen, MAC_value, sizeof(MAC_value), ALGORITHM_INFO_value1, key_index); return PM3_SUCCESS; @@ -1244,7 +1244,7 @@ static int seos_gdf_select(int key_index) { uint8_t MAC_value[8] = {0}; // MAC Value uint8_t RNDICC[8] = {0}; - seos_challenge_get(RNDICC, sizeof(RNDICC), 0x09); + seos_challenge_get(RNDICC, sizeof(RNDICC), keys[key_index].keyslot); select_df_decode(response, (resplen - 2), &ALGORITHM_INFO_value1, &ALGORITHM_INFO_value2, CRYPTOGRAM_encrypted_data, MAC_value); select_DF_verify(response, resplen, MAC_value, sizeof(MAC_value), ALGORITHM_INFO_value1, key_index); @@ -1291,7 +1291,7 @@ static int seos_print_keys(bool verbose) { if (verbose) { for (int i = 0; i < ARRAYLEN(keys); i++) { PrintAndLogEx(INFO, "Key Index........................ " _YELLOW_("%u"), i); - PrintAndLogEx(INFO, "Nonce............................ " _YELLOW_("%s"), sprint_hex(keys[i].nonce, 8)); + PrintAndLogEx(INFO, "Keyslot.......................... " _YELLOW_("%u"), keys[i].keyslot); PrintAndLogEx(INFO, "Privacy Encryption Key........... " _YELLOW_("%s"), sprint_hex(keys[i].privEncKey, 16)); PrintAndLogEx(INFO, "Privacy MAC Key.................. " _YELLOW_("%s"), sprint_hex(keys[i].privMacKey, 16)); PrintAndLogEx(INFO, "Read Key......................... " _YELLOW_("%s"), sprint_hex(keys[i].readKey, 16)); @@ -1300,15 +1300,15 @@ static int seos_print_keys(bool verbose) { PrintAndLogEx(INFO, "----------------------------"); } } else { - PrintAndLogEx(INFO, "idx| key"); - PrintAndLogEx(INFO, "---+------------------------"); + PrintAndLogEx(INFO, "idx|slot| key"); + PrintAndLogEx(INFO, "---+----+------------------------"); for (uint8_t i = 0; i < ARRAYLEN(keys); i++) { if (memcmp(keys[i].privEncKey, zeros, sizeof(zeros)) == 0) - PrintAndLogEx(INFO, " %u |", i); + PrintAndLogEx(INFO, " %u | |", i); else - PrintAndLogEx(INFO, " %u | " _YELLOW_("%s"), i, sprint_hex(keys[i].nonce, 8)); + PrintAndLogEx(INFO, " %u | " _YELLOW_("% 2u") " | " _YELLOW_("%s"), i, keys[i].keyslot, sprint_hex(keys[i].readKey, 8)); } - PrintAndLogEx(INFO, "---+------------------------"); + PrintAndLogEx(INFO, "---+----+------------------------"); }; PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; @@ -1335,12 +1335,12 @@ static int seos_load_keys(char *filename) { size_t i = 0; for (; i < bytes_read / kn; i++) { - memcpy(keys[i].nonce, dump + (i * kn), 8); - memcpy(keys[i].privEncKey, dump + ((i * kn) + 8), 16); - memcpy(keys[i].privMacKey, dump + ((i * kn) + 24), 16); - memcpy(keys[i].readKey, dump + ((i * kn) + 40), 16); - memcpy(keys[i].writeKey, dump + ((i * kn) + 56), 16); - memcpy(keys[i].adminKey, dump + ((i * kn) + 72), 16); + memcpy(&keys[i].keyslot, dump + (i * kn), 1); + memcpy(keys[i].privEncKey, dump + ((i * kn) + 1), 16); + memcpy(keys[i].privMacKey, dump + ((i * kn) + 17), 16); + memcpy(keys[i].readKey, dump + ((i * kn) + 33), 16); + memcpy(keys[i].writeKey, dump + ((i * kn) + 49), 16); + memcpy(keys[i].adminKey, dump + ((i * kn) + 65), 16); } free(dump); @@ -1375,9 +1375,9 @@ static int CmdHfSeosGDF(const char *Cmd) { CLIParserInit(&ctx, "hf seos gdf", "Get Global Data File (GDF) from SEOS card\n\n" "By default:\n" - " - Key Index: 0\n", + " - Key Index: 3\n", "hf seos gdf" - "hf seos gdf --ki 0" + "hf seos gdf --ki 3" ); void *argtable[] = { arg_param_begin, @@ -1386,7 +1386,7 @@ static int CmdHfSeosGDF(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, true); - int key_index = arg_get_int_def(ctx, 1, 0); + int key_index = arg_get_int_def(ctx, 1, 3); CLIParserFree(ctx); return seos_global_df(key_index); @@ -1513,15 +1513,16 @@ static int CmdHfSeosManageKeys(const char *Cmd) { "Manage SEOS Keys in client memory, keys are required to authenticate with SEOS cards\n", "hf seos managekeys -p\n" "hf seos managekeys -p -v\n" - "hf seos managekeys --ki 0 --nonce 0102030405060708 -> Set nonce value at key index 0\n" - "hf seos managekeys --load -f mykeys.bin -p -> load from file and prints keys\n" - "hf seos managekeys --save -f mykeys.bin -> saves keys to file\n" + "hf seos managekeys --ki 0 --keyslot 1 -> Set keyslot value at key index 0\n" + "hf seos managekeys --ki 1 --read 0102030405060708 -> Set read key value at key index 1\n" + "hf seos managekeys --load -f mykeys.bin -p -> load from file and prints keys\n" + "hf seos managekeys --save -f mykeys.bin -> saves keys to file\n" ); void *argtable[] = { arg_param_begin, arg_int0(NULL, "ki", "", "Specify key index to set key in memory"), - arg_str0(NULL, "nonce", "", "Nonce value as 8 hex bytes"), + arg_int0(NULL, "keyslot", "", "Keyslot value"), arg_str0(NULL, "privenc", "", "Privacy Encryption key as 16 hex bytes"), arg_str0(NULL, "privmac", "", "Privacy MAC key as 16 hex bytes"), arg_str0(NULL, "read", "", "Undiversified Read key as 16 hex bytes"), @@ -1542,13 +1543,11 @@ static int CmdHfSeosManageKeys(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; uint8_t operation = 0; - uint8_t nonce[8] = {0}; uint8_t privenc[16] = {0}; uint8_t privmac[16] = {0}; uint8_t read[16] = {0}; uint8_t write[16] = {0}; uint8_t admin[16] = {0}; - int nonce_len = 0; int privenc_len = 0; int privmac_len = 0; int read_len = 0; @@ -1556,8 +1555,8 @@ static int CmdHfSeosManageKeys(const char *Cmd) { int admin_len = 0; int key_index = arg_get_int_def(ctx, 1, -1); + int keyslot = arg_get_int_def(ctx, 2, -1); - CLIGetHexWithReturn(ctx, 2, nonce, &nonce_len); CLIGetHexWithReturn(ctx, 3, privenc, &privenc_len); CLIGetHexWithReturn(ctx, 4, privmac, &privmac_len); CLIGetHexWithReturn(ctx, 5, read, &read_len); @@ -1569,8 +1568,8 @@ static int CmdHfSeosManageKeys(const char *Cmd) { if (key_index >= 0) { operation += 3; if (key_index < 4) { - if (nonce_len != 0) { - PrintAndLogEx(SUCCESS, "Current value for nonce[%d] " _GREEN_("%s"), key_index, sprint_hex_inrow(keys[key_index].nonce, 8)); + if (keyslot != -1) { + PrintAndLogEx(SUCCESS, "Current value for keyslot[%d] " _GREEN_("%u"), key_index, keys[key_index].keyslot); } if (privenc_len != 0) { PrintAndLogEx(SUCCESS, "Current value for Priv Enc[%d] " _GREEN_("%s"), key_index, sprint_hex_inrow(keys[key_index].privEncKey, 16)); @@ -1620,16 +1619,16 @@ static int CmdHfSeosManageKeys(const char *Cmd) { PrintAndLogEx(ERR, "You must enter a filename when loading or saving\n"); return PM3_EINVARG; } - if (((nonce_len > 0) || (privenc_len > 0) || (privmac_len > 0) || (read_len > 0) || (write_len > 0) || (admin_len > 0)) && key_index == -1) { + if (((keyslot != -1) || (privenc_len > 0) || (privmac_len > 0) || (read_len > 0) || (write_len > 0) || (admin_len > 0)) && key_index == -1) { PrintAndLogEx(ERR, "Please specify key index when specifying key"); return PM3_EINVARG; } switch (operation) { case 3: - if (nonce_len != 0) { - memcpy(keys[key_index].nonce, nonce, 8); - PrintAndLogEx(SUCCESS, "New value for nonce[%d] " _GREEN_("%s"), key_index, sprint_hex_inrow(keys[key_index].nonce, 8)); + if (keyslot != -1) { + keys[key_index].keyslot = keyslot; + PrintAndLogEx(SUCCESS, "New value for keyslot[%d] " _GREEN_("%u"), key_index, keys[key_index].keyslot); } if (privenc_len != 0) { memcpy(keys[key_index].privEncKey, privenc, 16);