mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge pull request #2652 from n-hutton/cherry_pick_emv
Cherry pick POC of emv simulation
This commit is contained in:
+3
-2
@@ -37,7 +37,8 @@ APP_CFLAGS = $(PLATFORM_DEFS) \
|
||||
SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c
|
||||
SRC_HF = hfops.c
|
||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c sam_common.c sam_mfc.c sam_seos.c
|
||||
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c sam_common.c sam_mfc.c sam_seos.c emvsim.c
|
||||
|
||||
#UNUSED: mifaresniff.c
|
||||
SRC_ISO14443b = iso14443b.c
|
||||
SRC_FELICA = felica.c
|
||||
@@ -59,7 +60,7 @@ else
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring WITH_SMARTCARD,$(APP_CFLAGS)))
|
||||
SRC_SMARTCARD = i2c.c
|
||||
SRC_SMARTCARD = i2c.c i2c_direct.c
|
||||
else
|
||||
SRC_SMARTCARD =
|
||||
endif
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "mifarecmd.h"
|
||||
#include "mifaredesfire.h"
|
||||
#include "mifaresim.h"
|
||||
#include "emvsim.h"
|
||||
#include "pcf7931.h"
|
||||
#include "Standalone/standalone.h"
|
||||
#include "util.h"
|
||||
@@ -1662,6 +1663,19 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
ReaderIso14443a(packet);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO14443A_EMV_SIMULATE: {
|
||||
struct p {
|
||||
uint16_t flags;
|
||||
uint8_t exitAfter;
|
||||
uint8_t uid[7];
|
||||
uint16_t atqa;
|
||||
uint8_t sak;
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
|
||||
EMVsim(payload->flags, payload->exitAfter, payload->uid, payload->atqa, payload->sak);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO14443A_SIMULATE: {
|
||||
struct p {
|
||||
uint8_t tagtype;
|
||||
|
||||
+787
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) Gerhard de Koning Gans - May 2008
|
||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// See LICENSE.txt for the text of the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Mifare Classic Card Simulation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __EMVSIM_H
|
||||
#define __EMVSIM_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define AUTHKEYNONE 0xff
|
||||
|
||||
void EMVsim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,371 @@
|
||||
// //-----------------------------------------------------------------------------
|
||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// See LICENSE.txt for the text of the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// The main i2c code, for communications with smart card module
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "BigBuf.h"
|
||||
#include "iso14443a.h"
|
||||
#include "BigBuf.h"
|
||||
#include "string.h"
|
||||
#include "mifareutil.h"
|
||||
#include "fpgaloader.h"
|
||||
#include "proxmark3_arm.h"
|
||||
#include "cmd.h"
|
||||
#include "protocols.h"
|
||||
#include "appmain.h"
|
||||
#include "util.h"
|
||||
#include "commonutil.h"
|
||||
#include "crc16.h"
|
||||
#include "dbprint.h"
|
||||
#include "ticks.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c_direct.h"
|
||||
|
||||
static uint8_t fci_template[] = {0x02, 0x6f, 0x5e, 0x84, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0xa5, 0x53, 0x50, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x9f, 0x38, 0x18, 0x9f, 0x66, 0x04, 0x9f, 0x02, 0x06, 0x9f, 0x03, 0x06, 0x9f, 0x1a, 0x02, 0x95, 0x05, 0x5f, 0x2a, 0x02, 0x9a, 0x03, 0x9c, 0x01, 0x9f, 0x37, 0x04, 0x5f, 0x2d, 0x02, 0x65, 0x6e, 0x9f, 0x11, 0x01, 0x01, 0x9f, 0x12, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0xbf, 0x0c, 0x13, 0x9f, 0x5a, 0x05, 0x31, 0x08, 0x26, 0x08, 0x26, 0x9f, 0x0a, 0x08, 0x00, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0xd8, 0x15};
|
||||
|
||||
static uint8_t pay1_response[] = { 0x6F, 0x1E, 0x84, 0x0E, 0x31, 0x50, 0x41, 0x59 };
|
||||
static uint8_t pay2_response[] = { 0x03, 0x6f, 0x3e, 0x84, 0x0e, 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, 0xa5, 0x2c, 0xbf, 0x0c, 0x29, 0x61, 0x27, 0x4f, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0x50, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x9f, 0x0a, 0x08, 0x00, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x63, 0x04, 0xdf, 0x20, 0x01, 0x80, 0x90, 0x00, 0x07, 0x9d};
|
||||
|
||||
void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint8_t *output, uint16_t *olen) {
|
||||
LED_D_ON();
|
||||
|
||||
uint16_t len = 0;
|
||||
uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
resp[0] = prepend;
|
||||
// check if alloacted...
|
||||
smartcard_command_t flags = p->flags;
|
||||
|
||||
//if ((flags & SC_CLEARLOG) == SC_CLEARLOG)
|
||||
//clear_trace();
|
||||
|
||||
if ((flags & SC_LOG) == SC_LOG)
|
||||
set_tracing(true);
|
||||
else
|
||||
set_tracing(false);
|
||||
|
||||
if ((flags & SC_CONNECT) == SC_CONNECT) {
|
||||
|
||||
I2C_Reset_EnterMainProgram();
|
||||
|
||||
if ((flags & SC_SELECT) == SC_SELECT) {
|
||||
smart_card_atr_t card;
|
||||
bool gotATR = GetATR(&card, true);
|
||||
//reply_old(CMD_ACK, gotATR, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t));
|
||||
if (gotATR == false) {
|
||||
Dbprintf("No ATR received...\n");
|
||||
//reply_ng(CMD_SMART_RAW, PM3_ESOFT, NULL, 0);
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t wait = SIM_WAIT_DELAY;
|
||||
|
||||
if (((flags & SC_RAW) == SC_RAW) || ((flags & SC_RAW_T0) == SC_RAW_T0)) {
|
||||
|
||||
if ((flags & SC_WAIT) == SC_WAIT) {
|
||||
wait = (uint32_t)((p->wait_delay * 1000) / 3.07);
|
||||
}
|
||||
|
||||
LogTrace(p->data, p->len, 0, 0, NULL, true);
|
||||
|
||||
bool res = I2C_BufferWrite(
|
||||
p->data,
|
||||
p->len,
|
||||
(((flags & SC_RAW_T0) == SC_RAW_T0) ? I2C_DEVICE_CMD_SEND_T0 : I2C_DEVICE_CMD_SEND),
|
||||
I2C_DEVICE_ADDRESS_MAIN
|
||||
);
|
||||
|
||||
if (res == false && g_dbglevel > 3) {
|
||||
//DbpString(I2C_ERROR);
|
||||
//reply_ng(CMD_SMART_RAW, PM3_ESOFT, NULL, 0);
|
||||
Dbprintf("SmartCardDirectSend: I2C_BufferWrite failed\n");
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
// read bytes from module
|
||||
len = ISO7816_MAX_FRAME;
|
||||
res = sc_rx_bytes(&resp[1], &len, wait);
|
||||
if (res) {
|
||||
LogTrace(&resp[1], len, 0, 0, NULL, false);
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 2 && resp[1] == 0x61) {
|
||||
//Dbprintf("Data to be read: len = %d\n", len);
|
||||
//Dbprintf("\n");
|
||||
|
||||
uint8_t cmd_getresp[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, resp[2]};
|
||||
//smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + sizeof(cmd_getresp));
|
||||
smart_card_raw_t *payload = (smart_card_raw_t *)BigBuf_calloc(sizeof(smart_card_raw_t) + sizeof(cmd_getresp));
|
||||
payload->flags = SC_RAW | SC_LOG;
|
||||
payload->len = sizeof(cmd_getresp);
|
||||
payload->wait_delay = 0;
|
||||
memcpy(payload->data, cmd_getresp, sizeof(cmd_getresp));
|
||||
|
||||
SmartCardDirectSend(prepend, payload, output, olen);
|
||||
} else if (len == 2) {
|
||||
Dbprintf("***** BAD response from card (response unsupported)...");
|
||||
Dbhexdump(3, &resp[0], false);
|
||||
resp[0] = prepend;
|
||||
resp[1] = 0x6a;
|
||||
resp[2] =0x82;
|
||||
AddCrc14A(resp, 3);
|
||||
|
||||
//Dbhexdump(5, &resp[0], false); // special print
|
||||
//EmSendCmd(&resp[0], 5);
|
||||
memcpy(output, resp, 5);
|
||||
*olen = 5;
|
||||
}
|
||||
|
||||
if (resp[1] == 0x6a && resp[2] == 0x82) {
|
||||
Dbprintf("***** bad response from card (file not found)...");
|
||||
resp[0] = prepend;
|
||||
resp[1] = 0x6a;
|
||||
resp[2] =0x82;
|
||||
AddCrc14A(resp, 3);
|
||||
|
||||
//Dbhexdump(5, &resp[0], false); // special print
|
||||
//EmSendCmd14443aRaw(&resp[0], 5);
|
||||
//EmSendCmd(&resp[0], 5);
|
||||
memcpy(output, resp, 5);
|
||||
*olen = 5;
|
||||
FpgaDisableTracing();
|
||||
}
|
||||
|
||||
if (len > 2) {
|
||||
Dbprintf("***** sending it over the wire... len: %d =>\n", len);
|
||||
resp[1] = prepend;
|
||||
|
||||
// if we have a generate AC request, lets extract the data and populate the template
|
||||
if (resp[1] != 0xff && resp[2] == 0x77) {
|
||||
Dbprintf("we have detected a generate ac response, lets repackage it!");
|
||||
Dbhexdump(len, &resp[1], false); // special print
|
||||
// 11 and 12 are trans counter.
|
||||
// 16 to 24 are the cryptogram
|
||||
// 27 to 34 is issuer application data
|
||||
Dbprintf("atc: %d %d, cryptogram: %d ", resp[11], resp[12], resp[13]);
|
||||
|
||||
// then, on the template:
|
||||
// 61 and 62 for counter
|
||||
// 46 to 54 for cryptogram
|
||||
// 36 to 43 for issuer application data
|
||||
|
||||
uint8_t template[] = { 0x00, 0x00, 0x77, 0x47, 0x82, 0x02, 0x39, 0x00, 0x57, 0x13, 0x47, 0x62, 0x28, 0x00, 0x05, 0x93, 0x38, 0x64, 0xd2, 0x70, 0x92, 0x01, 0x00, 0x00, 0x01, 0x42, 0x00, 0x00, 0x0f, 0x5f, 0x34, 0x01, 0x00, 0x9f, 0x10, 0x07, 0x06, 0x01, 0x12, 0x03, 0xa0, 0x20, 0x00, 0x9f, 0x26, 0x08, 0x56, 0xcb, 0x4e, 0xe1, 0xa4, 0xef, 0xac, 0x74, 0x9f, 0x27, 0x01, 0x80, 0x9f, 0x36, 0x02, 0x00, 0x07, 0x9f, 0x6c, 0x02, 0x3e, 0x00, 0x9f, 0x6e, 0x04, 0x20, 0x70, 0x00, 0x00, 0x90, 0x00, 0xff, 0xff};
|
||||
|
||||
// do the replacement
|
||||
template[1] = resp[1]; // class bit
|
||||
|
||||
template[61] = resp[11];
|
||||
template[62] = resp[12];
|
||||
|
||||
template[46] = resp[16];
|
||||
template[47] = resp[17];
|
||||
template[48] = resp[18];
|
||||
template[49] = resp[19];
|
||||
template[50] = resp[20];
|
||||
template[51] = resp[21];
|
||||
template[52] = resp[22];
|
||||
template[53] = resp[23];
|
||||
template[54] = resp[24];
|
||||
|
||||
template[36] = resp[27];
|
||||
template[37] = resp[28];
|
||||
template[38] = resp[29];
|
||||
template[39] = resp[30];
|
||||
template[40] = resp[31];
|
||||
template[41] = resp[32];
|
||||
template[42] = resp[33];
|
||||
|
||||
Dbprintf("\nrearranged is: ");
|
||||
len = sizeof(template);
|
||||
Dbhexdump(len, &template[0], false); // special print
|
||||
|
||||
AddCrc14A(&template[1], len-3);
|
||||
Dbprintf("\nafter crc rearranged is: ");
|
||||
Dbhexdump(len, &template[0], false); // special print
|
||||
Dbprintf("\n");
|
||||
|
||||
//EmSendCmd(&template[1], len-1);
|
||||
memcpy(output, &template[1], len-1);
|
||||
*olen = len-1;
|
||||
|
||||
BigBuf_free();
|
||||
return;
|
||||
}
|
||||
|
||||
//Dbhexdump(len, &resp[1], false); // special print
|
||||
AddCrc14A(&resp[1], len);
|
||||
Dbhexdump(len+2, &resp[1], false); // special print
|
||||
|
||||
// Check we don't want to modify the response (application profile response)
|
||||
//uint8_t modifyme[] = {0x03, 0x77, 0x0e, 0x82, 0x02};
|
||||
|
||||
BigBuf_free();
|
||||
|
||||
if (prepend == 0xff) {
|
||||
Dbprintf("pdol request, we can can the response...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp(&resp[2], &pay1_response[0], sizeof(pay1_response)) == 0 && true) {
|
||||
Dbprintf("Switching out the pay1 response for a pay2 response...");
|
||||
//EmSendCmd(&pay2_response[0], sizeof(pay2_response));
|
||||
memcpy(output, &pay2_response[0], sizeof(pay2_response));
|
||||
*olen = sizeof(pay2_response);
|
||||
}
|
||||
else if (memcmp(&resp[1], &fci_template[0], 2) == 0 && true) {
|
||||
Dbprintf("***** modifying response to have full fci template...!");
|
||||
//EmSendCmd(&fci_template[0], sizeof(fci_template));
|
||||
memcpy(output, &fci_template[0], sizeof(fci_template));
|
||||
*olen = sizeof(fci_template);
|
||||
} else {
|
||||
//Dbprintf("***** not modifying response...");
|
||||
//EmSendCmd(&resp[1], len + 2);
|
||||
memcpy(output, &resp[1], len + 2);
|
||||
*olen = len + 2;
|
||||
}
|
||||
|
||||
BigBuf_free();
|
||||
|
||||
//memcpy(saved_command, &resp[1], len+2);
|
||||
//saved_command_len = len+2;
|
||||
//EmSendCmd14443aRaw(&resp[1], len+2);
|
||||
//FpgaDisableTracing();
|
||||
//EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
||||
}
|
||||
|
||||
//reply_ng(CMD_SMART_RAW, PM3_SUCCESS, resp, len);
|
||||
|
||||
OUT:
|
||||
//BigBuf_free();
|
||||
//set_tracing(false);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
int CmdSmartRaw(const uint8_t prepend, const uint8_t *data, int dlen, uint8_t *output, uint16_t *olen) {
|
||||
|
||||
Dbprintf("sending command to smart card... %02x %02x %02x... =>", prepend, data[0], data[1]);
|
||||
Dbhexdump(dlen, data, false);
|
||||
|
||||
if (data[4] + 5 != dlen) {
|
||||
Dbprintf("invalid length of data. Received: %d, command specifies %d", dlen, data[4] + 5);
|
||||
dlen = data[4] + 5;
|
||||
}
|
||||
|
||||
//smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + dlen);
|
||||
smart_card_raw_t *payload = (smart_card_raw_t *)BigBuf_calloc(sizeof(smart_card_raw_t) + dlen);
|
||||
if (payload == NULL) {
|
||||
Dbprintf("failed to allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
payload->len = dlen;
|
||||
memcpy(payload->data, data, dlen);
|
||||
|
||||
payload->flags = SC_LOG;
|
||||
bool active = true;
|
||||
bool active_select = false;
|
||||
int timeout = 600;
|
||||
bool use_t0 = true;
|
||||
|
||||
if (active || active_select) {
|
||||
|
||||
payload->flags |= (SC_CONNECT | SC_CLEARLOG);
|
||||
if (active_select)
|
||||
payload->flags |= SC_SELECT;
|
||||
}
|
||||
|
||||
payload->wait_delay = 0;
|
||||
if (timeout > -1) {
|
||||
payload->flags |= SC_WAIT;
|
||||
payload->wait_delay = timeout;
|
||||
}
|
||||
//Dbprintf("SIM Card timeout... %u ms", payload->wait_delay);
|
||||
|
||||
if (dlen > 0) {
|
||||
if (use_t0)
|
||||
payload->flags |= SC_RAW_T0;
|
||||
else
|
||||
payload->flags |= SC_RAW;
|
||||
}
|
||||
|
||||
////uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
|
||||
//uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
|
||||
//if (buf == NULL) {
|
||||
// Dbprintf("failed to allocate memory");
|
||||
// free(payload);
|
||||
// return PM3_EMALLOC;
|
||||
//}
|
||||
|
||||
|
||||
//clearCommandBuffer();
|
||||
//SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + dlen);
|
||||
|
||||
//for (int i = 0; i < dlen; i++) {
|
||||
// Dbprintf("%02x ", data[i]);
|
||||
//}
|
||||
|
||||
SmartCardDirectSend(prepend, payload, output, olen);
|
||||
|
||||
//if (reply == false) {
|
||||
// Dbprintf("failed to talk to smart card!!!");
|
||||
// goto out;
|
||||
//}
|
||||
|
||||
//// reading response from smart card
|
||||
//int len = smart_response(buf, PM3_CMD_DATA_SIZE);
|
||||
//if (len < 0) {
|
||||
// free(payload);
|
||||
// free(buf);
|
||||
// return PM3_ESOFT;
|
||||
//}
|
||||
|
||||
//if (buf[0] == 0x6C) {
|
||||
|
||||
// // request more bytes to download
|
||||
// data[4] = buf[1];
|
||||
// memcpy(payload->data, data, dlen);
|
||||
// clearCommandBuffer();
|
||||
// SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + dlen);
|
||||
|
||||
// len = smart_response(buf, PM3_CMD_DATA_SIZE);
|
||||
|
||||
// data[4] = 0;
|
||||
//}
|
||||
|
||||
//if (decode_tlv && len > 4) {
|
||||
// TLVPrintFromBuffer(buf, len - 2);
|
||||
//} else {
|
||||
// if (len > 2) {
|
||||
// Dbprintf("Response data:");
|
||||
// Dbprintf(" # | bytes | ascii");
|
||||
// Dbprintf("---+-------------------------------------------------+-----------------");
|
||||
// print_hex_break(buf, len, 16);
|
||||
// }
|
||||
//}
|
||||
|
||||
//memcpy(buffer, buf, len);
|
||||
|
||||
//out:
|
||||
//free(payload);
|
||||
//free(buf);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// See LICENSE.txt for the text of the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __I2C_DIRECT_H
|
||||
#define __I2C_DIRECT_H
|
||||
|
||||
int CmdSmartRaw(const uint8_t prepend, const uint8_t *data, int dlen, uint8_t *output, uint16_t *olen);
|
||||
|
||||
#endif
|
||||
+69
-2
@@ -39,7 +39,6 @@
|
||||
#include "crypto/libpcrypto.h"
|
||||
#include "iso4217.h" // currency lookup
|
||||
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
#define TLV_ADD(tag, value)( tlvdb_change_or_add_node(tlvRoot, tag, sizeof(value) - 1, (const unsigned char *)value) )
|
||||
@@ -630,6 +629,73 @@ static int CmdEMVSelect(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdEMVSmartToNFC(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "emv smart2nfc",
|
||||
"Executes ISO14443a payment, TX using ISO7816 interface for authentication",
|
||||
"emv smart2nfc -t -> test that the attached card is working (must be VISA)\n");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("t", "test", "test that the attached card is working (must be VISA)"),
|
||||
arg_str0("u", "uid", "<hex>", "optional 7 hex bytes UID"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
int uid_len = 0;
|
||||
uint8_t uid[7] = {0};
|
||||
CLIGetHexWithReturn(ctx, 2, uid, &uid_len);
|
||||
|
||||
if (uid_len == 0) {
|
||||
PrintAndLogEx(SUCCESS, "No UID provided, using default.");
|
||||
uint8_t default_uid[7] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
memcpy(uid, default_uid, sizeof(default_uid));
|
||||
uid_len = sizeof(default_uid);
|
||||
} else if (uid_len != 7) {
|
||||
PrintAndLogEx(FAILED, "UID must be 7 bytes long.");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "UID length is %d", uid_len);
|
||||
|
||||
bool testMode = arg_get_lit(ctx, 1);
|
||||
bool show_apdu = true;
|
||||
|
||||
if (testMode) {
|
||||
PrintAndLogEx(SUCCESS, "Test mode enabled.");
|
||||
} else {
|
||||
PrintAndLogEx(SUCCESS, "Test mode disabled.");
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// todo: check this is relevant for us.
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
struct {
|
||||
uint16_t flags;
|
||||
uint8_t exitAfter;
|
||||
uint8_t uid[7];
|
||||
uint16_t atqa;
|
||||
uint8_t sak;
|
||||
} PACKED payload;
|
||||
|
||||
memcpy(payload.uid, uid, uid_len);
|
||||
payload.flags = 0x1204;
|
||||
payload.exitAfter = 0x1;
|
||||
payload.atqa = 0x0;
|
||||
payload.sak = 0x20;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(0x0386, (uint8_t *)&payload, sizeof(payload));
|
||||
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " to abort simulation");
|
||||
|
||||
SetAPDULogging(false);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdEMVSearch(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
@@ -2913,8 +2979,9 @@ static command_t CommandTable[] = {
|
||||
{"scan", CmdEMVScan, IfPm3Iso14443, "Scan EMV card and save it contents to json file for emulator"},
|
||||
{"search", CmdEMVSearch, IfPm3Iso14443, "Try to select all applets from applets list and print installed applets"},
|
||||
{"select", CmdEMVSelect, IfPm3Iso14443, "Select applet"},
|
||||
/*
|
||||
{"-----------", CmdHelp, IfPm3Iso14443a, "---------------------- " _CYAN_("simulation") " ---------------------"},
|
||||
{"smart2nfc", CmdEMVSmartToNFC, IfPm3Iso14443, "Complete transaction as a nfc smart card, using the ISO-7816 interface for auth"},
|
||||
/*
|
||||
{"getrng", CmdEMVGetrng, IfPm3Iso14443, "Get random number from terminal"},
|
||||
{"eload", CmdEmvELoad, IfPm3Iso14443, "Load EMV tag into device"},
|
||||
{"dump", CmdEmvDump, IfPm3Iso14443, "Dump EMV tag values"},
|
||||
|
||||
@@ -612,6 +612,7 @@ typedef struct {
|
||||
#define CMD_HF_ISO14443A_SIM_AID 0x1420
|
||||
|
||||
#define CMD_HF_ISO14443A_READER 0x0385
|
||||
#define CMD_HF_ISO14443A_EMV_SIMULATE 0x0386
|
||||
|
||||
#define CMD_HF_LEGIC_SIMULATE 0x0387
|
||||
#define CMD_HF_LEGIC_READER 0x0388
|
||||
|
||||
@@ -137,6 +137,7 @@ typedef struct {
|
||||
#define CMD_HF_ISO14443A_SNIFF 0x0383
|
||||
#define CMD_HF_ISO14443A_SIMULATE 0x0384
|
||||
#define CMD_HF_ISO14443A_READER 0x0385
|
||||
#define CMD_HF_ISO14443A_EMV_SIMULATE 0x0386
|
||||
|
||||
#define CMD_HF_LEGIC_SIMULATE 0x0387
|
||||
#define CMD_HF_LEGIC_READER 0x0388
|
||||
@@ -180,7 +181,7 @@ typedef struct {
|
||||
|
||||
#define CMD_HF_MIFARE_READER 0x0611
|
||||
#define CMD_HF_MIFARE_NESTED 0x0612
|
||||
#define CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES 0x0613
|
||||
#define CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES 0x0613
|
||||
|
||||
|
||||
#define CMD_HF_MIFARE_READBL 0x0620
|
||||
|
||||
Reference in New Issue
Block a user