@@ -47,7 +47,7 @@ static uint8_t zeros[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4747static int CmdHelp (const char * Cmd );
4848
4949typedef struct {
50- uint8_t nonce [ 8 ] ;
50+ uint8_t keyslot ;
5151 uint8_t privEncKey [16 ];
5252 uint8_t privMacKey [16 ];
5353 uint8_t readKey [16 ];
@@ -57,31 +57,31 @@ typedef struct {
5757
5858keyset_t keys [] = {
5959 {
60- { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // Nonce
60+ 0x01 , // Keyslot
6161 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // privEncKey
6262 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // privMacKey
6363 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // readKey
6464 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // writeKey
6565 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } // adminKey
6666 },
6767 {
68- { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // Nonce
68+ 0x01 , // Keyslot
6969 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // privEncKey
7070 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // privMacKey
7171 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // readKey
7272 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // writeKey
7373 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } // adminKey
7474 },
7575 {
76- { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // Nonce
76+ 0x02 , // Keyslot
7777 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // privEncKey
7878 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // privMacKey
7979 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // readKey
8080 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // writeKey
8181 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } // adminKey
8282 },
8383 {
84- { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // Nonce
84+ 0x09 , // Keyslot
8585 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // privEncKey
8686 { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // privMacKey
8787 { 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
469469
470470 // const char keyslot_str[3] = "01";
471471 //strcat(getChallengePre, keyslot_str);
472- snprintf (getChallengePre + strlen (getChallengePre ), 3 , "%02u " , keyslot );
472+ snprintf (getChallengePre + strlen (getChallengePre ), 3 , "%02X " , keyslot );
473473 strcat (getChallengePre , "047c02810000" );
474474
475475 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
10911091
10921092 resplen -= 2 ;
10931093
1094- uint8_t keyslot = 0x01 ;
1094+ uint8_t keyslot = keys [ key_index ]. keyslot ;
10951095 seos_challenge_get (RNDICC , sizeof (RNDICC ), keyslot );
10961096 select_df_decode (response , resplen , & ALGORITHM_INFO_value1 , & ALGORITHM_INFO_value2 , CRYPTOGRAM_encrypted_data , MAC_value );
10971097 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) {
12011201
12021202 resplen -= 2 ;
12031203
1204- seos_challenge_get (RNDICC , sizeof (RNDICC ), 0x01 );
1204+ seos_challenge_get (RNDICC , sizeof (RNDICC ), keys [ key_index ]. keyslot );
12051205 select_df_decode (response , resplen , & ALGORITHM_INFO_value1 , & ALGORITHM_INFO_value2 , CRYPTOGRAM_encrypted_data , MAC_value );
12061206 select_DF_verify (response , resplen , MAC_value , sizeof (MAC_value ), ALGORITHM_INFO_value1 , key_index );
12071207 return PM3_SUCCESS ;
@@ -1244,7 +1244,7 @@ static int seos_gdf_select(int key_index) {
12441244 uint8_t MAC_value [8 ] = {0 }; // MAC Value
12451245 uint8_t RNDICC [8 ] = {0 };
12461246
1247- seos_challenge_get (RNDICC , sizeof (RNDICC ), 0x09 );
1247+ seos_challenge_get (RNDICC , sizeof (RNDICC ), keys [ key_index ]. keyslot );
12481248 select_df_decode (response , (resplen - 2 ), & ALGORITHM_INFO_value1 , & ALGORITHM_INFO_value2 , CRYPTOGRAM_encrypted_data , MAC_value );
12491249 select_DF_verify (response , resplen , MAC_value , sizeof (MAC_value ), ALGORITHM_INFO_value1 , key_index );
12501250
@@ -1291,7 +1291,7 @@ static int seos_print_keys(bool verbose) {
12911291 if (verbose ) {
12921292 for (int i = 0 ; i < ARRAYLEN (keys ); i ++ ) {
12931293 PrintAndLogEx (INFO , "Key Index........................ " _YELLOW_ ("%u" ), i );
1294- PrintAndLogEx (INFO , "Nonce ............................ " _YELLOW_ ("%s " ), sprint_hex ( keys [i ].nonce , 8 ) );
1294+ PrintAndLogEx (INFO , "Keyslot .......................... " _YELLOW_ ("%u " ), keys [i ].keyslot );
12951295 PrintAndLogEx (INFO , "Privacy Encryption Key........... " _YELLOW_ ("%s" ), sprint_hex (keys [i ].privEncKey , 16 ));
12961296 PrintAndLogEx (INFO , "Privacy MAC Key.................. " _YELLOW_ ("%s" ), sprint_hex (keys [i ].privMacKey , 16 ));
12971297 PrintAndLogEx (INFO , "Read Key......................... " _YELLOW_ ("%s" ), sprint_hex (keys [i ].readKey , 16 ));
@@ -1300,15 +1300,15 @@ static int seos_print_keys(bool verbose) {
13001300 PrintAndLogEx (INFO , "----------------------------" );
13011301 }
13021302 } else {
1303- PrintAndLogEx (INFO , "idx| key" );
1304- PrintAndLogEx (INFO , "---+------------------------" );
1303+ PrintAndLogEx (INFO , "idx|slot| key" );
1304+ PrintAndLogEx (INFO , "---+----+---- --------------------" );
13051305 for (uint8_t i = 0 ; i < ARRAYLEN (keys ); i ++ ) {
13061306 if (memcmp (keys [i ].privEncKey , zeros , sizeof (zeros )) == 0 )
1307- PrintAndLogEx (INFO , " %u |" , i );
1307+ PrintAndLogEx (INFO , " %u | | " , i );
13081308 else
1309- PrintAndLogEx (INFO , " %u | " _YELLOW_ ("%s" ), i , sprint_hex (keys [i ].nonce , 8 ));
1309+ PrintAndLogEx (INFO , " %u | " _YELLOW_ ("% 2u" ) " | " _YELLOW_ ( "% s" ), i , keys [ i ]. keyslot , sprint_hex (keys [i ].readKey , 8 ));
13101310 }
1311- PrintAndLogEx (INFO , "---+------------------------" );
1311+ PrintAndLogEx (INFO , "---+----+---- --------------------" );
13121312 };
13131313 PrintAndLogEx (NORMAL , "" );
13141314 return PM3_SUCCESS ;
@@ -1335,12 +1335,12 @@ static int seos_load_keys(char *filename) {
13351335
13361336 size_t i = 0 ;
13371337 for (; i < bytes_read / kn ; i ++ ) {
1338- memcpy (keys [i ].nonce , dump + (i * kn ), 8 );
1339- memcpy (keys [i ].privEncKey , dump + ((i * kn ) + 8 ), 16 );
1340- memcpy (keys [i ].privMacKey , dump + ((i * kn ) + 24 ), 16 );
1341- memcpy (keys [i ].readKey , dump + ((i * kn ) + 40 ), 16 );
1342- memcpy (keys [i ].writeKey , dump + ((i * kn ) + 56 ), 16 );
1343- memcpy (keys [i ].adminKey , dump + ((i * kn ) + 72 ), 16 );
1338+ memcpy (& keys [i ].keyslot , dump + (i * kn ), 1 );
1339+ memcpy (keys [i ].privEncKey , dump + ((i * kn ) + 1 ), 16 );
1340+ memcpy (keys [i ].privMacKey , dump + ((i * kn ) + 17 ), 16 );
1341+ memcpy (keys [i ].readKey , dump + ((i * kn ) + 33 ), 16 );
1342+ memcpy (keys [i ].writeKey , dump + ((i * kn ) + 49 ), 16 );
1343+ memcpy (keys [i ].adminKey , dump + ((i * kn ) + 65 ), 16 );
13441344 }
13451345
13461346 free (dump );
@@ -1375,9 +1375,9 @@ static int CmdHfSeosGDF(const char *Cmd) {
13751375 CLIParserInit (& ctx , "hf seos gdf" ,
13761376 "Get Global Data File (GDF) from SEOS card\n\n"
13771377 "By default:\n"
1378- " - Key Index: 0 \n" ,
1378+ " - Key Index: 3 \n" ,
13791379 "hf seos gdf"
1380- "hf seos gdf --ki 0 "
1380+ "hf seos gdf --ki 3 "
13811381 );
13821382 void * argtable [] = {
13831383 arg_param_begin ,
@@ -1386,7 +1386,7 @@ static int CmdHfSeosGDF(const char *Cmd) {
13861386 };
13871387 CLIExecWithReturn (ctx , Cmd , argtable , true);
13881388
1389- int key_index = arg_get_int_def (ctx , 1 , 0 );
1389+ int key_index = arg_get_int_def (ctx , 1 , 3 );
13901390
13911391 CLIParserFree (ctx );
13921392 return seos_global_df (key_index );
@@ -1513,15 +1513,16 @@ static int CmdHfSeosManageKeys(const char *Cmd) {
15131513 "Manage SEOS Keys in client memory, keys are required to authenticate with SEOS cards\n" ,
15141514 "hf seos managekeys -p\n"
15151515 "hf seos managekeys -p -v\n"
1516- "hf seos managekeys --ki 0 --nonce 0102030405060708 -> Set nonce value at key index 0\n"
1517- "hf seos managekeys --load -f mykeys.bin -p -> load from file and prints keys\n"
1518- "hf seos managekeys --save -f mykeys.bin -> saves keys to file\n"
1516+ "hf seos managekeys --ki 0 --keyslot 1 -> Set keyslot value at key index 0\n"
1517+ "hf seos managekeys --ki 1 --read 0102030405060708 -> Set read key value at key index 1\n"
1518+ "hf seos managekeys --load -f mykeys.bin -p -> load from file and prints keys\n"
1519+ "hf seos managekeys --save -f mykeys.bin -> saves keys to file\n"
15191520 );
15201521
15211522 void * argtable [] = {
15221523 arg_param_begin ,
15231524 arg_int0 (NULL , "ki" , "<dec>" , "Specify key index to set key in memory" ),
1524- arg_str0 (NULL , "nonce " , "<hex >" , "Nonce value as 8 hex bytes " ),
1525+ arg_int0 (NULL , "keyslot " , "<dec >" , "Keyslot value" ),
15251526 arg_str0 (NULL , "privenc" , "<hex>" , "Privacy Encryption key as 16 hex bytes" ),
15261527 arg_str0 (NULL , "privmac" , "<hex>" , "Privacy MAC key as 16 hex bytes" ),
15271528 arg_str0 (NULL , "read" , "<hex>" , "Undiversified Read key as 16 hex bytes" ),
@@ -1542,22 +1543,20 @@ static int CmdHfSeosManageKeys(const char *Cmd) {
15421543 char filename [FILE_PATH_SIZE ] = {0 };
15431544 uint8_t operation = 0 ;
15441545
1545- uint8_t nonce [8 ] = {0 };
15461546 uint8_t privenc [16 ] = {0 };
15471547 uint8_t privmac [16 ] = {0 };
15481548 uint8_t read [16 ] = {0 };
15491549 uint8_t write [16 ] = {0 };
15501550 uint8_t admin [16 ] = {0 };
1551- int nonce_len = 0 ;
15521551 int privenc_len = 0 ;
15531552 int privmac_len = 0 ;
15541553 int read_len = 0 ;
15551554 int write_len = 0 ;
15561555 int admin_len = 0 ;
15571556
15581557 int key_index = arg_get_int_def (ctx , 1 , -1 );
1558+ int keyslot = arg_get_int_def (ctx , 2 , -1 );
15591559
1560- CLIGetHexWithReturn (ctx , 2 , nonce , & nonce_len );
15611560 CLIGetHexWithReturn (ctx , 3 , privenc , & privenc_len );
15621561 CLIGetHexWithReturn (ctx , 4 , privmac , & privmac_len );
15631562 CLIGetHexWithReturn (ctx , 5 , read , & read_len );
@@ -1569,8 +1568,8 @@ static int CmdHfSeosManageKeys(const char *Cmd) {
15691568 if (key_index >= 0 ) {
15701569 operation += 3 ;
15711570 if (key_index < 4 ) {
1572- if (nonce_len != 0 ) {
1573- PrintAndLogEx (SUCCESS , "Current value for nonce [%d] " _GREEN_ ("%s " ), key_index , sprint_hex_inrow ( keys [key_index ].nonce , 8 ) );
1571+ if (keyslot != -1 ) {
1572+ PrintAndLogEx (SUCCESS , "Current value for keyslot [%d] " _GREEN_ ("%u " ), key_index , keys [key_index ].keyslot );
15741573 }
15751574 if (privenc_len != 0 ) {
15761575 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) {
16201619 PrintAndLogEx (ERR , "You must enter a filename when loading or saving\n" );
16211620 return PM3_EINVARG ;
16221621 }
1623- if (((nonce_len > 0 ) || (privenc_len > 0 ) || (privmac_len > 0 ) || (read_len > 0 ) || (write_len > 0 ) || (admin_len > 0 )) && key_index == -1 ) {
1622+ if (((keyslot != -1 ) || (privenc_len > 0 ) || (privmac_len > 0 ) || (read_len > 0 ) || (write_len > 0 ) || (admin_len > 0 )) && key_index == -1 ) {
16241623 PrintAndLogEx (ERR , "Please specify key index when specifying key" );
16251624 return PM3_EINVARG ;
16261625 }
16271626
16281627 switch (operation ) {
16291628 case 3 :
1630- if (nonce_len != 0 ) {
1631- memcpy ( keys [key_index ].nonce , nonce , 8 ) ;
1632- PrintAndLogEx (SUCCESS , "New value for nonce [%d] " _GREEN_ ("%s " ), key_index , sprint_hex_inrow ( keys [key_index ].nonce , 8 ) );
1629+ if (keyslot != -1 ) {
1630+ keys [key_index ].keyslot = keyslot ;
1631+ PrintAndLogEx (SUCCESS , "New value for keyslot [%d] " _GREEN_ ("%u " ), key_index , keys [key_index ].keyslot );
16331632 }
16341633 if (privenc_len != 0 ) {
16351634 memcpy (keys [key_index ].privEncKey , privenc , 16 );
0 commit comments