59dafedc57e5661c693d72f13b8799e7620642cf
1 //-----------------------------------------------------------------------------
3 // Many authors, that makes it possible
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
8 //-----------------------------------------------------------------------------
9 // code for work with mifare cards.
10 //-----------------------------------------------------------------------------
12 #include "proxmark3.h"
17 #include "iso14443crc.h"
18 #include "iso14443a.h"
20 #include "mifareutil.h"
22 uint8_t* mifare_get_bigbufptr(void) {
23 return (((uint8_t *)BigBuf
) + 3560); // was 3560 - tied to other size changes
26 int mifare_sendcmd_short(struct Crypto1State
*pcs
, uint8_t crypted
, uint8_t cmd
, uint8_t data
, uint8_t* answer
)
28 uint8_t dcmd
[4], ecmd
[4];
29 uint32_t pos
, par
, res
;
33 AppendCrc14443a(dcmd
, 2);
35 memcpy(ecmd
, dcmd
, sizeof(dcmd
));
39 for (pos
= 0; pos
< 4; pos
++)
41 ecmd
[pos
] = crypto1_byte(pcs
, 0x00, 0) ^ dcmd
[pos
];
42 par
= (par
>> 1) | ( ((filter(pcs
->odd
) ^ oddparity(dcmd
[pos
])) & 0x01) * 0x08 );
45 ReaderTransmitPar(ecmd
, sizeof(ecmd
), par
);
48 ReaderTransmit(dcmd
, sizeof(dcmd
));
51 int len
= ReaderReceive(answer
);
53 if (crypted
== CRYPT_ALL
) {
56 for (pos
= 0; pos
< 4; pos
++)
57 res
|= (crypto1_bit(pcs
, 0, 0) ^ BIT(answer
[0], pos
)) << pos
;
62 for (pos
= 0; pos
< len
; pos
++)
64 answer
[pos
] = crypto1_byte(pcs
, 0x00, 0) ^ answer
[pos
];
72 int mifare_classic_auth(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t keyType
, uint64_t ui64Key
, uint64_t isNested
)
80 uint32_t nt
, ntpp
; // Supplied tag nonce
82 uint8_t mf_nr_ar
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
83 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
85 // Transmit MIFARE_CLASSIC_AUTH
86 len
= mifare_sendcmd_short(pcs
, isNested
, 0x60 + (keyType
& 0x01), blockNo
, receivedAnswer
);
87 // Dbprintf("rand nonce len: %x", len);
88 if (len
!= 4) return 1;
95 // Save the tag nonce (nt)
96 nt
= bytes_to_num(receivedAnswer
, 4);
98 // ----------------------------- crypto1 create
100 crypto1_destroy(pcs
);
102 // Init cipher with key
103 crypto1_create(pcs
, ui64Key
);
105 if (isNested
== AUTH_NESTED
) {
106 // decrypt nt with help of new key
107 nt
= crypto1_word(pcs
, nt
^ uid
, 1) ^ nt
;
109 // Load (plain) uid^nt into the cipher
110 crypto1_word(pcs
, nt
^ uid
, 0);
114 Dbprintf("auth uid: %08x nt: %08x", uid
, nt
);
117 // Generate (encrypted) nr+parity by loading it into the cipher (Nr)
118 for (pos
= 0; pos
< 4; pos
++)
120 mf_nr_ar
[pos
] = crypto1_byte(pcs
, ar
[pos
], 0) ^ ar
[pos
];
121 par
= (par
>> 1) | ( ((filter(pcs
->odd
) ^ oddparity(ar
[pos
])) & 0x01) * 0x80 );
124 // Skip 32 bits in pseudo random generator
125 nt
= prng_successor(nt
,32);
128 for (pos
= 4; pos
< 8; pos
++)
130 nt
= prng_successor(nt
,8);
131 mf_nr_ar
[pos
] = crypto1_byte(pcs
,0x00,0) ^ (nt
& 0xff);
132 par
= (par
>> 1)| ( ((filter(pcs
->odd
) ^ oddparity(nt
& 0xff)) & 0x01) * 0x80 );
135 // Transmit reader nonce and reader answer
136 ReaderTransmitPar(mf_nr_ar
, sizeof(mf_nr_ar
), par
);
138 // Receive 4 bit answer
139 len
= ReaderReceive(receivedAnswer
);
142 Dbprintf("Authentication failed. Card timeout.");
146 memcpy(tmp4
, receivedAnswer
, 4);
147 ntpp
= prng_successor(nt
, 32) ^ crypto1_word(pcs
, 0,0);
149 if (ntpp
!= bytes_to_num(tmp4
, 4)) {
150 Dbprintf("Authentication failed. Error card response.");
157 int mifare_classic_readblock(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t *blockData
)
163 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
165 // command MIFARE_CLASSIC_READBLOCK
166 len
= mifare_sendcmd_short(pcs
, 1, 0x30, blockNo
, receivedAnswer
);
168 Dbprintf("Cmd Error: %02x", receivedAnswer
[0]);
172 Dbprintf("Cmd Error: card timeout. len: %x", len
);
176 memcpy(bt
, receivedAnswer
+ 16, 2);
177 AppendCrc14443a(receivedAnswer
, 16);
178 if (bt
[0] != receivedAnswer
[16] || bt
[1] != receivedAnswer
[17]) {
179 Dbprintf("Cmd CRC response error.");
183 memcpy(blockData
, receivedAnswer
, 16);
187 int mifare_classic_writeblock(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t *blockData
)
195 uint8_t d_block
[18], d_block_enc
[18];
196 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
198 // command MIFARE_CLASSIC_WRITEBLOCK
199 len
= mifare_sendcmd_short(pcs
, 1, 0xA0, blockNo
, receivedAnswer
);
201 if ((len
!= 1) || (receivedAnswer
[0] != 0x0A)) { // 0x0a - ACK
202 Dbprintf("Cmd Error: %02x", receivedAnswer
[0]);
206 memcpy(d_block
, blockData
, 16);
207 AppendCrc14443a(d_block
, 16);
211 for (pos
= 0; pos
< 18; pos
++)
213 d_block_enc
[pos
] = crypto1_byte(pcs
, 0x00, 0) ^ d_block
[pos
];
214 par
= (par
>> 1) | ( ((filter(pcs
->odd
) ^ oddparity(d_block
[pos
])) & 0x01) * 0x20000 );
217 ReaderTransmitPar(d_block_enc
, sizeof(d_block_enc
), par
);
219 // Receive the response
220 len
= ReaderReceive(receivedAnswer
);
223 for (i
= 0; i
< 4; i
++)
224 res
|= (crypto1_bit(pcs
, 0, 0) ^ BIT(receivedAnswer
[0], i
)) << i
;
226 if ((len
!= 1) || (res
!= 0x0A)) {
227 Dbprintf("Cmd send data2 Error: %02x", res
);
234 int mifare_classic_halt(struct Crypto1State
*pcs
, uint32_t uid
)
240 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
242 len
= mifare_sendcmd_short(pcs
, 1, 0x50, 0x00, receivedAnswer
);
244 Dbprintf("halt error. response len: %x", len
);