1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) Merlok - 2017 
   4 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   5 // at your option, any later version. See the LICENSE.txt file for the text of 
   7 //----------------------------------------------------------------------------- 
   8 // Command: hf mf list. It shows data from arm buffer. 
   9 //----------------------------------------------------------------------------- 
  11 #include "cmdhflist.h" 
  21 #include "iso14443crc.h" 
  23 #include "protocols.h" 
  24 #include "crapto1/crapto1.h" 
  25 #include "mifarehost.h" 
  26 #include "mifaredefault.h" 
  39 static enum MifareAuthSeq MifareAuthState
; 
  40 static TAuthData AuthData
; 
  42 void ClearAuthData() { 
  45         AuthData
.first_auth 
= true; 
  51  * @brief iso14443A_CRC_check Checks CRC in command or response 
  55  * @return  0 : CRC-command, CRC not ok 
  56  *          1 : CRC-command, CRC ok 
  59 uint8_t iso14443A_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
) 
  63         if(len 
<= 2) return 2; 
  65         if(isResponse 
& (len 
< 6)) return 2; 
  67         ComputeCrc14443(CRC_14443_A
, data
, len
-2, &b1
, &b2
); 
  68         if (b1 
!= data
[len
-2] || b2 
!= data
[len
-1]) { 
  75 uint8_t mifare_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
) 
  77         switch(MifareAuthState
) { 
  80                         return iso14443A_CRC_check(isResponse
, data
, len
); 
  86 void annotateIso14443a(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
  90         case ISO14443A_CMD_WUPA
:         
  91                 snprintf(exp
,size
,"WUPA");  
  93         case ISO14443A_CMD_ANTICOLL_OR_SELECT
:{ 
  94                 // 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor) 
  95                 // 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK) 
  98                         snprintf(exp
,size
,"SELECT_UID"); break; 
 101                         snprintf(exp
,size
,"ANTICOLL"); break; 
 104         case ISO14443A_CMD_ANTICOLL_OR_SELECT_2
:{ 
 105                 //95 20 = Anticollision of cascade level2 
 106                 //95 70 = Select of cascade level2 
 109                         snprintf(exp
,size
,"SELECT_UID-2"); break; 
 112                         snprintf(exp
,size
,"ANTICOLL-2"); break; 
 115         case ISO14443A_CMD_REQA
:                 
 116                 snprintf(exp
,size
,"REQA");  
 118         case ISO14443A_CMD_READBLOCK
:   snprintf(exp
,size
,"READBLOCK(%d)",cmd
[1]); break; 
 119         case ISO14443A_CMD_WRITEBLOCK
:  snprintf(exp
,size
,"WRITEBLOCK(%d)",cmd
[1]); break; 
 120         case ISO14443A_CMD_HALT
:                 
 121                 snprintf(exp
,size
,"HALT");  
 122                 MifareAuthState 
= masNone
; 
 124         case ISO14443A_CMD_RATS
:                snprintf(exp
,size
,"RATS"); break; 
 125         case MIFARE_CMD_INC
:                    snprintf(exp
,size
,"INC(%d)",cmd
[1]); break; 
 126         case MIFARE_CMD_DEC
:                    snprintf(exp
,size
,"DEC(%d)",cmd
[1]); break; 
 127         case MIFARE_CMD_RESTORE
:                snprintf(exp
,size
,"RESTORE(%d)",cmd
[1]); break; 
 128         case MIFARE_CMD_TRANSFER
:               snprintf(exp
,size
,"TRANSFER(%d)",cmd
[1]); break; 
 129         case MIFARE_AUTH_KEYA
: 
 131                         snprintf(exp
,size
,"AUTH-A(%d)",cmd
[1]);  
 132                         MifareAuthState 
= masNt
; 
 134                         //      case MIFARE_ULEV1_VERSION :  both 0x60. 
 135                         snprintf(exp
,size
,"EV1 VERSION"); 
 138         case MIFARE_AUTH_KEYB
: 
 139                 MifareAuthState 
= masNt
; 
 140                 snprintf(exp
,size
,"AUTH-B(%d)",cmd
[1]);  
 142         case MIFARE_MAGICWUPC1
:                 snprintf(exp
,size
,"MAGIC WUPC1"); break; 
 143         case MIFARE_MAGICWUPC2
:                 snprintf(exp
,size
,"MAGIC WUPC2"); break; 
 144         case MIFARE_MAGICWIPEC
:                 snprintf(exp
,size
,"MAGIC WIPEC"); break; 
 145         case MIFARE_ULC_AUTH_1
:         snprintf(exp
,size
,"AUTH "); break; 
 146         case MIFARE_ULC_AUTH_2
:         snprintf(exp
,size
,"AUTH_ANSW"); break; 
 147         case MIFARE_ULEV1_AUTH
: 
 149                         snprintf(exp
,size
,"PWD-AUTH KEY: 0x%02x%02x%02x%02x", cmd
[1], cmd
[2], cmd
[3], cmd
[4] ); 
 151                         snprintf(exp
,size
,"PWD-AUTH"); 
 153         case MIFARE_ULEV1_FASTREAD
:{ 
 154                 if ( cmdsize 
>=3 && cmd
[2] <= 0xE6) 
 155                         snprintf(exp
,size
,"READ RANGE (%d-%d)",cmd
[1],cmd
[2]);  
 157                         snprintf(exp
,size
,"?"); 
 160         case MIFARE_ULC_WRITE
:{ 
 162                         snprintf(exp
,size
,"WRITEBLOCK(%d)",cmd
[1]);  
 164                         snprintf(exp
,size
,"?"); 
 167         case MIFARE_ULEV1_READ_CNT
:{ 
 169                         snprintf(exp
,size
,"READ CNT(%d)",cmd
[1]); 
 171                         snprintf(exp
,size
,"?"); 
 174         case MIFARE_ULEV1_INCR_CNT
:{ 
 176                         snprintf(exp
,size
,"INCR(%d)",cmd
[1]); 
 178                         snprintf(exp
,size
,"?"); 
 181         case MIFARE_ULEV1_READSIG
:              snprintf(exp
,size
,"READ_SIG"); break; 
 182         case MIFARE_ULEV1_CHECKTEAR
:    snprintf(exp
,size
,"CHK_TEARING(%d)",cmd
[1]); break; 
 183         case MIFARE_ULEV1_VCSL
:         snprintf(exp
,size
,"VCSL"); break; 
 184         default:                                                snprintf(exp
,size
,"?"); break; 
 189 void annotateMifare(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
, uint8_t* parity
, uint8_t paritysize
, bool isResponse
) { 
 190         if (!isResponse 
&& cmdsize 
== 1) { 
 192                         case ISO14443A_CMD_WUPA
:         
 193                         case ISO14443A_CMD_REQA
:                 
 194                                 MifareAuthState 
= masNone
; 
 202         if (MifareAuthState 
== masNone
) { 
 203                 if (cmdsize 
== 9 && cmd
[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT 
&& cmd
[1] == 0x70) { 
 205                         AuthData
.uid 
= bytes_to_num(&cmd
[2], 4); 
 207                 if (cmdsize 
== 9 && cmd
[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 
&& cmd
[1] == 0x70) { 
 209                         AuthData
.uid 
= bytes_to_num(&cmd
[2], 4); 
 213         switch(MifareAuthState
) { 
 215                         if (cmdsize 
== 4 && isResponse
) { 
 216                                 snprintf(exp
,size
,"AUTH: nt %s", (AuthData
.first_auth
) ? "" : "(enc)"); 
 217                                 MifareAuthState 
= masNrAr
; 
 218                                 if (AuthData
.first_auth
) 
 219                                         AuthData
.nt 
= bytes_to_num(cmd
, 4); 
 221                                         AuthData
.nt_enc 
= bytes_to_num(cmd
, 4); 
 222                                         AuthData
.nt_enc_par 
= parity
[0]; 
 225                                 MifareAuthState 
= masError
; 
 229                         if (cmdsize 
== 8 && !isResponse
) { 
 230                                 snprintf(exp
,size
,"AUTH: nr ar (enc)"); 
 231                                 MifareAuthState 
= masAt
; 
 232                                 AuthData
.nr_enc 
= bytes_to_num(cmd
, 4); 
 233                                 AuthData
.ar_enc 
= bytes_to_num(&cmd
[4], 4); 
 234                                 AuthData
.ar_enc_par 
= parity
[0] << 4; 
 237                                 MifareAuthState 
= masError
; 
 241                         if (cmdsize 
== 4 && isResponse
) { 
 242                                 snprintf(exp
,size
,"AUTH: at (enc)"); 
 243                                 MifareAuthState 
= masAuthComplete
; 
 244                                 AuthData
.at_enc 
= bytes_to_num(cmd
, 4); 
 245                                 AuthData
.at_enc_par 
= parity
[0]; 
 248                                 MifareAuthState 
= masError
; 
 255         if (!isResponse 
&& ((MifareAuthState 
== masNone
) || (MifareAuthState 
== masError
))) 
 256                 annotateIso14443a(exp
, size
, cmd
, cmdsize
); 
 260 bool DecodeMifareData(uint8_t *cmd
, uint8_t cmdsize
, uint8_t *parity
, bool isResponse
, uint8_t *mfData
, size_t *mfDataLen
) { 
 261         static struct Crypto1State 
*traceCrypto1
;        
 262         static uint64_t mfLastKey
; 
 266         if (MifareAuthState 
== masAuthComplete
) { 
 268                         crypto1_destroy(traceCrypto1
); 
 271                 MifareAuthState 
= masFirstData
; 
 278         if (MifareAuthState 
== masFirstData
) { 
 279                 if (AuthData
.first_auth
) { 
 280                         AuthData
.ks2 
= AuthData
.ar_enc 
^ prng_successor(AuthData
.nt
, 64); 
 281                         AuthData
.ks3 
= AuthData
.at_enc 
^ prng_successor(AuthData
.nt
, 96); 
 282                         struct Crypto1State 
*revstate 
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
); 
 283                         lfsr_rollback_word(revstate
, 0, 0); 
 284                         lfsr_rollback_word(revstate
, 0, 0); 
 285                         lfsr_rollback_word(revstate
, AuthData
.nr_enc
, 1); 
 286                         lfsr_rollback_word(revstate
, AuthData
.uid 
^ AuthData
.nt
, 0); 
 289                         crypto1_get_lfsr(revstate
, &lfsr
); 
 290                         crypto1_destroy(revstate
); 
 292                         PrintAndLog("            |          * | key | probable key:%x%x Prng:%s   ks2:%08x ks3:%08x |     |",  
 293                                 (unsigned int)((lfsr 
& 0xFFFFFFFF00000000) >> 32),  
 294                                 (unsigned int)(lfsr 
& 0xFFFFFFFF),  
 295                                 validate_prng_nonce(AuthData
.nt
) ? "WEAK": "HARD", 
 299                         AuthData
.first_auth 
= false; 
 301                         traceCrypto1 
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
); 
 303                         // check last used key 
 305                                 if (NestedCheckKey(mfLastKey
, &AuthData
, cmd
, cmdsize
, parity
)) { 
 306                                         PrintAndLog("            |          * | key | last used key:%x%x            ks2:%08x ks3:%08x |     |",  
 307                                                 (unsigned int)((mfLastKey 
& 0xFFFFFFFF00000000) >> 32),  
 308                                                 (unsigned int)(mfLastKey 
& 0xFFFFFFFF), 
 312                                 traceCrypto1 
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
); 
 316                         // check default keys 
 318                                 for (int defaultKeyCounter 
= 0; defaultKeyCounter 
< MifareDefaultKeysSize
; defaultKeyCounter
++){ 
 319                                         if (NestedCheckKey(MifareDefaultKeys
[defaultKeyCounter
], &AuthData
, cmd
, cmdsize
, parity
)) { 
 320                                                 PrintAndLog("            |          * | key | default key:%x%x              ks2:%08x ks3:%08x |     |",  
 321                                                         (unsigned int)((MifareDefaultKeys
[defaultKeyCounter
] & 0xFFFFFFFF00000000) >> 32),  
 322                                                         (unsigned int)(MifareDefaultKeys
[defaultKeyCounter
] & 0xFFFFFFFF), 
 326                                                 traceCrypto1 
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
); 
 333                         if (!traceCrypto1 
&& validate_prng_nonce(AuthData
.nt
)) { 
 334 printf("nested. uid:%x nt:%x ar_enc:%x at_enc:%x\n", AuthData
.uid
, AuthData
.nt
, AuthData
.ar_enc
, AuthData
.at_enc
); 
 335                                 uint32_t ntx 
= prng_successor(AuthData
.nt
, 90); 
 336                                 for (int i 
= 0; i 
< 16383; i
++) { 
 337                                         ntx 
= prng_successor(ntx
, 1); 
 338                                         if (NTParityChk(&AuthData
, ntx
)){ 
 340                                                 uint32_t ks2 
= AuthData
.ar_enc 
^ prng_successor(ntx
, 64); 
 341                                                 uint32_t ks3 
= AuthData
.at_enc 
^ prng_successor(ntx
, 96); 
 342                                                 struct Crypto1State 
*pcs 
= lfsr_recovery64(ks2
, ks3
); 
 343                                                 memcpy(mfData
, cmd
, cmdsize
); 
 344                                                 mf_crypto1_decrypt(pcs
, mfData
, cmdsize
, 0); 
 346                                                 crypto1_destroy(pcs
); 
 347                                                 if (CheckCrc14443(CRC_14443_A
, mfData
, cmdsize
)) { 
 350                                                         traceCrypto1 
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
); 
 356                                         printf("key> nt=%08x nonce distance=%d \n", ntx
, nonce_distance(AuthData
.nt
, ntx
)); 
 358                                         printf("key> don't have any valid nt( \n");                                      
 363                                 printf("hardnested not implemented. uid:%x nt:%x ar_enc:%x at_enc:%x\n", AuthData
.uid
, AuthData
.nt
, AuthData
.ar_enc
, AuthData
.at_enc
); 
 369                 MifareAuthState 
= masData
; 
 372         if (MifareAuthState 
== masData 
&& traceCrypto1
) { 
 373                 memcpy(mfData
, cmd
, cmdsize
); 
 374                 mf_crypto1_decrypt(traceCrypto1
, mfData
, cmdsize
, 0); 
 375                 *mfDataLen 
= cmdsize
; 
 378         return *mfDataLen 
> 0; 
 381 bool NTParityChk(TAuthData 
*ad
, uint32_t ntx
) { 
 383                 (oddparity8(ntx 
>> 8 & 0xff) ^ (ntx 
& 0x01) ^ ((ad
->nt_enc_par 
>> 5) & 0x01) ^ (ad
->nt_enc 
& 0x01)) || 
 384                 (oddparity8(ntx 
>> 16 & 0xff) ^ (ntx 
>> 8 & 0x01) ^ ((ad
->nt_enc_par 
>> 6) & 0x01) ^ (ad
->nt_enc 
>> 8 & 0x01)) || 
 385                 (oddparity8(ntx 
>> 24 & 0xff) ^ (ntx 
>> 16 & 0x01) ^ ((ad
->nt_enc_par 
>> 7) & 0x01) ^ (ad
->nt_enc 
>> 16 & 0x01)) 
 389         uint32_t ar 
= prng_successor(ntx
, 64); 
 391                 (oddparity8(ar 
>> 8 & 0xff) ^ (ar 
& 0x01) ^ ((ad
->ar_enc_par 
>> 5) & 0x01) ^ (ad
->ar_enc 
& 0x01)) || 
 392                 (oddparity8(ar 
>> 16 & 0xff) ^ (ar 
>> 8 & 0x01) ^ ((ad
->ar_enc_par 
>> 6) & 0x01) ^ (ad
->ar_enc 
>> 8 & 0x01)) || 
 393                 (oddparity8(ar 
>> 24 & 0xff) ^ (ar 
>> 16 & 0x01) ^ ((ad
->ar_enc_par 
>> 7) & 0x01) ^ (ad
->ar_enc 
>> 16 & 0x01)) 
 397         uint32_t at 
= prng_successor(ntx
, 96); 
 399                 (oddparity8(ar 
& 0xff) ^ (at 
>> 24 & 0x01) ^ ((ad
->ar_enc_par 
>> 4) & 0x01) ^ (ad
->at_enc 
>> 24 & 0x01)) || 
 400                 (oddparity8(at 
>> 8 & 0xff) ^ (at 
& 0x01) ^ ((ad
->at_enc_par 
>> 5) & 0x01) ^ (ad
->at_enc 
& 0x01)) || 
 401                 (oddparity8(at 
>> 16 & 0xff) ^ (at 
>> 8 & 0x01) ^ ((ad
->at_enc_par 
>> 6) & 0x01) ^ (ad
->at_enc 
>> 8 & 0x01)) || 
 402                 (oddparity8(at 
>> 24 & 0xff) ^ (at 
>> 16 & 0x01) ^ ((ad
->at_enc_par 
>> 7) & 0x01) ^ (ad
->at_enc 
>> 16 & 0x01)) 
 409 bool NestedCheckKey(uint64_t key
, TAuthData 
*ad
, uint8_t *cmd
, uint8_t cmdsize
, uint8_t *parity
) { 
 410         uint8_t buf
[32] = {0}; 
 411         struct Crypto1State 
*pcs
; 
 416         pcs 
= crypto1_create(key
); 
 417         uint32_t nt1 
= crypto1_word(pcs
, ad
->nt_enc 
^ ad
->uid
, 1) ^ ad
->nt_enc
; 
 418         uint32_t ar 
= prng_successor(nt1
, 64); 
 419         uint32_t at 
= prng_successor(nt1
, 96); 
 421         crypto1_word(pcs
, ad
->nr_enc
, 1); 
 422 //      uint32_t nr1 = crypto1_word(pcs, ad->nr_enc, 1) ^ ad->nr_enc;  // if needs deciphered nr 
 423         uint32_t ar1 
= crypto1_word(pcs
, 0, 0) ^ ad
->ar_enc
; 
 424         uint32_t at1 
= crypto1_word(pcs
, 0, 0) ^ ad
->at_enc
; 
 426         if (!(ar 
== ar1 
&& at 
== at1 
&& NTParityChk(ad
, nt1
))) 
 429         memcpy(buf
, cmd
, cmdsize
); 
 430         mf_crypto1_decrypt(pcs
, buf
, cmdsize
, 0); 
 432         crypto1_destroy(pcs
); 
 434         if (!CheckCrypto1Parity(cmd
, cmdsize
, buf
, parity
)) 
 437         if(!CheckCrc14443(CRC_14443_A
, buf
, cmdsize
))  
 440         AuthData
.ks2 
= AuthData
.ar_enc 
^ ar
; 
 441         AuthData
.ks3 
= AuthData
.at_enc 
^ at
; 
 446 bool CheckCrypto1Parity(uint8_t *cmd_enc
, uint8_t cmdsize
, uint8_t *cmd
, uint8_t *parity_enc
) { 
 448         oddparitybuf(cmd
, cmdsize
, parity
); 
 449         printf("parity check. size=%d\n", cmdsize
); 
 450         printf("cmd    =%s\n", sprint_hex(cmd
, cmdsize
)); 
 451         printf("cmd_enc=%s\n", sprint_hex(cmd_enc
, cmdsize
)); 
 452         printf("parity    =%s\n", printBitsPar(parity
, cmdsize
)); 
 453         printf("parity_enc=%s\n", printBitsPar(parity_enc
, cmdsize
)); 
 454 //      (oddparity8(ntx >> 8 & 0xff) ^ (ntx & 0x01) ^ ((ad->nt_enc_par >> 5) & 0x01) ^ (ad->nt_enc & 0x01)) || 
 455 //      (oddparity8(ntx >> 24 & 0xff) ^ (ntx >> 16 & 0x01) ^ ((ad->nt_enc_par >> 7) & 0x01) ^ (ad->nt_enc >> 16 & 0x01)) 
 456         for (int i 
= 0; i 
< cmdsize 
- 1; i
++) { 
 457                 bool b 
= oddparity8(cmd
[i
]) ^ (cmd
[i 
+ 1] & 0x01) ^ ((parity_enc
[i 
/ 8] >> (7 - i 
% 8)) & 0x01) ^ (cmd_enc
[i 
+ 1] & 0x01); 
 459                         printf("!!! i=%d \n", i
);