]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/mifarehost.c
   2 // people from mifare@nethemba.com, 2010 
   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 //----------------------------------------------------------------------------- 
   9 //----------------------------------------------------------------------------- 
  11 #include "mifarehost.h" 
  14 extern int compar_int(const void * a
, const void * b
) { 
  15         // didn't work: (the result is truncated to 32 bits) 
  16         //return (*(uint64_t*)b - *(uint64_t*)a); 
  19         if (*(uint64_t*)b 
> *(uint64_t*)a
) return 1; 
  20         if (*(uint64_t*)b 
< *(uint64_t*)a
) return -1;    
  23         //return (*(uint64_t*)b > *(uint64_t*)a) - (*(uint64_t*)b < *(uint64_t*)a); 
  26 // Compare 16 Bits out of cryptostate 
  27 int Compare16Bits(const void * a
, const void * b
) { 
  28          if ((*(uint64_t*)b 
& 0x00ff000000ff0000) > (*(uint64_t*)a 
& 0x00ff000000ff0000)) return 1;      
  29          if ((*(uint64_t*)b 
& 0x00ff000000ff0000) < (*(uint64_t*)a 
& 0x00ff000000ff0000)) return -1; 
  33                 ((*(uint64_t*)b & 0x00ff000000ff0000) > (*(uint64_t*)a & 0x00ff000000ff0000)) 
  35                 ((*(uint64_t*)b & 0x00ff000000ff0000) < (*(uint64_t*)a & 0x00ff000000ff0000)) 
  40 // wrapper function for multi-threaded lfsr_recovery32 
  41 void* nested_worker_thread(void *arg
) 
  43         struct Crypto1State 
*p1
; 
  44         StateList_t 
*statelist 
= arg
; 
  45         statelist
->head
.slhead 
= lfsr_recovery32(statelist
->ks1
, statelist
->nt 
^ statelist
->uid
);        
  47         for (p1 
= statelist
->head
.slhead
; *(uint64_t *)p1 
!= 0; p1
++); 
  49         statelist
->len 
= p1 
- statelist
->head
.slhead
; 
  50         statelist
->tail
.sltail 
= --p1
; 
  51         qsort(statelist
->head
.slhead
, statelist
->len
, sizeof(uint64_t), Compare16Bits
); 
  52         return statelist
->head
.slhead
; 
  55 int mfnested(uint8_t blockNo
, uint8_t keyType
, uint8_t * key
, uint8_t trgBlockNo
, uint8_t trgKeyType
, uint8_t * resultKey
, bool calibrate
)  
  60         StateList_t statelists
[2]; 
  61         struct Crypto1State 
*p1
, *p2
, *p3
, *p4
; 
  63         UsbCommand c 
= {CMD_MIFARE_NESTED
, {blockNo 
+ keyType 
* 0x100, trgBlockNo 
+ trgKeyType 
* 0x100, calibrate
}}; 
  64         memcpy(c
.d
.asBytes
, key
, 6); 
  67         if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) return -1; 
  69         // error during nested 
  70         if (resp
.arg
[0]) return resp
.arg
[0]; 
  72         memcpy(&uid
, resp
.d
.asBytes
, 4); 
  74         for (i 
= 0; i 
< 2; i
++) { 
  75                 statelists
[i
].blockNo 
= resp
.arg
[2] & 0xff; 
  76                 statelists
[i
].keyType 
= (resp
.arg
[2] >> 8) & 0xff; 
  77                 statelists
[i
].uid 
= uid
; 
  78                 memcpy(&statelists
[i
].nt
,  (void *)(resp
.d
.asBytes 
+ 4 + i 
* 8 + 0), 4); 
  79                 memcpy(&statelists
[i
].ks1
, (void *)(resp
.d
.asBytes 
+ 4 + i 
* 8 + 4), 4); 
  83         pthread_t thread_id
[2]; 
  85         // create and run worker threads 
  86         for (i 
= 0; i 
< 2; i
++) 
  87                 pthread_create(thread_id 
+ i
, NULL
, nested_worker_thread
, &statelists
[i
]); 
  89         // wait for threads to terminate: 
  90         for (i 
= 0; i 
< 2; i
++) 
  91                 pthread_join(thread_id
[i
], (void*)&statelists
[i
].head
.slhead
); 
  93         // the first 16 Bits of the cryptostate already contain part of our key. 
  94         // Create the intersection of the two lists based on these 16 Bits and 
  95         // roll back the cryptostate 
  96         p1 
= p3 
= statelists
[0].head
.slhead
;  
  97         p2 
= p4 
= statelists
[1].head
.slhead
; 
  99         while (p1 
<= statelists
[0].tail
.sltail 
&& p2 
<= statelists
[1].tail
.sltail
) { 
 100                 if (Compare16Bits(p1
, p2
) == 0) { 
 102                         struct Crypto1State savestate
, *savep 
= &savestate
; 
 104                         while(Compare16Bits(p1
, savep
) == 0 && p1 
<= statelists
[0].tail
.sltail
) { 
 106                                 lfsr_rollback_word(p3
, statelists
[0].nt 
^ statelists
[0].uid
, 0); 
 111                         while(Compare16Bits(p2
, savep
) == 0 && p2 
<= statelists
[1].tail
.sltail
) { 
 113                                 lfsr_rollback_word(p4
, statelists
[1].nt 
^ statelists
[1].uid
, 0); 
 119                         while (Compare16Bits(p1
, p2
) == -1) p1
++; 
 120                         while (Compare16Bits(p1
, p2
) == 1) p2
++; 
 124         p3
->even 
= 0; p3
->odd 
= 0; 
 125         p4
->even 
= 0; p4
->odd 
= 0; 
 126         statelists
[0].len 
= p3 
- statelists
[0].head
.slhead
; 
 127         statelists
[1].len 
= p4 
- statelists
[1].head
.slhead
; 
 128         statelists
[0].tail
.sltail 
= --p3
; 
 129         statelists
[1].tail
.sltail 
= --p4
; 
 131         // the statelists now contain possible keys. The key we are searching for must be in the 
 132         // intersection of both lists. Create the intersection: 
 133         qsort(statelists
[0].head
.keyhead
, statelists
[0].len
, sizeof(uint64_t), compar_int
); 
 134         qsort(statelists
[1].head
.keyhead
, statelists
[1].len
, sizeof(uint64_t), compar_int
); 
 136         uint64_t *p5
, *p6
, *p7
; 
 137         p5 
= p7 
= statelists
[0].head
.keyhead
;  
 138         p6 
= statelists
[1].head
.keyhead
; 
 140         while (p5 
<= statelists
[0].tail
.keytail 
&& p6 
<= statelists
[1].tail
.keytail
) { 
 141                 if (compar_int(p5
, p6
) == 0) { 
 146                         while (compar_int(p5
, p6
) == -1) p5
++; 
 147                         while (compar_int(p5
, p6
) == 1) p6
++; 
 150         statelists
[0].len 
= p7 
- statelists
[0].head
.keyhead
; 
 151         statelists
[0].tail
.keytail 
= --p7
; 
 153         uint32_t numOfCandidates 
= statelists
[0].len
; 
 154         if ( numOfCandidates 
== 0 ) goto out
; 
 156         memset(resultKey
, 0, 6); 
 159         // The list may still contain several key candidates. Test each of them with mfCheckKeys 
 160         // uint32_t max_keys = keycnt > (USB_CMD_DATA_SIZE/6) ? (USB_CMD_DATA_SIZE/6) : keycnt; 
 161         uint8_t keyBlock
[USB_CMD_DATA_SIZE
] = {0x00}; 
 163         for (i 
= 0; i 
< numOfCandidates
; ++i
){ 
 164                 crypto1_get_lfsr(statelists
[0].head
.slhead 
+ i
, &key64
); 
 165                 num_to_bytes(key64
, 6, keyBlock 
+ i 
* 6); 
 168         if (!mfCheckKeys(statelists
[0].blockNo
, statelists
[0].keyType
, false, numOfCandidates
, keyBlock
, &key64
)) {              
 169                 free(statelists
[0].head
.slhead
); 
 170                 free(statelists
[1].head
.slhead
); 
 171                 num_to_bytes(key64
, 6, resultKey
); 
 173                 PrintAndLog("UID: %08x target block:%3u key type: %c  -- Found key [%012"llx
"]", 
 175                         (uint16_t)resp
.arg
[2] & 0xff, 
 176                         (resp
.arg
[2] >> 8) ? 'B' : 'A', 
 183         PrintAndLog("UID: %08x target block:%3u key type: %c", 
 185                         (uint16_t)resp
.arg
[2] & 0xff, 
 186                         (resp
.arg
[2] >> 8) ? 'B' : 'A' 
 189         free(statelists
[0].head
.slhead
); 
 190         free(statelists
[1].head
.slhead
); 
 194 int mfCheckKeys (uint8_t blockNo
, uint8_t keyType
, bool clear_trace
, uint8_t keycnt
, uint8_t * keyBlock
, uint64_t * key
){ 
 196         UsbCommand c 
= {CMD_MIFARE_CHKKEYS
, { (blockNo 
| (keyType
<<8)), clear_trace
, keycnt
}}; 
 197         memcpy(c
.d
.asBytes
, keyBlock
, 6 * keycnt
); 
 198         clearCommandBuffer(); 
 201         if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 2500)) return 1; 
 202         if ((resp
.arg
[0] & 0xff) != 0x01) return 2; 
 203         *key 
= bytes_to_num(resp
.d
.asBytes
, 6); 
 206 // PM3 imp of J-Run mf_key_brute (part 2) 
 207 // ref: https://github.com/J-Run/mf_key_brute 
 208 int mfKeyBrute(uint8_t blockNo
, uint8_t keyType
, uint8_t *key
, uint64_t *resultkey
){ 
 210         #define KEYS_IN_BLOCK 85 
 211         #define KEYBLOCK_SIZE 510 
 212         #define CANDIDATE_SIZE 0xFFFF * 6 
 213         uint8_t found 
= FALSE
; 
 215         uint8_t candidates
[CANDIDATE_SIZE
] = {0x00}; 
 216         uint8_t keyBlock
[KEYBLOCK_SIZE
] = {0x00}; 
 218         memset(candidates
, 0, sizeof(candidates
)); 
 219         memset(keyBlock
, 0, sizeof(keyBlock
)); 
 221         // Generate all possible keys for the first two unknown bytes. 
 222         for (uint16_t i 
= 0; i 
< 0xFFFF; ++i
) {          
 224                 candidates
[0 + j
] = i 
>> 8;      
 225                 candidates
[1 + j
] = i
; 
 226                 candidates
[2 + j
] = key
[2]; 
 227                 candidates
[3 + j
] = key
[3]; 
 228                 candidates
[4 + j
] = key
[4]; 
 229                 candidates
[5 + j
] = key
[5]; 
 232         for ( i 
= 0, counter 
= 1; i 
< CANDIDATE_SIZE
; i 
+= KEYBLOCK_SIZE
, ++counter
){ 
 236                 // copy candidatekeys to test key block 
 237                 memcpy(keyBlock
, candidates 
+ i
, KEYBLOCK_SIZE
); 
 239                 // check a block of generated candidate keys. 
 240                 if (!mfCheckKeys(blockNo
, keyType
, TRUE
, KEYS_IN_BLOCK
, keyBlock
, &key64
)) { 
 247                 if ( counter 
% 20 == 0 ) 
 248                         PrintAndLog("tried : %s.. \t %u keys", sprint_hex(candidates 
+ i
, 6),  counter 
* KEYS_IN_BLOCK  
); 
 254 int mfEmlGetMem(uint8_t *data
, int blockNum
, int blocksCount
) { 
 255         UsbCommand c 
= {CMD_MIFARE_EML_MEMGET
, {blockNum
, blocksCount
, 0}}; 
 256         clearCommandBuffer(); 
 259         if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) return 1; 
 260         memcpy(data
, resp
.d
.asBytes
, blocksCount 
* 16); 
 264 int mfEmlSetMem(uint8_t *data
, int blockNum
, int blocksCount
) { 
 265         return mfEmlSetMem_xt(data
, blockNum
, blocksCount
, 16); 
 268 int mfEmlSetMem_xt(uint8_t *data
, int blockNum
, int blocksCount
, int blockBtWidth
) { 
 269         UsbCommand c 
= {CMD_MIFARE_EML_MEMSET
, {blockNum
, blocksCount
, blockBtWidth
}}; 
 270         memcpy(c
.d
.asBytes
, data
, blocksCount 
* blockBtWidth
);  
 271         clearCommandBuffer(); 
 277 int mfCSetUID(uint8_t *uid
, uint8_t *atqa
, uint8_t *sak
, uint8_t *oldUID
, uint8_t wipecard
) { 
 279         uint8_t params 
= MAGIC_SINGLE
; 
 281         memset(block0
, 0x00, sizeof(block0
)); 
 283         int old 
= mfCGetBlock(0, block0
, params
); 
 285                 PrintAndLog("old block 0:  %s", sprint_hex(block0
, sizeof(block0
))); 
 287                 PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0.");        
 289         // fill in the new values 
 291         memcpy(block0
, uid
, 4);  
 293         block0
[4] = block0
[0]^block0
[1]^block0
[2]^block0
[3]; 
 294         // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed) 
 298         if ( atqa 
!= NULL 
) { 
 302         PrintAndLog("new block 0:  %s", sprint_hex(block0
,16)); 
 304         if ( wipecard 
)          params 
|= MAGIC_WIPE
;   
 305         if ( oldUID 
== NULL
) params 
|= MAGIC_UID
; 
 307         return mfCSetBlock(0, block0
, oldUID
, params
); 
 310 int mfCSetBlock(uint8_t blockNo
, uint8_t *data
, uint8_t *uid
, uint8_t params
) { 
 313         UsbCommand c 
= {CMD_MIFARE_CSETBLOCK
, {params
, blockNo
, 0}}; 
 314         memcpy(c
.d
.asBytes
, data
, 16);  
 315         clearCommandBuffer(); 
 318         if (WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) { 
 319                 isOK  
= resp
.arg
[0] & 0xff; 
 321                         memcpy(uid
, resp
.d
.asBytes
, 4); 
 325                 PrintAndLog("Command execute timeout"); 
 331 int mfCGetBlock(uint8_t blockNo
, uint8_t *data
, uint8_t params
) { 
 333         UsbCommand c 
= {CMD_MIFARE_CGETBLOCK
, {params
, blockNo
, 0}};     
 334         clearCommandBuffer(); 
 337         if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) { 
 338                 isOK  
= resp
.arg
[0] & 0xff; 
 339                 memcpy(data
, resp
.d
.asBytes
, 16); 
 342                 PrintAndLog("Command execute timeout"); 
 349 // [iceman] so many global variables.... 
 352 static uint8_t trailerAccessBytes
[4] = {0x08, 0x77, 0x8F, 0x00}; 
 355 char logHexFileName
[FILE_PATH_SIZE
] = {0x00}; 
 356 static uint8_t traceCard
[4096] = {0x00}; 
 357 static char traceFileName
[FILE_PATH_SIZE
] = {0x00}; 
 358 static int traceState 
= TRACE_IDLE
; 
 359 static uint8_t traceCurBlock 
= 0; 
 360 static uint8_t traceCurKey 
= 0; 
 362 struct Crypto1State 
*traceCrypto1 
= NULL
; 
 363 struct Crypto1State 
*revstate 
= NULL
; 
 368 uint32_t cuid 
= 0;    // serial number 
 369 uint32_t nt 
=0;      // tag challenge 
 370 uint32_t nr_enc 
=0;  // encrypted reader challenge 
 371 uint32_t ar_enc 
=0;  // encrypted reader response 
 372 uint32_t at_enc 
=0;  // encrypted tag response 
 374 int isTraceCardEmpty(void) { 
 375         return ((traceCard
[0] == 0) && (traceCard
[1] == 0) && (traceCard
[2] == 0) && (traceCard
[3] == 0)); 
 378 int isBlockEmpty(int blockN
) { 
 379         for (int i 
= 0; i 
< 16; i
++)  
 380                 if (traceCard
[blockN 
* 16 + i
] != 0) return 0; 
 385 int isBlockTrailer(int blockN
) { 
 386         return ((blockN 
& 0x03) == 0x03); 
 389 int loadTraceCard(uint8_t *tuid
, uint8_t uidlen
) { 
 391         char buf
[64] = {0x00}; 
 392         uint8_t buf8
[64] = {0x00}; 
 395         if (!isTraceCardEmpty())  
 398         memset(traceCard
, 0x00, 4096); 
 399         memcpy(traceCard
, tuid
, uidlen
); 
 401         FillFileNameByUID(traceFileName
, tuid
, ".eml", uidlen
); 
 403         f 
= fopen(traceFileName
, "r"); 
 410                 memset(buf
, 0, sizeof(buf
)); 
 411                 if (fgets(buf
, sizeof(buf
), f
) == NULL
) { 
 412                         PrintAndLog("No trace file found or reading error."); 
 420                 if (strlen(buf
) < 32){ 
 422                         PrintAndLog("File content error. Block data must include 32 HEX symbols"); 
 429                 for (i 
= 0; i 
< 32; i 
+= 2) 
 430                         sscanf(&buf
[i
], "%02X", (unsigned int *)&buf8
[i 
/ 2]); 
 432                 memcpy(traceCard 
+ blockNum 
* 16, buf8
, 16); 
 443 int saveTraceCard(void) { 
 445         if ((!strlen(traceFileName
)) || (isTraceCardEmpty())) return 0; 
 448         f 
= fopen(traceFileName
, "w+"); 
 451         for (int i 
= 0; i 
< 64; i
++) {  // blocks 
 452                 for (int j 
= 0; j 
< 16; j
++)  // bytes 
 453                         fprintf(f
, "%02X", *(traceCard 
+ i 
* 16 + j
));  
 464 int mfTraceInit(uint8_t *tuid
, uint8_t uidlen
, uint8_t *atqa
, uint8_t sak
, bool wantSaveToEmlFile
) { 
 467                 crypto1_destroy(traceCrypto1
); 
 471         if (wantSaveToEmlFile
)  
 472                 loadTraceCard(tuid
, uidlen
); 
 474         traceCard
[4] = traceCard
[0] ^ traceCard
[1] ^ traceCard
[2] ^ traceCard
[3]; 
 476         memcpy(&traceCard
[6], atqa
, 2); 
 478         cuid 
= bytes_to_num(tuid
+(uidlen
-4), 4); 
 479         traceState 
= TRACE_IDLE
; 
 483 void mf_crypto1_decrypt(struct Crypto1State 
*pcs
, uint8_t *data
, int len
, bool isEncrypted
){ 
 488                 for (i 
= 0; i 
< len
; i
++) 
 489                         data
[i
] = crypto1_byte(pcs
, 0x00, isEncrypted
) ^ data
[i
]; 
 492                 bt 
|= (crypto1_bit(pcs
, 0, isEncrypted
) ^ BIT(data
[0], 0)) << 0; 
 493                 bt 
|= (crypto1_bit(pcs
, 0, isEncrypted
) ^ BIT(data
[0], 1)) << 1; 
 494                 bt 
|= (crypto1_bit(pcs
, 0, isEncrypted
) ^ BIT(data
[0], 2)) << 2; 
 495                 bt 
|= (crypto1_bit(pcs
, 0, isEncrypted
) ^ BIT(data
[0], 3)) << 3;                         
 501 int mfTraceDecode(uint8_t *data_src
, int len
, bool wantSaveToEmlFile
) { 
 503         if (traceState 
== TRACE_ERROR
) return 1; 
 506                 traceState 
= TRACE_ERROR
; 
 511         memset(data
, 0x00, sizeof(data
)); 
 513         memcpy(data
, data_src
, len
); 
 515         if ((traceCrypto1
) && ((traceState 
== TRACE_IDLE
) || (traceState 
> TRACE_AUTH_OK
))) { 
 516                 mf_crypto1_decrypt(traceCrypto1
, data
, len
, 0); 
 517                 PrintAndLog("DEC| %s", sprint_hex(data
, len
)); 
 518                 AddLogHex(logHexFileName
, "DEC| ", data
, len
);  
 521         switch (traceState
) { 
 523                 // check packet crc16! 
 524                 if ((len 
>= 4) && (!CheckCrc14443(CRC_14443_A
, data
, len
))) { 
 525                         PrintAndLog("DEC| CRC ERROR!!!"); 
 526                         AddLogLine(logHexFileName
, "DEC| ", "CRC ERROR!!!");  
 527                         traceState 
= TRACE_ERROR
;  // do not decrypt the next commands 
 532                 if ((len 
== 4) && ((data
[0] == MIFARE_AUTH_KEYA
) || (data
[0] == MIFARE_AUTH_KEYB
))) { 
 533                         traceState 
= TRACE_AUTH1
; 
 534                         traceCurBlock 
= data
[1]; 
 535                         traceCurKey 
= data
[0] == 60 ? 1:0; 
 540                 if ((len 
==4) && ((data
[0] == ISO14443A_CMD_READBLOCK
))) { 
 541                         traceState 
= TRACE_READ_DATA
; 
 542                         traceCurBlock 
= data
[1]; 
 547                 if ((len 
==4) && ((data
[0] == ISO14443A_CMD_WRITEBLOCK
))) { 
 548                         traceState 
= TRACE_WRITE_OK
; 
 549                         traceCurBlock 
= data
[1]; 
 554                 if ((len 
==4) && ((data
[0] == ISO14443A_CMD_HALT
) && (data
[1] == 0x00))) { 
 555                         traceState 
= TRACE_ERROR
;  // do not decrypt the next commands 
 559         case TRACE_READ_DATA
:  
 561                         traceState 
= TRACE_IDLE
; 
 563                         if (isBlockTrailer(traceCurBlock
)) { 
 564                                 memcpy(traceCard 
+ traceCurBlock 
* 16 + 6, data 
+ 6, 4); 
 566                                 memcpy(traceCard 
+ traceCurBlock 
* 16, data
, 16); 
 568                         if (wantSaveToEmlFile
) saveTraceCard(); 
 571                         traceState 
= TRACE_ERROR
; 
 576                 if ((len 
== 1) && (data
[0] == 0x0a)) { 
 577                         traceState 
= TRACE_WRITE_DATA
; 
 580                         traceState 
= TRACE_ERROR
; 
 584         case TRACE_WRITE_DATA
:  
 586                         traceState 
= TRACE_IDLE
; 
 587                         memcpy(traceCard 
+ traceCurBlock 
* 16, data
, 16); 
 588                         if (wantSaveToEmlFile
) saveTraceCard(); 
 591                         traceState 
= TRACE_ERROR
; 
 597                         traceState 
= TRACE_AUTH2
; 
 598                         nt 
= bytes_to_num(data
, 4); 
 601                         traceState 
= TRACE_ERROR
; 
 607                         traceState 
= TRACE_AUTH_OK
; 
 608                         nr_enc 
= bytes_to_num(data
, 4); 
 609                         ar_enc 
= bytes_to_num(data 
+ 4, 4); 
 612                         traceState 
= TRACE_ERROR
; 
 618                         traceState 
= TRACE_IDLE
; 
 619                         at_enc 
= bytes_to_num(data
, 4); 
 622                         ks2 
= ar_enc 
^ prng_successor(nt
, 64); 
 623                         ks3 
= at_enc 
^ prng_successor(nt
, 96); 
 624                         revstate 
= lfsr_recovery64(ks2
, ks3
); 
 625                         lfsr_rollback_word(revstate
, 0, 0); 
 626                         lfsr_rollback_word(revstate
, 0, 0); 
 627                         lfsr_rollback_word(revstate
, nr_enc
, 1); 
 628                         lfsr_rollback_word(revstate
, cuid 
^ nt
, 0); 
 629                         crypto1_get_lfsr(revstate
, &key
); 
 630                         PrintAndLog("Found Key: [%012"llx
"]", key
); 
 632                         //if ( tryMfk64(cuid, nt, nr_enc, ar_enc, at_enc, &key) ) 
 633                         AddLogUint64(logHexFileName
, "Found Key: ", key
);  
 635                         int blockShift 
= ((traceCurBlock 
& 0xFC) + 3) * 16; 
 636                         if (isBlockEmpty((traceCurBlock 
& 0xFC) + 3)) memcpy(traceCard 
+ blockShift 
+ 6, trailerAccessBytes
, 4); 
 639                                 num_to_bytes(key
, 6, traceCard 
+ blockShift 
+ 10); 
 641                                 num_to_bytes(key
, 6, traceCard 
+ blockShift
); 
 643                         if (wantSaveToEmlFile
) 
 647                                 crypto1_destroy(traceCrypto1
); 
 649                         // set cryptosystem state 
 650                         traceCrypto1 
= lfsr_recovery64(ks2
, ks3
); 
 654                         traceState 
= TRACE_ERROR
; 
 659                 traceState 
= TRACE_ERROR
; 
 665 int tryDecryptWord(uint32_t nt
, uint32_t ar_enc
, uint32_t at_enc
, uint8_t *data
, int len
){ 
 666         PrintAndLog("\nEncrypted data: [%s]", sprint_hex(data
, len
) ); 
 667         struct Crypto1State 
*s
; 
 668         ks2 
= ar_enc 
^ prng_successor(nt
, 64); 
 669         ks3 
= at_enc 
^ prng_successor(nt
, 96); 
 670         s 
= lfsr_recovery64(ks2
, ks3
); 
 671         mf_crypto1_decrypt(s
, data
, len
, FALSE
); 
 672         PrintAndLog("Decrypted data: [%s]", sprint_hex(data
, len
) );