15b9c547cSRui Paulo /*
25b9c547cSRui Paulo * common module tests
34bc52338SCy Schubert * Copyright (c) 2014-2019, Jouni Malinen <j@w1.fi>
45b9c547cSRui Paulo *
55b9c547cSRui Paulo * This software may be distributed under the terms of the BSD license.
65b9c547cSRui Paulo * See README for more details.
75b9c547cSRui Paulo */
85b9c547cSRui Paulo
95b9c547cSRui Paulo #include "utils/includes.h"
105b9c547cSRui Paulo
115b9c547cSRui Paulo #include "utils/common.h"
12780fb4a2SCy Schubert #include "utils/module_tests.h"
134bc52338SCy Schubert #include "crypto/crypto.h"
14c1d255d3SCy Schubert #include "crypto/dh_groups.h"
155b9c547cSRui Paulo #include "ieee802_11_common.h"
16325151a3SRui Paulo #include "ieee802_11_defs.h"
17325151a3SRui Paulo #include "gas.h"
185b9c547cSRui Paulo #include "wpa_common.h"
194bc52338SCy Schubert #include "sae.h"
205b9c547cSRui Paulo
215b9c547cSRui Paulo
225b9c547cSRui Paulo struct ieee802_11_parse_test_data {
235b9c547cSRui Paulo u8 *data;
245b9c547cSRui Paulo size_t len;
255b9c547cSRui Paulo ParseRes result;
265b9c547cSRui Paulo int count;
275b9c547cSRui Paulo };
285b9c547cSRui Paulo
295b9c547cSRui Paulo static const struct ieee802_11_parse_test_data parse_tests[] = {
305b9c547cSRui Paulo { (u8 *) "", 0, ParseOK, 0 },
315b9c547cSRui Paulo { (u8 *) " ", 1, ParseFailed, 0 },
325b9c547cSRui Paulo { (u8 *) "\xff\x00", 2, ParseUnknown, 1 },
335b9c547cSRui Paulo { (u8 *) "\xff\x01", 2, ParseFailed, 0 },
345b9c547cSRui Paulo { (u8 *) "\xdd\x03\x01\x02\x03", 5, ParseUnknown, 1 },
355b9c547cSRui Paulo { (u8 *) "\xdd\x04\x01\x02\x03\x04", 6, ParseUnknown, 1 },
365b9c547cSRui Paulo { (u8 *) "\xdd\x04\x00\x50\xf2\x02", 6, ParseUnknown, 1 },
375b9c547cSRui Paulo { (u8 *) "\xdd\x05\x00\x50\xf2\x02\x02", 7, ParseOK, 1 },
385b9c547cSRui Paulo { (u8 *) "\xdd\x05\x00\x50\xf2\x02\xff", 7, ParseUnknown, 1 },
395b9c547cSRui Paulo { (u8 *) "\xdd\x04\x00\x50\xf2\xff", 6, ParseUnknown, 1 },
405b9c547cSRui Paulo { (u8 *) "\xdd\x04\x50\x6f\x9a\xff", 6, ParseUnknown, 1 },
415b9c547cSRui Paulo { (u8 *) "\xdd\x04\x00\x90\x4c\x33", 6, ParseOK, 1 },
425b9c547cSRui Paulo { (u8 *) "\xdd\x04\x00\x90\x4c\xff\xdd\x04\x00\x90\x4c\x33", 12,
435b9c547cSRui Paulo ParseUnknown, 2 },
445b9c547cSRui Paulo { (u8 *) "\x10\x01\x00\x21\x00", 5, ParseOK, 2 },
455b9c547cSRui Paulo { (u8 *) "\x24\x00", 2, ParseOK, 1 },
465b9c547cSRui Paulo { (u8 *) "\x38\x00", 2, ParseOK, 1 },
475b9c547cSRui Paulo { (u8 *) "\x54\x00", 2, ParseOK, 1 },
485b9c547cSRui Paulo { (u8 *) "\x5a\x00", 2, ParseOK, 1 },
495b9c547cSRui Paulo { (u8 *) "\x65\x00", 2, ParseOK, 1 },
505b9c547cSRui Paulo { (u8 *) "\x65\x12\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11",
515b9c547cSRui Paulo 20, ParseOK, 1 },
525b9c547cSRui Paulo { (u8 *) "\x6e\x00", 2, ParseOK, 1 },
535b9c547cSRui Paulo { (u8 *) "\xc7\x00", 2, ParseOK, 1 },
545b9c547cSRui Paulo { (u8 *) "\xc7\x01\x00", 3, ParseOK, 1 },
55325151a3SRui Paulo { (u8 *) "\x03\x00\x2a\x00\x36\x00\x37\x00\x38\x00\x2d\x00\x3d\x00\xbf\x00\xc0\x00",
56325151a3SRui Paulo 18, ParseOK, 9 },
57325151a3SRui Paulo { (u8 *) "\x8b\x00", 2, ParseOK, 1 },
58325151a3SRui Paulo { (u8 *) "\xdd\x04\x00\x90\x4c\x04", 6, ParseUnknown, 1 },
5985732ac8SCy Schubert { (u8 *) "\xed\x00", 2, ParseOK, 1 },
6085732ac8SCy Schubert { (u8 *) "\xef\x00", 2, ParseOK, 1 },
6185732ac8SCy Schubert { (u8 *) "\xef\x01\x11", 3, ParseOK, 1 },
6285732ac8SCy Schubert { (u8 *) "\xf0\x00", 2, ParseOK, 1 },
6385732ac8SCy Schubert { (u8 *) "\xf1\x00", 2, ParseOK, 1 },
6485732ac8SCy Schubert { (u8 *) "\xf1\x02\x11\x22", 4, ParseOK, 1 },
6585732ac8SCy Schubert { (u8 *) "\xf2\x00", 2, ParseOK, 1 },
6685732ac8SCy Schubert { (u8 *) "\xff\x00", 2, ParseUnknown, 1 },
6785732ac8SCy Schubert { (u8 *) "\xff\x01\x00", 3, ParseUnknown, 1 },
6885732ac8SCy Schubert { (u8 *) "\xff\x01\x01", 3, ParseOK, 1 },
6985732ac8SCy Schubert { (u8 *) "\xff\x02\x01\x00", 4, ParseOK, 1 },
7085732ac8SCy Schubert { (u8 *) "\xff\x01\x02", 3, ParseOK, 1 },
7185732ac8SCy Schubert { (u8 *) "\xff\x04\x02\x11\x22\x33", 6, ParseOK, 1 },
7285732ac8SCy Schubert { (u8 *) "\xff\x01\x04", 3, ParseOK, 1 },
7385732ac8SCy Schubert { (u8 *) "\xff\x01\x05", 3, ParseOK, 1 },
7485732ac8SCy Schubert { (u8 *) "\xff\x0d\x05\x11\x22\x33\x44\x55\x55\x11\x22\x33\x44\x55\x55",
7585732ac8SCy Schubert 15, ParseOK, 1 },
7685732ac8SCy Schubert { (u8 *) "\xff\x01\x06", 3, ParseOK, 1 },
7785732ac8SCy Schubert { (u8 *) "\xff\x02\x06\x00", 4, ParseOK, 1 },
7885732ac8SCy Schubert { (u8 *) "\xff\x01\x07", 3, ParseOK, 1 },
7985732ac8SCy Schubert { (u8 *) "\xff\x09\x07\x11\x22\x33\x44\x55\x66\x77\x88", 11,
8085732ac8SCy Schubert ParseOK, 1 },
8185732ac8SCy Schubert { (u8 *) "\xff\x01\x0c", 3, ParseOK, 1 },
8285732ac8SCy Schubert { (u8 *) "\xff\x02\x0c\x00", 4, ParseOK, 1 },
8385732ac8SCy Schubert { (u8 *) "\xff\x01\x0d", 3, ParseOK, 1 },
845b9c547cSRui Paulo { NULL, 0, ParseOK, 0 }
855b9c547cSRui Paulo };
865b9c547cSRui Paulo
ieee802_11_parse_tests(void)875b9c547cSRui Paulo static int ieee802_11_parse_tests(void)
885b9c547cSRui Paulo {
895b9c547cSRui Paulo int i, ret = 0;
9085732ac8SCy Schubert struct wpabuf *buf;
915b9c547cSRui Paulo
925b9c547cSRui Paulo wpa_printf(MSG_INFO, "ieee802_11_parse tests");
935b9c547cSRui Paulo
945b9c547cSRui Paulo for (i = 0; parse_tests[i].data; i++) {
955b9c547cSRui Paulo const struct ieee802_11_parse_test_data *test;
965b9c547cSRui Paulo struct ieee802_11_elems elems;
975b9c547cSRui Paulo ParseRes res;
985b9c547cSRui Paulo
995b9c547cSRui Paulo test = &parse_tests[i];
1005b9c547cSRui Paulo res = ieee802_11_parse_elems(test->data, test->len, &elems, 1);
1015b9c547cSRui Paulo if (res != test->result ||
1025b9c547cSRui Paulo ieee802_11_ie_count(test->data, test->len) != test->count) {
1035b9c547cSRui Paulo wpa_printf(MSG_ERROR, "ieee802_11_parse test %d failed",
1045b9c547cSRui Paulo i);
1055b9c547cSRui Paulo ret = -1;
1065b9c547cSRui Paulo }
1075b9c547cSRui Paulo }
1085b9c547cSRui Paulo
1095b9c547cSRui Paulo if (ieee802_11_vendor_ie_concat((const u8 *) "\x00\x01", 2, 0) != NULL)
1105b9c547cSRui Paulo {
1115b9c547cSRui Paulo wpa_printf(MSG_ERROR,
1125b9c547cSRui Paulo "ieee802_11_vendor_ie_concat test failed");
1135b9c547cSRui Paulo ret = -1;
1145b9c547cSRui Paulo }
1155b9c547cSRui Paulo
11685732ac8SCy Schubert buf = ieee802_11_vendor_ie_concat((const u8 *) "\xdd\x05\x11\x22\x33\x44\x01\xdd\x05\x11\x22\x33\x44\x02\x00\x01",
11785732ac8SCy Schubert 16, 0x11223344);
11885732ac8SCy Schubert do {
11985732ac8SCy Schubert const u8 *pos;
12085732ac8SCy Schubert
12185732ac8SCy Schubert if (!buf) {
12285732ac8SCy Schubert wpa_printf(MSG_ERROR,
12385732ac8SCy Schubert "ieee802_11_vendor_ie_concat test 2 failed");
12485732ac8SCy Schubert ret = -1;
12585732ac8SCy Schubert break;
12685732ac8SCy Schubert }
12785732ac8SCy Schubert
12885732ac8SCy Schubert if (wpabuf_len(buf) != 2) {
12985732ac8SCy Schubert wpa_printf(MSG_ERROR,
13085732ac8SCy Schubert "ieee802_11_vendor_ie_concat test 3 failed");
13185732ac8SCy Schubert ret = -1;
13285732ac8SCy Schubert break;
13385732ac8SCy Schubert }
13485732ac8SCy Schubert
13585732ac8SCy Schubert pos = wpabuf_head(buf);
13685732ac8SCy Schubert if (pos[0] != 0x01 || pos[1] != 0x02) {
13785732ac8SCy Schubert wpa_printf(MSG_ERROR,
13885732ac8SCy Schubert "ieee802_11_vendor_ie_concat test 3 failed");
13985732ac8SCy Schubert ret = -1;
14085732ac8SCy Schubert break;
14185732ac8SCy Schubert }
14285732ac8SCy Schubert } while (0);
14385732ac8SCy Schubert wpabuf_free(buf);
14485732ac8SCy Schubert
1455b9c547cSRui Paulo return ret;
1465b9c547cSRui Paulo }
1475b9c547cSRui Paulo
1485b9c547cSRui Paulo
1495b9c547cSRui Paulo struct rsn_ie_parse_test_data {
1505b9c547cSRui Paulo u8 *data;
1515b9c547cSRui Paulo size_t len;
1525b9c547cSRui Paulo int result;
1535b9c547cSRui Paulo };
1545b9c547cSRui Paulo
1555b9c547cSRui Paulo static const struct rsn_ie_parse_test_data rsn_parse_tests[] = {
1565b9c547cSRui Paulo { (u8 *) "", 0, -1 },
1575b9c547cSRui Paulo { (u8 *) "\x30\x00", 2, -1 },
1585b9c547cSRui Paulo { (u8 *) "\x30\x02\x01\x00", 4, 0 },
1595b9c547cSRui Paulo { (u8 *) "\x30\x02\x00\x00", 4, -2 },
1605b9c547cSRui Paulo { (u8 *) "\x30\x02\x02\x00", 4, -2 },
1615b9c547cSRui Paulo { (u8 *) "\x30\x02\x00\x01", 4, -2 },
1625b9c547cSRui Paulo { (u8 *) "\x30\x02\x00\x00\x00", 5, -2 },
1635b9c547cSRui Paulo { (u8 *) "\x30\x03\x01\x00\x00", 5, -3 },
1645b9c547cSRui Paulo { (u8 *) "\x30\x06\x01\x00\x00\x00\x00\x00", 8, -1 },
1655b9c547cSRui Paulo { (u8 *) "\x30\x06\x01\x00\x00\x0f\xac\x04", 8, 0 },
1665b9c547cSRui Paulo { (u8 *) "\x30\x07\x01\x00\x00\x0f\xac\x04\x00", 9, -5 },
1675b9c547cSRui Paulo { (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x00", 10, -4 },
1685b9c547cSRui Paulo { (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x01", 10, -4 },
1695b9c547cSRui Paulo { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
1705b9c547cSRui Paulo 14, 0 },
1715b9c547cSRui Paulo { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x00\x01\x00\x0f\xac\x04",
1725b9c547cSRui Paulo 14, -4 },
1735b9c547cSRui Paulo { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x06",
1745b9c547cSRui Paulo 14, -1 },
1755b9c547cSRui Paulo { (u8 *) "\x30\x10\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x08",
1765b9c547cSRui Paulo 18, 0 },
1775b9c547cSRui Paulo { (u8 *) "\x30\x0d\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00",
1785b9c547cSRui Paulo 15, -7 },
1795b9c547cSRui Paulo { (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x00",
1805b9c547cSRui Paulo 16, -6 },
1815b9c547cSRui Paulo { (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x01",
1825b9c547cSRui Paulo 16, -6 },
1835b9c547cSRui Paulo { (u8 *) "\x30\x12\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01",
1845b9c547cSRui Paulo 20, 0 },
1855b9c547cSRui Paulo { (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x01\x00\x0f\xac\x02",
1865b9c547cSRui Paulo 24, 0 },
1875b9c547cSRui Paulo { (u8 *) "\x30\x13\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00",
1885b9c547cSRui Paulo 21, 0 },
1895b9c547cSRui Paulo { (u8 *) "\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00",
1905b9c547cSRui Paulo 22, 0 },
1915b9c547cSRui Paulo { (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00",
1925b9c547cSRui Paulo 24, 0 },
1935b9c547cSRui Paulo { (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x01",
1945b9c547cSRui Paulo 24, -9 },
1955b9c547cSRui Paulo { (u8 *) "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x00\x00\x00",
1965b9c547cSRui Paulo 28, -10 },
1975b9c547cSRui Paulo { (u8 *) "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x0f\xac\x06",
1985b9c547cSRui Paulo 28, 0 },
1995b9c547cSRui Paulo { (u8 *) "\x30\x1c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x0f\xac\x06\x01\x02",
2005b9c547cSRui Paulo 30, 0 },
2015b9c547cSRui Paulo { NULL, 0, 0 }
2025b9c547cSRui Paulo };
2035b9c547cSRui Paulo
rsn_ie_parse_tests(void)2045b9c547cSRui Paulo static int rsn_ie_parse_tests(void)
2055b9c547cSRui Paulo {
2065b9c547cSRui Paulo int i, ret = 0;
2075b9c547cSRui Paulo
2085b9c547cSRui Paulo wpa_printf(MSG_INFO, "rsn_ie_parse tests");
2095b9c547cSRui Paulo
2105b9c547cSRui Paulo for (i = 0; rsn_parse_tests[i].data; i++) {
2115b9c547cSRui Paulo const struct rsn_ie_parse_test_data *test;
2125b9c547cSRui Paulo struct wpa_ie_data data;
2135b9c547cSRui Paulo
2145b9c547cSRui Paulo test = &rsn_parse_tests[i];
2155b9c547cSRui Paulo if (wpa_parse_wpa_ie_rsn(test->data, test->len, &data) !=
2165b9c547cSRui Paulo test->result) {
2175b9c547cSRui Paulo wpa_printf(MSG_ERROR, "rsn_ie_parse test %d failed", i);
2185b9c547cSRui Paulo ret = -1;
2195b9c547cSRui Paulo }
2205b9c547cSRui Paulo }
2215b9c547cSRui Paulo
2225b9c547cSRui Paulo return ret;
2235b9c547cSRui Paulo }
2245b9c547cSRui Paulo
2255b9c547cSRui Paulo
gas_tests(void)226325151a3SRui Paulo static int gas_tests(void)
227325151a3SRui Paulo {
228325151a3SRui Paulo struct wpabuf *buf;
229325151a3SRui Paulo
230325151a3SRui Paulo wpa_printf(MSG_INFO, "gas tests");
231325151a3SRui Paulo gas_anqp_set_len(NULL);
232325151a3SRui Paulo
233325151a3SRui Paulo buf = wpabuf_alloc(1);
234325151a3SRui Paulo if (buf == NULL)
235325151a3SRui Paulo return -1;
236325151a3SRui Paulo gas_anqp_set_len(buf);
237325151a3SRui Paulo wpabuf_free(buf);
238325151a3SRui Paulo
239325151a3SRui Paulo buf = wpabuf_alloc(20);
240325151a3SRui Paulo if (buf == NULL)
241325151a3SRui Paulo return -1;
242325151a3SRui Paulo wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
243325151a3SRui Paulo wpabuf_put_u8(buf, WLAN_PA_GAS_INITIAL_REQ);
244325151a3SRui Paulo wpabuf_put_u8(buf, 0);
245325151a3SRui Paulo wpabuf_put_be32(buf, 0);
246325151a3SRui Paulo wpabuf_put_u8(buf, 0);
247325151a3SRui Paulo gas_anqp_set_len(buf);
248325151a3SRui Paulo wpabuf_free(buf);
249325151a3SRui Paulo
250325151a3SRui Paulo return 0;
251325151a3SRui Paulo }
252325151a3SRui Paulo
253325151a3SRui Paulo
sae_tests(void)2544bc52338SCy Schubert static int sae_tests(void)
2554bc52338SCy Schubert {
2564bc52338SCy Schubert #ifdef CONFIG_SAE
2574bc52338SCy Schubert struct sae_data sae;
2584bc52338SCy Schubert int ret = -1;
259c1d255d3SCy Schubert /* IEEE Std 802.11-2020, Annex J.10 */
260c1d255d3SCy Schubert const u8 addr1[ETH_ALEN] = { 0x4d, 0x3f, 0x2f, 0xff, 0xe3, 0x87 };
261c1d255d3SCy Schubert const u8 addr2[ETH_ALEN] = { 0xa5, 0xd8, 0xaa, 0x95, 0x8e, 0x3c };
262c1d255d3SCy Schubert const char *ssid = "byteme";
2634bc52338SCy Schubert const char *pw = "mekmitasdigoat";
2644bc52338SCy Schubert const char *pwid = "psk4internet";
2654bc52338SCy Schubert const u8 local_rand[] = {
266c1d255d3SCy Schubert 0x99, 0x24, 0x65, 0xfd, 0x3d, 0xaa, 0x3c, 0x60,
267c1d255d3SCy Schubert 0xaa, 0x65, 0x65, 0xb7, 0xf6, 0x2a, 0x2a, 0x7f,
268c1d255d3SCy Schubert 0x2e, 0x12, 0xdd, 0x12, 0xf1, 0x98, 0xfa, 0xf4,
269c1d255d3SCy Schubert 0xfb, 0xed, 0x89, 0xd7, 0xff, 0x1a, 0xce, 0x94
2704bc52338SCy Schubert };
2714bc52338SCy Schubert const u8 local_mask[] = {
272c1d255d3SCy Schubert 0x95, 0x07, 0xa9, 0x0f, 0x77, 0x7a, 0x04, 0x4d,
273c1d255d3SCy Schubert 0x6a, 0x08, 0x30, 0xb9, 0x1e, 0xa3, 0xd5, 0xdd,
274c1d255d3SCy Schubert 0x70, 0xbe, 0xce, 0x44, 0xe1, 0xac, 0xff, 0xb8,
275c1d255d3SCy Schubert 0x69, 0x83, 0xb5, 0xe1, 0xbf, 0x9f, 0xb3, 0x22
2764bc52338SCy Schubert };
2774bc52338SCy Schubert const u8 local_commit[] = {
278c1d255d3SCy Schubert 0x13, 0x00, 0x2e, 0x2c, 0x0f, 0x0d, 0xb5, 0x24,
279c1d255d3SCy Schubert 0x40, 0xad, 0x14, 0x6d, 0x96, 0x71, 0x14, 0xce,
280c1d255d3SCy Schubert 0x00, 0x5c, 0xe1, 0xea, 0xb0, 0xaa, 0x2c, 0x2e,
281c1d255d3SCy Schubert 0x5c, 0x28, 0x71, 0xb7, 0x74, 0xf6, 0xc2, 0x57,
282c1d255d3SCy Schubert 0x5c, 0x65, 0xd5, 0xad, 0x9e, 0x00, 0x82, 0x97,
283c1d255d3SCy Schubert 0x07, 0xaa, 0x36, 0xba, 0x8b, 0x85, 0x97, 0x38,
284c1d255d3SCy Schubert 0xfc, 0x96, 0x1d, 0x08, 0x24, 0x35, 0x05, 0xf4,
285c1d255d3SCy Schubert 0x7c, 0x03, 0x53, 0x76, 0xd7, 0xac, 0x4b, 0xc8,
286c1d255d3SCy Schubert 0xd7, 0xb9, 0x50, 0x83, 0xbf, 0x43, 0x82, 0x7d,
287c1d255d3SCy Schubert 0x0f, 0xc3, 0x1e, 0xd7, 0x78, 0xdd, 0x36, 0x71,
288c1d255d3SCy Schubert 0xfd, 0x21, 0xa4, 0x6d, 0x10, 0x91, 0xd6, 0x4b,
289c1d255d3SCy Schubert 0x6f, 0x9a, 0x1e, 0x12, 0x72, 0x62, 0x13, 0x25,
290c1d255d3SCy Schubert 0xdb, 0xe1
2914bc52338SCy Schubert };
2924bc52338SCy Schubert const u8 peer_commit[] = {
293c1d255d3SCy Schubert 0x13, 0x00, 0x59, 0x1b, 0x96, 0xf3, 0x39, 0x7f,
294c1d255d3SCy Schubert 0xb9, 0x45, 0x10, 0x08, 0x48, 0xe7, 0xb5, 0x50,
295c1d255d3SCy Schubert 0x54, 0x3b, 0x67, 0x20, 0xd8, 0x83, 0x37, 0xee,
296c1d255d3SCy Schubert 0x93, 0xfc, 0x49, 0xfd, 0x6d, 0xf7, 0xe0, 0x8b,
297c1d255d3SCy Schubert 0x52, 0x23, 0xe7, 0x1b, 0x9b, 0xb0, 0x48, 0xd3,
298c1d255d3SCy Schubert 0x87, 0x3f, 0x20, 0x55, 0x69, 0x53, 0xa9, 0x6c,
299c1d255d3SCy Schubert 0x91, 0x53, 0x6f, 0xd8, 0xee, 0x6c, 0xa9, 0xb4,
300c1d255d3SCy Schubert 0xa6, 0x8a, 0x14, 0x8b, 0x05, 0x6a, 0x90, 0x9b,
301c1d255d3SCy Schubert 0xe0, 0x3e, 0x83, 0xae, 0x20, 0x8f, 0x60, 0xf8,
302c1d255d3SCy Schubert 0xef, 0x55, 0x37, 0x85, 0x80, 0x74, 0xdb, 0x06,
303c1d255d3SCy Schubert 0x68, 0x70, 0x32, 0x39, 0x98, 0x62, 0x99, 0x9b,
304c1d255d3SCy Schubert 0x51, 0x1e, 0x0a, 0x15, 0x52, 0xa5, 0xfe, 0xa3,
305c1d255d3SCy Schubert 0x17, 0xc2
3064bc52338SCy Schubert };
3074bc52338SCy Schubert const u8 kck[] = {
308c1d255d3SCy Schubert 0x1e, 0x73, 0x3f, 0x6d, 0x9b, 0xd5, 0x32, 0x56,
309c1d255d3SCy Schubert 0x28, 0x73, 0x04, 0x33, 0x88, 0x31, 0xb0, 0x9a,
310c1d255d3SCy Schubert 0x39, 0x40, 0x6d, 0x12, 0x10, 0x17, 0x07, 0x3a,
311c1d255d3SCy Schubert 0x5c, 0x30, 0xdb, 0x36, 0xf3, 0x6c, 0xb8, 0x1a
3124bc52338SCy Schubert };
3134bc52338SCy Schubert const u8 pmk[] = {
314c1d255d3SCy Schubert 0x4e, 0x4d, 0xfa, 0xb1, 0xa2, 0xdd, 0x8a, 0xc1,
315c1d255d3SCy Schubert 0xa9, 0x17, 0x90, 0xf9, 0x53, 0xfa, 0xaa, 0x45,
316c1d255d3SCy Schubert 0x2a, 0xe5, 0xc6, 0x87, 0x3a, 0xb7, 0x5b, 0x63,
317c1d255d3SCy Schubert 0x60, 0x5b, 0xa6, 0x63, 0xf8, 0xa7, 0xfe, 0x59
3184bc52338SCy Schubert };
3194bc52338SCy Schubert const u8 pmkid[] = {
320c1d255d3SCy Schubert 0x87, 0x47, 0xa6, 0x00, 0xee, 0xa3, 0xf9, 0xf2,
321c1d255d3SCy Schubert 0x24, 0x75, 0xdf, 0x58, 0xca, 0x1e, 0x54, 0x98
3224bc52338SCy Schubert };
3234bc52338SCy Schubert struct wpabuf *buf = NULL;
3244bc52338SCy Schubert struct crypto_bignum *mask = NULL;
325c1d255d3SCy Schubert const u8 pwe_19_x[32] = {
326c1d255d3SCy Schubert 0xc9, 0x30, 0x49, 0xb9, 0xe6, 0x40, 0x00, 0xf8,
327c1d255d3SCy Schubert 0x48, 0x20, 0x16, 0x49, 0xe9, 0x99, 0xf2, 0xb5,
328c1d255d3SCy Schubert 0xc2, 0x2d, 0xea, 0x69, 0xb5, 0x63, 0x2c, 0x9d,
329c1d255d3SCy Schubert 0xf4, 0xd6, 0x33, 0xb8, 0xaa, 0x1f, 0x6c, 0x1e
330c1d255d3SCy Schubert };
331c1d255d3SCy Schubert const u8 pwe_19_y[32] = {
332c1d255d3SCy Schubert 0x73, 0x63, 0x4e, 0x94, 0xb5, 0x3d, 0x82, 0xe7,
333c1d255d3SCy Schubert 0x38, 0x3a, 0x8d, 0x25, 0x81, 0x99, 0xd9, 0xdc,
334c1d255d3SCy Schubert 0x1a, 0x5e, 0xe8, 0x26, 0x9d, 0x06, 0x03, 0x82,
335c1d255d3SCy Schubert 0xcc, 0xbf, 0x33, 0xe6, 0x14, 0xff, 0x59, 0xa0
336c1d255d3SCy Schubert };
337c1d255d3SCy Schubert const u8 pwe_15[384] = {
338c1d255d3SCy Schubert 0x69, 0x68, 0x73, 0x65, 0x8f, 0x65, 0x31, 0x42,
339c1d255d3SCy Schubert 0x9f, 0x97, 0x39, 0x6f, 0xb8, 0x5f, 0x89, 0xe1,
340c1d255d3SCy Schubert 0xfc, 0xd2, 0xf6, 0x92, 0x19, 0xa9, 0x0e, 0x82,
341c1d255d3SCy Schubert 0x2f, 0xf7, 0xf4, 0xbc, 0x0b, 0xd8, 0xa7, 0x9f,
342c1d255d3SCy Schubert 0xf0, 0x80, 0x35, 0x31, 0x6f, 0xca, 0xe1, 0xa5,
343c1d255d3SCy Schubert 0x39, 0x77, 0xdc, 0x11, 0x2b, 0x0b, 0xfe, 0x2e,
344c1d255d3SCy Schubert 0x6f, 0x65, 0x6d, 0xc7, 0xd4, 0xa4, 0x5b, 0x08,
345c1d255d3SCy Schubert 0x1f, 0xd9, 0xbb, 0xe2, 0x22, 0x85, 0x31, 0x81,
346c1d255d3SCy Schubert 0x79, 0x70, 0xbe, 0xa1, 0x66, 0x58, 0x4a, 0x09,
347c1d255d3SCy Schubert 0x3c, 0x57, 0x34, 0x3c, 0x9d, 0x57, 0x8f, 0x42,
348c1d255d3SCy Schubert 0x58, 0xd0, 0x39, 0x81, 0xdb, 0x8f, 0x79, 0xa2,
349c1d255d3SCy Schubert 0x1b, 0x01, 0xcd, 0x27, 0xc9, 0xae, 0xcf, 0xcb,
350c1d255d3SCy Schubert 0x9c, 0xdb, 0x1f, 0x84, 0xb8, 0x88, 0x4e, 0x8f,
351c1d255d3SCy Schubert 0x50, 0x66, 0xb4, 0x29, 0x83, 0x1e, 0xb9, 0x89,
352c1d255d3SCy Schubert 0x0c, 0xa5, 0x47, 0x21, 0xba, 0x10, 0xd5, 0xaa,
353c1d255d3SCy Schubert 0x1a, 0x80, 0xce, 0xf1, 0x4c, 0xad, 0x16, 0xda,
354c1d255d3SCy Schubert 0x57, 0xb2, 0x41, 0x8a, 0xbe, 0x4b, 0x8c, 0xb0,
355c1d255d3SCy Schubert 0xb2, 0xeb, 0xf7, 0xa8, 0x0e, 0x3e, 0xcf, 0x22,
356c1d255d3SCy Schubert 0x8f, 0xd8, 0xb6, 0xdb, 0x79, 0x9c, 0x9b, 0x80,
357c1d255d3SCy Schubert 0xaf, 0xd7, 0x14, 0xad, 0x51, 0x82, 0xf4, 0x64,
358c1d255d3SCy Schubert 0xb6, 0x3f, 0x4c, 0x6c, 0xe5, 0x3f, 0xaa, 0x6f,
359c1d255d3SCy Schubert 0xbf, 0x3d, 0xc2, 0x3f, 0x77, 0xfd, 0xcb, 0xe1,
360c1d255d3SCy Schubert 0x9c, 0xe3, 0x1e, 0x8a, 0x0e, 0x97, 0xe2, 0x2b,
361c1d255d3SCy Schubert 0xe2, 0xdd, 0x37, 0x39, 0x88, 0xc2, 0x8e, 0xbe,
362c1d255d3SCy Schubert 0xfa, 0xac, 0x3d, 0x5b, 0x62, 0x2e, 0x1e, 0x74,
363c1d255d3SCy Schubert 0xa0, 0x9a, 0xf8, 0xed, 0xfa, 0xe1, 0xce, 0x9c,
364c1d255d3SCy Schubert 0xab, 0xbb, 0xdc, 0x36, 0xb1, 0x28, 0x46, 0x3c,
365c1d255d3SCy Schubert 0x7e, 0xa8, 0xbd, 0xb9, 0x36, 0x4c, 0x26, 0x75,
366c1d255d3SCy Schubert 0xe0, 0x17, 0x73, 0x1f, 0xe0, 0xfe, 0xf6, 0x49,
367c1d255d3SCy Schubert 0xfa, 0xa0, 0x45, 0xf4, 0x44, 0x05, 0x20, 0x27,
368c1d255d3SCy Schubert 0x25, 0xc2, 0x99, 0xde, 0x27, 0x8b, 0x70, 0xdc,
369c1d255d3SCy Schubert 0x54, 0x60, 0x90, 0x02, 0x1e, 0x29, 0x97, 0x9a,
370c1d255d3SCy Schubert 0xc4, 0xe7, 0xb6, 0xf5, 0x8b, 0xae, 0x7c, 0x34,
371c1d255d3SCy Schubert 0xaa, 0xef, 0x9b, 0xc6, 0x30, 0xf2, 0x80, 0x8d,
372c1d255d3SCy Schubert 0x80, 0x78, 0xc2, 0x55, 0x63, 0xa0, 0xa1, 0x38,
373c1d255d3SCy Schubert 0x70, 0xfb, 0xf4, 0x74, 0x8d, 0xcd, 0x87, 0x90,
374c1d255d3SCy Schubert 0xb4, 0x54, 0xc3, 0x75, 0xdf, 0x10, 0xc5, 0xb6,
375c1d255d3SCy Schubert 0xb2, 0x08, 0x59, 0x61, 0xe6, 0x68, 0xa5, 0x82,
376c1d255d3SCy Schubert 0xf8, 0x8f, 0x47, 0x30, 0x43, 0xb4, 0xdc, 0x31,
377c1d255d3SCy Schubert 0xfc, 0xbc, 0x69, 0xe7, 0xb4, 0x94, 0xb0, 0x6a,
378c1d255d3SCy Schubert 0x60, 0x59, 0x80, 0x2e, 0xd3, 0xa4, 0xe8, 0x97,
379c1d255d3SCy Schubert 0xa2, 0xa3, 0xc9, 0x08, 0x4b, 0x27, 0x6c, 0xc1,
380c1d255d3SCy Schubert 0x37, 0xe8, 0xfc, 0x5c, 0xe2, 0x54, 0x30, 0x3e,
381c1d255d3SCy Schubert 0xf8, 0xfe, 0xa2, 0xfc, 0xbb, 0xbd, 0x88, 0x6c,
382c1d255d3SCy Schubert 0x92, 0xa3, 0x2a, 0x40, 0x7a, 0x2c, 0x22, 0x38,
383c1d255d3SCy Schubert 0x8c, 0x86, 0x86, 0xfe, 0xb9, 0xd4, 0x6b, 0xd6,
384c1d255d3SCy Schubert 0x47, 0x88, 0xa7, 0xf6, 0x8e, 0x0f, 0x14, 0xad,
385c1d255d3SCy Schubert 0x1e, 0xac, 0xcf, 0x33, 0x01, 0x99, 0xc1, 0x62
386c1d255d3SCy Schubert };
387c1d255d3SCy Schubert int pt_groups[] = { 19, 20, 21, 25, 26, 28, 29, 30, 15, 0 };
388c1d255d3SCy Schubert struct sae_pt *pt_info, *pt;
389c1d255d3SCy Schubert const u8 addr1b[ETH_ALEN] = { 0x00, 0x09, 0x5b, 0x66, 0xec, 0x1e };
390c1d255d3SCy Schubert const u8 addr2b[ETH_ALEN] = { 0x00, 0x0b, 0x6b, 0xd9, 0x02, 0x46 };
3914bc52338SCy Schubert
3924bc52338SCy Schubert os_memset(&sae, 0, sizeof(sae));
3934bc52338SCy Schubert buf = wpabuf_alloc(1000);
3944bc52338SCy Schubert if (!buf ||
3954bc52338SCy Schubert sae_set_group(&sae, 19) < 0 ||
3964bc52338SCy Schubert sae_prepare_commit(addr1, addr2, (const u8 *) pw, os_strlen(pw),
397c1d255d3SCy Schubert &sae) < 0)
3984bc52338SCy Schubert goto fail;
3994bc52338SCy Schubert
4004bc52338SCy Schubert /* Override local values based on SAE test vector */
4014bc52338SCy Schubert crypto_bignum_deinit(sae.tmp->sae_rand, 1);
4024bc52338SCy Schubert sae.tmp->sae_rand = crypto_bignum_init_set(local_rand,
4034bc52338SCy Schubert sizeof(local_rand));
4044bc52338SCy Schubert mask = crypto_bignum_init_set(local_mask, sizeof(local_mask));
4054bc52338SCy Schubert if (!sae.tmp->sae_rand || !mask)
4064bc52338SCy Schubert goto fail;
4074bc52338SCy Schubert
4084bc52338SCy Schubert if (crypto_bignum_add(sae.tmp->sae_rand, mask,
4094bc52338SCy Schubert sae.tmp->own_commit_scalar) < 0 ||
4104bc52338SCy Schubert crypto_bignum_mod(sae.tmp->own_commit_scalar, sae.tmp->order,
4114bc52338SCy Schubert sae.tmp->own_commit_scalar) < 0 ||
4124bc52338SCy Schubert crypto_ec_point_mul(sae.tmp->ec, sae.tmp->pwe_ecc, mask,
4134bc52338SCy Schubert sae.tmp->own_commit_element_ecc) < 0 ||
4144bc52338SCy Schubert crypto_ec_point_invert(sae.tmp->ec,
4154bc52338SCy Schubert sae.tmp->own_commit_element_ecc) < 0)
4164bc52338SCy Schubert goto fail;
4174bc52338SCy Schubert
4184bc52338SCy Schubert /* Check that output matches the test vector */
419c1d255d3SCy Schubert if (sae_write_commit(&sae, buf, NULL, NULL) < 0)
420c1d255d3SCy Schubert goto fail;
4214bc52338SCy Schubert wpa_hexdump_buf(MSG_DEBUG, "SAE: Commit message", buf);
4224bc52338SCy Schubert
4234bc52338SCy Schubert if (wpabuf_len(buf) != sizeof(local_commit) ||
4244bc52338SCy Schubert os_memcmp(wpabuf_head(buf), local_commit,
4254bc52338SCy Schubert sizeof(local_commit)) != 0) {
4264bc52338SCy Schubert wpa_printf(MSG_ERROR, "SAE: Mismatch in local commit");
4274bc52338SCy Schubert goto fail;
4284bc52338SCy Schubert }
4294bc52338SCy Schubert
4304bc52338SCy Schubert if (sae_parse_commit(&sae, peer_commit, sizeof(peer_commit), NULL, NULL,
431*a90b9d01SCy Schubert NULL, 0, NULL) != 0 ||
4324bc52338SCy Schubert sae_process_commit(&sae) < 0)
4334bc52338SCy Schubert goto fail;
4344bc52338SCy Schubert
4354bc52338SCy Schubert if (os_memcmp(kck, sae.tmp->kck, SAE_KCK_LEN) != 0) {
4364bc52338SCy Schubert wpa_printf(MSG_ERROR, "SAE: Mismatch in KCK");
4374bc52338SCy Schubert goto fail;
4384bc52338SCy Schubert }
4394bc52338SCy Schubert
4404bc52338SCy Schubert if (os_memcmp(pmk, sae.pmk, SAE_PMK_LEN) != 0) {
4414bc52338SCy Schubert wpa_printf(MSG_ERROR, "SAE: Mismatch in PMK");
4424bc52338SCy Schubert goto fail;
4434bc52338SCy Schubert }
4444bc52338SCy Schubert
4454bc52338SCy Schubert if (os_memcmp(pmkid, sae.pmkid, SAE_PMKID_LEN) != 0) {
4464bc52338SCy Schubert wpa_printf(MSG_ERROR, "SAE: Mismatch in PMKID");
4474bc52338SCy Schubert goto fail;
4484bc52338SCy Schubert }
4494bc52338SCy Schubert
450c1d255d3SCy Schubert pt_info = sae_derive_pt(pt_groups,
451c1d255d3SCy Schubert (const u8 *) ssid, os_strlen(ssid),
452c1d255d3SCy Schubert (const u8 *) pw, os_strlen(pw), pwid);
453c1d255d3SCy Schubert if (!pt_info)
454c1d255d3SCy Schubert goto fail;
4554bc52338SCy Schubert
456c1d255d3SCy Schubert for (pt = pt_info; pt; pt = pt->next) {
457c1d255d3SCy Schubert if (pt->group == 19) {
458c1d255d3SCy Schubert struct crypto_ec_point *pwe;
459c1d255d3SCy Schubert u8 bin[SAE_MAX_ECC_PRIME_LEN * 2];
460c1d255d3SCy Schubert size_t prime_len = sizeof(pwe_19_x);
461c1d255d3SCy Schubert
462c1d255d3SCy Schubert pwe = sae_derive_pwe_from_pt_ecc(pt, addr1b, addr2b);
463c1d255d3SCy Schubert if (!pwe) {
464c1d255d3SCy Schubert sae_deinit_pt(pt);
4654bc52338SCy Schubert goto fail;
4664bc52338SCy Schubert }
467c1d255d3SCy Schubert if (crypto_ec_point_to_bin(pt->ec, pwe, bin,
468c1d255d3SCy Schubert bin + prime_len) < 0 ||
469c1d255d3SCy Schubert os_memcmp(pwe_19_x, bin, prime_len) != 0 ||
470c1d255d3SCy Schubert os_memcmp(pwe_19_y, bin + prime_len,
471c1d255d3SCy Schubert prime_len) != 0) {
472c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
473c1d255d3SCy Schubert "SAE: PT/PWE test vector mismatch");
474c1d255d3SCy Schubert crypto_ec_point_deinit(pwe, 1);
475c1d255d3SCy Schubert sae_deinit_pt(pt);
4764bc52338SCy Schubert goto fail;
477c1d255d3SCy Schubert }
478c1d255d3SCy Schubert crypto_ec_point_deinit(pwe, 1);
479c1d255d3SCy Schubert }
480c1d255d3SCy Schubert
481c1d255d3SCy Schubert if (pt->group == 15) {
482c1d255d3SCy Schubert struct crypto_bignum *pwe;
483c1d255d3SCy Schubert u8 bin[SAE_MAX_PRIME_LEN];
484c1d255d3SCy Schubert size_t prime_len = sizeof(pwe_15);
485c1d255d3SCy Schubert
486c1d255d3SCy Schubert pwe = sae_derive_pwe_from_pt_ffc(pt, addr1b, addr2b);
487c1d255d3SCy Schubert if (!pwe) {
488c1d255d3SCy Schubert sae_deinit_pt(pt);
489c1d255d3SCy Schubert goto fail;
490c1d255d3SCy Schubert }
491c1d255d3SCy Schubert if (crypto_bignum_to_bin(pwe, bin, sizeof(bin),
492c1d255d3SCy Schubert prime_len) < 0 ||
493c1d255d3SCy Schubert os_memcmp(pwe_15, bin, prime_len) != 0) {
494c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
495c1d255d3SCy Schubert "SAE: PT/PWE test vector mismatch");
496c1d255d3SCy Schubert crypto_bignum_deinit(pwe, 1);
497c1d255d3SCy Schubert sae_deinit_pt(pt);
498c1d255d3SCy Schubert goto fail;
499c1d255d3SCy Schubert }
500c1d255d3SCy Schubert crypto_bignum_deinit(pwe, 1);
501c1d255d3SCy Schubert }
502c1d255d3SCy Schubert }
503c1d255d3SCy Schubert
504c1d255d3SCy Schubert sae_deinit_pt(pt_info);
5054bc52338SCy Schubert
5064bc52338SCy Schubert ret = 0;
5074bc52338SCy Schubert fail:
5084bc52338SCy Schubert sae_clear_data(&sae);
5094bc52338SCy Schubert wpabuf_free(buf);
5104bc52338SCy Schubert crypto_bignum_deinit(mask, 1);
5114bc52338SCy Schubert return ret;
5124bc52338SCy Schubert #else /* CONFIG_SAE */
5134bc52338SCy Schubert return 0;
5144bc52338SCy Schubert #endif /* CONFIG_SAE */
5154bc52338SCy Schubert }
5164bc52338SCy Schubert
5174bc52338SCy Schubert
sae_pk_tests(void)518c1d255d3SCy Schubert static int sae_pk_tests(void)
519c1d255d3SCy Schubert {
520c1d255d3SCy Schubert #ifdef CONFIG_SAE_PK
521c1d255d3SCy Schubert const char *invalid[] = { "a2bc-de3f-ghim-", "a2bcde3fghim", "", NULL };
522c1d255d3SCy Schubert struct {
523c1d255d3SCy Schubert const char *pw;
524c1d255d3SCy Schubert const u8 *val;
525c1d255d3SCy Schubert } valid[] = {
526c1d255d3SCy Schubert { "a2bc-de3f-ghim", (u8 *) "\x06\x82\x21\x93\x65\x31\xd0\xc0" },
527c1d255d3SCy Schubert { "aaaa-aaaa-aaaj", (u8 *) "\x00\x00\x00\x00\x00\x00\x00\x90" },
528c1d255d3SCy Schubert { "7777-7777-777f", (u8 *) "\xff\xff\xff\xff\xff\xff\xfe\x50" },
529c1d255d3SCy Schubert { NULL, NULL }
530c1d255d3SCy Schubert };
531c1d255d3SCy Schubert int i;
532c1d255d3SCy Schubert bool failed;
533c1d255d3SCy Schubert
534c1d255d3SCy Schubert for (i = 0; invalid[i]; i++) {
535c1d255d3SCy Schubert if (sae_pk_valid_password(invalid[i])) {
536c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
537c1d255d3SCy Schubert "SAE-PK: Invalid password '%s' not recognized",
538c1d255d3SCy Schubert invalid[i]);
539c1d255d3SCy Schubert return -1;
540c1d255d3SCy Schubert }
541c1d255d3SCy Schubert }
542c1d255d3SCy Schubert
543c1d255d3SCy Schubert failed = false;
544c1d255d3SCy Schubert for (i = 0; valid[i].pw; i++) {
545c1d255d3SCy Schubert u8 *res;
546c1d255d3SCy Schubert size_t res_len;
547c1d255d3SCy Schubert char *b32;
548c1d255d3SCy Schubert const char *pw = valid[i].pw;
549c1d255d3SCy Schubert const u8 *val = valid[i].val;
550c1d255d3SCy Schubert size_t pw_len = os_strlen(pw);
551c1d255d3SCy Schubert size_t bits = (pw_len - pw_len / 5) * 5;
552c1d255d3SCy Schubert size_t bytes = (bits + 7) / 8;
553c1d255d3SCy Schubert
554c1d255d3SCy Schubert if (!sae_pk_valid_password(pw)) {
555c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
556c1d255d3SCy Schubert "SAE-PK: Valid password '%s' not recognized",
557c1d255d3SCy Schubert pw);
558c1d255d3SCy Schubert failed = true;
559c1d255d3SCy Schubert continue;
560c1d255d3SCy Schubert }
561c1d255d3SCy Schubert
562c1d255d3SCy Schubert res = sae_pk_base32_decode(pw, pw_len, &res_len);
563c1d255d3SCy Schubert if (!res) {
564c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
565c1d255d3SCy Schubert "SAE-PK: Failed to decode password '%s'",
566c1d255d3SCy Schubert valid[i].pw);
567c1d255d3SCy Schubert failed = true;
568c1d255d3SCy Schubert continue;
569c1d255d3SCy Schubert }
570c1d255d3SCy Schubert if (res_len != bytes || os_memcmp(val, res, res_len) != 0) {
571c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
572c1d255d3SCy Schubert "SAE-PK: Mismatch for decoded password '%s'",
573c1d255d3SCy Schubert valid[i].pw);
574c1d255d3SCy Schubert wpa_hexdump(MSG_INFO, "SAE-PK: Decoded value",
575c1d255d3SCy Schubert res, res_len);
576c1d255d3SCy Schubert wpa_hexdump(MSG_INFO, "SAE-PK: Expected value",
577c1d255d3SCy Schubert val, bytes);
578c1d255d3SCy Schubert failed = true;
579c1d255d3SCy Schubert }
580c1d255d3SCy Schubert os_free(res);
581c1d255d3SCy Schubert
582c1d255d3SCy Schubert b32 = sae_pk_base32_encode(val, bits - 5);
583c1d255d3SCy Schubert if (!b32) {
584c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
585c1d255d3SCy Schubert "SAE-PK: Failed to encode password '%s'",
586c1d255d3SCy Schubert pw);
587c1d255d3SCy Schubert failed = true;
588c1d255d3SCy Schubert continue;
589c1d255d3SCy Schubert }
590c1d255d3SCy Schubert if (os_strcmp(b32, pw) != 0) {
591c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
592c1d255d3SCy Schubert "SAE-PK: Mismatch for password '%s'", pw);
593c1d255d3SCy Schubert wpa_printf(MSG_INFO, "SAE-PK: Encoded value: '%s'",
594c1d255d3SCy Schubert b32);
595c1d255d3SCy Schubert failed = true;
596c1d255d3SCy Schubert }
597c1d255d3SCy Schubert os_free(b32);
598c1d255d3SCy Schubert }
599c1d255d3SCy Schubert
600c1d255d3SCy Schubert return failed ? -1 : 0;
601c1d255d3SCy Schubert #else /* CONFIG_SAE_PK */
602c1d255d3SCy Schubert return 0;
603c1d255d3SCy Schubert #endif /* CONFIG_SAE_PK */
604c1d255d3SCy Schubert }
605c1d255d3SCy Schubert
606c1d255d3SCy Schubert
607c1d255d3SCy Schubert #ifdef CONFIG_PASN
608c1d255d3SCy Schubert
pasn_test_pasn_auth(void)609c1d255d3SCy Schubert static int pasn_test_pasn_auth(void)
610c1d255d3SCy Schubert {
611c1d255d3SCy Schubert /* Test vector taken from IEEE P802.11az/D2.6, J.12 */
612c1d255d3SCy Schubert const u8 pmk[] = {
613c1d255d3SCy Schubert 0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
614c1d255d3SCy Schubert 0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
615c1d255d3SCy Schubert 0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
616c1d255d3SCy Schubert 0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
617c1d255d3SCy Schubert };
618c1d255d3SCy Schubert
619c1d255d3SCy Schubert const u8 spa_addr[] = {
620c1d255d3SCy Schubert 0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
621c1d255d3SCy Schubert };
622c1d255d3SCy Schubert const u8 bssid[] = {
623c1d255d3SCy Schubert 0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
624c1d255d3SCy Schubert };
625c1d255d3SCy Schubert const u8 dhss[] = {
626c1d255d3SCy Schubert 0xf8, 0x7b, 0x20, 0x8e, 0x7e, 0xd2, 0xb7, 0x37,
627c1d255d3SCy Schubert 0xaf, 0xdb, 0xc2, 0xe1, 0x3e, 0xae, 0x78, 0xda,
628c1d255d3SCy Schubert 0x30, 0x01, 0x23, 0xd4, 0xd8, 0x4b, 0xa8, 0xb0,
629c1d255d3SCy Schubert 0xea, 0xfe, 0x90, 0xc4, 0x8c, 0xdf, 0x1f, 0x93
630c1d255d3SCy Schubert };
631c1d255d3SCy Schubert const u8 kck[] = {
632c1d255d3SCy Schubert 0x7b, 0xb8, 0x21, 0xac, 0x0a, 0xa5, 0x90, 0x9d,
633c1d255d3SCy Schubert 0xd6, 0x54, 0xa5, 0x60, 0x65, 0xad, 0x7c, 0x77,
634c1d255d3SCy Schubert 0xeb, 0x88, 0x9c, 0xbe, 0x29, 0x05, 0xbb, 0xf0,
635c1d255d3SCy Schubert 0x5a, 0xbb, 0x1e, 0xea, 0xc8, 0x8b, 0xa3, 0x06
636c1d255d3SCy Schubert };
637c1d255d3SCy Schubert const u8 tk[] = {
638c1d255d3SCy Schubert 0x67, 0x3e, 0xab, 0x46, 0xb8, 0x32, 0xd5, 0xa8,
639c1d255d3SCy Schubert 0x0c, 0xbc, 0x02, 0x43, 0x01, 0x6e, 0x20, 0x7e
640c1d255d3SCy Schubert };
641c1d255d3SCy Schubert const u8 kdk[] = {
642c1d255d3SCy Schubert 0x2d, 0x0f, 0x0e, 0x82, 0xc7, 0x0d, 0xd2, 0x6b,
643c1d255d3SCy Schubert 0x79, 0x06, 0x1a, 0x46, 0x81, 0xe8, 0xdb, 0xb2,
644c1d255d3SCy Schubert 0xea, 0x83, 0xbe, 0xa3, 0x99, 0x84, 0x4b, 0xd5,
645c1d255d3SCy Schubert 0x89, 0x4e, 0xb3, 0x20, 0xf6, 0x9d, 0x7d, 0xd6
646c1d255d3SCy Schubert };
647c1d255d3SCy Schubert struct wpa_ptk ptk;
648c1d255d3SCy Schubert int ret;
649c1d255d3SCy Schubert
650c1d255d3SCy Schubert ret = pasn_pmk_to_ptk(pmk, sizeof(pmk),
651c1d255d3SCy Schubert spa_addr, bssid,
652c1d255d3SCy Schubert dhss, sizeof(dhss),
653c1d255d3SCy Schubert &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP,
654c1d255d3SCy Schubert WPA_KDK_MAX_LEN);
655c1d255d3SCy Schubert
656c1d255d3SCy Schubert if (ret)
657c1d255d3SCy Schubert return ret;
658c1d255d3SCy Schubert
659c1d255d3SCy Schubert if (ptk.kck_len != sizeof(kck) ||
660c1d255d3SCy Schubert os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
661c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "PASN: Mismatched KCK");
662c1d255d3SCy Schubert return -1;
663c1d255d3SCy Schubert }
664c1d255d3SCy Schubert
665c1d255d3SCy Schubert if (ptk.tk_len != sizeof(tk) ||
666c1d255d3SCy Schubert os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
667c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "PASN: Mismatched TK");
668c1d255d3SCy Schubert return -1;
669c1d255d3SCy Schubert }
670c1d255d3SCy Schubert
671c1d255d3SCy Schubert if (ptk.kdk_len != sizeof(kdk) ||
672c1d255d3SCy Schubert os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
673c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "PASN: Mismatched KDK");
674c1d255d3SCy Schubert return -1;
675c1d255d3SCy Schubert }
676c1d255d3SCy Schubert
677c1d255d3SCy Schubert return 0;
678c1d255d3SCy Schubert }
679c1d255d3SCy Schubert
680c1d255d3SCy Schubert
pasn_test_no_pasn_auth(void)681c1d255d3SCy Schubert static int pasn_test_no_pasn_auth(void)
682c1d255d3SCy Schubert {
683c1d255d3SCy Schubert /* Test vector taken from IEEE P802.11az/D2.6, J.13 */
684c1d255d3SCy Schubert const u8 pmk[] = {
685c1d255d3SCy Schubert 0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
686c1d255d3SCy Schubert 0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
687c1d255d3SCy Schubert 0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
688c1d255d3SCy Schubert 0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
689c1d255d3SCy Schubert };
690c1d255d3SCy Schubert const u8 aa[] = {
691c1d255d3SCy Schubert 0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
692c1d255d3SCy Schubert };
693c1d255d3SCy Schubert const u8 spa[] = {
694c1d255d3SCy Schubert 0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
695c1d255d3SCy Schubert };
696c1d255d3SCy Schubert const u8 anonce[] = {
697c1d255d3SCy Schubert 0xbe, 0x7a, 0x1c, 0xa2, 0x84, 0x34, 0x7b, 0x5b,
698c1d255d3SCy Schubert 0xd6, 0x7d, 0xbd, 0x2d, 0xfd, 0xb4, 0xd9, 0x9f,
699c1d255d3SCy Schubert 0x1a, 0xfa, 0xe0, 0xb8, 0x8b, 0xa1, 0x8e, 0x00,
700c1d255d3SCy Schubert 0x87, 0x18, 0x41, 0x7e, 0x4b, 0x27, 0xef, 0x5f
701c1d255d3SCy Schubert };
702c1d255d3SCy Schubert const u8 snonce[] = {
703c1d255d3SCy Schubert 0x40, 0x4b, 0x01, 0x2f, 0xfb, 0x43, 0xed, 0x0f,
704c1d255d3SCy Schubert 0xb4, 0x3e, 0xa1, 0xf2, 0x87, 0xc9, 0x1f, 0x25,
705c1d255d3SCy Schubert 0x06, 0xd2, 0x1b, 0x4a, 0x92, 0xd7, 0x4b, 0x5e,
706c1d255d3SCy Schubert 0xa5, 0x0c, 0x94, 0x33, 0x50, 0xce, 0x86, 0x71
707c1d255d3SCy Schubert };
708c1d255d3SCy Schubert const u8 kck[] = {
709c1d255d3SCy Schubert 0xcd, 0x7b, 0x9e, 0x75, 0x55, 0x36, 0x2d, 0xf0,
710c1d255d3SCy Schubert 0xb6, 0x35, 0x68, 0x48, 0x4a, 0x81, 0x12, 0xf5
711c1d255d3SCy Schubert };
712c1d255d3SCy Schubert const u8 kek[] = {
713c1d255d3SCy Schubert 0x99, 0xca, 0xd3, 0x58, 0x8d, 0xa0, 0xf1, 0xe6,
714c1d255d3SCy Schubert 0x3f, 0xd1, 0x90, 0x19, 0x10, 0x39, 0xbb, 0x4b
715c1d255d3SCy Schubert };
716c1d255d3SCy Schubert const u8 tk[] = {
717c1d255d3SCy Schubert 0x9e, 0x2e, 0x93, 0x77, 0xe7, 0x53, 0x2e, 0x73,
718c1d255d3SCy Schubert 0x7a, 0x1b, 0xc2, 0x50, 0xfe, 0x19, 0x4a, 0x03
719c1d255d3SCy Schubert };
720c1d255d3SCy Schubert const u8 kdk[] = {
721c1d255d3SCy Schubert 0x6c, 0x7f, 0xb9, 0x7c, 0xeb, 0x55, 0xb0, 0x1a,
722c1d255d3SCy Schubert 0xcf, 0xf0, 0x0f, 0x07, 0x09, 0x42, 0xbd, 0xf5,
723c1d255d3SCy Schubert 0x29, 0x1f, 0xeb, 0x4b, 0xee, 0x38, 0xe0, 0x36,
724c1d255d3SCy Schubert 0x5b, 0x25, 0xa2, 0x50, 0xbb, 0x2a, 0xc9, 0xff
725c1d255d3SCy Schubert };
726c1d255d3SCy Schubert struct wpa_ptk ptk;
727c1d255d3SCy Schubert int ret;
728c1d255d3SCy Schubert
729c1d255d3SCy Schubert ret = wpa_pmk_to_ptk(pmk, sizeof(pmk),
730c1d255d3SCy Schubert "Pairwise key expansion",
731c1d255d3SCy Schubert spa, aa, snonce, anonce,
732c1d255d3SCy Schubert &ptk, WPA_KEY_MGMT_SAE, WPA_CIPHER_CCMP,
733c1d255d3SCy Schubert NULL, 0, WPA_KDK_MAX_LEN);
734c1d255d3SCy Schubert
735c1d255d3SCy Schubert if (ret)
736c1d255d3SCy Schubert return ret;
737c1d255d3SCy Schubert
738c1d255d3SCy Schubert if (ptk.kck_len != sizeof(kck) ||
739c1d255d3SCy Schubert os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
740c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KCK");
741c1d255d3SCy Schubert return -1;
742c1d255d3SCy Schubert }
743c1d255d3SCy Schubert
744c1d255d3SCy Schubert if (ptk.kek_len != sizeof(kek) ||
745c1d255d3SCy Schubert os_memcmp(kek, ptk.kek, sizeof(kek)) != 0) {
746c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KEK");
747c1d255d3SCy Schubert return -1;
748c1d255d3SCy Schubert }
749c1d255d3SCy Schubert
750c1d255d3SCy Schubert if (ptk.tk_len != sizeof(tk) ||
751c1d255d3SCy Schubert os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
752c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched TK");
753c1d255d3SCy Schubert return -1;
754c1d255d3SCy Schubert }
755c1d255d3SCy Schubert
756c1d255d3SCy Schubert if (ptk.kdk_len != sizeof(kdk) ||
757c1d255d3SCy Schubert os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
758c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KDK");
759c1d255d3SCy Schubert return -1;
760c1d255d3SCy Schubert }
761c1d255d3SCy Schubert
762c1d255d3SCy Schubert return 0;
763c1d255d3SCy Schubert }
764c1d255d3SCy Schubert
765c1d255d3SCy Schubert #endif /* CONFIG_PASN */
766c1d255d3SCy Schubert
767c1d255d3SCy Schubert
pasn_tests(void)768c1d255d3SCy Schubert static int pasn_tests(void)
769c1d255d3SCy Schubert {
770c1d255d3SCy Schubert #ifdef CONFIG_PASN
771c1d255d3SCy Schubert if (pasn_test_pasn_auth() ||
772c1d255d3SCy Schubert pasn_test_no_pasn_auth())
773c1d255d3SCy Schubert return -1;
774c1d255d3SCy Schubert #endif /* CONFIG_PASN */
775c1d255d3SCy Schubert return 0;
776c1d255d3SCy Schubert }
777c1d255d3SCy Schubert
778c1d255d3SCy Schubert
common_module_tests(void)7795b9c547cSRui Paulo int common_module_tests(void)
7805b9c547cSRui Paulo {
7815b9c547cSRui Paulo int ret = 0;
7825b9c547cSRui Paulo
7835b9c547cSRui Paulo wpa_printf(MSG_INFO, "common module tests");
7845b9c547cSRui Paulo
7855b9c547cSRui Paulo if (ieee802_11_parse_tests() < 0 ||
786325151a3SRui Paulo gas_tests() < 0 ||
7874bc52338SCy Schubert sae_tests() < 0 ||
788c1d255d3SCy Schubert sae_pk_tests() < 0 ||
789c1d255d3SCy Schubert pasn_tests() < 0 ||
7905b9c547cSRui Paulo rsn_ie_parse_tests() < 0)
7915b9c547cSRui Paulo ret = -1;
7925b9c547cSRui Paulo
7935b9c547cSRui Paulo return ret;
7945b9c547cSRui Paulo }
795