]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - armsrc/mifareutil.c
1f8a4d17564faa202c2d64cab246177cee09061d
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 return mifare_sendcmd_shortex(pcs
, crypted
, cmd
, data
, answer
, NULL
);
31 int mifare_sendcmd_shortex(struct Crypto1State
*pcs
, uint8_t crypted
, uint8_t cmd
, uint8_t data
, uint8_t* answer
, uint32_t * parptr
)
33 uint8_t dcmd
[4], ecmd
[4];
34 uint32_t pos
, par
, res
;
38 AppendCrc14443a(dcmd
, 2);
40 memcpy(ecmd
, dcmd
, sizeof(dcmd
));
44 for (pos
= 0; pos
< 4; pos
++)
46 ecmd
[pos
] = crypto1_byte(pcs
, 0x00, 0) ^ dcmd
[pos
];
47 par
= (par
>> 1) | ( ((filter(pcs
->odd
) ^ oddparity(dcmd
[pos
])) & 0x01) * 0x08 );
50 ReaderTransmitPar(ecmd
, sizeof(ecmd
), par
);
53 ReaderTransmit(dcmd
, sizeof(dcmd
));
56 int len
= ReaderReceivePar(answer
, &par
);
58 if (parptr
) *parptr
= par
;
60 if (crypted
== CRYPT_ALL
) {
63 for (pos
= 0; pos
< 4; pos
++)
64 res
|= (crypto1_bit(pcs
, 0, 0) ^ BIT(answer
[0], pos
)) << pos
;
69 for (pos
= 0; pos
< len
; pos
++)
71 answer
[pos
] = crypto1_byte(pcs
, 0x00, 0) ^ answer
[pos
];
79 int mifare_classic_auth(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t keyType
, uint64_t ui64Key
, uint64_t isNested
)
81 return mifare_classic_authex(pcs
, uid
, blockNo
, keyType
, ui64Key
, isNested
, NULL
);
84 int mifare_classic_authex(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t keyType
, uint64_t ui64Key
, uint64_t isNested
, uint32_t * ntptr
)
92 uint32_t nt
, ntpp
; // Supplied tag nonce
94 uint8_t mf_nr_ar
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
95 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
97 // Transmit MIFARE_CLASSIC_AUTH
98 len
= mifare_sendcmd_short(pcs
, isNested
, 0x60 + (keyType
& 0x01), blockNo
, receivedAnswer
);
99 // Dbprintf("rand nonce len: %x", len);
100 if (len
!= 4) return 1;
107 // Save the tag nonce (nt)
108 nt
= bytes_to_num(receivedAnswer
, 4);
110 // ----------------------------- crypto1 create
112 crypto1_destroy(pcs
);
114 // Init cipher with key
115 crypto1_create(pcs
, ui64Key
);
117 if (isNested
== AUTH_NESTED
) {
118 // decrypt nt with help of new key
119 nt
= crypto1_word(pcs
, nt
^ uid
, 1) ^ nt
;
121 // Load (plain) uid^nt into the cipher
122 crypto1_word(pcs
, nt
^ uid
, 0);
127 Dbprintf("auth uid: %08x nt: %08x", uid
, nt
);
134 // Generate (encrypted) nr+parity by loading it into the cipher (Nr)
135 for (pos
= 0; pos
< 4; pos
++)
137 mf_nr_ar
[pos
] = crypto1_byte(pcs
, ar
[pos
], 0) ^ ar
[pos
];
138 par
= (par
>> 1) | ( ((filter(pcs
->odd
) ^ oddparity(ar
[pos
])) & 0x01) * 0x80 );
141 // Skip 32 bits in pseudo random generator
142 nt
= prng_successor(nt
,32);
145 for (pos
= 4; pos
< 8; pos
++)
147 nt
= prng_successor(nt
,8);
148 mf_nr_ar
[pos
] = crypto1_byte(pcs
,0x00,0) ^ (nt
& 0xff);
149 par
= (par
>> 1)| ( ((filter(pcs
->odd
) ^ oddparity(nt
& 0xff)) & 0x01) * 0x80 );
152 // Transmit reader nonce and reader answer
153 ReaderTransmitPar(mf_nr_ar
, sizeof(mf_nr_ar
), par
);
155 // Receive 4 bit answer
156 len
= ReaderReceive(receivedAnswer
);
159 Dbprintf("Authentication failed. Card timeout.");
163 memcpy(tmp4
, receivedAnswer
, 4);
164 ntpp
= prng_successor(nt
, 32) ^ crypto1_word(pcs
, 0,0);
166 if (ntpp
!= bytes_to_num(tmp4
, 4)) {
167 Dbprintf("Authentication failed. Error card response.");
174 int mifare_classic_readblock(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t *blockData
)
180 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
182 // command MIFARE_CLASSIC_READBLOCK
183 len
= mifare_sendcmd_short(pcs
, 1, 0x30, blockNo
, receivedAnswer
);
185 Dbprintf("Cmd Error: %02x", receivedAnswer
[0]);
189 Dbprintf("Cmd Error: card timeout. len: %x", len
);
193 memcpy(bt
, receivedAnswer
+ 16, 2);
194 AppendCrc14443a(receivedAnswer
, 16);
195 if (bt
[0] != receivedAnswer
[16] || bt
[1] != receivedAnswer
[17]) {
196 Dbprintf("Cmd CRC response error.");
200 memcpy(blockData
, receivedAnswer
, 16);
204 int mifare_classic_writeblock(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t *blockData
)
212 uint8_t d_block
[18], d_block_enc
[18];
213 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
215 // command MIFARE_CLASSIC_WRITEBLOCK
216 len
= mifare_sendcmd_short(pcs
, 1, 0xA0, blockNo
, receivedAnswer
);
218 if ((len
!= 1) || (receivedAnswer
[0] != 0x0A)) { // 0x0a - ACK
219 Dbprintf("Cmd Error: %02x", receivedAnswer
[0]);
223 memcpy(d_block
, blockData
, 16);
224 AppendCrc14443a(d_block
, 16);
228 for (pos
= 0; pos
< 18; pos
++)
230 d_block_enc
[pos
] = crypto1_byte(pcs
, 0x00, 0) ^ d_block
[pos
];
231 par
= (par
>> 1) | ( ((filter(pcs
->odd
) ^ oddparity(d_block
[pos
])) & 0x01) * 0x20000 );
234 ReaderTransmitPar(d_block_enc
, sizeof(d_block_enc
), par
);
236 // Receive the response
237 len
= ReaderReceive(receivedAnswer
);
240 for (i
= 0; i
< 4; i
++)
241 res
|= (crypto1_bit(pcs
, 0, 0) ^ BIT(receivedAnswer
[0], i
)) << i
;
243 if ((len
!= 1) || (res
!= 0x0A)) {
244 Dbprintf("Cmd send data2 Error: %02x", res
);
251 int mifare_classic_halt(struct Crypto1State
*pcs
, uint32_t uid
)
257 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
259 len
= mifare_sendcmd_short(pcs
, 1, 0x50, 0x00, receivedAnswer
);
261 Dbprintf("halt error. response len: %x", len
);