1 #include <stdarg.h>
2 #include <stddef.h>
3 #include <setjmp.h>
4 #include <cmocka.h>
5 
6 #include <assert.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/types.h>
10 
11 #ifdef USE_GCRYPT
12 #include "gcrypt-openssl-wrapper.h"
13 #include "sha1-git.h"
14 #else
15 #include <openssl/hmac.h>
16 #include <openssl/sha.h>
17 #endif
18 
19 #include "aircrack-util/common.h"
20 #include "aircrack-util/trampoline.h"
21 #include "aircrack-crypto/crypto_engine.h"
22 #include "aircrack-util/crypto_engine_loader.h"
23 
24 /*
25  * We must force linking to one of the support crypto libraries; however,
26  * because they are linked with our binary and not the crypto engine
27  * DSOs, at run-time we fail to run due to missing symbols.
28  *
29  * The "proper" way to handle this situation is to use --no-as-needed
30  * linker flag, specifying the libraries to always link against.
31  *
32  * Then there is Autoconf... It does not support the above flag.
33  *
34  * So, we force a bit of hacks to ensure we do link against it.
35  */
36 #ifdef USE_GCRYPT
37 void * keep_libgcrypt_ = &gcry_md_open;
38 #else
39 void * keep_libcrypto_ = &HMAC;
40 #endif
41 
perform_unit_testing(void ** state)42 void perform_unit_testing(void ** state)
43 {
44 	(void) state;
45 
46 	wpapsk_password key[MAX_KEYS_PER_CRYPT_SUPPORTED];
47 	uint8_t mic[8][20];
48 	uint8_t expected_mic[20]
49 		= "\xd5\x35\x53\x82\xb8\xa9\xb8\x06\xdc\xaf\x99\xcd\xaf\x56\x4e\xb6";
50 	uint8_t stmac[6] = "\x00\x13\x46\xfe\x32\x0c";
51 	uint8_t snonce[32]
52 		= "\x59\x16\x8b\xc3\xa5\xdf\x18\xd7\x1e\xfb\x64\x23\xf3\x40\x08\x8d"
53 		  "\xab\x9e\x1b\xa2\xbb\xc5\x86\x59\xe0\x7b\x37\x64\xb0\xde\x85\x70";
54 	uint8_t anonce[32]
55 		= "\x22\x58\x54\xb0\x44\x4d\xe3\xaf\x06\xd1\x49\x2b\x85\x29\x84\xf0"
56 		  "\x4c\xf6\x27\x4c\x0e\x32\x18\xb8\x68\x17\x56\x86\x4d\xb7\xa0\x55";
57 	uint8_t eapol[256]
58 		= "\x01\x03\x00\x75\x02\x01\x0a\x00\x10\x00\x00\x00\x00\x00\x00\x00"
59 		  "\x01\x59\x16\x8b\xc3\xa5\xdf\x18\xd7\x1e\xfb\x64\x23\xf3\x40\x08"
60 		  "\x8d\xab\x9e\x1b\xa2\xbb\xc5\x86\x59\xe0\x7b\x37\x64\xb0\xde\x85"
61 		  "\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
62 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
63 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
64 		  "\x00\x00\x16\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac"
65 		  "\x04\x01\x00\x00\x0f\xac\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00"
66 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
67 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
68 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
69 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
70 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
71 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
72 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
73 		  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
74 	uint32_t eapol_size = 121;
75 	ac_crypto_engine_t engine;
76 	uint8_t bssid[6] = "\x00\x14\x6c\x7e\x40\x80";
77 	uint8_t essid[33] = "Harkonen";
78 	int nparallel = dso_ac_crypto_engine_simd_width();
79 
80 	memset(&engine, 0, sizeof(engine));
81 	dso_ac_crypto_engine_init(&engine);
82 	dso_ac_crypto_engine_set_essid(&engine, &essid[0]);
83 	dso_ac_crypto_engine_thread_init(&engine, 1);
84 	dso_ac_crypto_engine_calc_pke(&engine, bssid, stmac, anonce, snonce, 1);
85 
86 	for (int i = 0; i < nparallel; ++i)
87 	{
88 		int rc = -1;
89 
90 		memset(key, 0, sizeof(key));
91 
92 		strcpy((char *) (key[i].v), "12345678");
93 		key[i].length = 8;
94 
95 		if ((rc = dso_ac_crypto_engine_wpa_crack(&engine,
96 												 key,
97 												 eapol,
98 												 eapol_size,
99 												 mic,
100 												 2,
101 												 expected_mic,
102 												 nparallel,
103 												 1))
104 			>= 0)
105 		{
106 			// does the returned SIMD lane equal where we placed the key?
107 			assert_int_equal(rc, i);
108 		}
109 		else
110 		{
111 			fail();
112 		}
113 	}
114 
115 	dso_ac_crypto_engine_thread_destroy(&engine, 1);
116 	dso_ac_crypto_engine_destroy(&engine);
117 }
118 
perform_unit_testing_for(void ** state,int simd_flag)119 void perform_unit_testing_for(void ** state, int simd_flag)
120 {
121 	int simd_features = (int) ((uintptr_t) *state);
122 
123 	// load the DSO
124 	ac_crypto_engine_loader_load(simd_flag);
125 
126 	// Check if this shared library CAN run on the machine, if not; skip testing it.
127 	if (simd_features < dso_ac_crypto_engine_supported_features())
128 	{
129 		// unit-test cannot run without an illegal instruction.
130 		skip();
131 	}
132 	else
133 	{
134 		// Perform the unit-testing; we can run without an illegal instruction exception.
135 		perform_unit_testing(state);
136 	}
137 
138 #if !defined(SANITIZE_ADDRESS)
139 	ac_crypto_engine_loader_unload();
140 #endif
141 }
142 
test_crypto_engine_x86_avx512f(void ** state)143 void test_crypto_engine_x86_avx512f(void ** state)
144 {
145 	perform_unit_testing_for(state, SIMD_SUPPORTS_AVX512F);
146 }
147 
test_crypto_engine_x86_avx2(void ** state)148 void test_crypto_engine_x86_avx2(void ** state)
149 {
150 	perform_unit_testing_for(state, SIMD_SUPPORTS_AVX2);
151 }
152 
test_crypto_engine_x86_avx(void ** state)153 void test_crypto_engine_x86_avx(void ** state)
154 {
155 	perform_unit_testing_for(state, SIMD_SUPPORTS_AVX);
156 }
157 
test_crypto_engine_x86_sse2(void ** state)158 void test_crypto_engine_x86_sse2(void ** state)
159 {
160 	perform_unit_testing_for(state, SIMD_SUPPORTS_SSE2);
161 }
162 
test_crypto_engine_arm_neon(void ** state)163 void test_crypto_engine_arm_neon(void ** state)
164 {
165 	perform_unit_testing_for(state, SIMD_SUPPORTS_NEON);
166 }
167 
test_crypto_engine_ppc_altivec(void ** state)168 void test_crypto_engine_ppc_altivec(void ** state)
169 {
170 	perform_unit_testing_for(state, SIMD_SUPPORTS_ALTIVEC);
171 }
172 
test_crypto_engine_ppc_power8(void ** state)173 void test_crypto_engine_ppc_power8(void ** state)
174 {
175 	perform_unit_testing_for(state, SIMD_SUPPORTS_POWER8);
176 }
177 
test_crypto_engine_generic(void ** state)178 void test_crypto_engine_generic(void ** state)
179 {
180 	perform_unit_testing_for(state, SIMD_SUPPORTS_NONE);
181 }
182 
group_setup(void ** state)183 int group_setup(void ** state)
184 {
185 	*state = (void *) ((uintptr_t) simd_get_supported_features());
186 
187 	return 0;
188 }
189 
main(int argc,char * argv[])190 int main(int argc, char * argv[])
191 {
192 	(void) argc;
193 	(void) argv;
194 
195 	const struct CMUnitTest tests[]
196 		= { cmocka_unit_test(test_crypto_engine_generic),
197 #if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86)
198 #if defined(__AVX512F__)
199 			cmocka_unit_test(test_crypto_engine_x86_avx512f),
200 #endif
201 			cmocka_unit_test(test_crypto_engine_x86_avx2),
202 			cmocka_unit_test(test_crypto_engine_x86_avx),
203 			cmocka_unit_test(test_crypto_engine_x86_sse2),
204 #elif defined(__arm) || defined(__aarch64) || defined(__aarch64__)
205 			cmocka_unit_test(test_crypto_engine_arm_neon),
206 #elif defined(__PPC__) || defined(__PPC64__)
207 			cmocka_unit_test(test_crypto_engine_ppc_altivec),
208 			cmocka_unit_test(test_crypto_engine_ppc_power8),
209 #else
210 #warning "SIMD not available."
211 #endif
212 		  };
213 	return cmocka_run_group_tests(tests, group_setup, NULL);
214 }
215