1 /*
2 * Find expanded AES keys in memory
3 *
4 * Algorithm discovered and developed by Victor Muñoz
5 * - PoC and source published at 24c3 at December 2007
6 *
7 * Thanks for the great moments and code snippets!
8 *
9 * This source is public domain. Feel free to use it and distribute it.
10 */
11
12 #include <r_search.h>
13 #include <r_crypto/r_aes.h>
14
15 #define AES128_SEARCH_LENGTH 24
16 #define AES192_SEARCH_LENGTH 32
17 #define AES256_SEARCH_LENGTH 40
18 #define AES128_KEY_LENGTH 16
19 #define AES192_KEY_LENGTH 24
20 #define AES256_KEY_LENGTH 32
21
aes256_key_test(const unsigned char * buf)22 static bool aes256_key_test(const unsigned char *buf) {
23 bool word1 = buf[32] == (buf[0] ^ Sbox[buf[29]] ^ 1) \
24 && buf[33] == (buf[1] ^ Sbox[buf[30]]) \
25 && buf[34] == (buf[2] ^ Sbox[buf[31]]) \
26 && buf[35] == (buf[3] ^ Sbox[buf[28]]);
27 bool word2 = (buf[36] == (buf[4] ^ buf[32]) \
28 && buf[37] == (buf[5] ^ buf[33]) \
29 && buf[38] == (buf[6] ^ buf[34]) \
30 && buf[39] == (buf[7] ^ buf[35]));
31 return word1 && word2;
32 }
33
aes192_key_test(const unsigned char * buf)34 static bool aes192_key_test(const unsigned char *buf) {
35 bool word1 = buf[24] == (buf[0] ^ Sbox[buf[21]] ^ 1) \
36 && buf[25] == (buf[1] ^ Sbox[buf[22]]) \
37 && buf[26] == (buf[2] ^ Sbox[buf[23]]) \
38 && buf[27] == (buf[3] ^ Sbox[buf[20]]);
39 bool word2 = buf[28] == (buf[4] ^ buf[24]) \
40 && buf[29] == (buf[5] ^ buf[25]) \
41 && buf[30] == (buf[6] ^ buf[26]) \
42 && buf[31] == (buf[7] ^ buf[27]);
43 return word1 && word2;
44 }
45
aes128_key_test(const unsigned char * buf)46 static bool aes128_key_test(const unsigned char *buf) {
47 bool word1 = buf[16] == (buf[0] ^ Sbox[buf[13]] ^ 1) \
48 && buf[17] == (buf[1] ^ Sbox[buf[14]]) \
49 && buf[18] == (buf[2] ^ Sbox[buf[15]]) \
50 && buf[19] == (buf[3] ^ Sbox[buf[12]]);
51 bool word2 = buf[20] == (buf[4] ^ buf[16]) \
52 && buf[21] == (buf[5] ^ buf[17]) \
53 && buf[22] == (buf[6] ^ buf[18]) \
54 && buf[23] == (buf[7] ^ buf[19]);
55 return word1 && word2;
56 }
57
r_search_aes_update(RSearch * s,ut64 from,const ut8 * buf,int len)58 R_API int r_search_aes_update(RSearch *s, ut64 from, const ut8 *buf, int len) {
59 int i, t, last = len - AES128_SEARCH_LENGTH;
60 RListIter *iter;
61 RSearchKeyword *kw;
62 const int old_nhits = s->nhits;
63
64 r_list_foreach (s->kws, iter, kw) {
65 if (last >= 0) {
66 for (i = 0; i < last; i++) {
67 if (aes128_key_test (buf + i)) {
68 kw->keyword_length = AES128_KEY_LENGTH;
69 t = r_search_hit_new (s, kw, from + i);
70 if (!t) {
71 return -1;
72 }
73 if (t > 1) {
74 return s->nhits - old_nhits;
75 }
76 i += AES128_SEARCH_LENGTH;
77 }
78 if (len - i - AES192_SEARCH_LENGTH >= 0 && aes192_key_test (buf + i)) {
79 kw->keyword_length = AES192_KEY_LENGTH;
80 t = r_search_hit_new (s, kw, from + i);
81 if (!t) {
82 return -1;
83 }
84 if (t > 1) {
85 return s->nhits - old_nhits;
86 }
87 i = i + AES192_SEARCH_LENGTH;
88 }
89 if (len - i - AES256_SEARCH_LENGTH >= 0 && aes256_key_test (buf + i)) {
90 kw->keyword_length = AES256_KEY_LENGTH;
91 t = r_search_hit_new (s, kw, from + i);
92 if (!t) {
93 return -1;
94 }
95 if (t > 1) {
96 return s->nhits - old_nhits;
97 }
98 i = i + AES256_SEARCH_LENGTH;
99 }
100 }
101 }
102 }
103 return -1;
104 }