FreeCalypso > hg > freecalypso-reveng
annotate imeibrute.c @ 92:708f2452d1ae
armdis: full ldr/str decoding implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 30 Mar 2014 01:47:28 +0000 |
parents | 1e797f846563 |
children |
rev | line source |
---|---|
60
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
1 /* |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
2 * The IMEI "protection" implemented by TI for Calypso (as opposed to Calypso+ |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
3 * or LoCosto) platforms for those device manufs who desired to obfuscate their |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
4 * IMEIs (not everyone did - Openmoko opted out, for example), as seen in |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
5 * g23m/condat/com/src/comlib/cl_imei.c in the Leonardo semi-src by Sotovik, |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
6 * encrypts the IMEI using plain DES, using a key derived from the Calypso die |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
7 * ID. However, only 28 effective key bits are used, and the key is then also |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
8 * encrypted with itself and stored right after the encrypted IMEI, and is used |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
9 * by the decryption & verification routine. Per TI's source, the 16-byte |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
10 * encrypted IMEI record is to be stored in FFS in /gsm/imei.enc; the DP-L10 |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
11 * phone by Pirelli/Foxconn has been found to use the same scheme, but store |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
12 * the 16-byte record in question in their "factory block" instead, at absolute |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
13 * address 0x027F0504 as seen by the ARM7 CPU. |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
14 * |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
15 * The encryption scheme seems so weak to me (28 effective key bits and an easy |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
16 * hit detection criterion for a brute force cracker) that I decided to see, |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
17 * just for fun, how long it would take to crack that encryption by brute force |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
18 * alone, and using a totally non-optimized program to do that. |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
19 */ |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
20 |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
21 #include <sys/types.h> |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
22 #include <openssl/des.h> |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
23 #include <stdio.h> |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
24 #include <stdlib.h> |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
25 |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
26 DES_cblock ciphertext[2], dieid_key, decrypted[2]; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
27 DES_key_schedule keysched; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
28 |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
29 read_ciphertext(filename, offset_arg) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
30 char *filename, *offset_arg; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
31 { |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
32 FILE *f; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
33 u_long offset_val; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
34 |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
35 f = fopen(filename, "r"); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
36 if (!f) { |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
37 perror(filename); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
38 exit(1); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
39 } |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
40 if (offset_arg) { |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
41 offset_val = strtoul(offset_arg, 0, 16); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
42 fseek(f, offset_val, 0); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
43 } |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
44 fread(ciphertext, 8, 2, f); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
45 fclose(f); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
46 } |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
47 |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
48 print_des_cblock(msg, blk) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
49 char *msg; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
50 DES_cblock blk; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
51 { |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
52 printf("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", msg, |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
53 blk[0], blk[1], blk[2], blk[3], blk[4], blk[5], blk[6], blk[7]); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
54 } |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
55 |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
56 try() |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
57 { |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
58 DES_set_key_unchecked(&dieid_key, &keysched); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
59 DES_ecb_encrypt(&ciphertext[1], &decrypted[1], &keysched, DES_DECRYPT); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
60 if (decrypted[1][0] & 0xFE != dieid_key[0]) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
61 return; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
62 if (decrypted[1][1]) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
63 return; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
64 if (decrypted[1][2] & 0xFE != dieid_key[2]) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
65 return; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
66 if (decrypted[1][3]) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
67 return; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
68 if (decrypted[1][4] & 0xFE != dieid_key[4]) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
69 return; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
70 if (decrypted[1][5]) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
71 return; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
72 if (decrypted[1][6] & 0xFE != dieid_key[6]) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
73 return; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
74 if (decrypted[1][7]) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
75 return; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
76 print_des_cblock("Hit", &decrypted[1]); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
77 DES_ecb_encrypt(&ciphertext[0], &decrypted[0], &keysched, DES_DECRYPT); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
78 print_des_cblock("IMEI", &decrypted[0]); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
79 } |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
80 |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
81 main(argc, argv) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
82 char **argv; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
83 { |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
84 if (argc < 2 || argc > 3) { |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
85 fprintf(stderr, "usage: %s binfile [offset]\n", argv[0]); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
86 exit(1); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
87 } |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
88 read_ciphertext(argv[1], argv[2]); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
89 dieid_key[1] = 0; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
90 dieid_key[3] = 0; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
91 dieid_key[5] = 0; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
92 dieid_key[7] = 0; |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
93 for (dieid_key[0] = 0; dieid_key[0] <= 0xFE; dieid_key[0] += 2) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
94 for (dieid_key[2] = 0; dieid_key[2] <= 0xFE; dieid_key[2] += 2) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
95 for (dieid_key[4] = 0; dieid_key[4] <= 0xFE; dieid_key[4] += 2) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
96 for (dieid_key[6] = 0; dieid_key[6] <= 0xFE; dieid_key[6] += 2) |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
97 try(); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
98 exit(0); |
1e797f846563
imeibrute written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
99 } |