hf mf fchk - output style
[RRG-proxmark3.git] / tools / hitag2crack / crack3 / ht2crack3.c
blobfba050d677096c9657749e7b2001a0f6d4a91a6c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <pthread.h>
4 #include <inttypes.h>
5 #include <string.h>
7 #include "hitagcrypto.h"
8 #include "ht2crackutils.h"
10 // max number of NrAr pairs to load - you only need 136 good pairs, but this
11 // is the max
12 #define NUM_NRAR 1024
13 #define NUM_THREADS 8
15 // table entry for Tkleft
16 struct Tklower {
17 uint64_t yxorb;
18 char notb32;
19 uint64_t klowery;
22 // table entry for nR aR pair
23 struct nRaR {
24 uint64_t nR;
25 uint64_t aR;
28 // struct to hold data for thread
29 struct threaddata {
30 uint64_t uid;
31 struct nRaR *TnRaR;
32 unsigned int numnrar;
33 uint64_t klowerstart;
34 uint64_t klowerrange;
37 // macros to pick out 4 bits in various patterns of 1s & 2s & make a new number
38 // these and the following hitag2_crypt function taken from Rfidler
39 #define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) )
40 #define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
41 ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) )
42 #define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
43 ((S >> (C - 2)) & 0xC) )
44 #define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \
45 ((S >> (C - 3)) & 8) )
46 #define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \
47 ((S >> (C - 3)) & 8) )
50 static uint32_t hitag2_crypt(uint64_t s) {
51 const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
52 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
53 const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
54 uint32_t bitindex;
56 bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1;
57 bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02;
58 bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04;
59 bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08;
60 bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
62 return (ht2_function5c >> bitindex) & 1;
66 // this function is a modification of the filter function f, based heavily
67 // on the hitag2_crypt function in Rfidler
68 static int fnP(uint64_t klowery) {
69 const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
70 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
71 const uint32_t ht2_function4p = 0xAE83; // 1010 1110 1000 0011
72 uint32_t i;
74 i = (ht2_function4a >> pickbits2_2(klowery, 2, 5)) & 1;
75 i |= ((ht2_function4b << 1) >> pickbits1_1_2(klowery, 8, 12, 14)) & 0x02;
76 i |= ((ht2_function4b << 2) >> pickbits1x4(klowery, 17, 21, 23, 26)) & 0x04;
77 i |= ((ht2_function4b << 3) >> pickbits2_1_1(klowery, 28, 31, 33)) & 0x08;
79 // modified to use reference implementation approach
80 // orig fc table is 0x7907287B = 0111 1001 0000 0111 0010 1000 0111 1011
81 // we ignore the top bit (bit 4) of the parameter, so therefore create a new
82 // table that indicates which bit positions are the same if the top bit is 1 or 0
83 return (ht2_function4p >> i) & 1;
86 // comparison function for sorting/searching Tklower entries
87 static int Tk_cmp(const void *v1, const void *v2) {
88 const struct Tklower *Tk1 = (struct Tklower *)v1;
89 const struct Tklower *Tk2 = (struct Tklower *)v2;
91 if (Tk1->yxorb < Tk2->yxorb) {
92 return -1;
93 } else if (Tk1->yxorb > Tk2->yxorb) {
94 return 1;
97 return 0;
100 // test for bad guesses of kmiddle
101 static int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) {
103 struct Tklower *result, target;
105 // "If there is an entry in Tklower for which y ^ b = z but !b32 != aR[0]
106 // then the attacker learns that kmiddle is a bad guess... otherwise, if
107 // !b32 == aR[0] then kmiddle is still a viable guess."
109 target.yxorb = z;
110 target.notb32 = 0;
111 result = (struct Tklower *)bsearch(&target, Tk, max, sizeof(struct Tklower), Tk_cmp);
113 if (result) {
114 if (result->notb32 != aR0) {
115 return 1;
117 } else {
118 return 2;
121 return 0;
124 // function to test if a partial key is valid
125 static int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR) {
126 uint64_t kupper;
127 uint64_t key;
128 Hitag_State hstate;
129 uint64_t b;
130 uint32_t revaR;
131 uint32_t normaR;
133 // normalise aR
134 revaR = rev32(aR);
135 normaR = ((revaR >> 24) | ((revaR >> 8) & 0xff00) | ((revaR << 8) & 0xff0000) | (revaR << 24));
137 // search for remaining 14 bits
138 for (kupper = 0; kupper < 0x3fff; kupper++) {
139 key = (kupper << 34) | pkey;
140 hitag2_init(&hstate, key, uid, nR);
141 b = hitag2_nstep(&hstate, 32);
142 if ((normaR ^ b) == 0xffffffff) {
143 *out = key;
144 return 1;
147 return 0;
150 // some notes on how I think this attack should work.
151 // due to the way fc works, in a number of cases, it doesn't matter what
152 // the most significant bits are doing for it to produce the same result.
153 // These are the most sig 14 bits to be clear. Looking at fc it is poss
154 // to see cases where the most sig bit of the input to fc (which is made
155 // from fa on 4 of the most sig bits from bit 34 onwards) does not affect
156 // whether it gives a 0 or 1 as the input 0b0ABCD gives the same bit value
157 // as input 0b1ABCD.
158 // The PRNG is initialised by setting the lower 32 bits to the UID, with
159 // the upper 16 bits set to the lower 16 bits of the key. Next the 32
160 // upper bits of the key are XORed with the private nonce and these are
161 // shifted in, with the PRNG outputting bits b0 to b31. These bits are
162 // used to encrypt (XOR with) the nonce to produce nR, which is sent to
163 // the card.
164 // (The card should init the PRNG with the same UID and lower 16 bits of
165 // the key, receive the nR, then shift it in bit by bit while xoring each
166 // bit with its output, and the key - this essentially decrypts the nR to
167 // the nonce XOR the upper 32 bits of the key, while shifting it in.
168 // The card's PRNG will then be in the same state as the RWD.)
169 // By knowing the UID and guessing the lower 16 bits of the key, and
170 // focusing on nR values that don't affect the upper bits of fc, we can
171 // limit our guesses to a smaller set than a full brute force and
172 // effectively work out candidates for the lower 34 bits of the key.
174 static void *crack(void *d) {
175 struct threaddata *data = (struct threaddata *)d;
176 uint64_t uid;
177 struct nRaR *TnRaR;
178 unsigned int numnrar;
180 Hitag_State hstate;
181 int i, j;
183 uint64_t klower, kmiddle, klowery;
184 uint64_t y, b, z, bit;
185 uint64_t ytmp;
186 unsigned int count;
187 uint64_t foundkey, revkey;
188 int ret;
189 unsigned int found;
190 unsigned int badguess;
191 struct Tklower *Tk = NULL;
193 if (!data) {
194 printf("Thread data is NULL\n");
195 exit(1);
198 uid = data->uid;
199 TnRaR = data->TnRaR;
200 numnrar = data->numnrar;
202 // create space for tables
203 Tk = (struct Tklower *)malloc(sizeof(struct Tklower) * 0x40000);
204 if (!Tk) {
205 printf("Failed to allocate memory (Tk)\n");
206 exit(1);
209 // find keys
210 for (klower = data->klowerstart; klower < (data->klowerstart + data->klowerrange); klower++) {
211 printf("trying klower = 0x%05"PRIx64"\n", klower);
212 // build table
213 count = 0;
214 for (y = 0; y < 0x40000; y++) {
215 // create klowery
216 klowery = (y << 16) | klower;
217 // check for cases where right most bit of fc doesn't matter
219 if (fnP(klowery)) {
220 // store klowery
221 Tk[count].klowery = klowery;
222 // build the initial prng state
223 hstate.shiftreg = (klower << 32) | uid;
224 // zero the lfsr so only 0s are inserted
225 hstate.lfsr = 0;
226 // insert y into shiftreg and extract keystream, reversed order
227 b = 0;
228 ytmp = y;
229 for (j = 0; j < 2; j++) {
230 hstate.shiftreg = hstate.shiftreg | ((ytmp & 0xffff) << 48);
231 for (i = 0; i < 16; i++) {
232 hstate.shiftreg = hstate.shiftreg >> 1;
233 bit = hitag2_crypt(hstate.shiftreg);
234 b = (b >> 1) | (bit << 31);
236 ytmp = ytmp >> 16;
239 // store the xor of y and b0-17
240 Tk[count].yxorb = y ^ (b & 0x3ffff);
242 // get and store inverse of next bit from prng
243 // don't need to worry about shifting in the new bit because
244 // it doesn't affect the filter function anyway
245 hstate.shiftreg = hstate.shiftreg >> 1;
246 Tk[count].notb32 = hitag2_crypt(hstate.shiftreg) ^ 0x1;
248 // increase count
249 count++;
253 qsort(Tk, count, sizeof(struct Tklower), Tk_cmp);
255 // look for matches
256 for (kmiddle = 0; kmiddle < 0x40000; kmiddle++) {
257 // loop over nRaR pairs
258 badguess = 0;
259 found = 0;
260 for (i = 0; (i < numnrar) && (!badguess); i++) {
261 z = kmiddle ^ (TnRaR[i].nR & 0x3ffff);
262 ret = is_kmiddle_badguess(z, Tk, count, TnRaR[i].aR & 0x1);
263 if (ret == 1) {
264 badguess = 1;
265 } else if (ret == 0) {
266 found++;
270 if ((found) && (!badguess)) {
271 // brute
272 printf("possible partial key found: 0x%012"PRIx64"\n", ((uint64_t)kmiddle << 16) | klower);
274 if (testkey(&foundkey, uid, (kmiddle << 16 | klower), TnRaR[0].nR, TnRaR[0].aR) &&
275 testkey(&foundkey, uid, (kmiddle << 16 | klower), TnRaR[1].nR, TnRaR[1].aR)) {
276 // normalise foundkey
277 revkey = rev64(foundkey);
278 foundkey = ((revkey >> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000);
279 printf("\n\nSuccess - key = %012"PRIx64"\n", foundkey);
280 exit(0);
282 return (void *)foundkey;
290 free(Tk);
291 return NULL;
293 int main(int argc, char *argv[]) {
294 FILE *fp;
295 int i;
296 pthread_t threads[NUM_THREADS];
297 void *status;
299 uint64_t uid;
300 uint64_t klowerstart;
301 unsigned int numnrar = 0;
302 char *buf = NULL;
303 char *buft1 = NULL;
304 char *buft2 = NULL;
305 size_t lenbuf = 64;
307 struct nRaR *TnRaR = NULL;
308 struct threaddata *tdata = NULL;
310 if (argc < 3) {
311 printf("%s uid nRaRfile\n", argv[0]);
312 exit(1);
315 // read the UID into internal format
316 if (!strncmp(argv[1], "0x", 2)) {
317 uid = rev32(hexreversetoulong(argv[1] + 2));
318 } else {
319 uid = rev32(hexreversetoulong(argv[1]));
322 // create table of nR aR pairs
323 TnRaR = (struct nRaR *)malloc(sizeof(struct nRaR) * NUM_NRAR);
325 // open file
326 fp = fopen(argv[2], "r");
327 if (!fp) {
328 printf("cannot open nRaRfile\n");
329 exit(1);
332 // set klowerstart (for debugging)
333 if (argc > 3) {
334 klowerstart = strtol(argv[3], NULL, 0);
335 } else {
336 klowerstart = 0;
339 // read in nR aR pairs
340 numnrar = 0;
341 buf = (char *)malloc(lenbuf);
342 if (!buf) {
343 printf("cannot malloc buf\n");
344 exit(1);
347 while (getline(&buf, &lenbuf, fp) > 0) {
348 buft1 = strchr(buf, ' ');
349 if (!buft1) {
350 printf("invalid file input on line %u\n", numnrar + 1);
351 exit(1);
353 *buft1 = 0x00;
354 buft1++;
355 buft2 = strchr(buft1, '\n');
356 if (!buft2) {
357 printf("no CR on line %u\n", numnrar + 1);
358 exit(1);
360 *buft2 = 0x00;
361 if (!strncmp(buf, "0x", 2)) {
362 TnRaR[numnrar].nR = rev32(hexreversetoulong(buf + 2));
363 TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1 + 2));
364 } else {
365 TnRaR[numnrar].nR = rev32(hexreversetoulong(buf));
366 TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1));
368 numnrar++;
371 // close file
372 fclose(fp);
374 printf("Loaded %u NrAr pairs\n", numnrar);
376 // create table of thread data
377 tdata = (struct threaddata *)malloc(sizeof(struct threaddata) * NUM_THREADS);
378 if (!tdata) {
379 printf("cannot malloc threaddata\n");
380 exit(1);
383 for (i = 0; i < NUM_THREADS; i++) {
384 tdata[i].uid = uid;
385 tdata[i].TnRaR = TnRaR;
386 tdata[i].numnrar = numnrar;
387 tdata[i].klowerrange = 0x10000 / NUM_THREADS;
388 tdata[i].klowerstart = i * tdata[i].klowerrange;
391 if (klowerstart) {
392 // debug mode only runs one thread from klowerstart
393 tdata[0].klowerstart = klowerstart;
394 crack(tdata);
395 } else {
396 // run full threaded mode
397 for (i = 0; i < NUM_THREADS; i++) {
398 if (pthread_create(&(threads[i]), NULL, crack, (void *)(tdata + i))) {
399 printf("cannot start thread %d\n", i);
400 exit(1);
405 // wait for threads to finish
406 for (i = 0; i < NUM_THREADS; i++) {
407 if (pthread_join(threads[i], &status)) {
408 printf("cannot join thread %d\n", i);
409 exit(1);
411 printf("thread %i finished\n", i);
412 if (status) {
413 printf("Key = %012"PRIx64"\n", (uint64_t)status);
414 exit(0);
418 printf("Did not find key :(\n");
419 pthread_exit(NULL);
421 return 0;