]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - armsrc/mifareutil.c
ede1cbc9de0bce383e8d3aeb0de34f5a0d05faa4
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
);
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);
97 Dbprintf("uid: %x nt: %x", uid
, nt
);
99 // ----------------------------- crypto1 create
100 // Init cipher with key
101 crypto1_create(pcs
, ui64Key
);
103 // Load (plain) uid^nt into the cipher
104 crypto1_word(pcs
, nt
^ uid
, 0);
107 // Generate (encrypted) nr+parity by loading it into the cipher (Nr)
108 for (pos
= 0; pos
< 4; pos
++)
110 mf_nr_ar
[pos
] = crypto1_byte(pcs
, ar
[pos
], 0) ^ ar
[pos
];
111 par
= (par
>> 1) | ( ((filter(pcs
->odd
) ^ oddparity(ar
[pos
])) & 0x01) * 0x80 );
114 // Skip 32 bits in pseudo random generator
115 nt
= prng_successor(nt
,32);
118 for (pos
= 4; pos
< 8; pos
++)
120 nt
= prng_successor(nt
,8);
121 mf_nr_ar
[pos
] = crypto1_byte(pcs
,0x00,0) ^ (nt
& 0xff);
122 par
= (par
>> 1)| ( ((filter(pcs
->odd
) ^ oddparity(nt
& 0xff)) & 0x01) * 0x80 );
125 // Transmit reader nonce and reader answer
126 ReaderTransmitPar(mf_nr_ar
, sizeof(mf_nr_ar
), par
);
128 // Receive 4 bit answer
129 len
= ReaderReceive(receivedAnswer
);
132 Dbprintf("Authentication failed. Card timeout.");
136 memcpy(tmp4
, receivedAnswer
, 4);
137 ntpp
= prng_successor(nt
, 32) ^ crypto1_word(pcs
, 0,0);
139 if (ntpp
!= bytes_to_num(tmp4
, 4)) {
140 Dbprintf("Authentication failed. Error card response.");
147 int mifare_classic_readblock(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t *blockData
)
153 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
155 // command MIFARE_CLASSIC_READBLOCK
156 len
= mifare_sendcmd_short(pcs
, 1, 0x30, blockNo
, receivedAnswer
);
158 Dbprintf("Cmd Error: %02x", receivedAnswer
[0]);
162 Dbprintf("Cmd Error: card timeout. len: %x", len
);
166 memcpy(bt
, receivedAnswer
+ 16, 2);
167 AppendCrc14443a(receivedAnswer
, 16);
168 if (bt
[0] != receivedAnswer
[16] || bt
[1] != receivedAnswer
[17]) {
169 Dbprintf("Cmd CRC response error.");
173 memcpy(blockData
, receivedAnswer
, 16);
177 int mifare_classic_writeblock(struct Crypto1State
*pcs
, uint32_t uid
, uint8_t blockNo
, uint8_t *blockData
)
185 uint8_t d_block
[18], d_block_enc
[18];
186 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
188 // command MIFARE_CLASSIC_WRITEBLOCK
189 len
= mifare_sendcmd_short(pcs
, 1, 0xA0, blockNo
, receivedAnswer
);
191 if ((len
!= 1) || (receivedAnswer
[0] != 0x0A)) { // 0x0a - ACK
192 Dbprintf("Cmd Error: %02x", receivedAnswer
[0]);
196 memcpy(d_block
, blockData
, 16);
197 AppendCrc14443a(d_block
, 16);
201 for (pos
= 0; pos
< 18; pos
++)
203 d_block_enc
[pos
] = crypto1_byte(pcs
, 0x00, 0) ^ d_block
[pos
];
204 par
= (par
>> 1) | ( ((filter(pcs
->odd
) ^ oddparity(d_block
[pos
])) & 0x01) * 0x20000 );
207 ReaderTransmitPar(d_block_enc
, sizeof(d_block_enc
), par
);
209 // Receive the response
210 len
= ReaderReceive(receivedAnswer
);
213 for (i
= 0; i
< 4; i
++)
214 res
|= (crypto1_bit(pcs
, 0, 0) ^ BIT(receivedAnswer
[0], i
)) << i
;
216 if ((len
!= 1) || (res
!= 0x0A)) {
217 Dbprintf("Cmd send data2 Error: %02x", res
);
224 int mifare_classic_halt(struct Crypto1State
*pcs
, uint32_t uid
)
230 uint8_t* receivedAnswer
= mifare_get_bigbufptr();
232 len
= mifare_sendcmd_short(pcs
, 1, 0x50, 0x00, receivedAnswer
);
234 Dbprintf("halt error. response len: %x", len
);