]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/emvcmd.c
FIX: mental note to self, don't forget to adjust messages to new logic
[proxmark3-svn] / armsrc / emvcmd.c
CommitLineData
9206d3b0 1//Peter Fillmore - 2014
2//
3//--------------------------------------------------------------------------------
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
6// the license.
7//--------------------------------------------------------------------------------
8//--------------------------------------------------------------------------------
9//Routines to support EMV transactions
10//--------------------------------------------------------------------------------
11
12#include "mifare.h"
13#include "iso14443a.h"
14#include "emvutil.h"
15#include "emvcmd.h"
16#include "apps.h"
17#include "emvdataels.h"
18
19static emvtags currentcard; //use to hold emv tags for the reader/card during communications
20static tUart Uart;
21
22// The FPGA will report its internal sending delay in
23uint16_t FpgaSendQueueDelay;
24//variables used for timing purposes:
25//these are in ssp_clk cycles:
26//static uint32_t NextTransferTime;
27static uint32_t LastTimeProxToAirStart;
28//static uint32_t LastProxToAirDuration;
29
30//load individual tag into current card
31void EMVloadvalue(uint32_t tag, uint8_t *datain){
32 //Dbprintf("TAG=%i\n", tag);
33 //Dbprintf("DATA=%s\n", datain);
34 emv_settag(tag, datain, &currentcard);
35}
36
37void EMVReadRecord(uint8_t arg0, uint8_t arg1,emvtags *currentcard)
38{
39 uint8_t record = arg0;
40 uint8_t sfi = arg1 & 0x0F; //convert arg1 to number
41 uint8_t receivedAnswer[MAX_FRAME_SIZE];
42
43 //uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
44
45 //variables
46 tlvtag inputtag; //create the tag structure
47 //perform read
48 //write the result to the provided card
49 if(!emv_readrecord(record,sfi,receivedAnswer)) {
50 if(EMV_DBGLEVEL >= 1) Dbprintf("readrecord failed");
51 }
52 if(*(receivedAnswer+1) == 0x70){
53 decode_ber_tlv_item(receivedAnswer+1, &inputtag);
54 emv_decode_field(inputtag.value, inputtag.valuelength, currentcard);
55 }
56 else
57 {
58 if(EMV_DBGLEVEL >= 1)
59 Dbprintf("Record not found SFI=%i RECORD=%i", sfi, record);
60 }
61 return;
62}
63
64void EMVSelectAID(uint8_t *AID, uint8_t AIDlen, emvtags* inputcard)
65{
66 uint8_t receivedAnswer[MAX_FRAME_SIZE];
67 //uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
68
69 //variables
70 tlvtag inputtag; //create the tag structure
71 //perform select
72 if(!emv_select(AID, AIDlen, receivedAnswer)){
73 if(EMV_DBGLEVEL >= 1) Dbprintf("AID Select failed");
74 return;
75 }
76 //write the result to the provided card
77 if(*(receivedAnswer+1) == 0x6F){
78 //decode the 6F template
79 decode_ber_tlv_item(receivedAnswer+1, &inputtag);
80 //store 84 and A5 tags
81 emv_decode_field(inputtag.value, inputtag.valuelength, &currentcard);
82 //decode the A5 tag
83 if(currentcard.tag_A5_len > 0)
84 emv_decode_field(currentcard.tag_A5, currentcard.tag_A5_len, &currentcard);
85
86 //copy this result to the DFName
87 if(currentcard.tag_84_len == 0)
88 memcpy(currentcard.tag_DFName, currentcard.tag_84, currentcard.tag_84_len);
89
90 //decode the BF0C result, assuming 1 directory entry for now
91 if(currentcard.tag_BF0C_len !=0){
92 emv_decode_field(currentcard.tag_BF0C, currentcard.tag_BF0C_len, &currentcard);}
93 //retrieve the AID, use the AID to decide what transaction flow to use
94 if(currentcard.tag_61_len !=0){
95 emv_decode_field(currentcard.tag_61, currentcard.tag_61_len, &currentcard);}
96 }
97 if(EMV_DBGLEVEL >= 2)
98 DbpString("SELECT AID COMPLETED");
99}
100
101int EMVGetProcessingOptions(uint8_t *PDOL, uint8_t PDOLlen, emvtags* inputcard)
102{
103 uint8_t receivedAnswer[MAX_FRAME_SIZE];
104 //uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
105
106 //variables
107 tlvtag inputtag; //create the tag structure
108 //perform pdol
109 if(!emv_getprocessingoptions(PDOL, PDOLlen, receivedAnswer)){
110 if(EMV_DBGLEVEL >= 1) Dbprintf("get processing options failed");
111 return 0;
112 }
113 //write the result to the provided card
114 //FORMAT 1 received
115 if(receivedAnswer[1] == 0x80){
116 //store AIP
117 //decode tag 80
118 decode_ber_tlv_item(receivedAnswer+1, &inputtag);
119 memcpy(currentcard.tag_82, &inputtag.value, sizeof(currentcard.tag_82));
120 memcpy(currentcard.tag_94, &inputtag.value[2], inputtag.valuelength - sizeof(currentcard.tag_82));
121 currentcard.tag_94_len = inputtag.valuelength - sizeof(currentcard.tag_82);
122 }
123 else if(receivedAnswer[1] == 0x77){
124 //decode the 77 template
125 decode_ber_tlv_item(receivedAnswer+1, &inputtag);
126 //store 82 and 94 tags (AIP, AFL)
127 emv_decode_field(inputtag.value, inputtag.valuelength, &currentcard);
128 }
129 if(EMV_DBGLEVEL >= 2)
130 DbpString("GET PROCESSING OPTIONS COMPLETE");
131 return 1;
132}
133
134int EMVGetChallenge(emvtags* inputcard)
135{
136 uint8_t receivedAnswer[MAX_FRAME_SIZE];
137 //uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
138 //variables
139 //tlvtag inputtag; //create the tag structure
140 //perform select
141 if(!emv_getchallenge(receivedAnswer)){
142 if(EMV_DBGLEVEL >= 1) Dbprintf("get processing options failed");
143 return 1;
144 }
145 return 0;
146}
147
148int EMVGenerateAC(uint8_t refcontrol, emvtags* inputcard)
149{
150 uint8_t receivedAnswer[MAX_FRAME_SIZE];
151 uint8_t cdolcommand[MAX_FRAME_SIZE];
152 uint8_t cdolcommandlen = 0;
153 tlvtag temptag;
154
155 //uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
156 if(currentcard.tag_8C_len > 0) {
157 emv_generateDOL(currentcard.tag_8C, currentcard.tag_8C_len, &currentcard, cdolcommand, &cdolcommandlen); }
158 else{
159 //cdolcommand = NULL; //cdol val is null
160 cdolcommandlen = 0;
161 }
162 //variables
163 //tlvtag inputtag; //create the tag structure
164 //perform select
165 if(!emv_generateAC(refcontrol, cdolcommand, cdolcommandlen,receivedAnswer)){
166 if(EMV_DBGLEVEL >= 1) Dbprintf("get processing options failed");
167 return 1;
168 }
169 if(receivedAnswer[2] == 0x77) //format 2 data field returned
170 {
171 decode_ber_tlv_item(&receivedAnswer[2], &temptag);
172 emv_decode_field(temptag.value, temptag.valuelength, &currentcard);
173 }
174
175 return 0;
176}
177
178//function to perform paywave transaction
179//takes in TTQ, amount authorised, unpredicable number and transaction currency code
180int EMV_PaywaveTransaction()
181{
182 uint8_t cardMode = 0;
183 //determine mode of transaction from TTQ
184 if((currentcard.tag_9F66[0] & 0x40) == 0x40) {
185 cardMode = VISA_EMV;
186 }
187 else if((currentcard.tag_9F66[0] & 0x20) == 0x20) {
188 cardMode = VISA_FDDA;
189 }
190 else if((currentcard.tag_9F66[0] & 0x80) == 0x80) {
191 if((currentcard.tag_9F66[1] & 0x80) == 1) { //CVN17
192 cardMode = VISA_CVN17;
193 }
194 else{
195 cardMode = VISA_DCVV;
196 }
197 }
198
199 EMVSelectAID(currentcard.tag_4F,currentcard.tag_4F_len, &currentcard); //perform second AID command
200
201 //get PDOL
202 uint8_t pdolcommand[20]; //20 byte buffer for pdol data
203 uint8_t pdolcommandlen = 0;
204 if(currentcard.tag_9F38_len > 0) {
205 emv_generateDOL(currentcard.tag_9F38, currentcard.tag_9F38_len, &currentcard, pdolcommand, &pdolcommandlen);
206 }
207 Dbhexdump(pdolcommandlen, pdolcommand,false);
208
209 if(!EMVGetProcessingOptions(pdolcommand,pdolcommandlen, &currentcard)) {
210 if(EMV_DBGLEVEL >= 1) Dbprintf("PDOL failed");
211 return 1;
212 }
213
214 Dbprintf("AFL=");
215 Dbhexdump(currentcard.tag_94_len, currentcard.tag_94,false);
216 Dbprintf("AIP=");
217 Dbhexdump(2, currentcard.tag_82, false);
218 emv_decodeAIP(currentcard.tag_82);
219//
220// //decode the AFL list and read records
221 uint8_t i = 0;
222 uint8_t sfi = 0;
223 uint8_t recordstart = 0;
224 uint8_t recordend = 0;
225 if(currentcard.tag_94_len > 0){
226 while( i < currentcard.tag_94_len){
227 sfi = (currentcard.tag_94[i++] & 0xF8) >> 3;
228 recordstart = currentcard.tag_94[i++];
229 recordend = currentcard.tag_94[i++];
230 for(int j=recordstart; j<(recordend+1); j++){
231 //read records
232 EMVReadRecord(j,sfi, &currentcard);
233 //while(responsebuffer[0] == 0xF2) {
234 // EMVReadRecord(j,sfi, &currentcard);
235 //}
236 }
237 i++;
238 }
239 }
240 else {
241 EMVReadRecord(1,1,&currentcard);
242 EMVReadRecord(1,2,&currentcard);
243 EMVReadRecord(1,3,&currentcard);
244 EMVReadRecord(2,1,&currentcard);
245 EMVReadRecord(2,2,&currentcard);
246 EMVReadRecord(2,3,&currentcard);
247 EMVReadRecord(3,1,&currentcard);
248 EMVReadRecord(3,3,&currentcard);
249 EMVReadRecord(4,2,&currentcard);
250 }
251 //EMVGetChallenge(&currentcard);
252 //memcpy(currentcard.tag_9F4C,&responsebuffer[1],8); // ICC UN
253 EMVGenerateAC(0x81,&currentcard);
254
255 Dbprintf("CARDMODE=%i",cardMode);
256 return 0;
257}
258
259
260int EMV_PaypassTransaction()
261{
262 //uint8_t *responsebuffer = emv_get_bigbufptr();
263 //tlvtag temptag; //buffer for decoded tags
264 //get the current block counter
265 //select the AID (Mastercard
266 EMVSelectAID(currentcard.tag_4F,currentcard.tag_4F_len, &currentcard);
267
268 //get PDOL
269 uint8_t pdolcommand[20]; //20 byte buffer for pdol data
270 uint8_t pdolcommandlen = 0;
271 if(currentcard.tag_9F38_len > 0) {
272 emv_generateDOL(currentcard.tag_9F38, currentcard.tag_9F38_len, &currentcard, pdolcommand, &pdolcommandlen);
273 }
274 if(EMVGetProcessingOptions(pdolcommand,pdolcommandlen, &currentcard)) {
275 if(EMV_DBGLEVEL >= 1) Dbprintf("PDOL failed");
276 return 1;
277 }
278
279 Dbprintf("AFL=");
280 Dbhexdump(currentcard.tag_94_len, currentcard.tag_94,false);
281 Dbprintf("AIP=");
282 Dbhexdump(2, currentcard.tag_82, false);
283 emv_decodeAIP(currentcard.tag_82);
284
285 //decode the AFL list and read records
286 uint8_t i = 0;
287 uint8_t sfi = 0;
288 uint8_t recordstart = 0;
289 uint8_t recordend = 0;
290
291 while( i< currentcard.tag_94_len){
292 sfi = (currentcard.tag_94[i++] & 0xF8) >> 3;
293 recordstart = currentcard.tag_94[i++];
294 recordend = currentcard.tag_94[i++];
295 for(int j=recordstart; j<(recordend+1); j++){
296 //read records
297 EMVReadRecord(j,sfi, &currentcard);
298 //while(responsebuffer[0] == 0xF2) {
299 // EMVReadRecord(j,sfi, &currentcard);
300 //}
301 }
302 i++;
303 }
304 /* get ICC dynamic data */
305 if((currentcard.tag_82[0] & AIP_CDA_SUPPORTED) == AIP_CDA_SUPPORTED)
306 {
307 //DDA supported, so perform GENERATE AC
308 //generate the iCC UN
309 EMVGetChallenge(&currentcard);
310 //memcpy(currentcard.tag_9F4C,&responsebuffer[1],8); // ICC UN
311 EMVGenerateAC(0x80,&currentcard);
312
313
314 //generate AC2
315 //if(currentcard.tag_8D_len > 0) {
316 // emv_generateDOL(currentcard.tag_8D, currentcard.tag_8D_len, &currentcard, cdolcommand, &cdolcommandlen); }
317 //else{
318 // //cdolcommand = NULL; //cdol val is null
319 // cdolcommandlen = 0;
320 //}
321 //emv_generateAC(0x80, cdolcommand,cdolcommandlen, &currentcard);
322
323 //if(responsebuffer[1] == 0x77) //format 2 data field returned
324 //{
325 // decode_ber_tlv_item(&responsebuffer[1], &temptag);
326 // emv_decode_field(temptag.value, temptag.valuelength, &currentcard);
327 //}
328 }
329 //generate cryptographic checksum
330 //uint8_t udol[4] = {0x00,0x00,0x00,0x00};
331 //emv_computecryptogram(udol, sizeof(udol));
332 //if(responsebuffer[1] == 0x77) //format 2 data field returned
333 //{
334 // decode_ber_tlv_item(&responsebuffer[1], &temptag);
335 // emv_decode_field(temptag.value, temptag.valuelength, &currentcard);
336 //}
337 return 0;
338}
339
340void EMVTransaction()
341{
342 //params
343 uint8_t uid[10] = {0x00};
344 uint32_t cuid = 0;
345
346 //setup stuff
347 BigBuf_free(); BigBuf_Clear_ext(false);
348 clear_trace();
349 set_tracing(TRUE);
350
351 LED_A_ON();
352 LED_B_OFF();
353 LED_C_OFF();
354
355 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
356 while(true) {
357 if(!iso14443a_select_card(uid,NULL,&cuid)) {
358 if(EMV_DBGLEVEL >= 1) Dbprintf("Can't select card");
359 break;
360 }
361 //selectPPSE
362 EMVSelectAID((uint8_t *)DF_PSE, 14, &currentcard); //hard coded len
363 //get response
364 if (!memcmp(currentcard.tag_4F, AID_MASTERCARD, sizeof(AID_MASTERCARD))){
365 Dbprintf("Mastercard Paypass Card Detected");
366 EMV_PaypassTransaction();
367 }
368 else if (!memcmp(currentcard.tag_4F, AID_VISA, sizeof(AID_VISA))){
369 Dbprintf("VISA Paywave Card Detected");
370 EMV_PaywaveTransaction();
371 }
372 //TODO: add other card schemes like AMEX, JCB, China Unionpay etc
373 break;
374 }
375 if (EMV_DBGLEVEL >= 2) DbpString("EMV TRANSACTION FINISHED");
376 //finish up
377 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
378 LEDsoff();
379}
380
381void EMVdumpcard(void){
382 dumpCard(&currentcard);
383}
384
385//SIMULATOR CODE
386//-----------------------------------------------------------------------------
387// Main loop of simulated tag: receive commands from reader, decide what
388// response to send, and send it.
389//-----------------------------------------------------------------------------
390void SimulateEMVcard()
391{
392 //uint8_t sak; //select ACKnowledge
393 uint16_t readerPacketLen = 64; //reader packet length - provided by RATS, default to 64 bytes if RATS not supported
394
395 // The first response contains the ATQA (note: bytes are transmitted in reverse order).
396 //uint8_t atqapacket[2];
397
398 // The second response contains the (mandatory) first 24 bits of the UID
399 uint8_t uid0packet[5] = {0x00};
400 memcpy(uid0packet, currentcard.UID, sizeof(uid0packet));
401 // Check if the uid uses the (optional) part
402 uint8_t uid1packet[5] = {0x00};
403 memcpy(uid1packet, currentcard.UID, sizeof(uid1packet));
404
405 // Calculate the BitCountCheck (BCC) for the first 4 bytes of the UID.
406 uid0packet[4] = uid0packet[0] ^ uid0packet[1] ^ uid0packet[2] ^ uid0packet[3];
407
408 // Prepare the mandatory SAK (for 4 and 7 byte UID)
409 uint8_t sak0packet[3] = {0x00};
410 memcpy(sak0packet,&currentcard.SAK1,1);
411 ComputeCrc14443(CRC_14443_A, sak0packet, 1, &sak0packet[1], &sak0packet[2]);
412 uint8_t sak1packet[3] = {0x00};
413 memcpy(sak1packet,&currentcard.SAK2,1);
414 // Prepare the optional second SAK (for 7 byte UID), drop the cascade bit
415 ComputeCrc14443(CRC_14443_A, sak1packet, 1, &sak1packet[1], &sak1packet[2]);
416
417 uint8_t authanspacket[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce
418 //setup response to ATS
419 uint8_t ratspacket[currentcard.ATS_len];
420 memcpy(ratspacket,currentcard.ATS, currentcard.ATS_len);
421 AppendCrc14443a(ratspacket,sizeof(ratspacket)-2);
422
423 // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
424 // TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
425 // TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us)
426 // TC(1) = 0x02: CID supported, NAD not supported
427 //ComputeCrc14443(CRC_14443_A, response6, 4, &response6[4], &response6[5]);
428
429 //Receive Acknowledge responses differ by PCB byte
430 uint8_t rack0packet[] = {0xa2,0x00,0x00};
431 AppendCrc14443a(rack0packet,1);
432 uint8_t rack1packet[] = {0xa3,0x00,0x00};
433 AppendCrc14443a(rack1packet,1);
434 //Negative Acknowledge
435 uint8_t rnak0packet[] = {0xb2,0x00,0x00};
436 uint8_t rnak1packet[] = {0xb3,0x00,0x00};
437 AppendCrc14443a(rnak0packet,1);
438 AppendCrc14443a(rnak1packet,1);
439
440 //Protocol and parameter selection response, just say yes
441 uint8_t ppspacket[] = {0xd0,0x00,0x00};
442 AppendCrc14443a(ppspacket,1);
443
444 //hardcoded WTX packet - set to max time (49)
445 uint8_t wtxpacket[] ={0xf2,0x31,0x00,0x00};
446 AppendCrc14443a(wtxpacket,2);
447
448 //added additional responses for different readers, namely protocol parameter select and Receive acknowledments. - peter fillmore.
449 //added defininitions for predone responses to aid readability
450 #define ATR 0
451 #define UID1 1
452 #define UID2 2
453 #define SELACK1 3
454 #define SELACK2 4
455 #define AUTH_ANS 5
456 #define ATS 6
457 #define RACK0 7
458 #define RACK1 8
459 #define RNAK0 9
460 #define RNAK1 10
461 #define PPSresponse 11
462 #define WTX 12
463
464 #define TAG_RESPONSE_COUNT 13
465 tag_response_info_t responses[TAG_RESPONSE_COUNT] = {
466 { .response = currentcard.ATQA, .response_n = sizeof(currentcard.ATQA) }, // Answer to request - respond with card type
467 { .response = uid0packet, .response_n = sizeof(uid0packet) }, // Anticollision cascade1 - respond with uid
468 { .response = uid1packet, .response_n = sizeof(uid1packet) }, // Anticollision cascade2 - respond with 2nd half of uid if asked
469 { .response = sak0packet, .response_n = sizeof(sak0packet) }, // Acknowledge select - cascade 1
470 { .response = sak1packet, .response_n = sizeof(sak1packet) }, // Acknowledge select - cascade 2
471 { .response = authanspacket, .response_n = sizeof(authanspacket) }, // Authentication answer (random nonce)
472 { .response = ratspacket, .response_n = sizeof(ratspacket) }, // dummy ATS (pseudo-ATR), answer to RATS
473 { .response = rack0packet, .response_n = sizeof(rack0packet) }, //R(ACK)0
474 { .response = rack1packet, .response_n = sizeof(rack1packet) }, //R(ACK)0
475 { .response = rnak0packet, .response_n = sizeof(rnak0packet) }, //R(NAK)0
476 { .response = rnak1packet, .response_n = sizeof(rnak1packet) }, //R(NAK)1
477 { .response = ppspacket, .response_n = sizeof(ppspacket)}, //PPS packet
478 { .response = wtxpacket, .response_n = sizeof(wtxpacket)}, //WTX packet
479};
480
481 //calculated length of predone responses
482 uint16_t allocatedtaglen = 0;
483 for(int i=0;i<TAG_RESPONSE_COUNT;i++){
484 allocatedtaglen += responses[i].response_n;
485 }
486 //uint8_t selectOrder = 0;
487
488 BigBuf_free_keep_EM();
489 // Allocate 512 bytes for the dynamic modulation, created when the reader queries for it
490 // Such a response is less time critical, so we can prepare them on the fly
491
492 #define DYNAMIC_RESPONSE_BUFFER_SIZE 256 //max frame size
493 #define DYNAMIC_MODULATION_BUFFER_SIZE 2 + 9*DYNAMIC_RESPONSE_BUFFER_SIZE //(start and stop bit, 8 bit packet with 1 bit parity
494
495 //uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE];
496 //uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE];
497 uint8_t *dynamic_response_buffer = BigBuf_malloc(DYNAMIC_RESPONSE_BUFFER_SIZE);
498 uint8_t *dynamic_modulation_buffer = BigBuf_malloc(DYNAMIC_MODULATION_BUFFER_SIZE);
499
500 tag_response_info_t dynamic_response_info = {
501 .response = dynamic_response_buffer,
502 .response_n = 0,
503 .modulation = dynamic_modulation_buffer,
504 .modulation_n = 0
505 };
506 // allocate buffers from BigBuf (so we're not in the stack)
507 uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
508 uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
509 //uint8_t* free_buffer_pointer;
510 //free_buffer_pointer = BigBuf_malloc((allocatedtaglen*8) +(allocatedtaglen) + (TAG_RESPONSE_COUNT * 3));
511 BigBuf_malloc((allocatedtaglen*8) +(allocatedtaglen) + (TAG_RESPONSE_COUNT * 3));
512 // clear trace
513 clear_trace();
514 set_tracing(TRUE);
515
516 // Prepare the responses of the anticollision phase
517 // there will be not enough time to do this at the moment the reader sends it REQA
518 for (size_t i=0; i<TAG_RESPONSE_COUNT; i++)
519 prepare_allocated_tag_modulation(&responses[i]);
520
521 int len = 0;
522
523 // To control where we are in the protocol
524 int order = 0;
525 int lastorder;
526 int currentblock = 1; //init to 1
527 int previousblock = 0; //used to store previous block counter
528
529 // Just to allow some checks
530 int happened = 0;
531 int happened2 = 0;
532 int cmdsRecvd = 0;
533
534 // We need to listen to the high-frequency, peak-detected path.
535 iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
536
537 cmdsRecvd = 0;
538 tag_response_info_t* p_response;
539
540 LED_A_ON();
541 for(;;) {
542 // Clean receive command buffer
543
544 if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
545 DbpString("Button press");
546 break;
547 }
548
549 p_response = NULL;
550
551 // Okay, look at the command now.
552 previousblock = currentblock; //get previous block
553 lastorder = order;
554 currentblock = receivedCmd[0] & 0x01;
555
556 if(receivedCmd[0] == 0x26) { // Received a REQUEST
557 p_response = &responses[ATR]; order = REQA;
558 } else if(receivedCmd[0] == 0x52) { // Received a WAKEUP
559 p_response = &responses[ATR]; order = WUPA;
560 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x93) { // Received request for UID (cascade 1)
561 p_response = &responses[UID1]; order = SELUID1;
562 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x95) { // Received request for UID (cascade 2)
563 p_response = &responses[UID2]; order = SELUID2;
564 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] == 0x93) { // Received a SELECT (cascade 1)
565 p_response = &responses[SELACK1]; order = SEL1;
566 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] == 0x95) { // Received a SELECT (cascade 2)
567 p_response = &responses[SELACK2]; order = SEL2;
568 } else if((receivedCmd[0] & 0xA2) == 0xA2){ //R-Block received
569 if(previousblock == currentblock){ //rule 11, retransmit last block
570 p_response = &dynamic_response_info;
571 } else {
572 if((receivedCmd[0] & 0xB2) == 0xB2){ //RNAK, rule 12
573 if(currentblock == 0)
574 p_response = &responses[RACK0];
575 else
576 p_response = &responses[RACK1];
577 } else {
578 //rule 13
579 //TODO: implement chaining
580 }
581 }
582 }
583 else if(receivedCmd[0] == 0xD0){ //Protocol and parameter selection response
584 p_response = &responses[PPSresponse];
585 order = PPS;
586 }
587 else if(receivedCmd[0] == 0x30) { // Received a (plain) READ
588 //we're an EMV card - so no read commands
589 p_response = NULL;
590 } else if(receivedCmd[0] == 0x50) { // Received a HALT
591 LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
592 p_response = NULL;
593 order = HLTA;
594 } else if(receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61) { // Received an authentication request
595 p_response = &responses[AUTH_ANS];
596 order = AUTH;
597 } else if(receivedCmd[0] == 0xE0) { // Received a RATS request
598 readerPacketLen = GetReaderLength(receivedCmd); //get length of supported packet
599 p_response = &responses[ATS];
600 order = RATS;
601 } else if (order == AUTH && len == 8) { // Received {nr] and {ar} (part of authentication)
602 LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
603 uint32_t nr = bytes_to_num(receivedCmd,4);
604 uint32_t ar = bytes_to_num(receivedCmd+4,4);
605 Dbprintf("Auth attempt {nr}{ar}: %08x %08x",nr,ar);
606 } else {
607 // Check for ISO 14443A-4 compliant commands, look at left nibble
608 switch (receivedCmd[0]) {
609 case 0x0B:
610 case 0x0A: // IBlock (command)
611 case 0x02:
612 case 0x03: {
613 dynamic_response_info.response_n = 0;
614 dynamic_response_info.response[0] = receivedCmd[0]; // copy PCB
615 //dynamic_response_info.response[1] = receivedCmd[1]; // copy PCB
616 dynamic_response_info.response_n++ ;
617 switch(receivedCmd[1]) {
618 case 0x00:
619 switch(receivedCmd[2]){
620 case 0xA4: //select
621 if(receivedCmd[5] == 0x0E){
622 }
623 else if(receivedCmd[5] == 0x07){
624 //selectOrder = 0;
625 }
626 else{ //send not supported msg
627 memcpy(dynamic_response_info.response+1, "\x6a\x82", 2);
628 dynamic_response_info.response_n += 2;
629 }
630 break;
631 case 0xB2: //read record
632 if(receivedCmd[3] == 0x01 && receivedCmd[4] == 0x0C){
633 dynamic_response_info.response_n += 2;
634 Dbprintf("READ RECORD 1 1");
635 }
636 break;
637 }
638 break;
639 case 0x80:
640 switch(receivedCmd[2]){
641 case 0xA8: //get processing options
642 break;
643 }
644 }
645 }break;
646 case 0x1A:
647 case 0x1B: { // Chaining command
648 dynamic_response_info.response[0] = 0xaa | ((receivedCmd[0]) & 1);
649 dynamic_response_info.response_n = 2;
650 } break;
651
652 case 0xaa:
653 case 0xbb: {
654 dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11;
655 dynamic_response_info.response_n = 2;
656 } break;
657
658 case 0xBA: { //
659 memcpy(dynamic_response_info.response,"\xAB\x00",2);
660 dynamic_response_info.response_n = 2;
661 } break;
662
663 case 0xCA:
664 case 0xC2: { // Readers sends deselect command
665 //we send the command back - this is what tags do in android implemenation i believe - peterfillmore
666 memcpy(dynamic_response_info.response,receivedCmd,1);
667 dynamic_response_info.response_n = 1;
668 } break;
669
670 default: {
671 // Never seen this command before
672 LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
673 Dbprintf("Received unknown command (len=%d):",len);
674 Dbhexdump(len,receivedCmd,false);
675 // Do not respond
676 dynamic_response_info.response_n = 0;
677 } break;
678 }
679
680 if (dynamic_response_info.response_n > 0) {
681 // Copy the CID from the reader query
682 //dynamic_response_info.response[1] = receivedCmd[1];
683
684 // Add CRC bytes, always used in ISO 14443A-4 compliant cards
685 AppendCrc14443a(dynamic_response_info.response,dynamic_response_info.response_n);
686 dynamic_response_info.response_n += 2;
687 if(dynamic_response_info.response_n > readerPacketLen){ //throw error if our reader doesn't support the send packet length
688 Dbprintf("Error: tag response is longer then what the reader supports, TODO:implement command chaining");
689 LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
690 break;
691 }
692 if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
693 Dbprintf("Error preparing tag response");
694 LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
695 break;
696 }
697 p_response = &dynamic_response_info;
698 }
699 }
700
701 // Count number of wakeups received after a halt
702 if(order == HLTA && lastorder == PPS) { happened++; }
703
704 // Count number of other messages after a halt
705 if(order != HLTA && lastorder == PPS) { happened2++; }
706
707 if(cmdsRecvd > 999) {
708 DbpString("1000 commands later...");
709 break;
710 }
711 cmdsRecvd++;
712
713 if (p_response != NULL) {
714 EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n, receivedCmd[0] == 0x52);
715 // do the tracing for the previous reader request and this tag answer:
716 uint8_t par[MAX_PARITY_SIZE] = {0x00};
717 GetParity(p_response->response, p_response->response_n, par);
718
719 EmLogTrace(Uart.output,
720 Uart.len,
721 Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG,
722 Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG,
723 Uart.parity,
724 p_response->response,
725 p_response->response_n,
726 LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG,
727 (LastTimeProxToAirStart + p_response->ProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG,
728 par);
729 }
730
731 if (!tracing) {
732 Dbprintf("Trace Full. Simulation stopped.");
733 break;
734 }
735 }
736
737 Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
738 LED_A_OFF();
739 BigBuf_free_keep_EM();
740}
Impressum, Datenschutz