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