1 /* 2 * common module tests 3 * Copyright (c) 2014-2019, 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/module_tests.h" 13 #include "crypto/crypto.h" 14 #include "crypto/dh_groups.h" 15 #include "ieee802_11_common.h" 16 #include "ieee802_11_defs.h" 17 #include "gas.h" 18 #include "wpa_common.h" 19 #include "sae.h" 20 21 22 struct ieee802_11_parse_test_data { 23 u8 *data; 24 size_t len; 25 ParseRes result; 26 int count; 27 }; 28 29 static const struct ieee802_11_parse_test_data parse_tests[] = { 30 { (u8 *) "", 0, ParseOK, 0 }, 31 { (u8 *) " ", 1, ParseFailed, 0 }, 32 { (u8 *) "\xff\x00", 2, ParseUnknown, 1 }, 33 { (u8 *) "\xff\x01", 2, ParseFailed, 0 }, 34 { (u8 *) "\xdd\x03\x01\x02\x03", 5, ParseUnknown, 1 }, 35 { (u8 *) "\xdd\x04\x01\x02\x03\x04", 6, ParseUnknown, 1 }, 36 { (u8 *) "\xdd\x04\x00\x50\xf2\x02", 6, ParseUnknown, 1 }, 37 { (u8 *) "\xdd\x05\x00\x50\xf2\x02\x02", 7, ParseOK, 1 }, 38 { (u8 *) "\xdd\x05\x00\x50\xf2\x02\xff", 7, ParseUnknown, 1 }, 39 { (u8 *) "\xdd\x04\x00\x50\xf2\xff", 6, ParseUnknown, 1 }, 40 { (u8 *) "\xdd\x04\x50\x6f\x9a\xff", 6, ParseUnknown, 1 }, 41 { (u8 *) "\xdd\x04\x00\x90\x4c\x33", 6, ParseOK, 1 }, 42 { (u8 *) "\xdd\x04\x00\x90\x4c\xff\xdd\x04\x00\x90\x4c\x33", 12, 43 ParseUnknown, 2 }, 44 { (u8 *) "\x10\x01\x00\x21\x00", 5, ParseOK, 2 }, 45 { (u8 *) "\x24\x00", 2, ParseOK, 1 }, 46 { (u8 *) "\x38\x00", 2, ParseOK, 1 }, 47 { (u8 *) "\x54\x00", 2, ParseOK, 1 }, 48 { (u8 *) "\x5a\x00", 2, ParseOK, 1 }, 49 { (u8 *) "\x65\x00", 2, ParseOK, 1 }, 50 { (u8 *) "\x65\x12\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11", 51 20, ParseOK, 1 }, 52 { (u8 *) "\x6e\x00", 2, ParseOK, 1 }, 53 { (u8 *) "\xc7\x00", 2, ParseOK, 1 }, 54 { (u8 *) "\xc7\x01\x00", 3, ParseOK, 1 }, 55 { (u8 *) "\x03\x00\x2a\x00\x36\x00\x37\x00\x38\x00\x2d\x00\x3d\x00\xbf\x00\xc0\x00", 56 18, ParseOK, 9 }, 57 { (u8 *) "\x8b\x00", 2, ParseOK, 1 }, 58 { (u8 *) "\xdd\x04\x00\x90\x4c\x04", 6, ParseUnknown, 1 }, 59 { (u8 *) "\xed\x00", 2, ParseOK, 1 }, 60 { (u8 *) "\xef\x00", 2, ParseOK, 1 }, 61 { (u8 *) "\xef\x01\x11", 3, ParseOK, 1 }, 62 { (u8 *) "\xf0\x00", 2, ParseOK, 1 }, 63 { (u8 *) "\xf1\x00", 2, ParseOK, 1 }, 64 { (u8 *) "\xf1\x02\x11\x22", 4, ParseOK, 1 }, 65 { (u8 *) "\xf2\x00", 2, ParseOK, 1 }, 66 { (u8 *) "\xff\x00", 2, ParseUnknown, 1 }, 67 { (u8 *) "\xff\x01\x00", 3, ParseUnknown, 1 }, 68 { (u8 *) "\xff\x01\x01", 3, ParseOK, 1 }, 69 { (u8 *) "\xff\x02\x01\x00", 4, ParseOK, 1 }, 70 { (u8 *) "\xff\x01\x02", 3, ParseOK, 1 }, 71 { (u8 *) "\xff\x04\x02\x11\x22\x33", 6, ParseOK, 1 }, 72 { (u8 *) "\xff\x01\x04", 3, ParseOK, 1 }, 73 { (u8 *) "\xff\x01\x05", 3, ParseOK, 1 }, 74 { (u8 *) "\xff\x0d\x05\x11\x22\x33\x44\x55\x55\x11\x22\x33\x44\x55\x55", 75 15, ParseOK, 1 }, 76 { (u8 *) "\xff\x01\x06", 3, ParseOK, 1 }, 77 { (u8 *) "\xff\x02\x06\x00", 4, ParseOK, 1 }, 78 { (u8 *) "\xff\x01\x07", 3, ParseOK, 1 }, 79 { (u8 *) "\xff\x09\x07\x11\x22\x33\x44\x55\x66\x77\x88", 11, 80 ParseOK, 1 }, 81 { (u8 *) "\xff\x01\x0c", 3, ParseOK, 1 }, 82 { (u8 *) "\xff\x02\x0c\x00", 4, ParseOK, 1 }, 83 { (u8 *) "\xff\x01\x0d", 3, ParseOK, 1 }, 84 { NULL, 0, ParseOK, 0 } 85 }; 86 87 static int ieee802_11_parse_tests(void) 88 { 89 int i, ret = 0; 90 struct wpabuf *buf; 91 92 wpa_printf(MSG_INFO, "ieee802_11_parse tests"); 93 94 for (i = 0; parse_tests[i].data; i++) { 95 const struct ieee802_11_parse_test_data *test; 96 struct ieee802_11_elems elems; 97 ParseRes res; 98 99 test = &parse_tests[i]; 100 res = ieee802_11_parse_elems(test->data, test->len, &elems, 1); 101 if (res != test->result || 102 ieee802_11_ie_count(test->data, test->len) != test->count) { 103 wpa_printf(MSG_ERROR, "ieee802_11_parse test %d failed", 104 i); 105 ret = -1; 106 } 107 } 108 109 if (ieee802_11_vendor_ie_concat((const u8 *) "\x00\x01", 2, 0) != NULL) 110 { 111 wpa_printf(MSG_ERROR, 112 "ieee802_11_vendor_ie_concat test failed"); 113 ret = -1; 114 } 115 116 buf = ieee802_11_vendor_ie_concat((const u8 *) "\xdd\x05\x11\x22\x33\x44\x01\xdd\x05\x11\x22\x33\x44\x02\x00\x01", 117 16, 0x11223344); 118 do { 119 const u8 *pos; 120 121 if (!buf) { 122 wpa_printf(MSG_ERROR, 123 "ieee802_11_vendor_ie_concat test 2 failed"); 124 ret = -1; 125 break; 126 } 127 128 if (wpabuf_len(buf) != 2) { 129 wpa_printf(MSG_ERROR, 130 "ieee802_11_vendor_ie_concat test 3 failed"); 131 ret = -1; 132 break; 133 } 134 135 pos = wpabuf_head(buf); 136 if (pos[0] != 0x01 || pos[1] != 0x02) { 137 wpa_printf(MSG_ERROR, 138 "ieee802_11_vendor_ie_concat test 3 failed"); 139 ret = -1; 140 break; 141 } 142 } while (0); 143 wpabuf_free(buf); 144 145 return ret; 146 } 147 148 149 struct rsn_ie_parse_test_data { 150 u8 *data; 151 size_t len; 152 int result; 153 }; 154 155 static const struct rsn_ie_parse_test_data rsn_parse_tests[] = { 156 { (u8 *) "", 0, -1 }, 157 { (u8 *) "\x30\x00", 2, -1 }, 158 { (u8 *) "\x30\x02\x01\x00", 4, 0 }, 159 { (u8 *) "\x30\x02\x00\x00", 4, -2 }, 160 { (u8 *) "\x30\x02\x02\x00", 4, -2 }, 161 { (u8 *) "\x30\x02\x00\x01", 4, -2 }, 162 { (u8 *) "\x30\x02\x00\x00\x00", 5, -2 }, 163 { (u8 *) "\x30\x03\x01\x00\x00", 5, -3 }, 164 { (u8 *) "\x30\x06\x01\x00\x00\x00\x00\x00", 8, -1 }, 165 { (u8 *) "\x30\x06\x01\x00\x00\x0f\xac\x04", 8, 0 }, 166 { (u8 *) "\x30\x07\x01\x00\x00\x0f\xac\x04\x00", 9, -5 }, 167 { (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x00", 10, -4 }, 168 { (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x01", 10, -4 }, 169 { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04", 170 14, 0 }, 171 { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x00\x01\x00\x0f\xac\x04", 172 14, -4 }, 173 { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x06", 174 14, -1 }, 175 { (u8 *) "\x30\x10\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x08", 176 18, 0 }, 177 { (u8 *) "\x30\x0d\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00", 178 15, -7 }, 179 { (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x00", 180 16, -6 }, 181 { (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x01", 182 16, -6 }, 183 { (u8 *) "\x30\x12\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01", 184 20, 0 }, 185 { (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", 186 24, 0 }, 187 { (u8 *) "\x30\x13\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00", 188 21, 0 }, 189 { (u8 *) "\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00", 190 22, 0 }, 191 { (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", 192 24, 0 }, 193 { (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", 194 24, -9 }, 195 { (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", 196 28, -10 }, 197 { (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", 198 28, 0 }, 199 { (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", 200 30, 0 }, 201 { NULL, 0, 0 } 202 }; 203 204 static int rsn_ie_parse_tests(void) 205 { 206 int i, ret = 0; 207 208 wpa_printf(MSG_INFO, "rsn_ie_parse tests"); 209 210 for (i = 0; rsn_parse_tests[i].data; i++) { 211 const struct rsn_ie_parse_test_data *test; 212 struct wpa_ie_data data; 213 214 test = &rsn_parse_tests[i]; 215 if (wpa_parse_wpa_ie_rsn(test->data, test->len, &data) != 216 test->result) { 217 wpa_printf(MSG_ERROR, "rsn_ie_parse test %d failed", i); 218 ret = -1; 219 } 220 } 221 222 return ret; 223 } 224 225 226 static int gas_tests(void) 227 { 228 struct wpabuf *buf; 229 230 wpa_printf(MSG_INFO, "gas tests"); 231 gas_anqp_set_len(NULL); 232 233 buf = wpabuf_alloc(1); 234 if (buf == NULL) 235 return -1; 236 gas_anqp_set_len(buf); 237 wpabuf_free(buf); 238 239 buf = wpabuf_alloc(20); 240 if (buf == NULL) 241 return -1; 242 wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); 243 wpabuf_put_u8(buf, WLAN_PA_GAS_INITIAL_REQ); 244 wpabuf_put_u8(buf, 0); 245 wpabuf_put_be32(buf, 0); 246 wpabuf_put_u8(buf, 0); 247 gas_anqp_set_len(buf); 248 wpabuf_free(buf); 249 250 return 0; 251 } 252 253 254 static int sae_tests(void) 255 { 256 #ifdef CONFIG_SAE 257 struct sae_data sae; 258 int ret = -1; 259 /* IEEE Std 802.11-2020, Annex J.10 */ 260 const u8 addr1[ETH_ALEN] = { 0x4d, 0x3f, 0x2f, 0xff, 0xe3, 0x87 }; 261 const u8 addr2[ETH_ALEN] = { 0xa5, 0xd8, 0xaa, 0x95, 0x8e, 0x3c }; 262 const char *ssid = "byteme"; 263 const char *pw = "mekmitasdigoat"; 264 const char *pwid = "psk4internet"; 265 const u8 local_rand[] = { 266 0x99, 0x24, 0x65, 0xfd, 0x3d, 0xaa, 0x3c, 0x60, 267 0xaa, 0x65, 0x65, 0xb7, 0xf6, 0x2a, 0x2a, 0x7f, 268 0x2e, 0x12, 0xdd, 0x12, 0xf1, 0x98, 0xfa, 0xf4, 269 0xfb, 0xed, 0x89, 0xd7, 0xff, 0x1a, 0xce, 0x94 270 }; 271 const u8 local_mask[] = { 272 0x95, 0x07, 0xa9, 0x0f, 0x77, 0x7a, 0x04, 0x4d, 273 0x6a, 0x08, 0x30, 0xb9, 0x1e, 0xa3, 0xd5, 0xdd, 274 0x70, 0xbe, 0xce, 0x44, 0xe1, 0xac, 0xff, 0xb8, 275 0x69, 0x83, 0xb5, 0xe1, 0xbf, 0x9f, 0xb3, 0x22 276 }; 277 const u8 local_commit[] = { 278 0x13, 0x00, 0x2e, 0x2c, 0x0f, 0x0d, 0xb5, 0x24, 279 0x40, 0xad, 0x14, 0x6d, 0x96, 0x71, 0x14, 0xce, 280 0x00, 0x5c, 0xe1, 0xea, 0xb0, 0xaa, 0x2c, 0x2e, 281 0x5c, 0x28, 0x71, 0xb7, 0x74, 0xf6, 0xc2, 0x57, 282 0x5c, 0x65, 0xd5, 0xad, 0x9e, 0x00, 0x82, 0x97, 283 0x07, 0xaa, 0x36, 0xba, 0x8b, 0x85, 0x97, 0x38, 284 0xfc, 0x96, 0x1d, 0x08, 0x24, 0x35, 0x05, 0xf4, 285 0x7c, 0x03, 0x53, 0x76, 0xd7, 0xac, 0x4b, 0xc8, 286 0xd7, 0xb9, 0x50, 0x83, 0xbf, 0x43, 0x82, 0x7d, 287 0x0f, 0xc3, 0x1e, 0xd7, 0x78, 0xdd, 0x36, 0x71, 288 0xfd, 0x21, 0xa4, 0x6d, 0x10, 0x91, 0xd6, 0x4b, 289 0x6f, 0x9a, 0x1e, 0x12, 0x72, 0x62, 0x13, 0x25, 290 0xdb, 0xe1 291 }; 292 const u8 peer_commit[] = { 293 0x13, 0x00, 0x59, 0x1b, 0x96, 0xf3, 0x39, 0x7f, 294 0xb9, 0x45, 0x10, 0x08, 0x48, 0xe7, 0xb5, 0x50, 295 0x54, 0x3b, 0x67, 0x20, 0xd8, 0x83, 0x37, 0xee, 296 0x93, 0xfc, 0x49, 0xfd, 0x6d, 0xf7, 0xe0, 0x8b, 297 0x52, 0x23, 0xe7, 0x1b, 0x9b, 0xb0, 0x48, 0xd3, 298 0x87, 0x3f, 0x20, 0x55, 0x69, 0x53, 0xa9, 0x6c, 299 0x91, 0x53, 0x6f, 0xd8, 0xee, 0x6c, 0xa9, 0xb4, 300 0xa6, 0x8a, 0x14, 0x8b, 0x05, 0x6a, 0x90, 0x9b, 301 0xe0, 0x3e, 0x83, 0xae, 0x20, 0x8f, 0x60, 0xf8, 302 0xef, 0x55, 0x37, 0x85, 0x80, 0x74, 0xdb, 0x06, 303 0x68, 0x70, 0x32, 0x39, 0x98, 0x62, 0x99, 0x9b, 304 0x51, 0x1e, 0x0a, 0x15, 0x52, 0xa5, 0xfe, 0xa3, 305 0x17, 0xc2 306 }; 307 const u8 kck[] = { 308 0x1e, 0x73, 0x3f, 0x6d, 0x9b, 0xd5, 0x32, 0x56, 309 0x28, 0x73, 0x04, 0x33, 0x88, 0x31, 0xb0, 0x9a, 310 0x39, 0x40, 0x6d, 0x12, 0x10, 0x17, 0x07, 0x3a, 311 0x5c, 0x30, 0xdb, 0x36, 0xf3, 0x6c, 0xb8, 0x1a 312 }; 313 const u8 pmk[] = { 314 0x4e, 0x4d, 0xfa, 0xb1, 0xa2, 0xdd, 0x8a, 0xc1, 315 0xa9, 0x17, 0x90, 0xf9, 0x53, 0xfa, 0xaa, 0x45, 316 0x2a, 0xe5, 0xc6, 0x87, 0x3a, 0xb7, 0x5b, 0x63, 317 0x60, 0x5b, 0xa6, 0x63, 0xf8, 0xa7, 0xfe, 0x59 318 }; 319 const u8 pmkid[] = { 320 0x87, 0x47, 0xa6, 0x00, 0xee, 0xa3, 0xf9, 0xf2, 321 0x24, 0x75, 0xdf, 0x58, 0xca, 0x1e, 0x54, 0x98 322 }; 323 struct wpabuf *buf = NULL; 324 struct crypto_bignum *mask = NULL; 325 const u8 pwe_19_x[32] = { 326 0xc9, 0x30, 0x49, 0xb9, 0xe6, 0x40, 0x00, 0xf8, 327 0x48, 0x20, 0x16, 0x49, 0xe9, 0x99, 0xf2, 0xb5, 328 0xc2, 0x2d, 0xea, 0x69, 0xb5, 0x63, 0x2c, 0x9d, 329 0xf4, 0xd6, 0x33, 0xb8, 0xaa, 0x1f, 0x6c, 0x1e 330 }; 331 const u8 pwe_19_y[32] = { 332 0x73, 0x63, 0x4e, 0x94, 0xb5, 0x3d, 0x82, 0xe7, 333 0x38, 0x3a, 0x8d, 0x25, 0x81, 0x99, 0xd9, 0xdc, 334 0x1a, 0x5e, 0xe8, 0x26, 0x9d, 0x06, 0x03, 0x82, 335 0xcc, 0xbf, 0x33, 0xe6, 0x14, 0xff, 0x59, 0xa0 336 }; 337 const u8 pwe_15[384] = { 338 0x69, 0x68, 0x73, 0x65, 0x8f, 0x65, 0x31, 0x42, 339 0x9f, 0x97, 0x39, 0x6f, 0xb8, 0x5f, 0x89, 0xe1, 340 0xfc, 0xd2, 0xf6, 0x92, 0x19, 0xa9, 0x0e, 0x82, 341 0x2f, 0xf7, 0xf4, 0xbc, 0x0b, 0xd8, 0xa7, 0x9f, 342 0xf0, 0x80, 0x35, 0x31, 0x6f, 0xca, 0xe1, 0xa5, 343 0x39, 0x77, 0xdc, 0x11, 0x2b, 0x0b, 0xfe, 0x2e, 344 0x6f, 0x65, 0x6d, 0xc7, 0xd4, 0xa4, 0x5b, 0x08, 345 0x1f, 0xd9, 0xbb, 0xe2, 0x22, 0x85, 0x31, 0x81, 346 0x79, 0x70, 0xbe, 0xa1, 0x66, 0x58, 0x4a, 0x09, 347 0x3c, 0x57, 0x34, 0x3c, 0x9d, 0x57, 0x8f, 0x42, 348 0x58, 0xd0, 0x39, 0x81, 0xdb, 0x8f, 0x79, 0xa2, 349 0x1b, 0x01, 0xcd, 0x27, 0xc9, 0xae, 0xcf, 0xcb, 350 0x9c, 0xdb, 0x1f, 0x84, 0xb8, 0x88, 0x4e, 0x8f, 351 0x50, 0x66, 0xb4, 0x29, 0x83, 0x1e, 0xb9, 0x89, 352 0x0c, 0xa5, 0x47, 0x21, 0xba, 0x10, 0xd5, 0xaa, 353 0x1a, 0x80, 0xce, 0xf1, 0x4c, 0xad, 0x16, 0xda, 354 0x57, 0xb2, 0x41, 0x8a, 0xbe, 0x4b, 0x8c, 0xb0, 355 0xb2, 0xeb, 0xf7, 0xa8, 0x0e, 0x3e, 0xcf, 0x22, 356 0x8f, 0xd8, 0xb6, 0xdb, 0x79, 0x9c, 0x9b, 0x80, 357 0xaf, 0xd7, 0x14, 0xad, 0x51, 0x82, 0xf4, 0x64, 358 0xb6, 0x3f, 0x4c, 0x6c, 0xe5, 0x3f, 0xaa, 0x6f, 359 0xbf, 0x3d, 0xc2, 0x3f, 0x77, 0xfd, 0xcb, 0xe1, 360 0x9c, 0xe3, 0x1e, 0x8a, 0x0e, 0x97, 0xe2, 0x2b, 361 0xe2, 0xdd, 0x37, 0x39, 0x88, 0xc2, 0x8e, 0xbe, 362 0xfa, 0xac, 0x3d, 0x5b, 0x62, 0x2e, 0x1e, 0x74, 363 0xa0, 0x9a, 0xf8, 0xed, 0xfa, 0xe1, 0xce, 0x9c, 364 0xab, 0xbb, 0xdc, 0x36, 0xb1, 0x28, 0x46, 0x3c, 365 0x7e, 0xa8, 0xbd, 0xb9, 0x36, 0x4c, 0x26, 0x75, 366 0xe0, 0x17, 0x73, 0x1f, 0xe0, 0xfe, 0xf6, 0x49, 367 0xfa, 0xa0, 0x45, 0xf4, 0x44, 0x05, 0x20, 0x27, 368 0x25, 0xc2, 0x99, 0xde, 0x27, 0x8b, 0x70, 0xdc, 369 0x54, 0x60, 0x90, 0x02, 0x1e, 0x29, 0x97, 0x9a, 370 0xc4, 0xe7, 0xb6, 0xf5, 0x8b, 0xae, 0x7c, 0x34, 371 0xaa, 0xef, 0x9b, 0xc6, 0x30, 0xf2, 0x80, 0x8d, 372 0x80, 0x78, 0xc2, 0x55, 0x63, 0xa0, 0xa1, 0x38, 373 0x70, 0xfb, 0xf4, 0x74, 0x8d, 0xcd, 0x87, 0x90, 374 0xb4, 0x54, 0xc3, 0x75, 0xdf, 0x10, 0xc5, 0xb6, 375 0xb2, 0x08, 0x59, 0x61, 0xe6, 0x68, 0xa5, 0x82, 376 0xf8, 0x8f, 0x47, 0x30, 0x43, 0xb4, 0xdc, 0x31, 377 0xfc, 0xbc, 0x69, 0xe7, 0xb4, 0x94, 0xb0, 0x6a, 378 0x60, 0x59, 0x80, 0x2e, 0xd3, 0xa4, 0xe8, 0x97, 379 0xa2, 0xa3, 0xc9, 0x08, 0x4b, 0x27, 0x6c, 0xc1, 380 0x37, 0xe8, 0xfc, 0x5c, 0xe2, 0x54, 0x30, 0x3e, 381 0xf8, 0xfe, 0xa2, 0xfc, 0xbb, 0xbd, 0x88, 0x6c, 382 0x92, 0xa3, 0x2a, 0x40, 0x7a, 0x2c, 0x22, 0x38, 383 0x8c, 0x86, 0x86, 0xfe, 0xb9, 0xd4, 0x6b, 0xd6, 384 0x47, 0x88, 0xa7, 0xf6, 0x8e, 0x0f, 0x14, 0xad, 385 0x1e, 0xac, 0xcf, 0x33, 0x01, 0x99, 0xc1, 0x62 386 }; 387 int pt_groups[] = { 19, 20, 21, 25, 26, 28, 29, 30, 15, 0 }; 388 struct sae_pt *pt_info, *pt; 389 const u8 addr1b[ETH_ALEN] = { 0x00, 0x09, 0x5b, 0x66, 0xec, 0x1e }; 390 const u8 addr2b[ETH_ALEN] = { 0x00, 0x0b, 0x6b, 0xd9, 0x02, 0x46 }; 391 392 os_memset(&sae, 0, sizeof(sae)); 393 buf = wpabuf_alloc(1000); 394 if (!buf || 395 sae_set_group(&sae, 19) < 0 || 396 sae_prepare_commit(addr1, addr2, (const u8 *) pw, os_strlen(pw), 397 &sae) < 0) 398 goto fail; 399 400 /* Override local values based on SAE test vector */ 401 crypto_bignum_deinit(sae.tmp->sae_rand, 1); 402 sae.tmp->sae_rand = crypto_bignum_init_set(local_rand, 403 sizeof(local_rand)); 404 mask = crypto_bignum_init_set(local_mask, sizeof(local_mask)); 405 if (!sae.tmp->sae_rand || !mask) 406 goto fail; 407 408 if (crypto_bignum_add(sae.tmp->sae_rand, mask, 409 sae.tmp->own_commit_scalar) < 0 || 410 crypto_bignum_mod(sae.tmp->own_commit_scalar, sae.tmp->order, 411 sae.tmp->own_commit_scalar) < 0 || 412 crypto_ec_point_mul(sae.tmp->ec, sae.tmp->pwe_ecc, mask, 413 sae.tmp->own_commit_element_ecc) < 0 || 414 crypto_ec_point_invert(sae.tmp->ec, 415 sae.tmp->own_commit_element_ecc) < 0) 416 goto fail; 417 418 /* Check that output matches the test vector */ 419 if (sae_write_commit(&sae, buf, NULL, NULL) < 0) 420 goto fail; 421 wpa_hexdump_buf(MSG_DEBUG, "SAE: Commit message", buf); 422 423 if (wpabuf_len(buf) != sizeof(local_commit) || 424 os_memcmp(wpabuf_head(buf), local_commit, 425 sizeof(local_commit)) != 0) { 426 wpa_printf(MSG_ERROR, "SAE: Mismatch in local commit"); 427 goto fail; 428 } 429 430 if (sae_parse_commit(&sae, peer_commit, sizeof(peer_commit), NULL, NULL, 431 NULL, 0) != 0 || 432 sae_process_commit(&sae) < 0) 433 goto fail; 434 435 if (os_memcmp(kck, sae.tmp->kck, SAE_KCK_LEN) != 0) { 436 wpa_printf(MSG_ERROR, "SAE: Mismatch in KCK"); 437 goto fail; 438 } 439 440 if (os_memcmp(pmk, sae.pmk, SAE_PMK_LEN) != 0) { 441 wpa_printf(MSG_ERROR, "SAE: Mismatch in PMK"); 442 goto fail; 443 } 444 445 if (os_memcmp(pmkid, sae.pmkid, SAE_PMKID_LEN) != 0) { 446 wpa_printf(MSG_ERROR, "SAE: Mismatch in PMKID"); 447 goto fail; 448 } 449 450 pt_info = sae_derive_pt(pt_groups, 451 (const u8 *) ssid, os_strlen(ssid), 452 (const u8 *) pw, os_strlen(pw), pwid); 453 if (!pt_info) 454 goto fail; 455 456 for (pt = pt_info; pt; pt = pt->next) { 457 if (pt->group == 19) { 458 struct crypto_ec_point *pwe; 459 u8 bin[SAE_MAX_ECC_PRIME_LEN * 2]; 460 size_t prime_len = sizeof(pwe_19_x); 461 462 pwe = sae_derive_pwe_from_pt_ecc(pt, addr1b, addr2b); 463 if (!pwe) { 464 sae_deinit_pt(pt); 465 goto fail; 466 } 467 if (crypto_ec_point_to_bin(pt->ec, pwe, bin, 468 bin + prime_len) < 0 || 469 os_memcmp(pwe_19_x, bin, prime_len) != 0 || 470 os_memcmp(pwe_19_y, bin + prime_len, 471 prime_len) != 0) { 472 wpa_printf(MSG_ERROR, 473 "SAE: PT/PWE test vector mismatch"); 474 crypto_ec_point_deinit(pwe, 1); 475 sae_deinit_pt(pt); 476 goto fail; 477 } 478 crypto_ec_point_deinit(pwe, 1); 479 } 480 481 if (pt->group == 15) { 482 struct crypto_bignum *pwe; 483 u8 bin[SAE_MAX_PRIME_LEN]; 484 size_t prime_len = sizeof(pwe_15); 485 486 pwe = sae_derive_pwe_from_pt_ffc(pt, addr1b, addr2b); 487 if (!pwe) { 488 sae_deinit_pt(pt); 489 goto fail; 490 } 491 if (crypto_bignum_to_bin(pwe, bin, sizeof(bin), 492 prime_len) < 0 || 493 os_memcmp(pwe_15, bin, prime_len) != 0) { 494 wpa_printf(MSG_ERROR, 495 "SAE: PT/PWE test vector mismatch"); 496 crypto_bignum_deinit(pwe, 1); 497 sae_deinit_pt(pt); 498 goto fail; 499 } 500 crypto_bignum_deinit(pwe, 1); 501 } 502 } 503 504 sae_deinit_pt(pt_info); 505 506 ret = 0; 507 fail: 508 sae_clear_data(&sae); 509 wpabuf_free(buf); 510 crypto_bignum_deinit(mask, 1); 511 return ret; 512 #else /* CONFIG_SAE */ 513 return 0; 514 #endif /* CONFIG_SAE */ 515 } 516 517 518 static int sae_pk_tests(void) 519 { 520 #ifdef CONFIG_SAE_PK 521 const char *invalid[] = { "a2bc-de3f-ghim-", "a2bcde3fghim", "", NULL }; 522 struct { 523 const char *pw; 524 const u8 *val; 525 } valid[] = { 526 { "a2bc-de3f-ghim", (u8 *) "\x06\x82\x21\x93\x65\x31\xd0\xc0" }, 527 { "aaaa-aaaa-aaaj", (u8 *) "\x00\x00\x00\x00\x00\x00\x00\x90" }, 528 { "7777-7777-777f", (u8 *) "\xff\xff\xff\xff\xff\xff\xfe\x50" }, 529 { NULL, NULL } 530 }; 531 int i; 532 bool failed; 533 534 for (i = 0; invalid[i]; i++) { 535 if (sae_pk_valid_password(invalid[i])) { 536 wpa_printf(MSG_ERROR, 537 "SAE-PK: Invalid password '%s' not recognized", 538 invalid[i]); 539 return -1; 540 } 541 } 542 543 failed = false; 544 for (i = 0; valid[i].pw; i++) { 545 u8 *res; 546 size_t res_len; 547 char *b32; 548 const char *pw = valid[i].pw; 549 const u8 *val = valid[i].val; 550 size_t pw_len = os_strlen(pw); 551 size_t bits = (pw_len - pw_len / 5) * 5; 552 size_t bytes = (bits + 7) / 8; 553 554 if (!sae_pk_valid_password(pw)) { 555 wpa_printf(MSG_ERROR, 556 "SAE-PK: Valid password '%s' not recognized", 557 pw); 558 failed = true; 559 continue; 560 } 561 562 res = sae_pk_base32_decode(pw, pw_len, &res_len); 563 if (!res) { 564 wpa_printf(MSG_ERROR, 565 "SAE-PK: Failed to decode password '%s'", 566 valid[i].pw); 567 failed = true; 568 continue; 569 } 570 if (res_len != bytes || os_memcmp(val, res, res_len) != 0) { 571 wpa_printf(MSG_ERROR, 572 "SAE-PK: Mismatch for decoded password '%s'", 573 valid[i].pw); 574 wpa_hexdump(MSG_INFO, "SAE-PK: Decoded value", 575 res, res_len); 576 wpa_hexdump(MSG_INFO, "SAE-PK: Expected value", 577 val, bytes); 578 failed = true; 579 } 580 os_free(res); 581 582 b32 = sae_pk_base32_encode(val, bits - 5); 583 if (!b32) { 584 wpa_printf(MSG_ERROR, 585 "SAE-PK: Failed to encode password '%s'", 586 pw); 587 failed = true; 588 continue; 589 } 590 if (os_strcmp(b32, pw) != 0) { 591 wpa_printf(MSG_ERROR, 592 "SAE-PK: Mismatch for password '%s'", pw); 593 wpa_printf(MSG_INFO, "SAE-PK: Encoded value: '%s'", 594 b32); 595 failed = true; 596 } 597 os_free(b32); 598 } 599 600 return failed ? -1 : 0; 601 #else /* CONFIG_SAE_PK */ 602 return 0; 603 #endif /* CONFIG_SAE_PK */ 604 } 605 606 607 #ifdef CONFIG_PASN 608 609 static int pasn_test_pasn_auth(void) 610 { 611 /* Test vector taken from IEEE P802.11az/D2.6, J.12 */ 612 const u8 pmk[] = { 613 0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6, 614 0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef, 615 0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9, 616 0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad 617 }; 618 619 const u8 spa_addr[] = { 620 0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07 621 }; 622 const u8 bssid[] = { 623 0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1 624 }; 625 const u8 dhss[] = { 626 0xf8, 0x7b, 0x20, 0x8e, 0x7e, 0xd2, 0xb7, 0x37, 627 0xaf, 0xdb, 0xc2, 0xe1, 0x3e, 0xae, 0x78, 0xda, 628 0x30, 0x01, 0x23, 0xd4, 0xd8, 0x4b, 0xa8, 0xb0, 629 0xea, 0xfe, 0x90, 0xc4, 0x8c, 0xdf, 0x1f, 0x93 630 }; 631 const u8 kck[] = { 632 0x7b, 0xb8, 0x21, 0xac, 0x0a, 0xa5, 0x90, 0x9d, 633 0xd6, 0x54, 0xa5, 0x60, 0x65, 0xad, 0x7c, 0x77, 634 0xeb, 0x88, 0x9c, 0xbe, 0x29, 0x05, 0xbb, 0xf0, 635 0x5a, 0xbb, 0x1e, 0xea, 0xc8, 0x8b, 0xa3, 0x06 636 }; 637 const u8 tk[] = { 638 0x67, 0x3e, 0xab, 0x46, 0xb8, 0x32, 0xd5, 0xa8, 639 0x0c, 0xbc, 0x02, 0x43, 0x01, 0x6e, 0x20, 0x7e 640 }; 641 const u8 kdk[] = { 642 0x2d, 0x0f, 0x0e, 0x82, 0xc7, 0x0d, 0xd2, 0x6b, 643 0x79, 0x06, 0x1a, 0x46, 0x81, 0xe8, 0xdb, 0xb2, 644 0xea, 0x83, 0xbe, 0xa3, 0x99, 0x84, 0x4b, 0xd5, 645 0x89, 0x4e, 0xb3, 0x20, 0xf6, 0x9d, 0x7d, 0xd6 646 }; 647 struct wpa_ptk ptk; 648 int ret; 649 650 ret = pasn_pmk_to_ptk(pmk, sizeof(pmk), 651 spa_addr, bssid, 652 dhss, sizeof(dhss), 653 &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP, 654 WPA_KDK_MAX_LEN); 655 656 if (ret) 657 return ret; 658 659 if (ptk.kck_len != sizeof(kck) || 660 os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) { 661 wpa_printf(MSG_ERROR, "PASN: Mismatched KCK"); 662 return -1; 663 } 664 665 if (ptk.tk_len != sizeof(tk) || 666 os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) { 667 wpa_printf(MSG_ERROR, "PASN: Mismatched TK"); 668 return -1; 669 } 670 671 if (ptk.kdk_len != sizeof(kdk) || 672 os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) { 673 wpa_printf(MSG_ERROR, "PASN: Mismatched KDK"); 674 return -1; 675 } 676 677 return 0; 678 } 679 680 681 static int pasn_test_no_pasn_auth(void) 682 { 683 /* Test vector taken from IEEE P802.11az/D2.6, J.13 */ 684 const u8 pmk[] = { 685 0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6, 686 0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef, 687 0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9, 688 0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad 689 }; 690 const u8 aa[] = { 691 0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1 692 }; 693 const u8 spa[] = { 694 0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07 695 }; 696 const u8 anonce[] = { 697 0xbe, 0x7a, 0x1c, 0xa2, 0x84, 0x34, 0x7b, 0x5b, 698 0xd6, 0x7d, 0xbd, 0x2d, 0xfd, 0xb4, 0xd9, 0x9f, 699 0x1a, 0xfa, 0xe0, 0xb8, 0x8b, 0xa1, 0x8e, 0x00, 700 0x87, 0x18, 0x41, 0x7e, 0x4b, 0x27, 0xef, 0x5f 701 }; 702 const u8 snonce[] = { 703 0x40, 0x4b, 0x01, 0x2f, 0xfb, 0x43, 0xed, 0x0f, 704 0xb4, 0x3e, 0xa1, 0xf2, 0x87, 0xc9, 0x1f, 0x25, 705 0x06, 0xd2, 0x1b, 0x4a, 0x92, 0xd7, 0x4b, 0x5e, 706 0xa5, 0x0c, 0x94, 0x33, 0x50, 0xce, 0x86, 0x71 707 }; 708 const u8 kck[] = { 709 0xcd, 0x7b, 0x9e, 0x75, 0x55, 0x36, 0x2d, 0xf0, 710 0xb6, 0x35, 0x68, 0x48, 0x4a, 0x81, 0x12, 0xf5 711 }; 712 const u8 kek[] = { 713 0x99, 0xca, 0xd3, 0x58, 0x8d, 0xa0, 0xf1, 0xe6, 714 0x3f, 0xd1, 0x90, 0x19, 0x10, 0x39, 0xbb, 0x4b 715 }; 716 const u8 tk[] = { 717 0x9e, 0x2e, 0x93, 0x77, 0xe7, 0x53, 0x2e, 0x73, 718 0x7a, 0x1b, 0xc2, 0x50, 0xfe, 0x19, 0x4a, 0x03 719 }; 720 const u8 kdk[] = { 721 0x6c, 0x7f, 0xb9, 0x7c, 0xeb, 0x55, 0xb0, 0x1a, 722 0xcf, 0xf0, 0x0f, 0x07, 0x09, 0x42, 0xbd, 0xf5, 723 0x29, 0x1f, 0xeb, 0x4b, 0xee, 0x38, 0xe0, 0x36, 724 0x5b, 0x25, 0xa2, 0x50, 0xbb, 0x2a, 0xc9, 0xff 725 }; 726 struct wpa_ptk ptk; 727 int ret; 728 729 ret = wpa_pmk_to_ptk(pmk, sizeof(pmk), 730 "Pairwise key expansion", 731 spa, aa, snonce, anonce, 732 &ptk, WPA_KEY_MGMT_SAE, WPA_CIPHER_CCMP, 733 NULL, 0, WPA_KDK_MAX_LEN); 734 735 if (ret) 736 return ret; 737 738 if (ptk.kck_len != sizeof(kck) || 739 os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) { 740 wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KCK"); 741 return -1; 742 } 743 744 if (ptk.kek_len != sizeof(kek) || 745 os_memcmp(kek, ptk.kek, sizeof(kek)) != 0) { 746 wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KEK"); 747 return -1; 748 } 749 750 if (ptk.tk_len != sizeof(tk) || 751 os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) { 752 wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched TK"); 753 return -1; 754 } 755 756 if (ptk.kdk_len != sizeof(kdk) || 757 os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) { 758 wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KDK"); 759 return -1; 760 } 761 762 return 0; 763 } 764 765 #endif /* CONFIG_PASN */ 766 767 768 static int pasn_tests(void) 769 { 770 #ifdef CONFIG_PASN 771 if (pasn_test_pasn_auth() || 772 pasn_test_no_pasn_auth()) 773 return -1; 774 #endif /* CONFIG_PASN */ 775 return 0; 776 } 777 778 779 int common_module_tests(void) 780 { 781 int ret = 0; 782 783 wpa_printf(MSG_INFO, "common module tests"); 784 785 if (ieee802_11_parse_tests() < 0 || 786 gas_tests() < 0 || 787 sae_tests() < 0 || 788 sae_pk_tests() < 0 || 789 pasn_tests() < 0 || 790 rsn_ie_parse_tests() < 0) 791 ret = -1; 792 793 return ret; 794 } 795