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" 14*c1d255d3SCy 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 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 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 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 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; 259*c1d255d3SCy Schubert /* IEEE Std 802.11-2020, Annex J.10 */ 260*c1d255d3SCy Schubert const u8 addr1[ETH_ALEN] = { 0x4d, 0x3f, 0x2f, 0xff, 0xe3, 0x87 }; 261*c1d255d3SCy Schubert const u8 addr2[ETH_ALEN] = { 0xa5, 0xd8, 0xaa, 0x95, 0x8e, 0x3c }; 262*c1d255d3SCy Schubert const char *ssid = "byteme"; 2634bc52338SCy Schubert const char *pw = "mekmitasdigoat"; 2644bc52338SCy Schubert const char *pwid = "psk4internet"; 2654bc52338SCy Schubert const u8 local_rand[] = { 266*c1d255d3SCy Schubert 0x99, 0x24, 0x65, 0xfd, 0x3d, 0xaa, 0x3c, 0x60, 267*c1d255d3SCy Schubert 0xaa, 0x65, 0x65, 0xb7, 0xf6, 0x2a, 0x2a, 0x7f, 268*c1d255d3SCy Schubert 0x2e, 0x12, 0xdd, 0x12, 0xf1, 0x98, 0xfa, 0xf4, 269*c1d255d3SCy Schubert 0xfb, 0xed, 0x89, 0xd7, 0xff, 0x1a, 0xce, 0x94 2704bc52338SCy Schubert }; 2714bc52338SCy Schubert const u8 local_mask[] = { 272*c1d255d3SCy Schubert 0x95, 0x07, 0xa9, 0x0f, 0x77, 0x7a, 0x04, 0x4d, 273*c1d255d3SCy Schubert 0x6a, 0x08, 0x30, 0xb9, 0x1e, 0xa3, 0xd5, 0xdd, 274*c1d255d3SCy Schubert 0x70, 0xbe, 0xce, 0x44, 0xe1, 0xac, 0xff, 0xb8, 275*c1d255d3SCy Schubert 0x69, 0x83, 0xb5, 0xe1, 0xbf, 0x9f, 0xb3, 0x22 2764bc52338SCy Schubert }; 2774bc52338SCy Schubert const u8 local_commit[] = { 278*c1d255d3SCy Schubert 0x13, 0x00, 0x2e, 0x2c, 0x0f, 0x0d, 0xb5, 0x24, 279*c1d255d3SCy Schubert 0x40, 0xad, 0x14, 0x6d, 0x96, 0x71, 0x14, 0xce, 280*c1d255d3SCy Schubert 0x00, 0x5c, 0xe1, 0xea, 0xb0, 0xaa, 0x2c, 0x2e, 281*c1d255d3SCy Schubert 0x5c, 0x28, 0x71, 0xb7, 0x74, 0xf6, 0xc2, 0x57, 282*c1d255d3SCy Schubert 0x5c, 0x65, 0xd5, 0xad, 0x9e, 0x00, 0x82, 0x97, 283*c1d255d3SCy Schubert 0x07, 0xaa, 0x36, 0xba, 0x8b, 0x85, 0x97, 0x38, 284*c1d255d3SCy Schubert 0xfc, 0x96, 0x1d, 0x08, 0x24, 0x35, 0x05, 0xf4, 285*c1d255d3SCy Schubert 0x7c, 0x03, 0x53, 0x76, 0xd7, 0xac, 0x4b, 0xc8, 286*c1d255d3SCy Schubert 0xd7, 0xb9, 0x50, 0x83, 0xbf, 0x43, 0x82, 0x7d, 287*c1d255d3SCy Schubert 0x0f, 0xc3, 0x1e, 0xd7, 0x78, 0xdd, 0x36, 0x71, 288*c1d255d3SCy Schubert 0xfd, 0x21, 0xa4, 0x6d, 0x10, 0x91, 0xd6, 0x4b, 289*c1d255d3SCy Schubert 0x6f, 0x9a, 0x1e, 0x12, 0x72, 0x62, 0x13, 0x25, 290*c1d255d3SCy Schubert 0xdb, 0xe1 2914bc52338SCy Schubert }; 2924bc52338SCy Schubert const u8 peer_commit[] = { 293*c1d255d3SCy Schubert 0x13, 0x00, 0x59, 0x1b, 0x96, 0xf3, 0x39, 0x7f, 294*c1d255d3SCy Schubert 0xb9, 0x45, 0x10, 0x08, 0x48, 0xe7, 0xb5, 0x50, 295*c1d255d3SCy Schubert 0x54, 0x3b, 0x67, 0x20, 0xd8, 0x83, 0x37, 0xee, 296*c1d255d3SCy Schubert 0x93, 0xfc, 0x49, 0xfd, 0x6d, 0xf7, 0xe0, 0x8b, 297*c1d255d3SCy Schubert 0x52, 0x23, 0xe7, 0x1b, 0x9b, 0xb0, 0x48, 0xd3, 298*c1d255d3SCy Schubert 0x87, 0x3f, 0x20, 0x55, 0x69, 0x53, 0xa9, 0x6c, 299*c1d255d3SCy Schubert 0x91, 0x53, 0x6f, 0xd8, 0xee, 0x6c, 0xa9, 0xb4, 300*c1d255d3SCy Schubert 0xa6, 0x8a, 0x14, 0x8b, 0x05, 0x6a, 0x90, 0x9b, 301*c1d255d3SCy Schubert 0xe0, 0x3e, 0x83, 0xae, 0x20, 0x8f, 0x60, 0xf8, 302*c1d255d3SCy Schubert 0xef, 0x55, 0x37, 0x85, 0x80, 0x74, 0xdb, 0x06, 303*c1d255d3SCy Schubert 0x68, 0x70, 0x32, 0x39, 0x98, 0x62, 0x99, 0x9b, 304*c1d255d3SCy Schubert 0x51, 0x1e, 0x0a, 0x15, 0x52, 0xa5, 0xfe, 0xa3, 305*c1d255d3SCy Schubert 0x17, 0xc2 3064bc52338SCy Schubert }; 3074bc52338SCy Schubert const u8 kck[] = { 308*c1d255d3SCy Schubert 0x1e, 0x73, 0x3f, 0x6d, 0x9b, 0xd5, 0x32, 0x56, 309*c1d255d3SCy Schubert 0x28, 0x73, 0x04, 0x33, 0x88, 0x31, 0xb0, 0x9a, 310*c1d255d3SCy Schubert 0x39, 0x40, 0x6d, 0x12, 0x10, 0x17, 0x07, 0x3a, 311*c1d255d3SCy Schubert 0x5c, 0x30, 0xdb, 0x36, 0xf3, 0x6c, 0xb8, 0x1a 3124bc52338SCy Schubert }; 3134bc52338SCy Schubert const u8 pmk[] = { 314*c1d255d3SCy Schubert 0x4e, 0x4d, 0xfa, 0xb1, 0xa2, 0xdd, 0x8a, 0xc1, 315*c1d255d3SCy Schubert 0xa9, 0x17, 0x90, 0xf9, 0x53, 0xfa, 0xaa, 0x45, 316*c1d255d3SCy Schubert 0x2a, 0xe5, 0xc6, 0x87, 0x3a, 0xb7, 0x5b, 0x63, 317*c1d255d3SCy Schubert 0x60, 0x5b, 0xa6, 0x63, 0xf8, 0xa7, 0xfe, 0x59 3184bc52338SCy Schubert }; 3194bc52338SCy Schubert const u8 pmkid[] = { 320*c1d255d3SCy Schubert 0x87, 0x47, 0xa6, 0x00, 0xee, 0xa3, 0xf9, 0xf2, 321*c1d255d3SCy Schubert 0x24, 0x75, 0xdf, 0x58, 0xca, 0x1e, 0x54, 0x98 3224bc52338SCy Schubert }; 3234bc52338SCy Schubert struct wpabuf *buf = NULL; 3244bc52338SCy Schubert struct crypto_bignum *mask = NULL; 325*c1d255d3SCy Schubert const u8 pwe_19_x[32] = { 326*c1d255d3SCy Schubert 0xc9, 0x30, 0x49, 0xb9, 0xe6, 0x40, 0x00, 0xf8, 327*c1d255d3SCy Schubert 0x48, 0x20, 0x16, 0x49, 0xe9, 0x99, 0xf2, 0xb5, 328*c1d255d3SCy Schubert 0xc2, 0x2d, 0xea, 0x69, 0xb5, 0x63, 0x2c, 0x9d, 329*c1d255d3SCy Schubert 0xf4, 0xd6, 0x33, 0xb8, 0xaa, 0x1f, 0x6c, 0x1e 330*c1d255d3SCy Schubert }; 331*c1d255d3SCy Schubert const u8 pwe_19_y[32] = { 332*c1d255d3SCy Schubert 0x73, 0x63, 0x4e, 0x94, 0xb5, 0x3d, 0x82, 0xe7, 333*c1d255d3SCy Schubert 0x38, 0x3a, 0x8d, 0x25, 0x81, 0x99, 0xd9, 0xdc, 334*c1d255d3SCy Schubert 0x1a, 0x5e, 0xe8, 0x26, 0x9d, 0x06, 0x03, 0x82, 335*c1d255d3SCy Schubert 0xcc, 0xbf, 0x33, 0xe6, 0x14, 0xff, 0x59, 0xa0 336*c1d255d3SCy Schubert }; 337*c1d255d3SCy Schubert const u8 pwe_15[384] = { 338*c1d255d3SCy Schubert 0x69, 0x68, 0x73, 0x65, 0x8f, 0x65, 0x31, 0x42, 339*c1d255d3SCy Schubert 0x9f, 0x97, 0x39, 0x6f, 0xb8, 0x5f, 0x89, 0xe1, 340*c1d255d3SCy Schubert 0xfc, 0xd2, 0xf6, 0x92, 0x19, 0xa9, 0x0e, 0x82, 341*c1d255d3SCy Schubert 0x2f, 0xf7, 0xf4, 0xbc, 0x0b, 0xd8, 0xa7, 0x9f, 342*c1d255d3SCy Schubert 0xf0, 0x80, 0x35, 0x31, 0x6f, 0xca, 0xe1, 0xa5, 343*c1d255d3SCy Schubert 0x39, 0x77, 0xdc, 0x11, 0x2b, 0x0b, 0xfe, 0x2e, 344*c1d255d3SCy Schubert 0x6f, 0x65, 0x6d, 0xc7, 0xd4, 0xa4, 0x5b, 0x08, 345*c1d255d3SCy Schubert 0x1f, 0xd9, 0xbb, 0xe2, 0x22, 0x85, 0x31, 0x81, 346*c1d255d3SCy Schubert 0x79, 0x70, 0xbe, 0xa1, 0x66, 0x58, 0x4a, 0x09, 347*c1d255d3SCy Schubert 0x3c, 0x57, 0x34, 0x3c, 0x9d, 0x57, 0x8f, 0x42, 348*c1d255d3SCy Schubert 0x58, 0xd0, 0x39, 0x81, 0xdb, 0x8f, 0x79, 0xa2, 349*c1d255d3SCy Schubert 0x1b, 0x01, 0xcd, 0x27, 0xc9, 0xae, 0xcf, 0xcb, 350*c1d255d3SCy Schubert 0x9c, 0xdb, 0x1f, 0x84, 0xb8, 0x88, 0x4e, 0x8f, 351*c1d255d3SCy Schubert 0x50, 0x66, 0xb4, 0x29, 0x83, 0x1e, 0xb9, 0x89, 352*c1d255d3SCy Schubert 0x0c, 0xa5, 0x47, 0x21, 0xba, 0x10, 0xd5, 0xaa, 353*c1d255d3SCy Schubert 0x1a, 0x80, 0xce, 0xf1, 0x4c, 0xad, 0x16, 0xda, 354*c1d255d3SCy Schubert 0x57, 0xb2, 0x41, 0x8a, 0xbe, 0x4b, 0x8c, 0xb0, 355*c1d255d3SCy Schubert 0xb2, 0xeb, 0xf7, 0xa8, 0x0e, 0x3e, 0xcf, 0x22, 356*c1d255d3SCy Schubert 0x8f, 0xd8, 0xb6, 0xdb, 0x79, 0x9c, 0x9b, 0x80, 357*c1d255d3SCy Schubert 0xaf, 0xd7, 0x14, 0xad, 0x51, 0x82, 0xf4, 0x64, 358*c1d255d3SCy Schubert 0xb6, 0x3f, 0x4c, 0x6c, 0xe5, 0x3f, 0xaa, 0x6f, 359*c1d255d3SCy Schubert 0xbf, 0x3d, 0xc2, 0x3f, 0x77, 0xfd, 0xcb, 0xe1, 360*c1d255d3SCy Schubert 0x9c, 0xe3, 0x1e, 0x8a, 0x0e, 0x97, 0xe2, 0x2b, 361*c1d255d3SCy Schubert 0xe2, 0xdd, 0x37, 0x39, 0x88, 0xc2, 0x8e, 0xbe, 362*c1d255d3SCy Schubert 0xfa, 0xac, 0x3d, 0x5b, 0x62, 0x2e, 0x1e, 0x74, 363*c1d255d3SCy Schubert 0xa0, 0x9a, 0xf8, 0xed, 0xfa, 0xe1, 0xce, 0x9c, 364*c1d255d3SCy Schubert 0xab, 0xbb, 0xdc, 0x36, 0xb1, 0x28, 0x46, 0x3c, 365*c1d255d3SCy Schubert 0x7e, 0xa8, 0xbd, 0xb9, 0x36, 0x4c, 0x26, 0x75, 366*c1d255d3SCy Schubert 0xe0, 0x17, 0x73, 0x1f, 0xe0, 0xfe, 0xf6, 0x49, 367*c1d255d3SCy Schubert 0xfa, 0xa0, 0x45, 0xf4, 0x44, 0x05, 0x20, 0x27, 368*c1d255d3SCy Schubert 0x25, 0xc2, 0x99, 0xde, 0x27, 0x8b, 0x70, 0xdc, 369*c1d255d3SCy Schubert 0x54, 0x60, 0x90, 0x02, 0x1e, 0x29, 0x97, 0x9a, 370*c1d255d3SCy Schubert 0xc4, 0xe7, 0xb6, 0xf5, 0x8b, 0xae, 0x7c, 0x34, 371*c1d255d3SCy Schubert 0xaa, 0xef, 0x9b, 0xc6, 0x30, 0xf2, 0x80, 0x8d, 372*c1d255d3SCy Schubert 0x80, 0x78, 0xc2, 0x55, 0x63, 0xa0, 0xa1, 0x38, 373*c1d255d3SCy Schubert 0x70, 0xfb, 0xf4, 0x74, 0x8d, 0xcd, 0x87, 0x90, 374*c1d255d3SCy Schubert 0xb4, 0x54, 0xc3, 0x75, 0xdf, 0x10, 0xc5, 0xb6, 375*c1d255d3SCy Schubert 0xb2, 0x08, 0x59, 0x61, 0xe6, 0x68, 0xa5, 0x82, 376*c1d255d3SCy Schubert 0xf8, 0x8f, 0x47, 0x30, 0x43, 0xb4, 0xdc, 0x31, 377*c1d255d3SCy Schubert 0xfc, 0xbc, 0x69, 0xe7, 0xb4, 0x94, 0xb0, 0x6a, 378*c1d255d3SCy Schubert 0x60, 0x59, 0x80, 0x2e, 0xd3, 0xa4, 0xe8, 0x97, 379*c1d255d3SCy Schubert 0xa2, 0xa3, 0xc9, 0x08, 0x4b, 0x27, 0x6c, 0xc1, 380*c1d255d3SCy Schubert 0x37, 0xe8, 0xfc, 0x5c, 0xe2, 0x54, 0x30, 0x3e, 381*c1d255d3SCy Schubert 0xf8, 0xfe, 0xa2, 0xfc, 0xbb, 0xbd, 0x88, 0x6c, 382*c1d255d3SCy Schubert 0x92, 0xa3, 0x2a, 0x40, 0x7a, 0x2c, 0x22, 0x38, 383*c1d255d3SCy Schubert 0x8c, 0x86, 0x86, 0xfe, 0xb9, 0xd4, 0x6b, 0xd6, 384*c1d255d3SCy Schubert 0x47, 0x88, 0xa7, 0xf6, 0x8e, 0x0f, 0x14, 0xad, 385*c1d255d3SCy Schubert 0x1e, 0xac, 0xcf, 0x33, 0x01, 0x99, 0xc1, 0x62 386*c1d255d3SCy Schubert }; 387*c1d255d3SCy Schubert int pt_groups[] = { 19, 20, 21, 25, 26, 28, 29, 30, 15, 0 }; 388*c1d255d3SCy Schubert struct sae_pt *pt_info, *pt; 389*c1d255d3SCy Schubert const u8 addr1b[ETH_ALEN] = { 0x00, 0x09, 0x5b, 0x66, 0xec, 0x1e }; 390*c1d255d3SCy 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), 397*c1d255d3SCy 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 */ 419*c1d255d3SCy Schubert if (sae_write_commit(&sae, buf, NULL, NULL) < 0) 420*c1d255d3SCy 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*c1d255d3SCy Schubert NULL, 0) != 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 450*c1d255d3SCy Schubert pt_info = sae_derive_pt(pt_groups, 451*c1d255d3SCy Schubert (const u8 *) ssid, os_strlen(ssid), 452*c1d255d3SCy Schubert (const u8 *) pw, os_strlen(pw), pwid); 453*c1d255d3SCy Schubert if (!pt_info) 454*c1d255d3SCy Schubert goto fail; 4554bc52338SCy Schubert 456*c1d255d3SCy Schubert for (pt = pt_info; pt; pt = pt->next) { 457*c1d255d3SCy Schubert if (pt->group == 19) { 458*c1d255d3SCy Schubert struct crypto_ec_point *pwe; 459*c1d255d3SCy Schubert u8 bin[SAE_MAX_ECC_PRIME_LEN * 2]; 460*c1d255d3SCy Schubert size_t prime_len = sizeof(pwe_19_x); 461*c1d255d3SCy Schubert 462*c1d255d3SCy Schubert pwe = sae_derive_pwe_from_pt_ecc(pt, addr1b, addr2b); 463*c1d255d3SCy Schubert if (!pwe) { 464*c1d255d3SCy Schubert sae_deinit_pt(pt); 4654bc52338SCy Schubert goto fail; 4664bc52338SCy Schubert } 467*c1d255d3SCy Schubert if (crypto_ec_point_to_bin(pt->ec, pwe, bin, 468*c1d255d3SCy Schubert bin + prime_len) < 0 || 469*c1d255d3SCy Schubert os_memcmp(pwe_19_x, bin, prime_len) != 0 || 470*c1d255d3SCy Schubert os_memcmp(pwe_19_y, bin + prime_len, 471*c1d255d3SCy Schubert prime_len) != 0) { 472*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, 473*c1d255d3SCy Schubert "SAE: PT/PWE test vector mismatch"); 474*c1d255d3SCy Schubert crypto_ec_point_deinit(pwe, 1); 475*c1d255d3SCy Schubert sae_deinit_pt(pt); 4764bc52338SCy Schubert goto fail; 477*c1d255d3SCy Schubert } 478*c1d255d3SCy Schubert crypto_ec_point_deinit(pwe, 1); 479*c1d255d3SCy Schubert } 480*c1d255d3SCy Schubert 481*c1d255d3SCy Schubert if (pt->group == 15) { 482*c1d255d3SCy Schubert struct crypto_bignum *pwe; 483*c1d255d3SCy Schubert u8 bin[SAE_MAX_PRIME_LEN]; 484*c1d255d3SCy Schubert size_t prime_len = sizeof(pwe_15); 485*c1d255d3SCy Schubert 486*c1d255d3SCy Schubert pwe = sae_derive_pwe_from_pt_ffc(pt, addr1b, addr2b); 487*c1d255d3SCy Schubert if (!pwe) { 488*c1d255d3SCy Schubert sae_deinit_pt(pt); 489*c1d255d3SCy Schubert goto fail; 490*c1d255d3SCy Schubert } 491*c1d255d3SCy Schubert if (crypto_bignum_to_bin(pwe, bin, sizeof(bin), 492*c1d255d3SCy Schubert prime_len) < 0 || 493*c1d255d3SCy Schubert os_memcmp(pwe_15, bin, prime_len) != 0) { 494*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, 495*c1d255d3SCy Schubert "SAE: PT/PWE test vector mismatch"); 496*c1d255d3SCy Schubert crypto_bignum_deinit(pwe, 1); 497*c1d255d3SCy Schubert sae_deinit_pt(pt); 498*c1d255d3SCy Schubert goto fail; 499*c1d255d3SCy Schubert } 500*c1d255d3SCy Schubert crypto_bignum_deinit(pwe, 1); 501*c1d255d3SCy Schubert } 502*c1d255d3SCy Schubert } 503*c1d255d3SCy Schubert 504*c1d255d3SCy 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 518*c1d255d3SCy Schubert static int sae_pk_tests(void) 519*c1d255d3SCy Schubert { 520*c1d255d3SCy Schubert #ifdef CONFIG_SAE_PK 521*c1d255d3SCy Schubert const char *invalid[] = { "a2bc-de3f-ghim-", "a2bcde3fghim", "", NULL }; 522*c1d255d3SCy Schubert struct { 523*c1d255d3SCy Schubert const char *pw; 524*c1d255d3SCy Schubert const u8 *val; 525*c1d255d3SCy Schubert } valid[] = { 526*c1d255d3SCy Schubert { "a2bc-de3f-ghim", (u8 *) "\x06\x82\x21\x93\x65\x31\xd0\xc0" }, 527*c1d255d3SCy Schubert { "aaaa-aaaa-aaaj", (u8 *) "\x00\x00\x00\x00\x00\x00\x00\x90" }, 528*c1d255d3SCy Schubert { "7777-7777-777f", (u8 *) "\xff\xff\xff\xff\xff\xff\xfe\x50" }, 529*c1d255d3SCy Schubert { NULL, NULL } 530*c1d255d3SCy Schubert }; 531*c1d255d3SCy Schubert int i; 532*c1d255d3SCy Schubert bool failed; 533*c1d255d3SCy Schubert 534*c1d255d3SCy Schubert for (i = 0; invalid[i]; i++) { 535*c1d255d3SCy Schubert if (sae_pk_valid_password(invalid[i])) { 536*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, 537*c1d255d3SCy Schubert "SAE-PK: Invalid password '%s' not recognized", 538*c1d255d3SCy Schubert invalid[i]); 539*c1d255d3SCy Schubert return -1; 540*c1d255d3SCy Schubert } 541*c1d255d3SCy Schubert } 542*c1d255d3SCy Schubert 543*c1d255d3SCy Schubert failed = false; 544*c1d255d3SCy Schubert for (i = 0; valid[i].pw; i++) { 545*c1d255d3SCy Schubert u8 *res; 546*c1d255d3SCy Schubert size_t res_len; 547*c1d255d3SCy Schubert char *b32; 548*c1d255d3SCy Schubert const char *pw = valid[i].pw; 549*c1d255d3SCy Schubert const u8 *val = valid[i].val; 550*c1d255d3SCy Schubert size_t pw_len = os_strlen(pw); 551*c1d255d3SCy Schubert size_t bits = (pw_len - pw_len / 5) * 5; 552*c1d255d3SCy Schubert size_t bytes = (bits + 7) / 8; 553*c1d255d3SCy Schubert 554*c1d255d3SCy Schubert if (!sae_pk_valid_password(pw)) { 555*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, 556*c1d255d3SCy Schubert "SAE-PK: Valid password '%s' not recognized", 557*c1d255d3SCy Schubert pw); 558*c1d255d3SCy Schubert failed = true; 559*c1d255d3SCy Schubert continue; 560*c1d255d3SCy Schubert } 561*c1d255d3SCy Schubert 562*c1d255d3SCy Schubert res = sae_pk_base32_decode(pw, pw_len, &res_len); 563*c1d255d3SCy Schubert if (!res) { 564*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, 565*c1d255d3SCy Schubert "SAE-PK: Failed to decode password '%s'", 566*c1d255d3SCy Schubert valid[i].pw); 567*c1d255d3SCy Schubert failed = true; 568*c1d255d3SCy Schubert continue; 569*c1d255d3SCy Schubert } 570*c1d255d3SCy Schubert if (res_len != bytes || os_memcmp(val, res, res_len) != 0) { 571*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, 572*c1d255d3SCy Schubert "SAE-PK: Mismatch for decoded password '%s'", 573*c1d255d3SCy Schubert valid[i].pw); 574*c1d255d3SCy Schubert wpa_hexdump(MSG_INFO, "SAE-PK: Decoded value", 575*c1d255d3SCy Schubert res, res_len); 576*c1d255d3SCy Schubert wpa_hexdump(MSG_INFO, "SAE-PK: Expected value", 577*c1d255d3SCy Schubert val, bytes); 578*c1d255d3SCy Schubert failed = true; 579*c1d255d3SCy Schubert } 580*c1d255d3SCy Schubert os_free(res); 581*c1d255d3SCy Schubert 582*c1d255d3SCy Schubert b32 = sae_pk_base32_encode(val, bits - 5); 583*c1d255d3SCy Schubert if (!b32) { 584*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, 585*c1d255d3SCy Schubert "SAE-PK: Failed to encode password '%s'", 586*c1d255d3SCy Schubert pw); 587*c1d255d3SCy Schubert failed = true; 588*c1d255d3SCy Schubert continue; 589*c1d255d3SCy Schubert } 590*c1d255d3SCy Schubert if (os_strcmp(b32, pw) != 0) { 591*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, 592*c1d255d3SCy Schubert "SAE-PK: Mismatch for password '%s'", pw); 593*c1d255d3SCy Schubert wpa_printf(MSG_INFO, "SAE-PK: Encoded value: '%s'", 594*c1d255d3SCy Schubert b32); 595*c1d255d3SCy Schubert failed = true; 596*c1d255d3SCy Schubert } 597*c1d255d3SCy Schubert os_free(b32); 598*c1d255d3SCy Schubert } 599*c1d255d3SCy Schubert 600*c1d255d3SCy Schubert return failed ? -1 : 0; 601*c1d255d3SCy Schubert #else /* CONFIG_SAE_PK */ 602*c1d255d3SCy Schubert return 0; 603*c1d255d3SCy Schubert #endif /* CONFIG_SAE_PK */ 604*c1d255d3SCy Schubert } 605*c1d255d3SCy Schubert 606*c1d255d3SCy Schubert 607*c1d255d3SCy Schubert #ifdef CONFIG_PASN 608*c1d255d3SCy Schubert 609*c1d255d3SCy Schubert static int pasn_test_pasn_auth(void) 610*c1d255d3SCy Schubert { 611*c1d255d3SCy Schubert /* Test vector taken from IEEE P802.11az/D2.6, J.12 */ 612*c1d255d3SCy Schubert const u8 pmk[] = { 613*c1d255d3SCy Schubert 0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6, 614*c1d255d3SCy Schubert 0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef, 615*c1d255d3SCy Schubert 0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9, 616*c1d255d3SCy Schubert 0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad 617*c1d255d3SCy Schubert }; 618*c1d255d3SCy Schubert 619*c1d255d3SCy Schubert const u8 spa_addr[] = { 620*c1d255d3SCy Schubert 0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07 621*c1d255d3SCy Schubert }; 622*c1d255d3SCy Schubert const u8 bssid[] = { 623*c1d255d3SCy Schubert 0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1 624*c1d255d3SCy Schubert }; 625*c1d255d3SCy Schubert const u8 dhss[] = { 626*c1d255d3SCy Schubert 0xf8, 0x7b, 0x20, 0x8e, 0x7e, 0xd2, 0xb7, 0x37, 627*c1d255d3SCy Schubert 0xaf, 0xdb, 0xc2, 0xe1, 0x3e, 0xae, 0x78, 0xda, 628*c1d255d3SCy Schubert 0x30, 0x01, 0x23, 0xd4, 0xd8, 0x4b, 0xa8, 0xb0, 629*c1d255d3SCy Schubert 0xea, 0xfe, 0x90, 0xc4, 0x8c, 0xdf, 0x1f, 0x93 630*c1d255d3SCy Schubert }; 631*c1d255d3SCy Schubert const u8 kck[] = { 632*c1d255d3SCy Schubert 0x7b, 0xb8, 0x21, 0xac, 0x0a, 0xa5, 0x90, 0x9d, 633*c1d255d3SCy Schubert 0xd6, 0x54, 0xa5, 0x60, 0x65, 0xad, 0x7c, 0x77, 634*c1d255d3SCy Schubert 0xeb, 0x88, 0x9c, 0xbe, 0x29, 0x05, 0xbb, 0xf0, 635*c1d255d3SCy Schubert 0x5a, 0xbb, 0x1e, 0xea, 0xc8, 0x8b, 0xa3, 0x06 636*c1d255d3SCy Schubert }; 637*c1d255d3SCy Schubert const u8 tk[] = { 638*c1d255d3SCy Schubert 0x67, 0x3e, 0xab, 0x46, 0xb8, 0x32, 0xd5, 0xa8, 639*c1d255d3SCy Schubert 0x0c, 0xbc, 0x02, 0x43, 0x01, 0x6e, 0x20, 0x7e 640*c1d255d3SCy Schubert }; 641*c1d255d3SCy Schubert const u8 kdk[] = { 642*c1d255d3SCy Schubert 0x2d, 0x0f, 0x0e, 0x82, 0xc7, 0x0d, 0xd2, 0x6b, 643*c1d255d3SCy Schubert 0x79, 0x06, 0x1a, 0x46, 0x81, 0xe8, 0xdb, 0xb2, 644*c1d255d3SCy Schubert 0xea, 0x83, 0xbe, 0xa3, 0x99, 0x84, 0x4b, 0xd5, 645*c1d255d3SCy Schubert 0x89, 0x4e, 0xb3, 0x20, 0xf6, 0x9d, 0x7d, 0xd6 646*c1d255d3SCy Schubert }; 647*c1d255d3SCy Schubert struct wpa_ptk ptk; 648*c1d255d3SCy Schubert int ret; 649*c1d255d3SCy Schubert 650*c1d255d3SCy Schubert ret = pasn_pmk_to_ptk(pmk, sizeof(pmk), 651*c1d255d3SCy Schubert spa_addr, bssid, 652*c1d255d3SCy Schubert dhss, sizeof(dhss), 653*c1d255d3SCy Schubert &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP, 654*c1d255d3SCy Schubert WPA_KDK_MAX_LEN); 655*c1d255d3SCy Schubert 656*c1d255d3SCy Schubert if (ret) 657*c1d255d3SCy Schubert return ret; 658*c1d255d3SCy Schubert 659*c1d255d3SCy Schubert if (ptk.kck_len != sizeof(kck) || 660*c1d255d3SCy Schubert os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) { 661*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "PASN: Mismatched KCK"); 662*c1d255d3SCy Schubert return -1; 663*c1d255d3SCy Schubert } 664*c1d255d3SCy Schubert 665*c1d255d3SCy Schubert if (ptk.tk_len != sizeof(tk) || 666*c1d255d3SCy Schubert os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) { 667*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "PASN: Mismatched TK"); 668*c1d255d3SCy Schubert return -1; 669*c1d255d3SCy Schubert } 670*c1d255d3SCy Schubert 671*c1d255d3SCy Schubert if (ptk.kdk_len != sizeof(kdk) || 672*c1d255d3SCy Schubert os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) { 673*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "PASN: Mismatched KDK"); 674*c1d255d3SCy Schubert return -1; 675*c1d255d3SCy Schubert } 676*c1d255d3SCy Schubert 677*c1d255d3SCy Schubert return 0; 678*c1d255d3SCy Schubert } 679*c1d255d3SCy Schubert 680*c1d255d3SCy Schubert 681*c1d255d3SCy Schubert static int pasn_test_no_pasn_auth(void) 682*c1d255d3SCy Schubert { 683*c1d255d3SCy Schubert /* Test vector taken from IEEE P802.11az/D2.6, J.13 */ 684*c1d255d3SCy Schubert const u8 pmk[] = { 685*c1d255d3SCy Schubert 0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6, 686*c1d255d3SCy Schubert 0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef, 687*c1d255d3SCy Schubert 0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9, 688*c1d255d3SCy Schubert 0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad 689*c1d255d3SCy Schubert }; 690*c1d255d3SCy Schubert const u8 aa[] = { 691*c1d255d3SCy Schubert 0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1 692*c1d255d3SCy Schubert }; 693*c1d255d3SCy Schubert const u8 spa[] = { 694*c1d255d3SCy Schubert 0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07 695*c1d255d3SCy Schubert }; 696*c1d255d3SCy Schubert const u8 anonce[] = { 697*c1d255d3SCy Schubert 0xbe, 0x7a, 0x1c, 0xa2, 0x84, 0x34, 0x7b, 0x5b, 698*c1d255d3SCy Schubert 0xd6, 0x7d, 0xbd, 0x2d, 0xfd, 0xb4, 0xd9, 0x9f, 699*c1d255d3SCy Schubert 0x1a, 0xfa, 0xe0, 0xb8, 0x8b, 0xa1, 0x8e, 0x00, 700*c1d255d3SCy Schubert 0x87, 0x18, 0x41, 0x7e, 0x4b, 0x27, 0xef, 0x5f 701*c1d255d3SCy Schubert }; 702*c1d255d3SCy Schubert const u8 snonce[] = { 703*c1d255d3SCy Schubert 0x40, 0x4b, 0x01, 0x2f, 0xfb, 0x43, 0xed, 0x0f, 704*c1d255d3SCy Schubert 0xb4, 0x3e, 0xa1, 0xf2, 0x87, 0xc9, 0x1f, 0x25, 705*c1d255d3SCy Schubert 0x06, 0xd2, 0x1b, 0x4a, 0x92, 0xd7, 0x4b, 0x5e, 706*c1d255d3SCy Schubert 0xa5, 0x0c, 0x94, 0x33, 0x50, 0xce, 0x86, 0x71 707*c1d255d3SCy Schubert }; 708*c1d255d3SCy Schubert const u8 kck[] = { 709*c1d255d3SCy Schubert 0xcd, 0x7b, 0x9e, 0x75, 0x55, 0x36, 0x2d, 0xf0, 710*c1d255d3SCy Schubert 0xb6, 0x35, 0x68, 0x48, 0x4a, 0x81, 0x12, 0xf5 711*c1d255d3SCy Schubert }; 712*c1d255d3SCy Schubert const u8 kek[] = { 713*c1d255d3SCy Schubert 0x99, 0xca, 0xd3, 0x58, 0x8d, 0xa0, 0xf1, 0xe6, 714*c1d255d3SCy Schubert 0x3f, 0xd1, 0x90, 0x19, 0x10, 0x39, 0xbb, 0x4b 715*c1d255d3SCy Schubert }; 716*c1d255d3SCy Schubert const u8 tk[] = { 717*c1d255d3SCy Schubert 0x9e, 0x2e, 0x93, 0x77, 0xe7, 0x53, 0x2e, 0x73, 718*c1d255d3SCy Schubert 0x7a, 0x1b, 0xc2, 0x50, 0xfe, 0x19, 0x4a, 0x03 719*c1d255d3SCy Schubert }; 720*c1d255d3SCy Schubert const u8 kdk[] = { 721*c1d255d3SCy Schubert 0x6c, 0x7f, 0xb9, 0x7c, 0xeb, 0x55, 0xb0, 0x1a, 722*c1d255d3SCy Schubert 0xcf, 0xf0, 0x0f, 0x07, 0x09, 0x42, 0xbd, 0xf5, 723*c1d255d3SCy Schubert 0x29, 0x1f, 0xeb, 0x4b, 0xee, 0x38, 0xe0, 0x36, 724*c1d255d3SCy Schubert 0x5b, 0x25, 0xa2, 0x50, 0xbb, 0x2a, 0xc9, 0xff 725*c1d255d3SCy Schubert }; 726*c1d255d3SCy Schubert struct wpa_ptk ptk; 727*c1d255d3SCy Schubert int ret; 728*c1d255d3SCy Schubert 729*c1d255d3SCy Schubert ret = wpa_pmk_to_ptk(pmk, sizeof(pmk), 730*c1d255d3SCy Schubert "Pairwise key expansion", 731*c1d255d3SCy Schubert spa, aa, snonce, anonce, 732*c1d255d3SCy Schubert &ptk, WPA_KEY_MGMT_SAE, WPA_CIPHER_CCMP, 733*c1d255d3SCy Schubert NULL, 0, WPA_KDK_MAX_LEN); 734*c1d255d3SCy Schubert 735*c1d255d3SCy Schubert if (ret) 736*c1d255d3SCy Schubert return ret; 737*c1d255d3SCy Schubert 738*c1d255d3SCy Schubert if (ptk.kck_len != sizeof(kck) || 739*c1d255d3SCy Schubert os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) { 740*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KCK"); 741*c1d255d3SCy Schubert return -1; 742*c1d255d3SCy Schubert } 743*c1d255d3SCy Schubert 744*c1d255d3SCy Schubert if (ptk.kek_len != sizeof(kek) || 745*c1d255d3SCy Schubert os_memcmp(kek, ptk.kek, sizeof(kek)) != 0) { 746*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KEK"); 747*c1d255d3SCy Schubert return -1; 748*c1d255d3SCy Schubert } 749*c1d255d3SCy Schubert 750*c1d255d3SCy Schubert if (ptk.tk_len != sizeof(tk) || 751*c1d255d3SCy Schubert os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) { 752*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched TK"); 753*c1d255d3SCy Schubert return -1; 754*c1d255d3SCy Schubert } 755*c1d255d3SCy Schubert 756*c1d255d3SCy Schubert if (ptk.kdk_len != sizeof(kdk) || 757*c1d255d3SCy Schubert os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) { 758*c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KDK"); 759*c1d255d3SCy Schubert return -1; 760*c1d255d3SCy Schubert } 761*c1d255d3SCy Schubert 762*c1d255d3SCy Schubert return 0; 763*c1d255d3SCy Schubert } 764*c1d255d3SCy Schubert 765*c1d255d3SCy Schubert #endif /* CONFIG_PASN */ 766*c1d255d3SCy Schubert 767*c1d255d3SCy Schubert 768*c1d255d3SCy Schubert static int pasn_tests(void) 769*c1d255d3SCy Schubert { 770*c1d255d3SCy Schubert #ifdef CONFIG_PASN 771*c1d255d3SCy Schubert if (pasn_test_pasn_auth() || 772*c1d255d3SCy Schubert pasn_test_no_pasn_auth()) 773*c1d255d3SCy Schubert return -1; 774*c1d255d3SCy Schubert #endif /* CONFIG_PASN */ 775*c1d255d3SCy Schubert return 0; 776*c1d255d3SCy Schubert } 777*c1d255d3SCy Schubert 778*c1d255d3SCy Schubert 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 || 788*c1d255d3SCy Schubert sae_pk_tests() < 0 || 789*c1d255d3SCy Schubert pasn_tests() < 0 || 7905b9c547cSRui Paulo rsn_ie_parse_tests() < 0) 7915b9c547cSRui Paulo ret = -1; 7925b9c547cSRui Paulo 7935b9c547cSRui Paulo return ret; 7945b9c547cSRui Paulo } 795