#include "mifarecmd.h"\r
#include "apps.h"\r
#include "util.h"\r
-\r
#include "crc.h"\r
\r
//-----------------------------------------------------------------------------\r
}\r
\r
for (int i = 0; i < blocks; i++){\r
- if ((i*4) + 4 > CARD_MEMORY_SIZE) {\r
+ if ((i*4) + 4 >= CARD_MEMORY_SIZE) {\r
Dbprintf("Data exceeds buffer!!");\r
break;\r
}\r
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks);\r
\r
countblocks *= 4;\r
- cmd_send(CMD_ACK, 1, countblocks, countblocks, 0, 0);\r
+\r
+ cmd_send(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
+ BigBuf_free();\r
}\r
\r
//-----------------------------------------------------------------------------\r
LEDsoff();\r
}\r
\r
-void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)\r
+/* // Command not needed but left for future testing \r
+void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain)\r
{\r
uint8_t blockNo = arg0;\r
byte_t blockdata[16] = {0x00};\r
return;\r
};\r
\r
- if(mifare_ultra_writeblock(blockNo, blockdata)) {\r
+ if(mifare_ultra_writeblock_compat(blockNo, blockdata)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
OnError(0);\r
return; };\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
+*/\r
\r
// Arg0 : Block to write to.\r
// Arg1 : 0 = use no authentication.\r
// 2 = use 0x1B authentication.\r
// datain : 4 first bytes is data to be written.\r
// : 4/16 next bytes is authentication key.\r
-void MifareUWriteBlock_Special(uint8_t arg0, uint8_t arg1, uint8_t *datain)\r
+void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)\r
{\r
uint8_t blockNo = arg0;\r
bool useKey = (arg1 == 1); //UL_C\r
}\r
}\r
\r
- if(mifare_ultra_special_writeblock(blockNo, blockdata)) {\r
+ if(mifare_ultra_writeblock(blockNo, blockdata)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
OnError(0);\r
return;\r
blockdata[1] = pwd[6];\r
blockdata[2] = pwd[5];\r
blockdata[3] = pwd[4];\r
- if(mifare_ultra_special_writeblock( 44, blockdata)) {\r
+ if(mifare_ultra_writeblock( 44, blockdata)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
OnError(44);\r
return;\r
blockdata[1] = pwd[2];\r
blockdata[2] = pwd[1];\r
blockdata[3] = pwd[0];\r
- if(mifare_ultra_special_writeblock( 45, blockdata)) {\r
+ if(mifare_ultra_writeblock( 45, blockdata)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
OnError(45);\r
return;\r
blockdata[1] = pwd[14];\r
blockdata[2] = pwd[13];\r
blockdata[3] = pwd[12];\r
- if(mifare_ultra_special_writeblock( 46, blockdata)) {\r
+ if(mifare_ultra_writeblock( 46, blockdata)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
OnError(46);\r
return;\r
blockdata[1] = pwd[10];\r
blockdata[2] = pwd[9];\r
blockdata[3] = pwd[8];\r
- if(mifare_ultra_special_writeblock( 47, blockdata)) {\r
+ if(mifare_ultra_writeblock( 47, blockdata)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
OnError(47);\r
return;\r
\r
\r
// statistics on nonce distance\r
+ int16_t isOK = 0;\r
+ #define NESTED_MAX_TRIES 12\r
+ uint16_t unsuccessfull_tries = 0;\r
if (calibrate) { // for first call only. Otherwise reuse previous calibration\r
LED_B_ON();\r
WDT_HIT();\r
\r
for (rtr = 0; rtr < 17; rtr++) {\r
\r
+ // Test if the action was cancelled\r
+ if(BUTTON_PRESS()) {\r
+ isOK = -2;\r
+ break;\r
+ }\r
+\r
// prepare next select. No need to power down the card.\r
if(mifare_classic_halt(pcs, cuid)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error");\r
delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing\r
}\r
if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i);\r
+ } else {\r
+ unsuccessfull_tries++;\r
+ if (unsuccessfull_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable)\r
+ isOK = -3;\r
+ }\r
}\r
}\r
- \r
- if (rtr <= 1) return;\r
\r
davg = (davg + (rtr - 1)/2) / (rtr - 1);\r
\r
- if (MF_DBGLEVEL >= 3) Dbprintf("min=%d max=%d avg=%d, delta_time=%d", dmin, dmax, davg, delta_time);\r
+ if (MF_DBGLEVEL >= 3) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time);\r
\r
dmin = davg - 2;\r
dmax = davg + 2;\r
LED_C_ON();\r
\r
// get crypted nonces for target sector\r
- for(i=0; i < 2; i++) { // look for exactly two different nonces\r
+ for(i=0; i < 2 && !isOK; i++) { // look for exactly two different nonces\r
\r
target_nt[i] = 0;\r
while(target_nt[i] == 0) { // continue until we have an unambiguous nonce\r
\r
// nested authentication\r
auth2_time = auth1_time + delta_time;\r
- len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);\r
+ len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);\r
if (len != 4) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len);\r
continue;\r
memcpy(buf+16, &target_ks[1], 4);\r
\r
LED_B_ON();\r
- cmd_send(CMD_ACK, 0, 2, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));\r
+ cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));\r
LED_B_OFF();\r
\r
if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED");\r