Release v4.15864 - Radium
[RRG-proxmark3.git] / armsrc / mifareutil.c
blobfd9d86cccff8a80ae7b01fed5bf3a784e4dd2117
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Gerhard de Koning Gans - May 2008
3 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // See LICENSE.txt for the text of the license.
16 //-----------------------------------------------------------------------------
17 // Work with mifare cards.
18 //-----------------------------------------------------------------------------
19 #include "mifareutil.h"
21 #include "string.h"
22 #include "BigBuf.h"
23 #include "iso14443a.h"
24 #include "ticks.h"
25 #include "dbprint.h"
26 #include "parity.h"
27 #include "commonutil.h"
28 #include "crc16.h"
29 #include "protocols.h"
30 #include "desfire_crypto.h"
32 // crypto1 helpers
33 void mf_crypto1_decryptEx(struct Crypto1State *pcs, const uint8_t *data_in, int len, uint8_t *data_out) {
34 if (len != 1) {
35 for (int i = 0; i < len; i++)
36 data_out[i] = crypto1_byte(pcs, 0x00, 0) ^ data_in[i];
37 } else {
38 uint8_t bt = 0;
39 bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 0)) << 0;
40 bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 1)) << 1;
41 bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 2)) << 2;
42 bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 3)) << 3;
43 data_out[0] = bt;
45 return;
48 void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len) {
49 mf_crypto1_decryptEx(pcs, data, len, data);
52 void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par) {
53 mf_crypto1_encryptEx(pcs, data, NULL, data, len, par);
56 void mf_crypto1_encryptEx(struct Crypto1State *pcs, const uint8_t *data_in, uint8_t *keystream, uint8_t *data_out, uint16_t len, uint8_t *par) {
57 int i;
58 par[0] = 0;
60 for (i = 0; i < len; i++) {
61 uint8_t bt = data_in[i];
62 data_out[i] = crypto1_byte(pcs, keystream ? keystream[i] : 0x00, 0) ^ data_in[i];
63 if ((i & 0x0007) == 0)
64 par[ i >> 3 ] = 0;
65 par[ i >> 3 ] |= (((filter(pcs->odd) ^ oddparity8(bt)) & 0x01) << (7 - (i & 0x0007)));
69 uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
70 uint8_t bt = 0;
71 bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 0)) << 0;
72 bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 1)) << 1;
73 bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 2)) << 2;
74 bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 3)) << 3;
75 return bt;
78 // send X byte basic commands
79 uint16_t mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) {
81 uint8_t dcmd[data_size + 3];
82 dcmd[0] = cmd;
83 if (data_size > 0)
84 memcpy(dcmd + 1, data, data_size);
86 AddCrc14A(dcmd, data_size + 1);
87 ReaderTransmit(dcmd, sizeof(dcmd), timing);
88 uint16_t len = ReaderReceive(answer, answer_parity);
89 if (len == 0) {
90 if (g_dbglevel >= DBG_ERROR) Dbprintf("%02X Cmd failed. Card timeout.", cmd);
91 len = ReaderReceive(answer, answer_parity);
93 return len;
96 // send 2 byte commands
97 uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) {
98 uint16_t pos;
99 uint8_t dcmd[4] = {cmd, data, 0x00, 0x00};
100 uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00};
101 uint8_t par[1] = {0x00}; // 1 Byte parity is enough here
102 AddCrc14A(dcmd, 2);
103 memcpy(ecmd, dcmd, sizeof(dcmd));
105 if (pcs && crypted) {
106 par[0] = 0;
107 for (pos = 0; pos < 4; pos++) {
108 ecmd[pos] = crypto1_byte(pcs, 0x00, 0) ^ dcmd[pos];
109 par[0] |= (((filter(pcs->odd) ^ oddparity8(dcmd[pos])) & 0x01) << (7 - pos));
111 ReaderTransmitPar(ecmd, sizeof(ecmd), par, timing);
112 } else {
113 ReaderTransmit(dcmd, sizeof(dcmd), timing);
116 uint16_t len = ReaderReceive(answer, par);
118 if (answer_parity) *answer_parity = par[0];
120 if (pcs && (crypted == CRYPT_ALL)) {
121 if (len == 1) {
122 uint16_t res = 0;
123 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 0)) << 0;
124 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 1)) << 1;
125 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 2)) << 2;
126 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 3)) << 3;
127 answer[0] = res;
128 } else {
129 for (pos = 0; pos < len; pos++)
130 answer[pos] = crypto1_byte(pcs, 0x00, 0) ^ answer[pos];
133 return len;
136 // mifare classic commands
137 int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) {
138 return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);
141 int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) {
142 int len;
143 uint32_t pos, nt, ntpp; // Supplied tag nonce
144 uint8_t par[1] = {0x00};
145 uint8_t nr[4];
146 uint8_t mf_nr_ar[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
147 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
148 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
150 // "random" reader nonce:
151 num_to_bytes(prng_successor(GetTickCount(), 32), 4, nr);
153 // Transmit MIFARE_CLASSIC_AUTH
154 len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);
155 if (len != 4) return 1;
157 // Save the tag nonce (nt)
158 nt = bytes_to_num(receivedAnswer, 4);
160 // ----------------------------- crypto1 create
161 if (isNested)
162 crypto1_deinit(pcs);
164 // Init cipher with key
165 crypto1_init(pcs, ui64Key);
167 if (isNested == AUTH_NESTED) {
168 // decrypt nt with help of new key
169 nt = crypto1_word(pcs, nt ^ uid, 1) ^ nt;
170 } else {
171 // Load (plain) uid^nt into the cipher
172 crypto1_word(pcs, nt ^ uid, 0);
175 // some statistic
176 if (!ntptr && (g_dbglevel >= DBG_EXTENDED))
177 Dbprintf("auth uid: %08x | nr: %02x%02x%02x%02x | nt: %08x", uid, nr[0], nr[1], nr[2], nr[3], nt);
179 // save Nt
180 if (ntptr)
181 *ntptr = nt;
183 // Generate (encrypted) nr+parity by loading it into the cipher (Nr)
184 par[0] = 0;
185 for (pos = 0; pos < 4; pos++) {
186 mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos];
187 par[0] |= (((filter(pcs->odd) ^ oddparity8(nr[pos])) & 0x01) << (7 - pos));
190 // Skip 32 bits in pseudo random generator
191 nt = prng_successor(nt, 32);
193 // ar+parity
194 for (pos = 4; pos < 8; pos++) {
195 nt = prng_successor(nt, 8);
196 mf_nr_ar[pos] = crypto1_byte(pcs, 0x00, 0) ^ (nt & 0xff);
197 par[0] |= (((filter(pcs->odd) ^ oddparity8(nt & 0xff)) & 0x01) << (7 - pos));
200 // Transmit reader nonce and reader answer
201 ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
203 // save standard timeout
204 uint32_t save_timeout = iso14a_get_timeout();
206 // set timeout for authentication response
207 if (save_timeout > 103)
208 iso14a_set_timeout(103);
210 // Receive 4 byte tag answer
211 len = ReaderReceive(receivedAnswer, receivedAnswerPar);
213 iso14a_set_timeout(save_timeout);
215 if (!len) {
216 if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Authentication failed. Card timeout");
217 return 2;
220 ntpp = prng_successor(nt, 32) ^ crypto1_word(pcs, 0, 0);
222 if (ntpp != bytes_to_num(receivedAnswer, 4)) {
223 if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Authentication failed. Error card response");
224 return 3;
226 return 0;
229 int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) {
231 int len;
232 uint8_t bt[2] = {0x00, 0x00};
233 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
234 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
236 len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
237 if (len == 1) {
238 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error %02x", receivedAnswer[0]);
239 return 1;
241 if (len != 18) {
242 if (g_dbglevel >= DBG_ERROR) Dbprintf("wrong response len %d (expected 18)", len);
243 return 2;
246 memcpy(bt, receivedAnswer + 16, 2);
247 AddCrc14A(receivedAnswer, 16);
248 if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
249 if (g_dbglevel >= DBG_INFO) Dbprintf("CRC response error");
250 return 3;
253 memcpy(blockData, receivedAnswer, 16);
254 return 0;
257 // mifare ultralight commands
258 int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack) {
260 uint16_t len = 0;
261 uint8_t resp[4] = {0x00, 0x00, 0x00, 0x00};
262 uint8_t respPar[1] = {0x00};
263 uint8_t key[4] = {0x00, 0x00, 0x00, 0x00};
264 memcpy(key, keybytes, 4);
266 if (g_dbglevel >= DBG_EXTENDED)
267 Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]);
269 len = mifare_sendcmd(MIFARE_ULEV1_AUTH, key, sizeof(key), resp, respPar, NULL);
271 if (len != 4) {
272 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len);
273 return 0;
276 if (g_dbglevel >= DBG_EXTENDED)
277 Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0], resp[1], resp[2], resp[3]);
279 memcpy(pack, resp, 4);
280 return 1;
283 int mifare_ultra_auth(uint8_t *keybytes) {
285 /// 3des2k
286 uint8_t random_a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
287 uint8_t random_b[8] = {0x00};
288 uint8_t enc_random_b[8] = {0x00};
289 uint8_t rnd_ab[16] = {0x00};
290 uint8_t IV[8] = {0x00};
291 uint8_t key[16] = {0x00};
292 memcpy(key, keybytes, 16);
294 uint16_t len = 0;
295 uint8_t resp[19] = {0x00};
296 uint8_t respPar[3] = {0, 0, 0};
298 // REQUEST AUTHENTICATION
299 len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULC_AUTH_1, 0x00, resp, respPar, NULL);
300 if (len != 11) {
301 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
302 return 0;
305 // tag nonce.
306 memcpy(enc_random_b, resp + 1, 8);
308 // decrypt nonce.
309 tdes_nxp_receive((void *)enc_random_b, (void *)random_b, sizeof(random_b), (const void *)key, IV, 2);
310 rol(random_b, 8);
311 memcpy(rnd_ab, random_a, 8);
312 memcpy(rnd_ab + 8, random_b, 8);
314 if (g_dbglevel >= DBG_EXTENDED) {
315 Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x",
316 enc_random_b[0], enc_random_b[1], enc_random_b[2], enc_random_b[3], enc_random_b[4], enc_random_b[5], enc_random_b[6], enc_random_b[7]);
318 Dbprintf(" B: %02x %02x %02x %02x %02x %02x %02x %02x",
319 random_b[0], random_b[1], random_b[2], random_b[3], random_b[4], random_b[5], random_b[6], random_b[7]);
321 Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x",
322 rnd_ab[0], rnd_ab[1], rnd_ab[2], rnd_ab[3], rnd_ab[4], rnd_ab[5], rnd_ab[6], rnd_ab[7]);
324 Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x",
325 rnd_ab[8], rnd_ab[9], rnd_ab[10], rnd_ab[11], rnd_ab[12], rnd_ab[13], rnd_ab[14], rnd_ab[15]);
328 // encrypt out, in, length, key, iv
329 tdes_nxp_send(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b, 2);
331 len = mifare_sendcmd(MIFARE_ULC_AUTH_2, rnd_ab, sizeof(rnd_ab), resp, respPar, NULL);
332 if (len != 11) {
333 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
334 return 0;
337 uint8_t enc_resp[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
338 uint8_t resp_random_a[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
339 memcpy(enc_resp, resp + 1, 8);
341 // decrypt out, in, length, key, iv
342 tdes_nxp_receive(enc_resp, resp_random_a, 8, key, enc_random_b, 2);
343 if (memcmp(resp_random_a, random_a, 8) != 0) {
344 if (g_dbglevel >= DBG_ERROR) Dbprintf("failed authentication");
345 return 0;
348 if (g_dbglevel >= DBG_EXTENDED) {
349 Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x",
350 rnd_ab[0], rnd_ab[1], rnd_ab[2], rnd_ab[3],
351 rnd_ab[4], rnd_ab[5], rnd_ab[6], rnd_ab[7]);
353 Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x",
354 rnd_ab[8], rnd_ab[9], rnd_ab[10], rnd_ab[11],
355 rnd_ab[12], rnd_ab[13], rnd_ab[14], rnd_ab[15]);
357 Dbprintf("a: %02x %02x %02x %02x %02x %02x %02x %02x",
358 random_a[0], random_a[1], random_a[2], random_a[3],
359 random_a[4], random_a[5], random_a[6], random_a[7]);
361 Dbprintf("b: %02x %02x %02x %02x %02x %02x %02x %02x",
362 resp_random_a[0], resp_random_a[1], resp_random_a[2], resp_random_a[3],
363 resp_random_a[4], resp_random_a[5], resp_random_a[6], resp_random_a[7]);
365 return 1;
368 static int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) {
369 uint16_t len = 0;
370 uint8_t bt[2] = {0x00, 0x00};
371 uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
372 uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00};
374 len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
375 if (len == 1) {
376 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
377 return 1;
379 if (len != 18) {
380 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len);
381 return 2;
384 memcpy(bt, receivedAnswer + 16, 2);
385 AddCrc14A(receivedAnswer, 16);
386 if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
387 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd CRC response error.");
388 return 3;
391 memcpy(blockData, receivedAnswer, 16);
392 return 0;
394 int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) {
395 #define MFU_MAX_RETRIES 5
396 uint8_t res;
398 for (uint8_t retries = 0; retries < MFU_MAX_RETRIES; ++retries) {
399 res = mifare_ultra_readblockEx(blockNo, blockData);
401 // break if OK, or NACK.
402 switch (res) {
403 case 0:
404 case 1:
405 return res;
406 default:
407 continue;
410 return res;
413 int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) {
414 // variables
415 uint16_t len = 0;
416 uint32_t pos = 0;
417 uint8_t par[3] = {0x00, 0x00, 0x00}; // enough for 18 Bytes to send
418 uint8_t res = 0;
420 uint8_t d_block[18], d_block_enc[18];
421 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
422 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
424 // command MIFARE_CLASSIC_WRITEBLOCK
425 len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
427 if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
428 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
429 return 1;
432 memcpy(d_block, blockData, 16);
433 AddCrc14A(d_block, 16);
435 // crypto
436 for (pos = 0; pos < 18; pos++) {
437 d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos];
438 par[pos >> 3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos & 0x0007)));
441 ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL);
443 // Receive the response
444 len = ReaderReceive(receivedAnswer, receivedAnswerPar);
446 res = 0;
447 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0;
448 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1;
449 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2;
450 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3;
452 if ((len != 1) || (res != 0x0A)) {
453 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res);
454 return 2;
456 return 0;
459 int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action) {
460 // variables
461 uint16_t len = 0;
462 uint32_t pos = 0;
463 uint8_t par[3] = {0x00, 0x00, 0x00}; // enough for 18 Bytes to send
464 uint8_t res = 0;
466 uint8_t d_block[18], d_block_enc[18];
467 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
468 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
470 uint8_t command = MIFARE_CMD_INC;
472 if (action == 0x01)
473 command = MIFARE_CMD_DEC;
475 // Send increment or decrement command
476 len = mifare_sendcmd_short(pcs, 1, command, blockNo, receivedAnswer, receivedAnswerPar, NULL);
478 if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
479 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
480 return 1;
483 memcpy(d_block, blockData, 4);
484 AddCrc14A(d_block, 4);
486 // crypto
487 for (pos = 0; pos < 6; pos++) {
488 d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos];
489 par[pos >> 3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos & 0x0007)));
492 ReaderTransmitPar(d_block_enc, 6, par, NULL);
494 // Receive the response NO Response means OK ... i.e. NOT NACK
495 len = ReaderReceive(receivedAnswer, receivedAnswerPar);
497 if (len != 0) { // Something not right, len == 0 (no response is ok as its waiting for transfer
498 res = 0;
499 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0;
500 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1;
501 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2;
502 res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3;
504 if ((len != 1) || (res != 0x0A)) {
505 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res);
506 return 2;
508 } else {
509 // send trnasfer (commit the change)
510 len = mifare_sendcmd_short(pcs, 1, MIFARE_CMD_TRANSFER, blockNo, receivedAnswer, receivedAnswerPar, NULL);
511 if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
512 if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
513 return 1;
517 return 0;
520 int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
521 // variables
522 uint16_t len = 0;
524 uint8_t d_block[18];
525 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
526 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
528 len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
530 if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
531 if (g_dbglevel >= DBG_ERROR)
532 Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0], len);
533 return 1;
536 memcpy(d_block, blockData, 16);
537 AddCrc14A(d_block, 16);
539 ReaderTransmit(d_block, sizeof(d_block), NULL);
541 // Receive the response
542 len = ReaderReceive(receivedAnswer, receivedAnswerPar);
544 if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
545 if (g_dbglevel >= DBG_ERROR)
546 Dbprintf("Cmd Send Data Error: %02x %d", receivedAnswer[0], len);
547 return 2;
549 return 0;
552 int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) {
553 uint16_t len = 0;
554 uint8_t block[5] = {blockNo, 0x00, 0x00, 0x00, 0x00 };
555 uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
556 uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
558 // command MIFARE_CLASSIC_WRITEBLOCK
559 memcpy(block + 1, blockData, 4);
561 len = mifare_sendcmd(MIFARE_ULC_WRITE, block, sizeof(block), receivedAnswer, receivedAnswerPar, NULL);
563 if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
564 if (g_dbglevel >= DBG_ERROR)
565 Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0], len);
566 return 1;
568 return 0;
570 int mifare_classic_halt_ex(struct Crypto1State *pcs) {
571 uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00};
572 uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL);
573 if (len != 0) {
574 if (g_dbglevel >= DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len);
575 return 1;
577 return 0;
579 int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) {
580 return mifare_classic_halt_ex(pcs);
583 int mifare_ultra_halt(void) {
584 uint16_t len = 0;
585 uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00};
586 len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL);
587 if (len != 0) {
588 if (g_dbglevel >= DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len);
589 return 1;
591 return 0;
595 // Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards),
596 // plus evtl. 8 sectors with 16 blocks each (4k cards)
597 uint8_t NumBlocksPerSector(uint8_t sectorNo) {
598 return (sectorNo < 32) ? 4 : 16;
601 uint8_t FirstBlockOfSector(uint8_t sectorNo) {
602 if (sectorNo < 32)
603 return sectorNo * 4;
604 else
605 return 32 * 4 + (sectorNo - 32) * 16;
609 // work with emulator memory
610 void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
611 emlSetMem_xt(data, blockNum, blocksCount, 16);
614 void emlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth) {
615 uint8_t *emCARD = BigBuf_get_EM_addr();
616 memcpy(emCARD + blockNum * blockBtWidth, data, blocksCount * blockBtWidth);
619 void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
620 uint8_t *emCARD = BigBuf_get_EM_addr();
621 memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
624 void emlGetMemBt(uint8_t *data, int offset, int byteCount) {
625 uint8_t *emCARD = BigBuf_get_EM_addr();
626 memcpy(data, emCARD + offset, byteCount);
629 int emlCheckValBl(int blockNum) {
630 uint8_t *emCARD = BigBuf_get_EM_addr();
631 uint8_t *data = emCARD + blockNum * 16;
633 if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) ||
634 (data[1] != (data[5] ^ 0xff)) || (data[1] != data[9]) ||
635 (data[2] != (data[6] ^ 0xff)) || (data[2] != data[10]) ||
636 (data[3] != (data[7] ^ 0xff)) || (data[3] != data[11]) ||
637 (data[12] != (data[13] ^ 0xff)) || (data[12] != data[14]) ||
638 (data[12] != (data[15] ^ 0xff))
640 return 1;
641 return 0;
644 int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
645 uint8_t *emCARD = BigBuf_get_EM_addr();
646 uint8_t *data = emCARD + blockNum * 16;
648 if (emlCheckValBl(blockNum))
649 return 1;
651 memcpy(blReg, data, 4);
652 *blBlock = data[12];
653 return 0;
656 int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
657 uint8_t *emCARD = BigBuf_get_EM_addr();
658 uint8_t *data = emCARD + blockNum * 16;
660 memcpy(data + 0, &blReg, 4);
661 memcpy(data + 8, &blReg, 4);
662 blReg = blReg ^ 0xffffffff;
663 memcpy(data + 4, &blReg, 4);
665 data[12] = blBlock;
666 data[13] = blBlock ^ 0xff;
667 data[14] = blBlock;
668 data[15] = blBlock ^ 0xff;
670 return 0;
673 uint64_t emlGetKey(int sectorNum, int keyType) {
674 uint8_t key[6] = {0x00};
675 uint8_t *emCARD = BigBuf_get_EM_addr();
676 memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
677 return bytes_to_num(key, 6);
680 void emlClearMem(void) {
681 const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
682 const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
683 uint8_t *emCARD = BigBuf_get_EM_addr();
684 memset(emCARD, 0, CARD_MEMORY_SIZE);
686 // fill sectors trailer data
687 for (uint16_t b = 3; b < MIFARE_4K_MAXBLOCK; ((b < MIFARE_2K_MAXBLOCK - 4) ? (b += 4) : (b += 16)))
688 emlSetMem((uint8_t *)trailer, b, 1);
690 // uid
691 emlSetMem((uint8_t *)uid, 0, 1);
692 return;
695 uint8_t SectorTrailer(uint8_t blockNo) {
696 if (blockNo <= MIFARE_2K_MAXBLOCK) {
697 if (g_dbglevel >= DBG_EXTENDED)
698 Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x03));
699 return (blockNo | 0x03);
700 } else {
701 if (g_dbglevel >= DBG_EXTENDED)
702 Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x0f));
703 return (blockNo | 0x0f);
707 bool IsSectorTrailer(uint8_t blockNo) {
708 return (blockNo == SectorTrailer(blockNo));
711 // Mifare desfire commands
712 int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) {
713 uint8_t dcmd[5] = {cmd, data[0], data[1], 0x00, 0x00};
714 AddCrc14A(dcmd, 3);
716 ReaderTransmit(dcmd, sizeof(dcmd), NULL);
717 int len = ReaderReceive(answer, answer_parity);
718 if (!len) {
719 if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed. Card timeout.");
720 return 1;
722 return len;
725 int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) {
726 uint8_t dcmd[20] = {0x00};
727 dcmd[0] = cmd;
728 memcpy(dcmd + 1, data, 17);
729 AddCrc14A(dcmd, 18);
731 ReaderTransmit(dcmd, sizeof(dcmd), NULL);
732 int len = ReaderReceive(answer, answer_parity);
733 if (!len) {
734 if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed. Card timeout.");
735 return 1;
737 return len;
740 int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData) {
742 int len;
743 // load key, keynumber
744 uint8_t data[2] = {MFDES_AUTHENTICATE, 0x00};
745 uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
746 uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00};
748 len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer, receivedAnswerPar, NULL);
749 if (len == 1) {
750 if (g_dbglevel >= DBG_ERROR)
751 Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
752 return 1;
755 if (len == 12) {
756 if (g_dbglevel >= DBG_EXTENDED) {
757 Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
758 receivedAnswer[0], receivedAnswer[1], receivedAnswer[2], receivedAnswer[3], receivedAnswer[4],
759 receivedAnswer[5], receivedAnswer[6], receivedAnswer[7], receivedAnswer[8], receivedAnswer[9],
760 receivedAnswer[10], receivedAnswer[11]);
762 memcpy(blockData, receivedAnswer, 12);
763 return 0;
765 return 1;
768 int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) {
770 int len;
771 uint8_t data[17] = {MFDES_ADDITIONAL_FRAME};
772 memcpy(data + 1, key, 16);
774 uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
775 uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00};
777 len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar, NULL);
779 if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) {
780 if (g_dbglevel >= DBG_ERROR)
781 Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]);
782 return 1;
785 if (len == 12) {
786 if (g_dbglevel >= DBG_EXTENDED) {
787 Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
788 receivedAnswer[0], receivedAnswer[1], receivedAnswer[2], receivedAnswer[3], receivedAnswer[4],
789 receivedAnswer[5], receivedAnswer[6], receivedAnswer[7], receivedAnswer[8], receivedAnswer[9],
790 receivedAnswer[10], receivedAnswer[11]);
792 memcpy(blockData, receivedAnswer, 12);
793 return 0;
795 return 1;