// Work with mifare cards.\r
//-----------------------------------------------------------------------------\r
\r
-#include <string.h>\r
#include "mifareutil.h"\r
+\r
+#include <string.h>\r
+#include <stdbool.h>\r
+\r
#include "proxmark3.h"\r
#include "apps.h"\r
#include "util.h"\r
#include "parity.h"\r
-\r
#include "iso14443crc.h"\r
#include "iso14443a.h"\r
#include "crapto1/crapto1.h"\r
-#include "polarssl/des.h"\r
+#include "mbedtls/des.h"\r
\r
int MF_DBGLEVEL = MF_DBG_ALL;\r
\r
// crypto1 helpers\r
-void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){\r
+void mf_crypto1_decryptEx(struct Crypto1State *pcs, uint8_t *data_in, int len, uint8_t *data_out){\r
uint8_t bt = 0;\r
int i;\r
\r
if (len != 1) {\r
for (i = 0; i < len; i++)\r
- data[i] = crypto1_byte(pcs, 0x00, 0) ^ data[i];\r
+ data_out[i] = crypto1_byte(pcs, 0x00, 0) ^ data_in[i];\r
} else {\r
bt = 0;\r
for (i = 0; i < 4; i++)\r
- bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data[0], i)) << i;\r
+ bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], i)) << i;\r
\r
- data[0] = bt;\r
+ data_out[0] = bt;\r
}\r
return;\r
}\r
\r
+void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){\r
+ mf_crypto1_decryptEx(pcs, data, len, data);\r
+}\r
+\r
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par) {\r
uint8_t bt = 0;\r
int i;\r
\r
/// 3des2k\r
\r
- des3_context ctx = { 0x00 };\r
+ mbedtls_des3_context ctx = { {0} };\r
uint8_t random_a[8] = {1,1,1,1,1,1,1,1};\r
uint8_t random_b[8] = {0x00};\r
uint8_t enc_random_b[8] = {0x00};\r
\r
// decrypt nonce.\r
// tdes_2key_dec(random_b, enc_random_b, sizeof(random_b), key, IV );\r
- des3_set2key_dec(&ctx, key);\r
- des3_crypt_cbc(&ctx // des3_context\r
- , DES_DECRYPT // int mode\r
+ mbedtls_des3_set2key_dec(&ctx, key);\r
+ mbedtls_des3_crypt_cbc(&ctx // des3_context\r
+ , MBEDTLS_DES_DECRYPT // int mode\r
, sizeof(random_b) // length\r
, IV // iv[8]\r
, enc_random_b // input\r
\r
// encrypt out, in, length, key, iv\r
//tdes_2key_enc(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b);\r
- des3_set2key_enc(&ctx, key);\r
- des3_crypt_cbc(&ctx // des3_context\r
- , DES_ENCRYPT // int mode\r
+ mbedtls_des3_set2key_enc(&ctx, key);\r
+ mbedtls_des3_crypt_cbc(&ctx // des3_context\r
+ , MBEDTLS_DES_ENCRYPT // int mode\r
, sizeof(rnd_ab) // length\r
, enc_random_b // iv[8]\r
, rnd_ab // input\r
\r
// decrypt out, in, length, key, iv \r
// tdes_2key_dec(resp_random_a, enc_resp, 8, key, enc_random_b);\r
- des3_set2key_dec(&ctx, key);\r
- des3_crypt_cbc(&ctx // des3_context\r
- , DES_DECRYPT // int mode\r
+ mbedtls_des3_set2key_dec(&ctx, key);\r
+ mbedtls_des3_crypt_cbc(&ctx // des3_context\r
+ , MBEDTLS_DES_DECRYPT // int mode\r
, 8 // length\r
, enc_random_b // iv[8]\r
, enc_resp // input\r
return 1;\r
}\r
\r
+\r
+#define MFU_MAX_RETRIES 5\r
int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)\r
{\r
uint16_t len;\r
uint8_t bt[2];\r
uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
- \r
+ uint8_t retries;\r
+ int result = 0;\r
\r
- len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
- if (len == 1) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
- return 1;\r
- }\r
- if (len != 18) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len);\r
- return 2;\r
+ for (retries = 0; retries < MFU_MAX_RETRIES; retries++) {\r
+ len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
+ if (len == 1) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+ result = 1;\r
+ continue;\r
+ }\r
+ if (len != 18) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len);\r
+ result = 2;\r
+ continue;\r
+ }\r
+\r
+ memcpy(bt, receivedAnswer + 16, 2);\r
+ AppendCrc14443a(receivedAnswer, 16);\r
+ if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error.");\r
+ result = 3;\r
+ continue;\r
+ }\r
+\r
+ // No errors encountered; don't retry\r
+ result = 0;\r
+ break;\r
}\r
- \r
- memcpy(bt, receivedAnswer + 16, 2);\r
- AppendCrc14443a(receivedAnswer, 16);\r
- if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error.");\r
- return 3;\r
+\r
+ if (result != 0) {\r
+ Dbprintf("Cmd Error: too many retries; read failed");\r
+ return result;\r
}\r
- \r
+\r
memcpy(blockData, receivedAnswer, 14);\r
return 0;\r
}\r
\r
}\r
\r
+uint8_t SectorTrailer(uint8_t blockNo)\r
+{\r
+ if (blockNo < 32*4) {\r
+ return (blockNo | 0x03);\r
+ } else {\r
+ return (blockNo | 0x0f);\r
+ }\r
+}\r
+\r
+bool IsSectorTrailer(uint8_t blockNo)\r
+{\r
+ return (blockNo == SectorTrailer(blockNo));\r
+}\r
\r
// work with emulator memory\r
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {\r