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 }