Merge branch 'master' into atrzerocheck

This commit is contained in:
Oleg Moiseenko 2018-12-20 23:07:30 +02:00 committed by GitHub
commit a47fa470c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 66 deletions

View file

@ -15,14 +15,15 @@ int usage_sm_raw(void) {
PrintAndLogEx(NORMAL, "Usage: sc raw [h|r|c] d <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " r : do not read response");
PrintAndLogEx(NORMAL, " a : active smartcard without select");
PrintAndLogEx(NORMAL, " s : active smartcard with select");
PrintAndLogEx(NORMAL, " a : active smartcard without select (reset sc module)");
PrintAndLogEx(NORMAL, " s : active smartcard with select (get ATR)");
PrintAndLogEx(NORMAL, " t : executes TLV decoder if it possible");
PrintAndLogEx(NORMAL, " 0 : use protocol T=0");
PrintAndLogEx(NORMAL, " d <bytes> : bytes to send");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " sc raw d 00a404000e315041592e5359532e444446303100 - `1PAY.SYS.DDF01` PPSE directory");
PrintAndLogEx(NORMAL, " sc raw d 00a404000e325041592e5359532e444446303100 - `2PAY.SYS.DDF01` PPSE directory");
PrintAndLogEx(NORMAL, " sc raw s 0 d 00a404000e315041592e5359532e4444463031 - `1PAY.SYS.DDF01` PPSE directory with get ATR");
PrintAndLogEx(NORMAL, " sc raw 0 d 00a404000e325041592e5359532e4444463031 - `2PAY.SYS.DDF01` PPSE directory");
return 0;
}
int usage_sm_reader(void) {
@ -79,7 +80,7 @@ uint8_t GetATRTA1(uint8_t *atr, size_t atrlen) {
return atr[2];
}
return 0x11; // default value is 0x11, corresponding to fmax=5 MHz, Fi=372, Di=1.
return 0x11; // default value is 0x11, corresponding to fmax=5 MHz, Fi=372, Di=1.
}
int DiArray[] = {
@ -158,58 +159,46 @@ float GetATRF(uint8_t *atr, size_t atrlen) {
}
static int PrintATR(uint8_t *atr, size_t atrlen) {
uint8_t vxor = 0;
for (int i = 1; i < atrlen; i++)
vxor ^= atr[i];
if (vxor)
PrintAndLogEx(WARNING, "Check summ error. Must be 0 but: 0x%02x", vxor);
else
PrintAndLogEx(INFO, "Check summ OK.");
if (atr[0] != 0x3b)
PrintAndLogEx(WARNING, "Not a direct convention: 0x%02x", atr[0]);
uint8_t T0 = atr[1];
uint8_t K = T0 & 0x0F;
uint8_t TD1 = 0;
uint8_t T1len = 0;
uint8_t TD1len = 0;
uint8_t TDilen = 0;
uint8_t TD1 = 0, T1len = 0, TD1len = 0, TDilen = 0;
if (T0 & 0x10) {
PrintAndLog("TA1 (Maximum clock frequency, proposed bit duration): 0x%02x", atr[2 + T1len]);
PrintAndLog("\t- TA1 (Maximum clock frequency, proposed bit duration) [ 0x%02x ]", atr[2 + T1len]);
T1len++;
}
if (T0 & 0x20) {
PrintAndLog("TB1 (Deprecated: VPP requirements): 0x%02x", atr[2 + T1len]);
PrintAndLog("\t- TB1 (Deprecated: VPP requirements) [ 0x%02x ]", atr[2 + T1len]);
T1len++;
}
if (T0 & 0x40) {
PrintAndLog("TC1 (Extra delay between bytes required by card): 0x%02x", atr[2 + T1len]);
PrintAndLog("\t- TC1 (Extra delay between bytes required by card) [ 0x%02x ]", atr[2 + T1len]);
T1len++;
}
if (T0 & 0x80) {
TD1 = atr[2 + T1len];
PrintAndLog("TD1 (First offered transmission protocol, presence of TA2..TD2): 0x%02x. Protocol T=%d", TD1, TD1 & 0x0f);
PrintAndLog("\t- TD1 (First offered transmission protocol, presence of TA2..TD2) [ 0x%02x ] Protocol T%d", TD1, TD1 & 0x0f);
T1len++;
if (TD1 & 0x10) {
PrintAndLog("TA2 (Specific protocol and parameters to be used after the ATR): 0x%02x", atr[2 + T1len + TD1len]);
PrintAndLog("\t- TA2 (Specific protocol and parameters to be used after the ATR) [ 0x%02x ]", atr[2 + T1len + TD1len]);
TD1len++;
}
if (TD1 & 0x20) {
PrintAndLog("TB2 (Deprecated: VPP precise voltage requirement): 0x%02x", atr[2 + T1len + TD1len]);
PrintAndLog("\t- TB2 (Deprecated: VPP precise voltage requirement) [ 0x%02x ]", atr[2 + T1len + TD1len]);
TD1len++;
}
if (TD1 & 0x40) {
PrintAndLog("TC2 (Maximum waiting time for protocol T=0): 0x%02x", atr[2 + T1len + TD1len]);
PrintAndLog("\t- TC2 (Maximum waiting time for protocol T=0) [ 0x%02x ]", atr[2 + T1len + TD1len]);
TD1len++;
}
if (TD1 & 0x80) {
uint8_t TDi = atr[2 + T1len + TD1len];
PrintAndLog("TD2 (A supported protocol or more global parameters, presence of TA3..TD3): 0x%02x. Protocol T=%d", TDi, TDi & 0x0f);
PrintAndLog("\t- TD2 (A supported protocol or more global parameters, presence of TA3..TD3) [ 0x%02x ] Protocol T%d", TDi, TDi & 0x0f);
TD1len++;
bool nextCycle = true;
@ -217,20 +206,20 @@ static int PrintATR(uint8_t *atr, size_t atrlen) {
while (nextCycle) {
nextCycle = false;
if (TDi & 0x10) {
PrintAndLog("TA%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
PrintAndLog("\t- TA%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
TDilen++;
}
if (TDi & 0x20) {
PrintAndLog("TB%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
PrintAndLog("\t- TB%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
TDilen++;
}
if (TDi & 0x40) {
PrintAndLog("TC%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
PrintAndLog("\t- TC%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
TDilen++;
}
if (TDi & 0x80) {
TDi = atr[2 + T1len + TD1len + TDilen];
PrintAndLog("TD%d: 0x%02x. Protocol T=%d", vi, TDi, TDi & 0x0f);
PrintAndLog("\t- TD%d [ 0x%02x ] Protocol T%d", vi, TDi, TDi & 0x0f);
TDilen++;
nextCycle = true;
@ -239,26 +228,36 @@ static int PrintATR(uint8_t *atr, size_t atrlen) {
}
}
}
uint8_t vxor = 0;
for (int i = 1; i < atrlen; i++)
vxor ^= atr[i];
if (vxor)
PrintAndLogEx(WARNING, "Check summ error. Must be 0 got 0x%02X", vxor);
else
PrintAndLogEx(INFO, "Check summ OK.");
if (atr[0] != 0x3b)
PrintAndLogEx(WARNING, "Not a direct convention [ 0x%02x ]", atr[0]);
uint8_t calen = 2 + T1len + TD1len + TDilen + K;
if (atrlen != calen && atrlen != calen + 1) // may be CRC
PrintAndLogEx(ERR, "ATR length error. len: %d, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K);
else
PrintAndLogEx(INFO, "ATR length OK.");
PrintAndLog("Historical bytes len: 0x%02x", K);
if (K > 0)
PrintAndLog("The format of historical bytes: %02x", atr[2 + T1len + TD1len + TDilen]);
PrintAndLogEx(INFO, "\nHistorical bytes | len 0x%02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]);
if (K > 1) {
PrintAndLog("Historical bytes:");
PrintAndLogEx(INFO, "\tHistorical bytes");
dump_buffer(&atr[2 + T1len + TD1len + TDilen], K, NULL, 1);
}
return 0;
}
static bool smart_select(bool silent) {
UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}};
clearCommandBuffer();
@ -288,7 +287,7 @@ static bool smart_select(bool silent) {
static int smart_wait(uint8_t *data) {
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
PrintAndLogEx(WARNING, "smart card response failed");
PrintAndLogEx(WARNING, "smart card response timeout");
return -1;
}
@ -298,11 +297,12 @@ static int smart_wait(uint8_t *data) {
return -2;
}
memcpy(data, resp.d.asBytes, len);
PrintAndLogEx(SUCCESS, " %d | %s", len, sprint_hex_inrow_ex(data, len, 32));
if (len >= 2) {
PrintAndLogEx(SUCCESS, "%02X%02X | %s", data[len - 2], data[len - 1], GetAPDUCodeDescription(data[len - 2], data[len - 1]));
} else {
PrintAndLogEx(SUCCESS, " %d | %s", len, sprint_hex_inrow_ex(data, len, 8));
}
return len;
}
@ -321,7 +321,7 @@ static int smart_response(uint8_t *data) {
if (needGetData) {
int len = data[datalen - 1];
PrintAndLogEx(INFO, "Requesting response. len=0x%x", len);
PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len);
uint8_t getstatus[] = {0x00, ISO7816_GETSTATUS, 0x00, 0x00, len};
UsbCommand cStatus = {CMD_SMART_RAW, {SC_RAW, sizeof(getstatus), 0}};
memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) );
@ -339,7 +339,7 @@ static int smart_response(uint8_t *data) {
// data with ACK
if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK
if (data[0] != ISO7816_GETSTATUS) {
PrintAndLogEx(ERR, "GetResponse ACK error. len=0x%x data[0]=%02x", len, data[0]);
PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, data[0]);
datalen = 0;
goto out;
}
@ -348,7 +348,7 @@ static int smart_response(uint8_t *data) {
memmove(data, &data[1], datalen);
} else {
// wrong length
PrintAndLogEx(WARNING, "GetResponse wrong length. Must be: 0x%02x but: 0x%02x", len, datalen - 3);
PrintAndLogEx(WARNING, "GetResponse wrong length. Must be 0x%02X got 0x%02X", len, datalen - 3);
}
}
}
@ -362,6 +362,7 @@ int CmdSmartRaw(const char *Cmd) {
int hexlen = 0;
bool active = false;
bool active_select = false;
bool useT0 = false;
uint8_t cmdp = 0;
bool errors = false, reply = true, decodeTLV = false, breakloop = false;
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
@ -385,6 +386,10 @@ int CmdSmartRaw(const char *Cmd) {
decodeTLV = true;
cmdp++;
break;
case '0':
useT0 = true;
cmdp++;
break;
case 'd': {
switch (param_gethex_to_eol(Cmd, cmdp+1, data, sizeof(data), &hexlen)) {
case 1:
@ -425,7 +430,10 @@ int CmdSmartRaw(const char *Cmd) {
}
if (hexlen > 0) {
c.arg[0] |= SC_RAW;
if (useT0)
c.arg[0] |= SC_RAW_T0;
else
c.arg[0] |= SC_RAW;
}
memcpy(c.d.asBytes, data, hexlen );
@ -457,7 +465,7 @@ int CmdSmartRaw(const char *Cmd) {
}
if (decodeTLV && len > 4)
TLVPrintFromBuffer(buf+1, len-3);
TLVPrintFromBuffer(buf, len-2);
free(buf);
}
@ -469,7 +477,8 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave
if (activateCard)
smart_select(false);
printf("* APDU SC\n");
PrintAndLogEx(DEBUG, "APDU SC");
UsbCommand c = {CMD_SMART_RAW, {SC_RAW_T0, datainlen, 0}};
if (activateCard) {
@ -504,7 +513,6 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave
return 0;
}
int CmdSmartUpgrade(const char *Cmd) {
PrintAndLogEx(WARNING, "WARNING - Smartcard socket firmware upgrade.");
@ -652,35 +660,35 @@ int CmdSmartInfo(const char *Cmd){
memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t));
// print header
PrintAndLogEx(INFO, "\n--- Smartcard Information ---------");
PrintAndLogEx(INFO, "--- Smartcard Information ---------");
PrintAndLogEx(INFO, "-------------------------------------------------------------");
PrintAndLogEx(INFO, "ISO76183 ATR : %s", sprint_hex(card.atr, card.atr_len));
PrintAndLogEx(INFO, "look up ATR");
PrintAndLogEx(INFO, "http://smartcard-atr.appspot.com/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len) );
PrintAndLogEx(INFO, "ISO7618-3 ATR : %s", sprint_hex(card.atr, card.atr_len));
PrintAndLogEx(INFO, "\nhttp://smartcard-atr.appspot.com/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len) );
// print ATR
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "* ATR:");
PrintAndLogEx(INFO, "ATR");
PrintATR(card.atr, card.atr_len);
// print D/F (brom byte TA1 or defaults)
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "* D/F (TA1):");
PrintAndLogEx(INFO, "D/F (TA1)");
int Di = GetATRDi(card.atr, card.atr_len);
int Fi = GetATRFi(card.atr, card.atr_len);
float F = GetATRF(card.atr, card.atr_len);
if (GetATRTA1(card.atr, card.atr_len) == 0x11)
PrintAndLogEx(INFO, "Using default values...");
PrintAndLogEx(NORMAL, "Di=%d", Di);
PrintAndLogEx(NORMAL, "Fi=%d", Fi);
PrintAndLogEx(NORMAL, "F=%.1f MHz", F);
PrintAndLogEx(NORMAL, "\t- Di=%d", Di);
PrintAndLogEx(NORMAL, "\t- Fi=%d", Fi);
PrintAndLogEx(NORMAL, "\t- F=%.1f MHz", F);
if (Di && Fi) {
PrintAndLogEx(NORMAL, "Cycles/ETU=%d", Fi/Di);
PrintAndLogEx(NORMAL, "%.1f bits/sec at 4MHz", (float)4000000 / (Fi/Di));
PrintAndLogEx(NORMAL, "%.1f bits/sec at Fmax=%.1fMHz", (F * 1000000) / (Fi/Di), F);
PrintAndLogEx(NORMAL, "\t- Cycles/ETU=%d", Fi/Di);
PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at 4MHz", (float)4000000 / (Fi/Di));
PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at Fmax=%.1fMHz", (F * 1000000) / (Fi/Di), F);
} else {
PrintAndLogEx(WARNING, "Di or Fi is RFU.");
PrintAndLogEx(WARNING, "\t- Di or Fi is RFU.");
};
return 0;
@ -801,8 +809,9 @@ int CmdSmartBruteforceSFI(const char *Cmd) {
}
PrintAndLogEx(INFO, "Selecting PPSE aid");
CmdSmartRaw("d 00a404000e325041592e5359532e444446303100");
CmdSmartRaw("d 00a4040007a000000004101000");
CmdSmartRaw("s 0 t d 00a404000e325041592e5359532e4444463031");
CmdSmartRaw("0 t d 00a4040007a000000004101000"); // mastercard
// CmdSmartRaw("0 t d 00a4040007a0000000031010"); // visa
PrintAndLogEx(INFO, "starting");
@ -823,7 +832,6 @@ int CmdSmartBruteforceSFI(const char *Cmd) {
smart_response(buf);
// if 0x6C
if ( buf[0] == 0x6C ) {
data[4] = buf[1];

View file

@ -575,7 +575,7 @@ void I2C_print_status(void) {
I2C_Reset_EnterMainProgram();
uint8_t len = I2C_BufferRead(resp, sizeof(resp), I2C_DEVICE_CMD_GETVERSION, I2C_DEVICE_ADDRESS_MAIN);
if ( len > 0 )
Dbprintf(" version.................v%x.%02x", resp[0], resp[1]);
Dbprintf(" version.................v%x.%02d", resp[0], resp[1]);
else
DbpString(" version.................FAILED");
}

BIN
tools/simmodule/SIM010.BIN Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
136e157364609e5c395540dc8dadbfd6 *SIM010.BIN

View file

@ -0,0 +1 @@
e6ac5e6f1d7cc86d56f2128f2a495f1395fe044bf6ff3b6ca24ce90d1e361ae835fe273a206f2fc90e4344a13b37b180dd017a2c7f23312f1ed163f10c01ea5a *SIM010.BIN

View file

@ -0,0 +1,36 @@
2018-12-20 Iceman
=======================================
The latest firmware for the SIM MODULE is : SIM010.bin
You can use it to upgrade you sim module via the pm3 client.
pm3 --> sc upgrade -h
pm3 --> sc upgrade f ../tools/simmodule/SIM010.bin
Even its a quite fast command you should be warned. You may brick it if you interrupt it.
Run hw status command to verify that the upgrade went well.
pm3 --> hw status
If you didn't download this file from the RRG Repo be aware that it might be corrupt or faulty.
You find to hash text files in this folder. They were generated with the following linux commands.
md5sum -b SIM010.bin > SIM010.md5.txt
sha512sum -b SIM010.bin > SIM010.sha512.txt
You should validate the SIM010.bin file against these hash files in order to be sure the file is not corrupt or faulty.