+
+//EMV clone a card - read up to the max SFI and max records for that SFI
+void EMVClone(uint8_t maxsfi, uint8_t maxrecord)
+{
+ //params
+ uint8_t uid[10];
+ uint32_t cuid;
+ uint8_t *resp = BigBuf_malloc(256);
+ iso14a_card_select_t hi14a_card; //card select values
+ //variables
+ tlvtag temptag; //used to buffer decoded tag valuesd
+
+ memset(¤tcard, 0x00, sizeof(currentcard)); //set all to zeros
+ //memcpy(currentcard.tag_9F66,"\x20\x00\x00\x00",4);
+ memcpy(currentcard.tag_9F66,"\xD7\x20\xC0\x00",4);
+ //memcpy(currentcard.tag_9F66,"\xC0\x00\x00\x00",2);
+ memcpy(currentcard.tag_9F02,"\x00\x00\x00\x00\x00\x20",6); //20 dollars
+ memcpy(currentcard.tag_9F37, "\x01\x02\x03\x04", 4); //UN
+ memcpy(currentcard.tag_5F2A, "\x00\x36",2); //currency code
+ //CDOL stuff
+ //memcpy(currentcard.tag_9F02,"\x00\x00\x00\x00\x00\x20",6);
+ memcpy(currentcard.tag_9F03,"\x00\x00\x00\x00\x00\x00",6);
+ memcpy(currentcard.tag_9F1A,"\x00\x36",2); //country code
+ memcpy(currentcard.tag_95,"\x00\x00\x00\x00\x00",5); //TVR
+ //memcpy(currentcard.tag_5F2A,"\x00\x36",2);
+ memcpy(currentcard.tag_9A,"\x14\x04x01",3); //date
+ memcpy(currentcard.tag_9C,"\x00",1); //processingcode;
+ memcpy(currentcard.tag_9F45, "\x00\x00", 2); //Data Authentication Code
+ memset(currentcard.tag_9F4C,0x00,8); // ICC UN
+ memcpy(currentcard.tag_9F35,"\x12",1);
+ memcpy(currentcard.tag_9F34,"\x3F\x00\x00", 3); //CVM
+
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
+ LED_A_ON();
+ LED_B_OFF();
+ LED_C_OFF();
+
+ while(true) {
+ if(!iso14443a_select_card(uid, &hi14a_card, &cuid, true, 0)) {
+ if(MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
+ break;
+ }
+ //copy UID and ATQA SAK and ATS values
+ memcpy(currentcard.UID, hi14a_card.uid, hi14a_card.uidlen);
+ currentcard.UID_len = hi14a_card.uidlen;
+ memcpy(currentcard.ATQA, hi14a_card.atqa, 2);
+ currentcard.SAK = (uint8_t)hi14a_card.sak;
+ memcpy(currentcard.ATS, hi14a_card.ats, hi14a_card.ats_len);
+ currentcard.ATS_len = hi14a_card.ats_len;
+
+ if(MF_DBGLEVEL >= 1){
+ Dbprintf("UID=");
+ Dbhexdump(currentcard.UID_len, currentcard.UID, false);
+ Dbprintf("ATQA=");
+ Dbhexdump(2, currentcard.ATQA,false);
+ Dbprintf("SAK=");
+ Dbhexdump(1, ¤tcard.SAK,false);
+ Dbprintf("ATS=");
+ Dbhexdump(currentcard.ATS_len, currentcard.ATS,false);
+ }
+ EMVSelectPPSE();
+ //get response
+ if(resp[1] == 0x6F){ //decode template
+ decode_ber_tlv_item(&resp[1], &temptag);
+ //decode 84 and A5 tags
+ emv_decode_field(temptag.value, temptag.valuelength, ¤tcard);
+ //decode the A5 tag
+ emv_decode_field(currentcard.tag_A5, currentcard.tag_A5_len, ¤tcard);
+ //decode the BF0C result, assuming 1 directory entry for now
+ if(currentcard.tag_BF0C_len !=0){
+ emv_decode_field(currentcard.tag_BF0C, currentcard.tag_BF0C_len, ¤tcard);}
+ //retrieve the AID, use the AID to decide what transaction flow to use
+ if(currentcard.tag_61_len !=0){
+ emv_decode_field(currentcard.tag_61, currentcard.tag_61_len, ¤tcard);}
+ }
+ //perform AID selection
+ EMVSelectAID(currentcard.tag_4F,currentcard.tag_4F_len, ¤tcard);
+ if(resp[1] == 0x6F){ //decode template
+ decode_ber_tlv_item(&resp[1], &temptag);
+ //decode 84 and A5 tags
+ emv_decode_field(temptag.value, temptag.valuelength, ¤tcard);
+ //decode the A5 tag
+ emv_decode_field(currentcard.tag_A5, currentcard.tag_A5_len, ¤tcard);
+ //decode the BF0C result, assuming 1 directory entry for now
+ }
+ //decode the AFL list and read records
+
+ //scan all card records
+ Dbprintf("Reading %u SFIs and %u records...", maxsfi, maxrecord);
+ for(uint8_t sfi = 1; sfi < maxsfi; sfi++){ //all possible SFI values
+ for(uint8_t record = 1; record < maxrecord; record++){
+ EMVReadRecord(record,sfi, ¤tcard);
+ if(resp[1] == 0x70){
+ Dbprintf("Record Found! SFI=%u RECORD=%u", sfi, record);
+ }
+ }
+ }
+ Dbprintf("Reading finished");
+
+ LED_B_ON();
+ //output the sensitive data
+ cmd_send(CMD_ACK, 0, 0,0,resp,100);
+ LED_B_OFF();
+ break;
+ }
+
+ if(MF_DBGLEVEL >= 2) DbpString("EMV TRANSACTION FINISHED");
+ //finish up
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LEDsoff();
+}