1 /*
2  * test_vectors - IEEE 802.11 test vector generator
3  * Copyright (c) 2012, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "utils/crc32.h"
13 #include "utils/eloop.h"
14 #include "common/ieee802_11_defs.h"
15 #include "wlantest.h"
16 
17 
test_vector_tkip(void)18 static void test_vector_tkip(void)
19 {
20 	u8 tk[] = {
21 		0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
22 		0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
23 		0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
24 		0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34
25 	};
26 	u8 pn[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
27 	u8 frame[] = {
28 		0x08, 0x42, 0x2c, 0x00, 0x02, 0x03, 0x04, 0x05,
29 		0x06, 0x08, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
30 		0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xd0, 0x02,
31 		/* 0x00, 0x20, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, */
32 		0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00,
33 		0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
34 		0x40, 0x01, 0xa5, 0x55, 0xc0, 0xa8, 0x0a, 0x02,
35 		0xc0, 0xa8, 0x0a, 0x01, 0x08, 0x00, 0x3a, 0xb0,
36 		0x00, 0x00, 0x00, 0x00, 0xcd, 0x4c, 0x05, 0x00,
37 		0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x0a, 0x0b,
38 		0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
39 		0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
40 		0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
41 		0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
42 		0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
43 		0x34, 0x35, 0x36, 0x37,
44 		/* 0x68, 0x81, 0xa3, 0xf3, 0xd6, 0x48, 0xd0, 0x3c */
45 	};
46 	u8 *enc, *plain;
47 	size_t enc_len, plain_len;
48 
49 	wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.6.3 TKIP test "
50 		   "vector\n");
51 
52 	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
53 	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
54 	wpa_hexdump(MSG_INFO, "Plaintext MPDU", frame, sizeof(frame));
55 
56 	enc = tkip_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0, &enc_len);
57 	if (enc == NULL) {
58 		wpa_printf(MSG_ERROR, "Failed to encrypt TKIP frame");
59 		return;
60 	}
61 
62 	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
63 
64 	wpa_debug_level = MSG_INFO;
65 	plain = tkip_decrypt(tk, (const struct ieee80211_hdr *) enc,
66 			     enc + 24, enc_len - 24, &plain_len, NULL, NULL);
67 	wpa_debug_level = MSG_EXCESSIVE;
68 	os_free(enc);
69 
70 	if (plain == NULL) {
71 		wpa_printf(MSG_ERROR, "Failed to decrypt TKIP frame");
72 		return;
73 	}
74 
75 	if (plain_len != sizeof(frame) - 24 ||
76 	    os_memcmp(plain, frame + 24, plain_len) != 0) {
77 		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
78 			    plain, plain_len);
79 	}
80 
81 	os_free(plain);
82 }
83 
84 
test_vector_ccmp(void)85 static void test_vector_ccmp(void)
86 {
87 	u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
88 		    0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f };
89 	u8 pn[] = { 0xB5, 0x03, 0x97, 0x76, 0xE7, 0x0C };
90 	u8 frame[] = {
91 		0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
92 		0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
93 		0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
94 		0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
95 		0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
96 		0x7e, 0x78, 0xa0, 0x50
97 	};
98 	u8 *enc, *plain;
99 	size_t enc_len, plain_len;
100 	u8 fcs[4];
101 
102 	wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.6.4 CCMP test "
103 		   "vector\n");
104 
105 	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
106 	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
107 	wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
108 	wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);
109 
110 	enc = ccmp_encrypt(tk, frame, sizeof(frame), 24, NULL, NULL, NULL, NULL,
111 			   pn, 0, &enc_len);
112 	if (enc == NULL) {
113 		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
114 		return;
115 	}
116 
117 	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
118 	WPA_PUT_LE32(fcs, ieee80211_crc32(enc, enc_len));
119 	wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
120 
121 	wpa_debug_level = MSG_INFO;
122 	plain = ccmp_decrypt(tk, (const struct ieee80211_hdr *) enc,
123 			     NULL, NULL, NULL, enc + 24, enc_len - 24,
124 			     &plain_len);
125 	wpa_debug_level = MSG_EXCESSIVE;
126 	os_free(enc);
127 
128 	if (plain == NULL) {
129 		wpa_printf(MSG_ERROR, "Failed to decrypt CCMP frame");
130 		return;
131 	}
132 
133 	if (plain_len != sizeof(frame) - 24 ||
134 	    os_memcmp(plain, frame + 24, plain_len) != 0) {
135 		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
136 			    plain, plain_len);
137 	}
138 
139 	os_free(plain);
140 }
141 
142 
test_vector_ccmp_pv1(void)143 static void test_vector_ccmp_pv1(void)
144 {
145 	u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
146 		    0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f };
147 	u8 pn[8];
148 	u8 frame1[] = {
149 		0x61, 0x00, 0xa2, 0xae, 0xa5, 0xb8, 0xfc, 0xba,
150 		0x07, 0x00, 0x80, 0x33,
151 		0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
152 		0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
153 		0x7e, 0x78, 0xa0, 0x50
154 	};
155 	u8 frame2[] = {
156 		0x61, 0x00, 0xa2, 0xae, 0xa5, 0xb8, 0xfc, 0xba,
157 		0x07, 0x20, 0x80, 0x33, 0x02, 0xd2, 0xe1, 0x28,
158 		0xa5, 0x7c,
159 		0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
160 		0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
161 		0x7e, 0x78, 0xa0, 0x50
162 	};
163 	u8 frame3[] = {
164 		0x6d, 0x00, 0xa2, 0xae, 0xa5, 0xb8, 0xfc, 0xba,
165 		0x52, 0x30, 0xf1, 0x84, 0x44, 0x08, 0x80, 0x33,
166 		0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
167 		0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
168 		0x7e, 0x78, 0xa0, 0x50
169 	};
170 	u8 *enc;
171 	size_t enc_len;
172 	u8 fcs[4];
173 	u8 bssid[ETH_ALEN] = { 0xa2, 0xae, 0xa5, 0xb8, 0xfc, 0xba };
174 	u8 da[ETH_ALEN] = { 0x02, 0xd2, 0xe1, 0x28, 0xa5, 0x7c };
175 	u8 sa[ETH_ALEN] = { 0x52, 0x30, 0xf1, 0x84, 0x44, 0x08 };
176 	u16 aid = 7;
177 	u32 bpn = 123;
178 	u16 sc = 0x3380;
179 	int key_id = 0;
180 	u16 fc;
181 	int tid = 3;
182 	u16 sid;
183 
184 	wpa_printf(MSG_INFO,
185 		   "\nIEEE P802.11ah/D10.0, J.6.4 CCMP PV1 test vectors\n");
186 
187 	wpa_printf(MSG_INFO, "BSSID: " MACSTR, MAC2STR(bssid));
188 	wpa_printf(MSG_INFO, "DA: " MACSTR, MAC2STR(da));
189 	wpa_printf(MSG_INFO, "SA: " MACSTR, MAC2STR(sa));
190 	wpa_printf(MSG_INFO, "Association ID: %u", aid);
191 	wpa_printf(MSG_INFO, "Base PN: %u (0x%08x)", bpn, bpn);
192 	wpa_printf(MSG_INFO, "SC = 0x%04x (FragNum=%u SeqNum=%u)",
193 		   sc, WLAN_GET_SEQ_FRAG(sc), WLAN_GET_SEQ_SEQ(sc));
194 	wpa_printf(MSG_INFO, "TID = %u", tid);
195 	wpa_printf(MSG_INFO, "Key ID: %u", key_id);
196 	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
197 	wpa_printf(MSG_INFO, "PN = SC||BPN");
198 	WPA_PUT_LE16(&pn[0], sc);
199 	WPA_PUT_LE32(&pn[2], bpn);
200 	wpa_hexdump(MSG_INFO, "PN (PN0..PN5)", pn, sizeof(pn));
201 
202 	wpa_printf(MSG_INFO,
203 		   "\nPV1 test vector #1:\nHeader compression used and A3 was previously stored at the receiver");
204 	fc = WPA_GET_LE16(frame1);
205 	wpa_printf(MSG_INFO,
206 		   "FC=0x%04x (PV=%u Type=%u PTID/Subtype=%u From_DS=%u More_Fragments=%u Power_Management=%u More_Data=%u Protected_Frame=%u End_of_SP=%u Relayed_Frame=%u Ack_Policy=%u)",
207 		   fc,
208 		   fc & WLAN_FC_PVER,
209 		   (fc & (BIT(2) | BIT(3) | BIT(4))) >> 2,
210 		   (fc & (BIT(5) | BIT(6) | BIT(7))) >> 5,
211 		   !!(fc & BIT(8)),
212 		   !!(fc & BIT(9)),
213 		   !!(fc & BIT(10)),
214 		   !!(fc & BIT(11)),
215 		   !!(fc & BIT(12)),
216 		   !!(fc & BIT(13)),
217 		   !!(fc & BIT(14)),
218 		   !!(fc & BIT(15)));
219 	wpa_printf(MSG_INFO, "A1=" MACSTR, MAC2STR(&frame1[2]));
220 	sid = WPA_GET_LE16(&frame1[8]);
221 	wpa_printf(MSG_INFO,
222 		   "A2=%02x %02x (SID: AID=%u A3_Present=%u A4_Present=%u A-MSDU=%u); corresponds to 52:30:f1:84:44:08 in uncompressed header",
223 		   frame1[8], frame1[9],
224 		   sid & ~(BIT(13) | BIT(14) | BIT(15)),
225 		   !!(sid & BIT(13)),
226 		   !!(sid & BIT(14)),
227 		   !!(sid & BIT(15)));
228 	sc = WPA_GET_LE16(&frame1[10]);
229 	wpa_printf(MSG_INFO, "Sequence Control: %02x %02x (FN=%u SN=%u)",
230 		   frame1[10], frame1[11],
231 		   WLAN_GET_SEQ_FRAG(sc), WLAN_GET_SEQ_SEQ(sc));
232 	wpa_printf(MSG_INFO, "A3 not present; corresponds to 02:d2:e1:28:a5:7c in uncompressed header");
233 	wpa_printf(MSG_INFO, "A4 not present");
234 	wpa_hexdump(MSG_INFO, "Plaintext Frame Header", frame1, 12);
235 	wpa_hexdump(MSG_INFO, "Plaintext Frame Body",
236 		    frame1 + 12, sizeof(frame1) - 12);
237 
238 	enc = ccmp_encrypt_pv1(tk, &frame1[2], sa, da, frame1, sizeof(frame1),
239 			       12, pn, key_id, &enc_len);
240 	if (enc == NULL) {
241 		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
242 		return;
243 	}
244 
245 	wpa_hexdump(MSG_INFO, "Encrypted Frame Header", enc, 12);
246 	wpa_hexdump(MSG_INFO, "Encrypted Frame Frame Body",
247 		    enc + 12, enc_len - 12);
248 	WPA_PUT_LE32(fcs, ieee80211_crc32(enc, enc_len));
249 	wpa_hexdump(MSG_INFO, "Encrypted Frame FCS", fcs, sizeof(fcs));
250 
251 	wpa_printf(MSG_INFO,
252 		   "\nPV1 test vector #2:\nHeader compression used and A3 was not previously stored at the receiver");
253 	fc = WPA_GET_LE16(frame2);
254 	wpa_printf(MSG_INFO,
255 		   "FC=0x%04x (PV=%u Type=%u PTID/Subtype=%u From_DS=%u More_Fragments=%u Power_Management=%u More_Data=%u Protected_Frame=%u End_of_SP=%u Relayed_Frame=%u Ack_Policy=%u)",
256 		   fc,
257 		   fc & WLAN_FC_PVER,
258 		   (fc & (BIT(2) | BIT(3) | BIT(4))) >> 2,
259 		   (fc & (BIT(5) | BIT(6) | BIT(7))) >> 5,
260 		   !!(fc & BIT(8)),
261 		   !!(fc & BIT(9)),
262 		   !!(fc & BIT(10)),
263 		   !!(fc & BIT(11)),
264 		   !!(fc & BIT(12)),
265 		   !!(fc & BIT(13)),
266 		   !!(fc & BIT(14)),
267 		   !!(fc & BIT(15)));
268 	wpa_printf(MSG_INFO, "A1=" MACSTR, MAC2STR(&frame2[2]));
269 	sid = WPA_GET_LE16(&frame2[8]);
270 	wpa_printf(MSG_INFO,
271 		   "A2=%02x %02x (SID: AID=%u A3_Present=%u A4_Present=%u A-MSDU=%u); corresponds to 52:30:f1:84:44:08 in uncompressed header",
272 		   frame2[8], frame2[9],
273 		   sid & ~(BIT(13) | BIT(14) | BIT(15)),
274 		   !!(sid & BIT(13)),
275 		   !!(sid & BIT(14)),
276 		   !!(sid & BIT(15)));
277 	sc = WPA_GET_LE16(&frame2[10]);
278 	wpa_printf(MSG_INFO, "Sequence Control: %02x %02x (FN=%u SN=%u)",
279 		   frame2[10], frame2[11],
280 		   WLAN_GET_SEQ_FRAG(sc), WLAN_GET_SEQ_SEQ(sc));
281 	wpa_printf(MSG_INFO, "A3=" MACSTR, MAC2STR(&frame2[12]));
282 	wpa_printf(MSG_INFO, "A4 not present");
283 	wpa_hexdump(MSG_INFO, "Plaintext Frame Header", frame2, 18);
284 	wpa_hexdump(MSG_INFO, "Plaintext Frame Body",
285 		    frame2 + 18, sizeof(frame2) - 18);
286 
287 	enc = ccmp_encrypt_pv1(tk, &frame2[2], sa, &frame2[12],
288 			       frame2, sizeof(frame2), 18, pn, key_id,
289 			       &enc_len);
290 	if (enc == NULL) {
291 		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
292 		return;
293 	}
294 
295 	wpa_hexdump(MSG_INFO, "Encrypted Frame Header", enc, 18);
296 	wpa_hexdump(MSG_INFO, "Encrypted Frame Frame Body",
297 		    enc + 18, enc_len - 18);
298 	WPA_PUT_LE32(fcs, ieee80211_crc32(enc, enc_len));
299 	wpa_hexdump(MSG_INFO, "Encrypted Frame FCS", fcs, sizeof(fcs));
300 
301 	wpa_printf(MSG_INFO,
302 		   "\nPV1 test vector #3:\nType 3 frame from SA to DA(=BSSID) (i.e., no separate DA in this example)");
303 	fc = WPA_GET_LE16(frame3);
304 	wpa_printf(MSG_INFO,
305 		   "FC=0x%04x (PV=%u Type=%u PTID/Subtype=%u From_DS=%u More_Fragments=%u Power_Management=%u More_Data=%u Protected_Frame=%u End_of_SP=%u Relayed_Frame=%u Ack_Policy=%u)",
306 		   fc,
307 		   fc & WLAN_FC_PVER,
308 		   (fc & (BIT(2) | BIT(3) | BIT(4))) >> 2,
309 		   (fc & (BIT(5) | BIT(6) | BIT(7))) >> 5,
310 		   !!(fc & BIT(8)),
311 		   !!(fc & BIT(9)),
312 		   !!(fc & BIT(10)),
313 		   !!(fc & BIT(11)),
314 		   !!(fc & BIT(12)),
315 		   !!(fc & BIT(13)),
316 		   !!(fc & BIT(14)),
317 		   !!(fc & BIT(15)));
318 	wpa_printf(MSG_INFO, "A1=" MACSTR, MAC2STR(&frame3[2]));
319 	wpa_printf(MSG_INFO, "A2=" MACSTR, MAC2STR(&frame3[8]));
320 	sc = WPA_GET_LE16(&frame3[14]);
321 	wpa_printf(MSG_INFO, "Sequence Control: %02x %02x (FN=%u SN=%u)",
322 		   frame3[14], frame3[15],
323 		   WLAN_GET_SEQ_FRAG(sc), WLAN_GET_SEQ_SEQ(sc));
324 	wpa_printf(MSG_INFO,
325 		   "A3 not present; corresponds to 02:d2:e1:28:a5:7c in uncompressed header");
326 	wpa_printf(MSG_INFO, "A4 not present");
327 	wpa_hexdump(MSG_INFO, "Plaintext Frame Header", frame3, 16);
328 	wpa_hexdump(MSG_INFO, "Plaintext Frame Body",
329 		    frame3 + 16, sizeof(frame3) - 16);
330 
331 	enc = ccmp_encrypt_pv1(tk, &frame3[2], &frame3[8], da,
332 			       frame3, sizeof(frame3), 16, pn, key_id,
333 			       &enc_len);
334 	if (enc == NULL) {
335 		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
336 		return;
337 	}
338 
339 	wpa_hexdump(MSG_INFO, "Encrypted Frame Header", enc, 16);
340 	wpa_hexdump(MSG_INFO, "Encrypted Frame Frame Body",
341 		    enc + 16, enc_len - 16);
342 	WPA_PUT_LE32(fcs, ieee80211_crc32(enc, enc_len));
343 	wpa_hexdump(MSG_INFO, "Encrypted Frame FCS", fcs, sizeof(fcs));
344 }
345 
346 
test_vector_bip(void)347 static void test_vector_bip(void)
348 {
349 	u8 igtk[] = {
350 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
351 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
352 	};
353 	u64 ipn = 0x04;
354 	u8 frame[] = {
355 		0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
356 		0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
357 		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
358 		0x02, 0x00
359 	};
360 	u8 *prot;
361 	size_t prot_len;
362 
363 	wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.9.1 BIP with broadcast "
364 		   "Deauthentication frame\n");
365 
366 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
367 	wpa_printf(MSG_INFO, "IPN: 0x%llx", (long long unsigned int) ipn);
368 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
369 
370 	prot = bip_protect(igtk, sizeof(igtk), frame, sizeof(frame),
371 			   ipn, 4, &prot_len);
372 	if (prot == NULL) {
373 		wpa_printf(MSG_ERROR, "Failed to protect BIP frame");
374 		return;
375 	}
376 
377 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
378 	os_free(prot);
379 }
380 
381 
test_vector_bip_s1g_beacon(void)382 static void test_vector_bip_s1g_beacon(void)
383 {
384 	const u8 igtk[] = {
385 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
386 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
387 	};
388 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
389 	/* FC 2 Dur 2 SA 6 Time 4 CS 1 Next 0/3 Comp 0/4 ANO 0/1
390 	 * FC: prot 2 type 2 subtype 4 next 1 comp 1 ano 1 bss bw 3 sec 1 ap
391 	 *	pm 1
392 	 * S1G Beacon, no extra header fields, S1G Beacon Compatibility element
393 	 */
394 	const u8 frame[] = {
395 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
396 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
397 		0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
398 		0x78
399 	};
400 	u8 *prot;
401 	size_t prot_len;
402 
403 	wpa_printf(MSG_INFO,
404 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-CMAC-128, no optional header fields, S1G Beacon Compatibility element in body\n");
405 
406 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
407 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
408 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
409 
410 	prot = bip_protect_s1g_beacon(igtk, sizeof(igtk), frame, sizeof(frame),
411 				      ipn, 7, false, &prot_len);
412 	if (!prot) {
413 		wpa_printf(MSG_ERROR,
414 			   "Failed to protect S1G Beacon frame with BIP-CMAC-128");
415 		return;
416 	}
417 
418 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
419 	os_free(prot);
420 }
421 
422 
test_vector_bip_s1g_beacon_ext(void)423 static void test_vector_bip_s1g_beacon_ext(void)
424 {
425 	const u8 igtk[] = {
426 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
427 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
428 	};
429 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
430 	/* FC 2 Dur 2 SA 6 Time 4 CS 1 Next 0/3 Comp 0/4 ANO 0/1
431 	 * FC: prot 2 type 2 subtype 4 next 1 comp 1 ano 1 bss bw 3 sec 1 ap
432 	 *	pm 1
433 	 * S1G Beacon, all possible extra header fields, no body fields */
434 	const u8 frame[] = {
435 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
436 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
438 	};
439 	u8 *prot;
440 	size_t prot_len;
441 
442 	wpa_printf(MSG_INFO,
443 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-CMAC-128, all optional header fields, no body elements\n");
444 
445 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
446 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
447 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
448 
449 	prot = bip_protect_s1g_beacon(igtk, sizeof(igtk), frame, sizeof(frame),
450 				      ipn, 6, false, &prot_len);
451 	if (!prot) {
452 		wpa_printf(MSG_ERROR,
453 			   "Failed to protect S1G Beacon frame with BIP-CMAC-128");
454 		return;
455 	}
456 
457 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
458 	os_free(prot);
459 }
460 
461 
test_vector_bip_s1g_beacon_bce(void)462 static void test_vector_bip_s1g_beacon_bce(void)
463 {
464 	const u8 igtk[] = {
465 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
466 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
467 	};
468 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
469 	/* FC 2 Dur 2 SA 6 Time 4 CS 1 Next 0/3 Comp 0/4 ANO 0/1
470 	 * FC: prot 2 type 2 subtype 4 next 1 comp 1 ano 1 bss bw 3 sec 1 ap
471 	 *	pm 1
472 	 * S1G Beacon, no extra header fields, S1G Beacon Compatibility element
473 	 */
474 	const u8 frame[] = {
475 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
476 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
477 		0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
478 		0x78
479 	};
480 	u8 *prot;
481 	size_t prot_len;
482 
483 	wpa_printf(MSG_INFO,
484 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-CMAC-128 using BCE, no optional header fields, S1G Beacon Compatibility element in body\n");
485 
486 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
487 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
488 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
489 
490 	prot = bip_protect_s1g_beacon(igtk, sizeof(igtk), frame, sizeof(frame),
491 				      ipn, 7, true, &prot_len);
492 	if (!prot) {
493 		wpa_printf(MSG_ERROR,
494 			   "Failed to protect S1G Beacon frame with BIP using BCE-CMAC-128");
495 		return;
496 	}
497 
498 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
499 	os_free(prot);
500 }
501 
502 
test_vector_bip_s1g_beacon_bce_ext(void)503 static void test_vector_bip_s1g_beacon_bce_ext(void)
504 {
505 	const u8 igtk[] = {
506 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
507 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
508 	};
509 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
510 	/* FC 2 Dur 2 SA 6 Time 4 CS 1 Next 0/3 Comp 0/4 ANO 0/1
511 	 * FC: prot 2 type 2 subtype 4 next 1 comp 1 ano 1 bss bw 3 sec 1 ap
512 	 *	pm 1
513 	 * S1G Beacon, all possible extra header fields, no body fields */
514 	const u8 frame[] = {
515 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
516 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
518 	};
519 	u8 *prot;
520 	size_t prot_len;
521 
522 	wpa_printf(MSG_INFO,
523 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-CMAC-128 using BCE, all optional header fields, no body elements\n");
524 
525 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
526 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
527 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
528 
529 	prot = bip_protect_s1g_beacon(igtk, sizeof(igtk), frame, sizeof(frame),
530 				      ipn, 6, true, &prot_len);
531 	if (!prot) {
532 		wpa_printf(MSG_ERROR,
533 			   "Failed to protect S1G Beacon frame with BIP using BCE-CMAC-128");
534 		return;
535 	}
536 
537 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
538 	os_free(prot);
539 }
540 
541 
test_vector_ccmp_mgmt(void)542 static void test_vector_ccmp_mgmt(void)
543 {
544 	u8 tk[] = { 0x66, 0xed, 0x21, 0x04, 0x2f, 0x9f, 0x26, 0xd7,
545 		    0x11, 0x57, 0x06, 0xe4, 0x04, 0x14, 0xcf, 0x2e };
546 	u8 pn[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
547 	u8 frame[] = {
548 		0xc0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
549 		0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
550 		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
551 		0x02, 0x00
552 	};
553 	u8 *enc, *plain;
554 	size_t enc_len, plain_len;
555 
556 	wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.9.2 CCMP with unicast "
557 		   "Deauthentication frame\n");
558 
559 	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
560 	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
561 	wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
562 	wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);
563 
564 	enc = ccmp_encrypt(tk, frame, sizeof(frame), 24, NULL, NULL, NULL, NULL,
565 			   pn, 0, &enc_len);
566 	if (enc == NULL) {
567 		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
568 		return;
569 	}
570 
571 	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
572 
573 	wpa_debug_level = MSG_INFO;
574 	plain = ccmp_decrypt(tk, (const struct ieee80211_hdr *) enc,
575 			     NULL, NULL, NULL, enc + 24, enc_len - 24,
576 			     &plain_len);
577 	wpa_debug_level = MSG_EXCESSIVE;
578 	os_free(enc);
579 
580 	if (plain == NULL) {
581 		wpa_printf(MSG_ERROR, "Failed to decrypt CCMP frame");
582 		return;
583 	}
584 
585 	if (plain_len != sizeof(frame) - 24 ||
586 	    os_memcmp(plain, frame + 24, plain_len) != 0) {
587 		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
588 			    plain, plain_len);
589 	}
590 
591 	os_free(plain);
592 }
593 
594 
595 struct gcmp_test {
596 	u8 tk[16];
597 	u8 pn[6];
598 	u8 frame[300];
599 	size_t hdr_len;
600 	size_t payload_len;
601 	u8 mic[16];
602 	u8 encr[300];
603 };
604 
605 static const struct gcmp_test gcmp_vectors[] =
606 {
607 	{
608 		.tk = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
609 			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
610 		.pn = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
611 		.frame = {
612 			0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 			0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
614 			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
615 
616 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 		},
649 		.hdr_len = 24,
650 		.payload_len = 256,
651 		.mic = {
652 			0x80, 0xCB, 0x06, 0x62, 0xEA, 0x71, 0xAB, 0xFD,
653 			0x9F, 0x04, 0xC7, 0xF8, 0x72, 0xF5, 0x80, 0x90 },
654 		.encr = {
655 			0x5F, 0x55, 0x78, 0xC1, 0x8F, 0x13, 0x7A, 0xD2,
656 			0x79, 0xBF, 0x3F, 0x2B, 0x24, 0xC7, 0xBD, 0x8F,
657 			0x27, 0x7A, 0x1B, 0xE6, 0x77, 0x0D, 0xA1, 0xD9,
658 			0x8B, 0x70, 0xC6, 0xD2, 0x8A, 0xE0, 0x1C, 0x55,
659 			0x9E, 0xCB, 0xA6, 0xA0, 0x1D, 0xB0, 0x67, 0xC5,
660 			0xA2, 0x7E, 0x4D, 0xB0, 0x8C, 0xDA, 0xDC, 0x77,
661 			0x52, 0xAD, 0x63, 0x7E, 0xAF, 0x0A, 0x18, 0xED,
662 			0x13, 0xFB, 0xAA, 0x14, 0x3B, 0xAF, 0xEF, 0x18,
663 			0xF8, 0xFB, 0xCE, 0x4C, 0x65, 0xE8, 0x6B, 0xD0,
664 			0x2A, 0x87, 0xB6, 0x01, 0xB7, 0xEA, 0xB9, 0x3F,
665 			0x2B, 0xBC, 0x87, 0x4C, 0x8A, 0x71, 0x05, 0x80,
666 			0xF5, 0x02, 0x34, 0x1A, 0x6A, 0x53, 0x39, 0x31,
667 			0x43, 0xDE, 0x4C, 0x9E, 0xC6, 0xA2, 0x86, 0xF1,
668 			0x25, 0x71, 0x83, 0x78, 0xAE, 0xDC, 0x84, 0xEB,
669 			0xA2, 0xB3, 0x0F, 0x5C, 0x28, 0xBB, 0x5D, 0x75,
670 			0xC6, 0xB0, 0x25, 0x46, 0x6D, 0x06, 0x51, 0xC7,
671 			0x22, 0xDC, 0x71, 0x15, 0x1F, 0x21, 0x2D, 0x68,
672 			0x87, 0x82, 0x8A, 0x03, 0x82, 0xE9, 0x28, 0x8A,
673 			0x7F, 0x43, 0xD5, 0x2B, 0x7D, 0x25, 0x08, 0x61,
674 			0x57, 0x64, 0x69, 0x54, 0xBB, 0x43, 0xB5, 0x7E,
675 			0xA5, 0x87, 0xA0, 0x25, 0xF4, 0x0C, 0xE7, 0x45,
676 			0x11, 0xE4, 0xDD, 0x22, 0x85, 0xB4, 0x0B, 0xA3,
677 			0xF3, 0xB9, 0x62, 0x62, 0xCB, 0xC2, 0x8C, 0x6A,
678 			0xA7, 0xBE, 0x44, 0x3E, 0x7B, 0x41, 0xE1, 0xEB,
679 			0xFF, 0x52, 0x48, 0x57, 0xA6, 0x81, 0x68, 0x97,
680 			0x75, 0x01, 0x15, 0xB0, 0x23, 0x1A, 0xB7, 0xC2,
681 			0x84, 0x72, 0xC0, 0x6D, 0xD0, 0xB4, 0x9B, 0xE9,
682 			0xF3, 0x69, 0xA8, 0xC3, 0x9C, 0xCD, 0x0D, 0xB7,
683 			0x98, 0x35, 0x10, 0xE1, 0xAE, 0x8F, 0x05, 0xD7,
684 			0x75, 0x45, 0xE0, 0x23, 0x5C, 0xDB, 0xD6, 0x12,
685 			0xF3, 0x15, 0x07, 0x54, 0xCE, 0xE5, 0xCE, 0x6A,
686 			0x12, 0x25, 0xD9, 0x95, 0x25, 0x02, 0x6F, 0x74
687 		}
688 	},
689 	{
690 		.tk = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
691 			0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f },
692 		.pn = { 0x00, 0x89, 0x5F, 0x5F, 0x2B, 0x08 },
693 		.frame = {
694 			0x88, 0x48, 0x0b, 0x00, 0x0f, 0xd2, 0xe1, 0x28,
695 			0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
696 			0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0x80, 0x33,
697 			0x03, 0x00,
698 
699 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
700 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
701 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
702 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
703 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
704 		},
705 		.hdr_len = 26,
706 		.payload_len = 40,
707 		.mic = {
708 			0xde, 0xf6, 0x19, 0xc2, 0xa3, 0x74, 0xb6, 0xdf,
709 			0x66, 0xff, 0xa5, 0x3b, 0x6c, 0x69, 0xd7, 0x9e },
710 		.encr = {
711 			0x60, 0xe9, 0x70, 0x0c, 0xc4, 0xd4, 0x0a, 0xc6,
712 			0xd2, 0x88, 0xb2, 0x01, 0xc3, 0x8f, 0x5b, 0xf0,
713 			0x8b, 0x80, 0x74, 0x42, 0x64, 0x0a, 0x15, 0x96,
714 			0xe5, 0xdb, 0xda, 0xd4, 0x1d, 0x1f, 0x36, 0x23,
715 			0xf4, 0x5d, 0x7a, 0x12, 0xdb, 0x7a, 0xfb, 0x23
716 		}
717 	}
718 };
719 
720 
run_gcmp(int idx,const struct gcmp_test * vector)721 static int run_gcmp(int idx, const struct gcmp_test *vector)
722 {
723 	u8 *enc, *plain;
724 	size_t enc_len, plain_len;
725 	u8 fcs[4];
726 	int err = 0;
727 
728 	wpa_printf(MSG_INFO,
729 		   "\nIEEE Std 802.11ad-2012, M.11.1 GCMP test mpdu #%d\n",
730 		   idx);
731 
732 	wpa_hexdump(MSG_INFO, "TK", vector->tk, sizeof(vector->tk));
733 	wpa_hexdump(MSG_INFO, "PN", vector->pn, sizeof(vector->pn));
734 	wpa_hexdump(MSG_INFO, "802.11 Header", vector->frame, vector->hdr_len);
735 	wpa_hexdump(MSG_INFO, "Plaintext Data",
736 		    vector->frame + vector->hdr_len,
737 		    vector->payload_len);
738 
739 	enc = gcmp_encrypt(vector->tk, sizeof(vector->tk),
740 			   vector->frame,
741 			   vector->hdr_len + vector->payload_len,
742 			   vector->hdr_len,
743 			   vector->hdr_len == 26 ?
744 			   vector->frame + vector->hdr_len - 2 : NULL,
745 			   NULL, NULL, NULL,
746 			   vector->pn, 0, &enc_len);
747 	if (enc == NULL) {
748 		wpa_printf(MSG_ERROR, "Failed to encrypt GCMP frame");
749 		return 1;
750 	}
751 
752 	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
753 	if (os_memcmp(vector->encr, enc + vector->hdr_len + 8,
754 		      vector->payload_len) != 0) {
755 		wpa_printf(MSG_ERROR, "GCMP test mpdu #%d enctypted data mismatch",
756 			   idx);
757 		err++;
758 	}
759 	if (os_memcmp(vector->mic, enc + enc_len - sizeof(vector->mic),
760 		      sizeof(vector->mic)) != 0) {
761 		wpa_printf(MSG_ERROR, "GCMP test mpdu #%d MIC mismatch", idx);
762 		err++;
763 	}
764 	WPA_PUT_LE32(fcs, ieee80211_crc32(enc, enc_len));
765 	wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
766 
767 	wpa_debug_level = MSG_INFO;
768 	plain = gcmp_decrypt(vector->tk, sizeof(vector->tk),
769 			     (const struct ieee80211_hdr *) enc, NULL, NULL,
770 			     NULL, enc + vector->hdr_len,
771 			     enc_len - vector->hdr_len, &plain_len);
772 	wpa_debug_level = MSG_EXCESSIVE;
773 	os_free(enc);
774 
775 	if (plain == NULL) {
776 		wpa_printf(MSG_ERROR, "Failed to decrypt GCMP frame");
777 		return 1;
778 	}
779 
780 	if (plain_len != vector->payload_len ||
781 	    os_memcmp(plain, vector->frame + vector->hdr_len, plain_len) != 0) {
782 		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
783 			    plain, plain_len);
784 		err++;
785 	}
786 
787 	os_free(plain);
788 
789 	return err;
790 }
791 
792 
test_vector_gcmp(void)793 static int test_vector_gcmp(void)
794 {
795 	int err = 0;
796 	int i;
797 
798 	for (i = 0; i < ARRAY_SIZE(gcmp_vectors); i++) {
799 		if (run_gcmp(i + 1, &gcmp_vectors[i]))
800 			err++;
801 
802 	}
803 
804 	return err;
805 }
806 
807 
test_vector_gcmp_256(void)808 static int test_vector_gcmp_256(void)
809 {
810 	u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
811 		    0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f,
812 		    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
813 		    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
814 	u8 pn[] = {
815 		0x00, 0x89, 0x5F, 0x5F, 0x2B, 0x08
816 	};
817 	u8 frame[] = {
818 		0x88, 0x48, 0x0b, 0x00, 0x0f, 0xd2, 0xe1, 0x28,
819 		0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
820 		0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0x80, 0x33,
821 		0x03, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
822 		0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
823 		0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
824 		0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
825 		0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
826 		0x26, 0x27
827 	};
828 	u8 encr[] = {
829 		0x88, 0x48, 0x0b, 0x00, 0x0f, 0xd2, 0xe1, 0x28,
830 		0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
831 		0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0x80, 0x33,
832 		0x03, 0x00, 0x08, 0x2b, 0x00, 0x20, 0x5f, 0x5f,
833 		0x89, 0x00, 0x65, 0x83, 0x43, 0xc8, 0xb1, 0x44,
834 		0x47, 0xd9, 0x21, 0x1d, 0xef, 0xd4, 0x6a, 0xd8,
835 		0x9c, 0x71, 0x0c, 0x6f, 0xc3, 0x33, 0x33, 0x23,
836 		0x6e, 0x39, 0x97, 0xb9, 0x17, 0x6a, 0x5a, 0x8b,
837 		0xe7, 0x79, 0xb2, 0x12, 0x66, 0x55, 0x5e, 0x70,
838 		0xad, 0x79, 0x11, 0x43, 0x16, 0x85, 0x90, 0x95,
839 		0x47, 0x3d, 0x5b, 0x1b, 0xd5, 0x96, 0xb3, 0xde,
840 		0xa3, 0xbf
841 	};
842 	u8 *enc, *plain;
843 	size_t enc_len, plain_len;
844 	u8 fcs[4];
845 	int err = 0;
846 
847 	wpa_printf(MSG_INFO, "\nIEEE P802.11ac/D7.0, M.11.1 GCMP-256 test vector\n");
848 
849 	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
850 	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
851 	wpa_hexdump(MSG_INFO, "802.11 Header", frame, 26);
852 	wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 26, sizeof(frame) - 26);
853 
854 	enc = gcmp_encrypt(tk, sizeof(tk), frame, sizeof(frame), 26, frame + 24,
855 			   NULL, NULL, NULL, pn, 0, &enc_len);
856 	if (enc == NULL) {
857 		wpa_printf(MSG_ERROR, "Failed to encrypt GCMP frame");
858 		return 1;
859 	}
860 
861 	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
862 	if (enc_len != sizeof(encr) || os_memcmp(enc, encr, enc_len) != 0) {
863 		wpa_printf(MSG_ERROR, "GCMP-256 test vector mismatch");
864 		err++;
865 	}
866 	WPA_PUT_LE32(fcs, ieee80211_crc32(enc, enc_len));
867 	wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
868 
869 	wpa_debug_level = MSG_INFO;
870 	plain = gcmp_decrypt(tk, sizeof(tk), (const struct ieee80211_hdr *) enc,
871 			     NULL, NULL, NULL, enc + 26, enc_len - 26,
872 			     &plain_len);
873 	wpa_debug_level = MSG_EXCESSIVE;
874 	os_free(enc);
875 
876 	if (plain == NULL) {
877 		wpa_printf(MSG_ERROR, "Failed to decrypt GCMP frame");
878 		return 1;
879 	}
880 
881 	if (plain_len != sizeof(frame) - 26 ||
882 	    os_memcmp(plain, frame + 26, plain_len) != 0) {
883 		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
884 			    plain, plain_len);
885 		err++;
886 	}
887 
888 	os_free(plain);
889 
890 	return err;
891 }
892 
893 
test_vector_ccmp_256(void)894 static int test_vector_ccmp_256(void)
895 {
896 	u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
897 		    0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f,
898 		    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
899 		    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
900 	u8 pn[] = { 0xB5, 0x03, 0x97, 0x76, 0xE7, 0x0C };
901 	u8 frame[] = {
902 		0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
903 		0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
904 		0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
905 		0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
906 		0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
907 		0x7e, 0x78, 0xa0, 0x50
908 	};
909 	u8 encr[] = {
910 		0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
911 		0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
912 		0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
913 		0x0c, 0xe7, 0x00, 0x20, 0x76, 0x97, 0x03, 0xb5,
914 		0x6d, 0x15, 0x5d, 0x88, 0x32, 0x66, 0x82, 0x56,
915 		0xd6, 0xa9, 0x2b, 0x78, 0xe1, 0x1d, 0x8e, 0x54,
916 		0x49, 0x5d, 0xd1, 0x74, 0x80, 0xaa, 0x56, 0xc9,
917 		0x49, 0x2e, 0x88, 0x2b, 0x97, 0x64, 0x2f, 0x80,
918 		0xd5, 0x0f, 0xe9, 0x7b
919 
920 	};
921 	u8 *enc, *plain;
922 	size_t enc_len, plain_len;
923 	u8 fcs[4];
924 	int err = 0;
925 
926 	wpa_printf(MSG_INFO, "\nIEEE P802.11ac/D7.0, M.6.4 CCMP-256 test vector\n");
927 
928 	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
929 	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
930 	wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
931 	wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);
932 
933 	enc = ccmp_256_encrypt(tk, frame, sizeof(frame), 24, NULL, NULL, NULL,
934 			       NULL, pn, 0, &enc_len);
935 	if (enc == NULL) {
936 		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
937 		return 1;
938 	}
939 
940 	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
941 	if (enc_len != sizeof(encr) || os_memcmp(enc, encr, enc_len) != 0) {
942 		wpa_printf(MSG_ERROR, "CCMP-256 test vector mismatch");
943 		err++;
944 	}
945 	WPA_PUT_LE32(fcs, ieee80211_crc32(enc, enc_len));
946 	wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
947 
948 	wpa_debug_level = MSG_INFO;
949 	plain = ccmp_256_decrypt(tk, (const struct ieee80211_hdr *) enc,
950 				 NULL, NULL, NULL, enc + 24, enc_len - 24,
951 				 &plain_len);
952 	wpa_debug_level = MSG_EXCESSIVE;
953 	os_free(enc);
954 
955 	if (plain == NULL) {
956 		wpa_printf(MSG_ERROR, "Failed to decrypt CCMP-256 frame");
957 		return 1;
958 	}
959 
960 	if (plain_len != sizeof(frame) - 24 ||
961 	    os_memcmp(plain, frame + 24, plain_len) != 0) {
962 		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
963 			    plain, plain_len);
964 		err++;
965 	}
966 
967 	os_free(plain);
968 
969 	return err;
970 }
971 
972 
test_vector_bip_gmac_128(void)973 static int test_vector_bip_gmac_128(void)
974 {
975 	u8 igtk[] = {
976 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
977 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
978 	};
979 	u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
980 	u8 frame[] = {
981 		0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
982 		0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
983 		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
984 		0x02, 0x00
985 	};
986 	u8 res[] = {
987 		0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
988 		0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
989 		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
990 		0x02, 0x00, 0x4c, 0x18, 0x04, 0x00, 0x04, 0x00,
991 		0x00, 0x00, 0x00, 0x00, 0x3e, 0xd8, 0x62, 0xfb,
992 		0x0f, 0x33, 0x38, 0xdd, 0x33, 0x86, 0xc8, 0x97,
993 		0xe2, 0xed, 0x05, 0x3d
994 	};
995 	u8 *prot;
996 	size_t prot_len;
997 	int err = 0;
998 
999 	wpa_printf(MSG_INFO, "\nIEEE P802.11ac/D7.0, M.9.1 BIP-GMAC-128 with broadcast "
1000 		   "Deauthentication frame\n");
1001 
1002 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1003 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1004 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1005 
1006 	prot = bip_gmac_protect(igtk, sizeof(igtk), frame, sizeof(frame),
1007 				ipn, 4, &prot_len);
1008 	if (prot == NULL) {
1009 		wpa_printf(MSG_ERROR, "Failed to protect BIP-GMAC-128 frame");
1010 		return 1;
1011 	}
1012 
1013 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1014 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1015 		wpa_printf(MSG_ERROR, "BIP-GMAC-128 test vector mismatch");
1016 		err++;
1017 	}
1018 	os_free(prot);
1019 
1020 	return err;
1021 }
1022 
1023 
test_vector_bip_gmac_128_s1g_beacon(void)1024 static int test_vector_bip_gmac_128_s1g_beacon(void)
1025 {
1026 	const u8 igtk[] = {
1027 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1028 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
1029 	};
1030 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1031 	const u8 frame[] = {
1032 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1033 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
1034 		0x08, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
1035 		0x78
1036 	};
1037 	const u8 res[] = {
1038 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1039 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5,
1040 		0x08, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
1041 		0x78, 0x4c, 0x18, 0x06, 0x00, 0x04, 0x00, 0x00,
1042 		0x00, 0x00, 0x00, 0xa5, 0xb2, 0x42, 0xc1, 0xc1,
1043 		0x1e, 0xab, 0x10, 0xc5, 0xa4, 0xe8, 0xb9, 0x53,
1044 		0x66, 0x19, 0x38
1045 	};
1046 	u8 *prot;
1047 	size_t prot_len;
1048 	int err = 0;
1049 
1050 	wpa_printf(MSG_INFO,
1051 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-128, no optional header fields, S1G Beacon Compatibility element in body\n");
1052 
1053 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1054 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1055 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1056 
1057 	prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
1058 					   sizeof(frame), ipn, 6, false,
1059 					   &prot_len);
1060 	if (!prot) {
1061 		wpa_printf(MSG_ERROR,
1062 			   "Failed to protect S1G Beacon frame with BIP-GMAC-128");
1063 		return 1;
1064 	}
1065 
1066 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1067 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1068 		wpa_printf(MSG_ERROR,
1069 			   "S1G Beacon frame with BIP-GMAC-128 test vector mismatch");
1070 		err++;
1071 	}
1072 	os_free(prot);
1073 
1074 	return err;
1075 }
1076 
1077 
test_vector_bip_gmac_128_s1g_beacon_ext(void)1078 static int test_vector_bip_gmac_128_s1g_beacon_ext(void)
1079 {
1080 	const u8 igtk[] = {
1081 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1082 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
1083 	};
1084 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1085 	const u8 frame[] = {
1086 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1087 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1088 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1089 	};
1090 	const u8 res[] = {
1091 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1092 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1093 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
1094 		0x18, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
1095 		0x00, 0x39, 0xd0, 0x0c, 0xc2, 0xee, 0xd7, 0x4c,
1096 		0x2a, 0xb7, 0x41, 0xcc, 0xf8, 0x08, 0x9b, 0x5b,
1097 		0x08
1098 	};
1099 	u8 *prot;
1100 	size_t prot_len;
1101 	int err = 0;
1102 
1103 	wpa_printf(MSG_INFO,
1104 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-128, all optional header fields, no body elements\n");
1105 
1106 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1107 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1108 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1109 
1110 	prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
1111 					   sizeof(frame), ipn, 7, false,
1112 					   &prot_len);
1113 	if (!prot) {
1114 		wpa_printf(MSG_ERROR,
1115 			   "Failed to protect S1G Beacon frame with BIP-GMAC-128");
1116 		return 1;
1117 	}
1118 
1119 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1120 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1121 		wpa_printf(MSG_ERROR,
1122 			   "S1G Beacon frame with BIP-GMAC-128 test vector mismatch");
1123 		err++;
1124 	}
1125 	os_free(prot);
1126 
1127 	return err;
1128 }
1129 
1130 
test_vector_bip_gmac_128_s1g_beacon_bce(void)1131 static int test_vector_bip_gmac_128_s1g_beacon_bce(void)
1132 {
1133 	const u8 igtk[] = {
1134 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1135 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
1136 	};
1137 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1138 	const u8 frame[] = {
1139 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1140 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
1141 		0x08, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
1142 		0x78
1143 	};
1144 	const u8 res[] = {
1145 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1146 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5,
1147 		0x08, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
1148 		0x78, 0x8c, 0x10, 0xa2, 0x5b, 0x7e, 0x67, 0x76,
1149 		0xf0, 0x11, 0x57, 0xa4, 0xfb, 0x4a, 0x2d, 0x66,
1150 		0xd0, 0x17, 0x66
1151 	};
1152 	u8 *prot;
1153 	size_t prot_len;
1154 	int err = 0;
1155 
1156 	wpa_printf(MSG_INFO,
1157 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-128 using BCE, no optional header fields, S1G Beacon Compatibility element in body\n");
1158 
1159 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1160 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1161 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1162 
1163 	prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
1164 					   sizeof(frame), ipn, 6, true,
1165 					   &prot_len);
1166 	if (!prot) {
1167 		wpa_printf(MSG_ERROR,
1168 			   "Failed to protect S1G Beacon frame with BIP-GMAC-128 using BCE");
1169 		return 1;
1170 	}
1171 
1172 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1173 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1174 		wpa_printf(MSG_ERROR,
1175 			   "S1G Beacon frame with BIP-GMAC-128 using BCE test vector mismatch");
1176 		err++;
1177 	}
1178 	os_free(prot);
1179 
1180 	return err;
1181 }
1182 
1183 
test_vector_bip_gmac_128_s1g_beacon_bce_ext(void)1184 static int test_vector_bip_gmac_128_s1g_beacon_bce_ext(void)
1185 {
1186 	const u8 igtk[] = {
1187 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1188 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
1189 	};
1190 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1191 	const u8 frame[] = {
1192 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1193 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1194 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1195 	};
1196 	const u8 res[] = {
1197 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1198 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1199 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c,
1200 		0x10, 0x86, 0xdd, 0xb6, 0xc0, 0x56, 0x21, 0x30,
1201 		0x9d, 0x3e, 0xbd, 0x25, 0x96, 0x67, 0x5b, 0xdd,
1202 		0xc3
1203 	};
1204 	u8 *prot;
1205 	size_t prot_len;
1206 	int err = 0;
1207 
1208 	wpa_printf(MSG_INFO,
1209 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-128 using BCE, all optional header fields, no body elements\n");
1210 
1211 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1212 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1213 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1214 
1215 	prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
1216 					   sizeof(frame), ipn, 7, true,
1217 					   &prot_len);
1218 	if (!prot) {
1219 		wpa_printf(MSG_ERROR,
1220 			   "Failed to protect S1G Beacon frame with BIP-GMAC-128 using BCE");
1221 		return 1;
1222 	}
1223 
1224 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1225 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1226 		wpa_printf(MSG_ERROR,
1227 			   "S1G Beacon frame with BIP-GMAC-128 using BCE test vector mismatch");
1228 		err++;
1229 	}
1230 	os_free(prot);
1231 
1232 	return err;
1233 }
1234 
1235 
test_vector_bip_gmac_256(void)1236 static int test_vector_bip_gmac_256(void)
1237 {
1238 	u8 igtk[] = {
1239 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1240 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
1241 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1242 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
1243 	};
1244 	u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1245 	u8 frame[] = {
1246 		0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1247 		0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
1248 		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
1249 		0x02, 0x00
1250 	};
1251 	u8 res[] = {
1252 		0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1253 		0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
1254 		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
1255 		0x02, 0x00, 0x4c, 0x18, 0x04, 0x00, 0x04, 0x00,
1256 		0x00, 0x00, 0x00, 0x00, 0x23, 0xbe, 0x59, 0xdc,
1257 		0xc7, 0x02, 0x2e, 0xe3, 0x83, 0x62, 0x7e, 0xbb,
1258 		0x10, 0x17, 0xdd, 0xfc
1259 	};
1260 	u8 *prot;
1261 	size_t prot_len;
1262 	int err = 0;
1263 
1264 	wpa_printf(MSG_INFO, "\nIEEE P802.11ac/D7.0, M.9.1 BIP-GMAC-256 with broadcast Deauthentication frame\n");
1265 
1266 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1267 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1268 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1269 
1270 	prot = bip_gmac_protect(igtk, sizeof(igtk), frame, sizeof(frame),
1271 				ipn, 4, &prot_len);
1272 	if (prot == NULL) {
1273 		wpa_printf(MSG_ERROR, "Failed to protect BIP-GMAC-256 frame");
1274 		return 1;
1275 	}
1276 
1277 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1278 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1279 		wpa_printf(MSG_ERROR, "BIP-GMAC-256 test vector mismatch");
1280 		err++;
1281 	}
1282 	os_free(prot);
1283 
1284 	return err;
1285 }
1286 
1287 
test_vector_bip_gmac_256_s1g_beacon(void)1288 static int test_vector_bip_gmac_256_s1g_beacon(void)
1289 {
1290 	const u8 igtk[] = {
1291 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1292 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
1293 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1294 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
1295 	};
1296 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1297 	const u8 frame[] = {
1298 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1299 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
1300 		0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
1301 		0x78
1302 	};
1303 	const u8 res[] = {
1304 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1305 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5,
1306 		0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
1307 		0x78, 0x4c, 0x18, 0x07, 0x00, 0x04, 0x00, 0x00,
1308 		0x00, 0x00, 0x00, 0x33, 0xa2, 0x6f, 0xc6, 0x7e,
1309 		0xbf, 0xfd, 0xa0, 0xac, 0x9b, 0x29, 0xaa, 0x70,
1310 		0xda, 0x3f, 0x51
1311 	};
1312 	u8 *prot;
1313 	size_t prot_len;
1314 	int err = 0;
1315 
1316 	wpa_printf(MSG_INFO,
1317 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-256, no optional header fields, S1G Beacon Compatibility element in body\n");
1318 
1319 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1320 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1321 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1322 
1323 	prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
1324 					   sizeof(frame), ipn, 7, false,
1325 					   &prot_len);
1326 	if (!prot) {
1327 		wpa_printf(MSG_ERROR,
1328 			   "Failed to protect S1G Beacon frame with BIP-GMAC-256");
1329 		return 1;
1330 	}
1331 
1332 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1333 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1334 		wpa_printf(MSG_ERROR,
1335 			   "S1G Beacon frame with BIP-GMAC-256 test vector mismatch");
1336 		err++;
1337 	}
1338 	os_free(prot);
1339 
1340 	return err;
1341 }
1342 
1343 
test_vector_bip_gmac_256_s1g_beacon_ext(void)1344 static int test_vector_bip_gmac_256_s1g_beacon_ext(void)
1345 {
1346 	const u8 igtk[] = {
1347 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1348 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
1349 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1350 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
1351 	};
1352 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1353 	const u8 frame[] = {
1354 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1355 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1356 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1357 	};
1358 	const u8 res[] = {
1359 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1360 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1361 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
1362 		0x18, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
1363 		0x00, 0x0a, 0x5f, 0xa0, 0xf4, 0x71, 0xdf, 0x73,
1364 		0x9e, 0x61, 0x4d, 0xcf, 0x5d, 0xbb, 0x36, 0xf9,
1365 		0x65
1366 	};
1367 	u8 *prot;
1368 	size_t prot_len;
1369 	int err = 0;
1370 
1371 	wpa_printf(MSG_INFO,
1372 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-256, all optional header fields, no body elements\n");
1373 
1374 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1375 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1376 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1377 
1378 	prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
1379 					   sizeof(frame), ipn, 6, false,
1380 					   &prot_len);
1381 	if (!prot) {
1382 		wpa_printf(MSG_ERROR,
1383 			   "Failed to protect S1B Beacon frame with BIP-GMAC-256");
1384 		return 1;
1385 	}
1386 
1387 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1388 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1389 		wpa_printf(MSG_ERROR,
1390 			   "S1G Beacon frame with BIP-GMAC-256 test vector mismatch");
1391 		err++;
1392 	}
1393 	os_free(prot);
1394 
1395 	return err;
1396 }
1397 
1398 
test_vector_bip_gmac_256_s1g_beacon_bce(void)1399 static int test_vector_bip_gmac_256_s1g_beacon_bce(void)
1400 {
1401 	const u8 igtk[] = {
1402 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1403 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
1404 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1405 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
1406 	};
1407 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1408 	const u8 frame[] = {
1409 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1410 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
1411 		0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
1412 		0x78
1413 	};
1414 	const u8 res[] = {
1415 		0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1416 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5,
1417 		0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
1418 		0x78, 0x8c, 0x10, 0xf8, 0x76, 0x22, 0x80, 0x3d,
1419 		0x9c, 0x22, 0x8a, 0xcb, 0x3c, 0x55, 0x8a, 0x33,
1420 		0x2e, 0x94, 0x13
1421 	};
1422 	u8 *prot;
1423 	size_t prot_len;
1424 	int err = 0;
1425 
1426 	wpa_printf(MSG_INFO,
1427 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-256 using BCE, no optional header fields, S1G Beacon Compatibility element in body\n");
1428 
1429 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1430 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1431 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1432 
1433 	prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
1434 					   sizeof(frame), ipn, 7, true,
1435 					   &prot_len);
1436 	if (!prot) {
1437 		wpa_printf(MSG_ERROR,
1438 			   "Failed to protect S1G Beacon frame with BIP-GMAC-256 using BCE");
1439 		return 1;
1440 	}
1441 
1442 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1443 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1444 		wpa_printf(MSG_ERROR,
1445 			   "S1G Beacon frame with BIP-GMAC-256 using BCE test vector mismatch");
1446 		err++;
1447 	}
1448 	os_free(prot);
1449 
1450 	return err;
1451 }
1452 
1453 
test_vector_bip_gmac_256_s1g_beacon_bce_ext(void)1454 static int test_vector_bip_gmac_256_s1g_beacon_bce_ext(void)
1455 {
1456 	const u8 igtk[] = {
1457 		0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
1458 		0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
1459 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1460 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
1461 	};
1462 	const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
1463 	const u8 frame[] = {
1464 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1465 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1466 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1467 	};
1468 	const u8 res[] = {
1469 		0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1470 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1471 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c,
1472 		0x10, 0x3c, 0x80, 0x49, 0xbe, 0x8c, 0x23, 0x34,
1473 		0x1f, 0x5c, 0x2f, 0x9c, 0xd6, 0x03, 0xe3, 0x7a,
1474 		0x5b
1475 	};
1476 	u8 *prot;
1477 	size_t prot_len;
1478 	int err = 0;
1479 
1480 	wpa_printf(MSG_INFO,
1481 		   "\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-256 using BCE, all optional header fields, no body elements\n");
1482 
1483 	wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
1484 	wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
1485 	wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
1486 
1487 	prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
1488 					   sizeof(frame), ipn, 6, true,
1489 					   &prot_len);
1490 	if (!prot) {
1491 		wpa_printf(MSG_ERROR,
1492 			   "Failed to protect S1B Beacon frame with BIP-GMAC-256 using BCE");
1493 		return 1;
1494 	}
1495 
1496 	wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
1497 	if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
1498 		wpa_printf(MSG_ERROR,
1499 			   "S1G Beacon frame with BIP-GMAC-256 using BCE test vector mismatch");
1500 		err++;
1501 	}
1502 	os_free(prot);
1503 
1504 	return err;
1505 }
1506 
1507 
main(int argc,char * argv[])1508 int main(int argc, char *argv[])
1509 {
1510 	int errors = 0;
1511 
1512 	wpa_debug_level = MSG_EXCESSIVE;
1513 	wpa_debug_show_keys = 1;
1514 
1515 	if (os_program_init())
1516 		return -1;
1517 
1518 	test_vector_tkip();
1519 	test_vector_ccmp();
1520 	test_vector_ccmp_pv1();
1521 	test_vector_bip();
1522 	test_vector_bip_s1g_beacon();
1523 	test_vector_bip_s1g_beacon_ext();
1524 	test_vector_bip_s1g_beacon_bce();
1525 	test_vector_bip_s1g_beacon_bce_ext();
1526 	test_vector_ccmp_mgmt();
1527 	errors += test_vector_gcmp();
1528 	errors += test_vector_gcmp_256();
1529 	errors += test_vector_ccmp_256();
1530 	errors += test_vector_bip_gmac_128();
1531 	errors += test_vector_bip_gmac_128_s1g_beacon();
1532 	errors += test_vector_bip_gmac_128_s1g_beacon_ext();
1533 	errors += test_vector_bip_gmac_128_s1g_beacon_bce();
1534 	errors += test_vector_bip_gmac_128_s1g_beacon_bce_ext();
1535 	errors += test_vector_bip_gmac_256();
1536 	errors += test_vector_bip_gmac_256_s1g_beacon();
1537 	errors += test_vector_bip_gmac_256_s1g_beacon_ext();
1538 	errors += test_vector_bip_gmac_256_s1g_beacon_bce();
1539 	errors += test_vector_bip_gmac_256_s1g_beacon_bce_ext();
1540 
1541 	if (errors)
1542 		wpa_printf(MSG_INFO, "One or more test vectors failed");
1543 	os_program_deinit();
1544 
1545 	return errors ? -1 : 0;
1546 }
1547