sae.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. /*
  2. * Simultaneous authentication of equals
  3. * Copyright (c) 2012-2016, 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. #include "includes.h"
  9. #include "common.h"
  10. #include "crypto/crypto.h"
  11. #include "crypto/sha256.h"
  12. #include "crypto/random.h"
  13. #include "crypto/dh_groups.h"
  14. #include "ieee802_11_defs.h"
  15. #include "sae.h"
  16. int sae_set_group(struct sae_data *sae, int group)
  17. {
  18. struct sae_temporary_data *tmp;
  19. sae_clear_data(sae);
  20. tmp = sae->tmp = os_zalloc(sizeof(*tmp));
  21. if (tmp == NULL)
  22. return -1;
  23. /* First, check if this is an ECC group */
  24. tmp->ec = crypto_ec_init(group);
  25. if (tmp->ec) {
  26. sae->group = group;
  27. tmp->prime_len = crypto_ec_prime_len(tmp->ec);
  28. tmp->prime = crypto_ec_get_prime(tmp->ec);
  29. tmp->order = crypto_ec_get_order(tmp->ec);
  30. return 0;
  31. }
  32. /* Not an ECC group, check FFC */
  33. tmp->dh = dh_groups_get(group);
  34. if (tmp->dh) {
  35. sae->group = group;
  36. tmp->prime_len = tmp->dh->prime_len;
  37. if (tmp->prime_len > SAE_MAX_PRIME_LEN) {
  38. sae_clear_data(sae);
  39. return -1;
  40. }
  41. tmp->prime_buf = crypto_bignum_init_set(tmp->dh->prime,
  42. tmp->prime_len);
  43. if (tmp->prime_buf == NULL) {
  44. sae_clear_data(sae);
  45. return -1;
  46. }
  47. tmp->prime = tmp->prime_buf;
  48. tmp->order_buf = crypto_bignum_init_set(tmp->dh->order,
  49. tmp->dh->order_len);
  50. if (tmp->order_buf == NULL) {
  51. sae_clear_data(sae);
  52. return -1;
  53. }
  54. tmp->order = tmp->order_buf;
  55. return 0;
  56. }
  57. /* Unsupported group */
  58. return -1;
  59. }
  60. void sae_clear_temp_data(struct sae_data *sae)
  61. {
  62. struct sae_temporary_data *tmp;
  63. if (sae == NULL || sae->tmp == NULL)
  64. return;
  65. tmp = sae->tmp;
  66. crypto_ec_deinit(tmp->ec);
  67. crypto_bignum_deinit(tmp->prime_buf, 0);
  68. crypto_bignum_deinit(tmp->order_buf, 0);
  69. crypto_bignum_deinit(tmp->sae_rand, 1);
  70. crypto_bignum_deinit(tmp->pwe_ffc, 1);
  71. crypto_bignum_deinit(tmp->own_commit_scalar, 0);
  72. crypto_bignum_deinit(tmp->own_commit_element_ffc, 0);
  73. crypto_bignum_deinit(tmp->peer_commit_element_ffc, 0);
  74. crypto_ec_point_deinit(tmp->pwe_ecc, 1);
  75. crypto_ec_point_deinit(tmp->own_commit_element_ecc, 0);
  76. crypto_ec_point_deinit(tmp->peer_commit_element_ecc, 0);
  77. wpabuf_free(tmp->anti_clogging_token);
  78. bin_clear_free(tmp, sizeof(*tmp));
  79. sae->tmp = NULL;
  80. }
  81. void sae_clear_data(struct sae_data *sae)
  82. {
  83. if (sae == NULL)
  84. return;
  85. sae_clear_temp_data(sae);
  86. crypto_bignum_deinit(sae->peer_commit_scalar, 0);
  87. os_memset(sae, 0, sizeof(*sae));
  88. }
  89. static void buf_shift_right(u8 *buf, size_t len, size_t bits)
  90. {
  91. size_t i;
  92. for (i = len - 1; i > 0; i--)
  93. buf[i] = (buf[i - 1] << (8 - bits)) | (buf[i] >> bits);
  94. buf[0] >>= bits;
  95. }
  96. static struct crypto_bignum * sae_get_rand(struct sae_data *sae)
  97. {
  98. u8 val[SAE_MAX_PRIME_LEN];
  99. int iter = 0;
  100. struct crypto_bignum *bn = NULL;
  101. int order_len_bits = crypto_bignum_bits(sae->tmp->order);
  102. size_t order_len = (order_len_bits + 7) / 8;
  103. if (order_len > sizeof(val))
  104. return NULL;
  105. for (;;) {
  106. if (iter++ > 100 || random_get_bytes(val, order_len) < 0)
  107. return NULL;
  108. if (order_len_bits % 8)
  109. buf_shift_right(val, order_len, 8 - order_len_bits % 8);
  110. bn = crypto_bignum_init_set(val, order_len);
  111. if (bn == NULL)
  112. return NULL;
  113. if (crypto_bignum_is_zero(bn) ||
  114. crypto_bignum_is_one(bn) ||
  115. crypto_bignum_cmp(bn, sae->tmp->order) >= 0) {
  116. crypto_bignum_deinit(bn, 0);
  117. continue;
  118. }
  119. break;
  120. }
  121. os_memset(val, 0, order_len);
  122. return bn;
  123. }
  124. static struct crypto_bignum * sae_get_rand_and_mask(struct sae_data *sae)
  125. {
  126. crypto_bignum_deinit(sae->tmp->sae_rand, 1);
  127. sae->tmp->sae_rand = sae_get_rand(sae);
  128. if (sae->tmp->sae_rand == NULL)
  129. return NULL;
  130. return sae_get_rand(sae);
  131. }
  132. static void sae_pwd_seed_key(const u8 *addr1, const u8 *addr2, u8 *key)
  133. {
  134. wpa_printf(MSG_DEBUG, "SAE: PWE derivation - addr1=" MACSTR
  135. " addr2=" MACSTR, MAC2STR(addr1), MAC2STR(addr2));
  136. if (os_memcmp(addr1, addr2, ETH_ALEN) > 0) {
  137. os_memcpy(key, addr1, ETH_ALEN);
  138. os_memcpy(key + ETH_ALEN, addr2, ETH_ALEN);
  139. } else {
  140. os_memcpy(key, addr2, ETH_ALEN);
  141. os_memcpy(key + ETH_ALEN, addr1, ETH_ALEN);
  142. }
  143. }
  144. static struct crypto_bignum *
  145. get_rand_1_to_p_1(const u8 *prime, size_t prime_len, size_t prime_bits,
  146. int *r_odd)
  147. {
  148. for (;;) {
  149. struct crypto_bignum *r;
  150. u8 tmp[SAE_MAX_ECC_PRIME_LEN];
  151. if (random_get_bytes(tmp, prime_len) < 0)
  152. break;
  153. if (prime_bits % 8)
  154. buf_shift_right(tmp, prime_len, 8 - prime_bits % 8);
  155. if (os_memcmp(tmp, prime, prime_len) >= 0)
  156. continue;
  157. r = crypto_bignum_init_set(tmp, prime_len);
  158. if (!r)
  159. break;
  160. if (crypto_bignum_is_zero(r)) {
  161. crypto_bignum_deinit(r, 0);
  162. continue;
  163. }
  164. *r_odd = tmp[prime_len - 1] & 0x01;
  165. return r;
  166. }
  167. return NULL;
  168. }
  169. static int is_quadratic_residue_blind(struct sae_data *sae,
  170. const u8 *prime, size_t bits,
  171. const struct crypto_bignum *qr,
  172. const struct crypto_bignum *qnr,
  173. const struct crypto_bignum *y_sqr)
  174. {
  175. struct crypto_bignum *r, *num;
  176. int r_odd, check, res = -1;
  177. /*
  178. * Use the blinding technique to mask y_sqr while determining
  179. * whether it is a quadratic residue modulo p to avoid leaking
  180. * timing information while determining the Legendre symbol.
  181. *
  182. * v = y_sqr
  183. * r = a random number between 1 and p-1, inclusive
  184. * num = (v * r * r) modulo p
  185. */
  186. r = get_rand_1_to_p_1(prime, sae->tmp->prime_len, bits, &r_odd);
  187. if (!r)
  188. return -1;
  189. num = crypto_bignum_init();
  190. if (!num ||
  191. crypto_bignum_mulmod(y_sqr, r, sae->tmp->prime, num) < 0 ||
  192. crypto_bignum_mulmod(num, r, sae->tmp->prime, num) < 0)
  193. goto fail;
  194. if (r_odd) {
  195. /*
  196. * num = (num * qr) module p
  197. * LGR(num, p) = 1 ==> quadratic residue
  198. */
  199. if (crypto_bignum_mulmod(num, qr, sae->tmp->prime, num) < 0)
  200. goto fail;
  201. check = 1;
  202. } else {
  203. /*
  204. * num = (num * qnr) module p
  205. * LGR(num, p) = -1 ==> quadratic residue
  206. */
  207. if (crypto_bignum_mulmod(num, qnr, sae->tmp->prime, num) < 0)
  208. goto fail;
  209. check = -1;
  210. }
  211. res = crypto_bignum_legendre(num, sae->tmp->prime);
  212. if (res == -2) {
  213. res = -1;
  214. goto fail;
  215. }
  216. res = res == check;
  217. fail:
  218. crypto_bignum_deinit(num, 1);
  219. crypto_bignum_deinit(r, 1);
  220. return res;
  221. }
  222. static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed,
  223. const u8 *prime,
  224. const struct crypto_bignum *qr,
  225. const struct crypto_bignum *qnr,
  226. struct crypto_bignum **ret_x_cand)
  227. {
  228. u8 pwd_value[SAE_MAX_ECC_PRIME_LEN];
  229. struct crypto_bignum *y_sqr, *x_cand;
  230. int res;
  231. size_t bits;
  232. *ret_x_cand = NULL;
  233. wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
  234. /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
  235. bits = crypto_ec_prime_len_bits(sae->tmp->ec);
  236. if (sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
  237. prime, sae->tmp->prime_len, pwd_value, bits) < 0)
  238. return -1;
  239. if (bits % 8)
  240. buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8);
  241. wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
  242. pwd_value, sae->tmp->prime_len);
  243. if (os_memcmp(pwd_value, prime, sae->tmp->prime_len) >= 0)
  244. return 0;
  245. x_cand = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
  246. if (!x_cand)
  247. return -1;
  248. y_sqr = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x_cand);
  249. if (!y_sqr) {
  250. crypto_bignum_deinit(x_cand, 1);
  251. return -1;
  252. }
  253. res = is_quadratic_residue_blind(sae, prime, bits, qr, qnr, y_sqr);
  254. crypto_bignum_deinit(y_sqr, 1);
  255. if (res <= 0) {
  256. crypto_bignum_deinit(x_cand, 1);
  257. return res;
  258. }
  259. *ret_x_cand = x_cand;
  260. return 1;
  261. }
  262. static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed,
  263. struct crypto_bignum *pwe)
  264. {
  265. u8 pwd_value[SAE_MAX_PRIME_LEN];
  266. size_t bits = sae->tmp->prime_len * 8;
  267. u8 exp[1];
  268. struct crypto_bignum *a, *b;
  269. int res;
  270. wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
  271. /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
  272. if (sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
  273. sae->tmp->dh->prime, sae->tmp->prime_len, pwd_value,
  274. bits) < 0)
  275. return -1;
  276. wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", pwd_value,
  277. sae->tmp->prime_len);
  278. if (os_memcmp(pwd_value, sae->tmp->dh->prime, sae->tmp->prime_len) >= 0)
  279. {
  280. wpa_printf(MSG_DEBUG, "SAE: pwd-value >= p");
  281. return 0;
  282. }
  283. /* PWE = pwd-value^((p-1)/r) modulo p */
  284. a = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
  285. if (sae->tmp->dh->safe_prime) {
  286. /*
  287. * r = (p-1)/2 for the group used here, so this becomes:
  288. * PWE = pwd-value^2 modulo p
  289. */
  290. exp[0] = 2;
  291. b = crypto_bignum_init_set(exp, sizeof(exp));
  292. } else {
  293. /* Calculate exponent: (p-1)/r */
  294. exp[0] = 1;
  295. b = crypto_bignum_init_set(exp, sizeof(exp));
  296. if (b == NULL ||
  297. crypto_bignum_sub(sae->tmp->prime, b, b) < 0 ||
  298. crypto_bignum_div(b, sae->tmp->order, b) < 0) {
  299. crypto_bignum_deinit(b, 0);
  300. b = NULL;
  301. }
  302. }
  303. if (a == NULL || b == NULL)
  304. res = -1;
  305. else
  306. res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
  307. crypto_bignum_deinit(a, 0);
  308. crypto_bignum_deinit(b, 0);
  309. if (res < 0) {
  310. wpa_printf(MSG_DEBUG, "SAE: Failed to calculate PWE");
  311. return -1;
  312. }
  313. /* if (PWE > 1) --> found */
  314. if (crypto_bignum_is_zero(pwe) || crypto_bignum_is_one(pwe)) {
  315. wpa_printf(MSG_DEBUG, "SAE: PWE <= 1");
  316. return 0;
  317. }
  318. wpa_printf(MSG_DEBUG, "SAE: PWE found");
  319. return 1;
  320. }
  321. static int get_random_qr_qnr(const u8 *prime, size_t prime_len,
  322. const struct crypto_bignum *prime_bn,
  323. size_t prime_bits, struct crypto_bignum **qr,
  324. struct crypto_bignum **qnr)
  325. {
  326. *qr = NULL;
  327. *qnr = NULL;
  328. while (!(*qr) || !(*qnr)) {
  329. u8 tmp[SAE_MAX_ECC_PRIME_LEN];
  330. struct crypto_bignum *q;
  331. int res;
  332. if (random_get_bytes(tmp, prime_len) < 0)
  333. break;
  334. if (prime_bits % 8)
  335. buf_shift_right(tmp, prime_len, 8 - prime_bits % 8);
  336. if (os_memcmp(tmp, prime, prime_len) >= 0)
  337. continue;
  338. q = crypto_bignum_init_set(tmp, prime_len);
  339. if (!q)
  340. break;
  341. res = crypto_bignum_legendre(q, prime_bn);
  342. if (res == 1 && !(*qr))
  343. *qr = q;
  344. else if (res == -1 && !(*qnr))
  345. *qnr = q;
  346. else
  347. crypto_bignum_deinit(q, 0);
  348. }
  349. return (*qr && *qnr) ? 0 : -1;
  350. }
  351. static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
  352. const u8 *addr2, const u8 *password,
  353. size_t password_len)
  354. {
  355. u8 counter, k = 40;
  356. u8 addrs[2 * ETH_ALEN];
  357. const u8 *addr[2];
  358. size_t len[2];
  359. u8 dummy_password[32];
  360. size_t dummy_password_len;
  361. int pwd_seed_odd = 0;
  362. u8 prime[SAE_MAX_ECC_PRIME_LEN];
  363. size_t prime_len;
  364. struct crypto_bignum *x = NULL, *qr, *qnr;
  365. size_t bits;
  366. int res;
  367. dummy_password_len = password_len;
  368. if (dummy_password_len > sizeof(dummy_password))
  369. dummy_password_len = sizeof(dummy_password);
  370. if (random_get_bytes(dummy_password, dummy_password_len) < 0)
  371. return -1;
  372. prime_len = sae->tmp->prime_len;
  373. if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
  374. prime_len) < 0)
  375. return -1;
  376. bits = crypto_ec_prime_len_bits(sae->tmp->ec);
  377. /*
  378. * Create a random quadratic residue (qr) and quadratic non-residue
  379. * (qnr) modulo p for blinding purposes during the loop.
  380. */
  381. if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits,
  382. &qr, &qnr) < 0)
  383. return -1;
  384. wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
  385. password, password_len);
  386. /*
  387. * H(salt, ikm) = HMAC-SHA256(salt, ikm)
  388. * base = password
  389. * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
  390. * base || counter)
  391. */
  392. sae_pwd_seed_key(addr1, addr2, addrs);
  393. addr[0] = password;
  394. len[0] = password_len;
  395. addr[1] = &counter;
  396. len[1] = sizeof(counter);
  397. /*
  398. * Continue for at least k iterations to protect against side-channel
  399. * attacks that attempt to determine the number of iterations required
  400. * in the loop.
  401. */
  402. for (counter = 1; counter <= k || !x; counter++) {
  403. u8 pwd_seed[SHA256_MAC_LEN];
  404. struct crypto_bignum *x_cand;
  405. if (counter > 200) {
  406. /* This should not happen in practice */
  407. wpa_printf(MSG_DEBUG, "SAE: Failed to derive PWE");
  408. break;
  409. }
  410. wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
  411. if (hmac_sha256_vector(addrs, sizeof(addrs), 2, addr, len,
  412. pwd_seed) < 0)
  413. break;
  414. res = sae_test_pwd_seed_ecc(sae, pwd_seed,
  415. prime, qr, qnr, &x_cand);
  416. if (res < 0)
  417. goto fail;
  418. if (res > 0 && !x) {
  419. wpa_printf(MSG_DEBUG,
  420. "SAE: Selected pwd-seed with counter %u",
  421. counter);
  422. x = x_cand;
  423. pwd_seed_odd = pwd_seed[SHA256_MAC_LEN - 1] & 0x01;
  424. os_memset(pwd_seed, 0, sizeof(pwd_seed));
  425. /*
  426. * Use a dummy password for the following rounds, if
  427. * any.
  428. */
  429. addr[0] = dummy_password;
  430. len[0] = dummy_password_len;
  431. } else if (res > 0) {
  432. crypto_bignum_deinit(x_cand, 1);
  433. }
  434. }
  435. if (!x) {
  436. wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE");
  437. res = -1;
  438. goto fail;
  439. }
  440. if (!sae->tmp->pwe_ecc)
  441. sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec);
  442. if (!sae->tmp->pwe_ecc)
  443. res = -1;
  444. else
  445. res = crypto_ec_point_solve_y_coord(sae->tmp->ec,
  446. sae->tmp->pwe_ecc, x,
  447. pwd_seed_odd);
  448. crypto_bignum_deinit(x, 1);
  449. if (res < 0) {
  450. /*
  451. * This should not happen since we already checked that there
  452. * is a result.
  453. */
  454. wpa_printf(MSG_DEBUG, "SAE: Could not solve y");
  455. }
  456. fail:
  457. crypto_bignum_deinit(qr, 0);
  458. crypto_bignum_deinit(qnr, 0);
  459. return res;
  460. }
  461. static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
  462. const u8 *addr2, const u8 *password,
  463. size_t password_len)
  464. {
  465. u8 counter;
  466. u8 addrs[2 * ETH_ALEN];
  467. const u8 *addr[2];
  468. size_t len[2];
  469. int found = 0;
  470. if (sae->tmp->pwe_ffc == NULL) {
  471. sae->tmp->pwe_ffc = crypto_bignum_init();
  472. if (sae->tmp->pwe_ffc == NULL)
  473. return -1;
  474. }
  475. wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
  476. password, password_len);
  477. /*
  478. * H(salt, ikm) = HMAC-SHA256(salt, ikm)
  479. * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
  480. * password || counter)
  481. */
  482. sae_pwd_seed_key(addr1, addr2, addrs);
  483. addr[0] = password;
  484. len[0] = password_len;
  485. addr[1] = &counter;
  486. len[1] = sizeof(counter);
  487. for (counter = 1; !found; counter++) {
  488. u8 pwd_seed[SHA256_MAC_LEN];
  489. int res;
  490. if (counter > 200) {
  491. /* This should not happen in practice */
  492. wpa_printf(MSG_DEBUG, "SAE: Failed to derive PWE");
  493. break;
  494. }
  495. wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
  496. if (hmac_sha256_vector(addrs, sizeof(addrs), 2, addr, len,
  497. pwd_seed) < 0)
  498. break;
  499. res = sae_test_pwd_seed_ffc(sae, pwd_seed, sae->tmp->pwe_ffc);
  500. if (res < 0)
  501. break;
  502. if (res > 0) {
  503. wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
  504. found = 1;
  505. }
  506. }
  507. return found ? 0 : -1;
  508. }
  509. static int sae_derive_commit_element_ecc(struct sae_data *sae,
  510. struct crypto_bignum *mask)
  511. {
  512. /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */
  513. if (!sae->tmp->own_commit_element_ecc) {
  514. sae->tmp->own_commit_element_ecc =
  515. crypto_ec_point_init(sae->tmp->ec);
  516. if (!sae->tmp->own_commit_element_ecc)
  517. return -1;
  518. }
  519. if (crypto_ec_point_mul(sae->tmp->ec, sae->tmp->pwe_ecc, mask,
  520. sae->tmp->own_commit_element_ecc) < 0 ||
  521. crypto_ec_point_invert(sae->tmp->ec,
  522. sae->tmp->own_commit_element_ecc) < 0) {
  523. wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element");
  524. return -1;
  525. }
  526. return 0;
  527. }
  528. static int sae_derive_commit_element_ffc(struct sae_data *sae,
  529. struct crypto_bignum *mask)
  530. {
  531. /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */
  532. if (!sae->tmp->own_commit_element_ffc) {
  533. sae->tmp->own_commit_element_ffc = crypto_bignum_init();
  534. if (!sae->tmp->own_commit_element_ffc)
  535. return -1;
  536. }
  537. if (crypto_bignum_exptmod(sae->tmp->pwe_ffc, mask, sae->tmp->prime,
  538. sae->tmp->own_commit_element_ffc) < 0 ||
  539. crypto_bignum_inverse(sae->tmp->own_commit_element_ffc,
  540. sae->tmp->prime,
  541. sae->tmp->own_commit_element_ffc) < 0) {
  542. wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element");
  543. return -1;
  544. }
  545. return 0;
  546. }
  547. static int sae_derive_commit(struct sae_data *sae)
  548. {
  549. struct crypto_bignum *mask;
  550. int ret = -1;
  551. unsigned int counter = 0;
  552. do {
  553. counter++;
  554. if (counter > 100) {
  555. /*
  556. * This cannot really happen in practice if the random
  557. * number generator is working. Anyway, to avoid even a
  558. * theoretical infinite loop, break out after 100
  559. * attemps.
  560. */
  561. return -1;
  562. }
  563. mask = sae_get_rand_and_mask(sae);
  564. if (mask == NULL) {
  565. wpa_printf(MSG_DEBUG, "SAE: Could not get rand/mask");
  566. return -1;
  567. }
  568. /* commit-scalar = (rand + mask) modulo r */
  569. if (!sae->tmp->own_commit_scalar) {
  570. sae->tmp->own_commit_scalar = crypto_bignum_init();
  571. if (!sae->tmp->own_commit_scalar)
  572. goto fail;
  573. }
  574. crypto_bignum_add(sae->tmp->sae_rand, mask,
  575. sae->tmp->own_commit_scalar);
  576. crypto_bignum_mod(sae->tmp->own_commit_scalar, sae->tmp->order,
  577. sae->tmp->own_commit_scalar);
  578. } while (crypto_bignum_is_zero(sae->tmp->own_commit_scalar) ||
  579. crypto_bignum_is_one(sae->tmp->own_commit_scalar));
  580. if ((sae->tmp->ec && sae_derive_commit_element_ecc(sae, mask) < 0) ||
  581. (sae->tmp->dh && sae_derive_commit_element_ffc(sae, mask) < 0))
  582. goto fail;
  583. ret = 0;
  584. fail:
  585. crypto_bignum_deinit(mask, 1);
  586. return ret;
  587. }
  588. int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
  589. const u8 *password, size_t password_len,
  590. struct sae_data *sae)
  591. {
  592. if (sae->tmp == NULL ||
  593. (sae->tmp->ec && sae_derive_pwe_ecc(sae, addr1, addr2, password,
  594. password_len) < 0) ||
  595. (sae->tmp->dh && sae_derive_pwe_ffc(sae, addr1, addr2, password,
  596. password_len) < 0) ||
  597. sae_derive_commit(sae) < 0)
  598. return -1;
  599. return 0;
  600. }
  601. static int sae_derive_k_ecc(struct sae_data *sae, u8 *k)
  602. {
  603. struct crypto_ec_point *K;
  604. int ret = -1;
  605. K = crypto_ec_point_init(sae->tmp->ec);
  606. if (K == NULL)
  607. goto fail;
  608. /*
  609. * K = scalar-op(rand, (elem-op(scalar-op(peer-commit-scalar, PWE),
  610. * PEER-COMMIT-ELEMENT)))
  611. * If K is identity element (point-at-infinity), reject
  612. * k = F(K) (= x coordinate)
  613. */
  614. if (crypto_ec_point_mul(sae->tmp->ec, sae->tmp->pwe_ecc,
  615. sae->peer_commit_scalar, K) < 0 ||
  616. crypto_ec_point_add(sae->tmp->ec, K,
  617. sae->tmp->peer_commit_element_ecc, K) < 0 ||
  618. crypto_ec_point_mul(sae->tmp->ec, K, sae->tmp->sae_rand, K) < 0 ||
  619. crypto_ec_point_is_at_infinity(sae->tmp->ec, K) ||
  620. crypto_ec_point_to_bin(sae->tmp->ec, K, k, NULL) < 0) {
  621. wpa_printf(MSG_DEBUG, "SAE: Failed to calculate K and k");
  622. goto fail;
  623. }
  624. wpa_hexdump_key(MSG_DEBUG, "SAE: k", k, sae->tmp->prime_len);
  625. ret = 0;
  626. fail:
  627. crypto_ec_point_deinit(K, 1);
  628. return ret;
  629. }
  630. static int sae_derive_k_ffc(struct sae_data *sae, u8 *k)
  631. {
  632. struct crypto_bignum *K;
  633. int ret = -1;
  634. K = crypto_bignum_init();
  635. if (K == NULL)
  636. goto fail;
  637. /*
  638. * K = scalar-op(rand, (elem-op(scalar-op(peer-commit-scalar, PWE),
  639. * PEER-COMMIT-ELEMENT)))
  640. * If K is identity element (one), reject.
  641. * k = F(K) (= x coordinate)
  642. */
  643. if (crypto_bignum_exptmod(sae->tmp->pwe_ffc, sae->peer_commit_scalar,
  644. sae->tmp->prime, K) < 0 ||
  645. crypto_bignum_mulmod(K, sae->tmp->peer_commit_element_ffc,
  646. sae->tmp->prime, K) < 0 ||
  647. crypto_bignum_exptmod(K, sae->tmp->sae_rand, sae->tmp->prime, K) < 0
  648. ||
  649. crypto_bignum_is_one(K) ||
  650. crypto_bignum_to_bin(K, k, SAE_MAX_PRIME_LEN, sae->tmp->prime_len) <
  651. 0) {
  652. wpa_printf(MSG_DEBUG, "SAE: Failed to calculate K and k");
  653. goto fail;
  654. }
  655. wpa_hexdump_key(MSG_DEBUG, "SAE: k", k, sae->tmp->prime_len);
  656. ret = 0;
  657. fail:
  658. crypto_bignum_deinit(K, 1);
  659. return ret;
  660. }
  661. static int sae_derive_keys(struct sae_data *sae, const u8 *k)
  662. {
  663. u8 null_key[SAE_KEYSEED_KEY_LEN], val[SAE_MAX_PRIME_LEN];
  664. u8 keyseed[SHA256_MAC_LEN];
  665. u8 keys[SAE_KCK_LEN + SAE_PMK_LEN];
  666. struct crypto_bignum *tmp;
  667. int ret = -1;
  668. tmp = crypto_bignum_init();
  669. if (tmp == NULL)
  670. goto fail;
  671. /* keyseed = H(<0>32, k)
  672. * KCK || PMK = KDF-512(keyseed, "SAE KCK and PMK",
  673. * (commit-scalar + peer-commit-scalar) modulo r)
  674. * PMKID = L((commit-scalar + peer-commit-scalar) modulo r, 0, 128)
  675. */
  676. os_memset(null_key, 0, sizeof(null_key));
  677. hmac_sha256(null_key, sizeof(null_key), k, sae->tmp->prime_len,
  678. keyseed);
  679. wpa_hexdump_key(MSG_DEBUG, "SAE: keyseed", keyseed, sizeof(keyseed));
  680. crypto_bignum_add(sae->tmp->own_commit_scalar, sae->peer_commit_scalar,
  681. tmp);
  682. crypto_bignum_mod(tmp, sae->tmp->order, tmp);
  683. crypto_bignum_to_bin(tmp, val, sizeof(val), sae->tmp->prime_len);
  684. wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN);
  685. if (sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK",
  686. val, sae->tmp->prime_len, keys, sizeof(keys)) < 0)
  687. goto fail;
  688. os_memset(keyseed, 0, sizeof(keyseed));
  689. os_memcpy(sae->tmp->kck, keys, SAE_KCK_LEN);
  690. os_memcpy(sae->pmk, keys + SAE_KCK_LEN, SAE_PMK_LEN);
  691. os_memcpy(sae->pmkid, val, SAE_PMKID_LEN);
  692. os_memset(keys, 0, sizeof(keys));
  693. wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", sae->tmp->kck, SAE_KCK_LEN);
  694. wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, SAE_PMK_LEN);
  695. ret = 0;
  696. fail:
  697. crypto_bignum_deinit(tmp, 0);
  698. return ret;
  699. }
  700. int sae_process_commit(struct sae_data *sae)
  701. {
  702. u8 k[SAE_MAX_PRIME_LEN];
  703. if (sae->tmp == NULL ||
  704. (sae->tmp->ec && sae_derive_k_ecc(sae, k) < 0) ||
  705. (sae->tmp->dh && sae_derive_k_ffc(sae, k) < 0) ||
  706. sae_derive_keys(sae, k) < 0)
  707. return -1;
  708. return 0;
  709. }
  710. void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
  711. const struct wpabuf *token)
  712. {
  713. u8 *pos;
  714. if (sae->tmp == NULL)
  715. return;
  716. wpabuf_put_le16(buf, sae->group); /* Finite Cyclic Group */
  717. if (token) {
  718. wpabuf_put_buf(buf, token);
  719. wpa_hexdump(MSG_DEBUG, "SAE: Anti-clogging token",
  720. wpabuf_head(token), wpabuf_len(token));
  721. }
  722. pos = wpabuf_put(buf, sae->tmp->prime_len);
  723. crypto_bignum_to_bin(sae->tmp->own_commit_scalar, pos,
  724. sae->tmp->prime_len, sae->tmp->prime_len);
  725. wpa_hexdump(MSG_DEBUG, "SAE: own commit-scalar",
  726. pos, sae->tmp->prime_len);
  727. if (sae->tmp->ec) {
  728. pos = wpabuf_put(buf, 2 * sae->tmp->prime_len);
  729. crypto_ec_point_to_bin(sae->tmp->ec,
  730. sae->tmp->own_commit_element_ecc,
  731. pos, pos + sae->tmp->prime_len);
  732. wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(x)",
  733. pos, sae->tmp->prime_len);
  734. wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(y)",
  735. pos + sae->tmp->prime_len, sae->tmp->prime_len);
  736. } else {
  737. pos = wpabuf_put(buf, sae->tmp->prime_len);
  738. crypto_bignum_to_bin(sae->tmp->own_commit_element_ffc, pos,
  739. sae->tmp->prime_len, sae->tmp->prime_len);
  740. wpa_hexdump(MSG_DEBUG, "SAE: own commit-element",
  741. pos, sae->tmp->prime_len);
  742. }
  743. }
  744. u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group)
  745. {
  746. if (allowed_groups) {
  747. int i;
  748. for (i = 0; allowed_groups[i] > 0; i++) {
  749. if (allowed_groups[i] == group)
  750. break;
  751. }
  752. if (allowed_groups[i] != group) {
  753. wpa_printf(MSG_DEBUG, "SAE: Proposed group %u not "
  754. "enabled in the current configuration",
  755. group);
  756. return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
  757. }
  758. }
  759. if (sae->state == SAE_COMMITTED && group != sae->group) {
  760. wpa_printf(MSG_DEBUG, "SAE: Do not allow group to be changed");
  761. return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
  762. }
  763. if (group != sae->group && sae_set_group(sae, group) < 0) {
  764. wpa_printf(MSG_DEBUG, "SAE: Unsupported Finite Cyclic Group %u",
  765. group);
  766. return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
  767. }
  768. if (sae->tmp == NULL) {
  769. wpa_printf(MSG_DEBUG, "SAE: Group information not yet initialized");
  770. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  771. }
  772. if (sae->tmp->dh && !allowed_groups) {
  773. wpa_printf(MSG_DEBUG, "SAE: Do not allow FFC group %u without "
  774. "explicit configuration enabling it", group);
  775. return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
  776. }
  777. return WLAN_STATUS_SUCCESS;
  778. }
  779. static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos,
  780. const u8 *end, const u8 **token,
  781. size_t *token_len)
  782. {
  783. if ((sae->tmp->ec ? 3 : 2) * sae->tmp->prime_len < end - *pos) {
  784. size_t tlen = end - (*pos + (sae->tmp->ec ? 3 : 2) *
  785. sae->tmp->prime_len);
  786. wpa_hexdump(MSG_DEBUG, "SAE: Anti-Clogging Token", *pos, tlen);
  787. if (token)
  788. *token = *pos;
  789. if (token_len)
  790. *token_len = tlen;
  791. *pos += tlen;
  792. } else {
  793. if (token)
  794. *token = NULL;
  795. if (token_len)
  796. *token_len = 0;
  797. }
  798. }
  799. static u16 sae_parse_commit_scalar(struct sae_data *sae, const u8 **pos,
  800. const u8 *end)
  801. {
  802. struct crypto_bignum *peer_scalar;
  803. if (sae->tmp->prime_len > end - *pos) {
  804. wpa_printf(MSG_DEBUG, "SAE: Not enough data for scalar");
  805. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  806. }
  807. peer_scalar = crypto_bignum_init_set(*pos, sae->tmp->prime_len);
  808. if (peer_scalar == NULL)
  809. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  810. /*
  811. * IEEE Std 802.11-2012, 11.3.8.6.1: If there is a protocol instance for
  812. * the peer and it is in Authenticated state, the new Commit Message
  813. * shall be dropped if the peer-scalar is identical to the one used in
  814. * the existing protocol instance.
  815. */
  816. if (sae->state == SAE_ACCEPTED && sae->peer_commit_scalar &&
  817. crypto_bignum_cmp(sae->peer_commit_scalar, peer_scalar) == 0) {
  818. wpa_printf(MSG_DEBUG, "SAE: Do not accept re-use of previous "
  819. "peer-commit-scalar");
  820. crypto_bignum_deinit(peer_scalar, 0);
  821. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  822. }
  823. /* 1 < scalar < r */
  824. if (crypto_bignum_is_zero(peer_scalar) ||
  825. crypto_bignum_is_one(peer_scalar) ||
  826. crypto_bignum_cmp(peer_scalar, sae->tmp->order) >= 0) {
  827. wpa_printf(MSG_DEBUG, "SAE: Invalid peer scalar");
  828. crypto_bignum_deinit(peer_scalar, 0);
  829. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  830. }
  831. crypto_bignum_deinit(sae->peer_commit_scalar, 0);
  832. sae->peer_commit_scalar = peer_scalar;
  833. wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-scalar",
  834. *pos, sae->tmp->prime_len);
  835. *pos += sae->tmp->prime_len;
  836. return WLAN_STATUS_SUCCESS;
  837. }
  838. static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 *pos,
  839. const u8 *end)
  840. {
  841. u8 prime[SAE_MAX_ECC_PRIME_LEN];
  842. if (2 * sae->tmp->prime_len > end - pos) {
  843. wpa_printf(MSG_DEBUG, "SAE: Not enough data for "
  844. "commit-element");
  845. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  846. }
  847. if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
  848. sae->tmp->prime_len) < 0)
  849. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  850. /* element x and y coordinates < p */
  851. if (os_memcmp(pos, prime, sae->tmp->prime_len) >= 0 ||
  852. os_memcmp(pos + sae->tmp->prime_len, prime,
  853. sae->tmp->prime_len) >= 0) {
  854. wpa_printf(MSG_DEBUG, "SAE: Invalid coordinates in peer "
  855. "element");
  856. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  857. }
  858. wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(x)",
  859. pos, sae->tmp->prime_len);
  860. wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(y)",
  861. pos + sae->tmp->prime_len, sae->tmp->prime_len);
  862. crypto_ec_point_deinit(sae->tmp->peer_commit_element_ecc, 0);
  863. sae->tmp->peer_commit_element_ecc =
  864. crypto_ec_point_from_bin(sae->tmp->ec, pos);
  865. if (sae->tmp->peer_commit_element_ecc == NULL)
  866. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  867. if (!crypto_ec_point_is_on_curve(sae->tmp->ec,
  868. sae->tmp->peer_commit_element_ecc)) {
  869. wpa_printf(MSG_DEBUG, "SAE: Peer element is not on curve");
  870. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  871. }
  872. return WLAN_STATUS_SUCCESS;
  873. }
  874. static u16 sae_parse_commit_element_ffc(struct sae_data *sae, const u8 *pos,
  875. const u8 *end)
  876. {
  877. struct crypto_bignum *res, *one;
  878. const u8 one_bin[1] = { 0x01 };
  879. if (sae->tmp->prime_len > end - pos) {
  880. wpa_printf(MSG_DEBUG, "SAE: Not enough data for "
  881. "commit-element");
  882. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  883. }
  884. wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element", pos,
  885. sae->tmp->prime_len);
  886. crypto_bignum_deinit(sae->tmp->peer_commit_element_ffc, 0);
  887. sae->tmp->peer_commit_element_ffc =
  888. crypto_bignum_init_set(pos, sae->tmp->prime_len);
  889. if (sae->tmp->peer_commit_element_ffc == NULL)
  890. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  891. /* 1 < element < p - 1 */
  892. res = crypto_bignum_init();
  893. one = crypto_bignum_init_set(one_bin, sizeof(one_bin));
  894. if (!res || !one ||
  895. crypto_bignum_sub(sae->tmp->prime, one, res) ||
  896. crypto_bignum_is_zero(sae->tmp->peer_commit_element_ffc) ||
  897. crypto_bignum_is_one(sae->tmp->peer_commit_element_ffc) ||
  898. crypto_bignum_cmp(sae->tmp->peer_commit_element_ffc, res) >= 0) {
  899. crypto_bignum_deinit(res, 0);
  900. crypto_bignum_deinit(one, 0);
  901. wpa_printf(MSG_DEBUG, "SAE: Invalid peer element");
  902. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  903. }
  904. crypto_bignum_deinit(one, 0);
  905. /* scalar-op(r, ELEMENT) = 1 modulo p */
  906. if (crypto_bignum_exptmod(sae->tmp->peer_commit_element_ffc,
  907. sae->tmp->order, sae->tmp->prime, res) < 0 ||
  908. !crypto_bignum_is_one(res)) {
  909. wpa_printf(MSG_DEBUG, "SAE: Invalid peer element (scalar-op)");
  910. crypto_bignum_deinit(res, 0);
  911. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  912. }
  913. crypto_bignum_deinit(res, 0);
  914. return WLAN_STATUS_SUCCESS;
  915. }
  916. static u16 sae_parse_commit_element(struct sae_data *sae, const u8 *pos,
  917. const u8 *end)
  918. {
  919. if (sae->tmp->dh)
  920. return sae_parse_commit_element_ffc(sae, pos, end);
  921. return sae_parse_commit_element_ecc(sae, pos, end);
  922. }
  923. u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
  924. const u8 **token, size_t *token_len, int *allowed_groups)
  925. {
  926. const u8 *pos = data, *end = data + len;
  927. u16 res;
  928. /* Check Finite Cyclic Group */
  929. if (end - pos < 2)
  930. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  931. res = sae_group_allowed(sae, allowed_groups, WPA_GET_LE16(pos));
  932. if (res != WLAN_STATUS_SUCCESS)
  933. return res;
  934. pos += 2;
  935. /* Optional Anti-Clogging Token */
  936. sae_parse_commit_token(sae, &pos, end, token, token_len);
  937. /* commit-scalar */
  938. res = sae_parse_commit_scalar(sae, &pos, end);
  939. if (res != WLAN_STATUS_SUCCESS)
  940. return res;
  941. /* commit-element */
  942. res = sae_parse_commit_element(sae, pos, end);
  943. if (res != WLAN_STATUS_SUCCESS)
  944. return res;
  945. /*
  946. * Check whether peer-commit-scalar and PEER-COMMIT-ELEMENT are same as
  947. * the values we sent which would be evidence of a reflection attack.
  948. */
  949. if (!sae->tmp->own_commit_scalar ||
  950. crypto_bignum_cmp(sae->tmp->own_commit_scalar,
  951. sae->peer_commit_scalar) != 0 ||
  952. (sae->tmp->dh &&
  953. (!sae->tmp->own_commit_element_ffc ||
  954. crypto_bignum_cmp(sae->tmp->own_commit_element_ffc,
  955. sae->tmp->peer_commit_element_ffc) != 0)) ||
  956. (sae->tmp->ec &&
  957. (!sae->tmp->own_commit_element_ecc ||
  958. crypto_ec_point_cmp(sae->tmp->ec,
  959. sae->tmp->own_commit_element_ecc,
  960. sae->tmp->peer_commit_element_ecc) != 0)))
  961. return WLAN_STATUS_SUCCESS; /* scalars/elements are different */
  962. /*
  963. * This is a reflection attack - return special value to trigger caller
  964. * to silently discard the frame instead of replying with a specific
  965. * status code.
  966. */
  967. return SAE_SILENTLY_DISCARD;
  968. }
  969. static void sae_cn_confirm(struct sae_data *sae, const u8 *sc,
  970. const struct crypto_bignum *scalar1,
  971. const u8 *element1, size_t element1_len,
  972. const struct crypto_bignum *scalar2,
  973. const u8 *element2, size_t element2_len,
  974. u8 *confirm)
  975. {
  976. const u8 *addr[5];
  977. size_t len[5];
  978. u8 scalar_b1[SAE_MAX_PRIME_LEN], scalar_b2[SAE_MAX_PRIME_LEN];
  979. /* Confirm
  980. * CN(key, X, Y, Z, ...) =
  981. * HMAC-SHA256(key, D2OS(X) || D2OS(Y) || D2OS(Z) | ...)
  982. * confirm = CN(KCK, send-confirm, commit-scalar, COMMIT-ELEMENT,
  983. * peer-commit-scalar, PEER-COMMIT-ELEMENT)
  984. * verifier = CN(KCK, peer-send-confirm, peer-commit-scalar,
  985. * PEER-COMMIT-ELEMENT, commit-scalar, COMMIT-ELEMENT)
  986. */
  987. addr[0] = sc;
  988. len[0] = 2;
  989. crypto_bignum_to_bin(scalar1, scalar_b1, sizeof(scalar_b1),
  990. sae->tmp->prime_len);
  991. addr[1] = scalar_b1;
  992. len[1] = sae->tmp->prime_len;
  993. addr[2] = element1;
  994. len[2] = element1_len;
  995. crypto_bignum_to_bin(scalar2, scalar_b2, sizeof(scalar_b2),
  996. sae->tmp->prime_len);
  997. addr[3] = scalar_b2;
  998. len[3] = sae->tmp->prime_len;
  999. addr[4] = element2;
  1000. len[4] = element2_len;
  1001. hmac_sha256_vector(sae->tmp->kck, sizeof(sae->tmp->kck), 5, addr, len,
  1002. confirm);
  1003. }
  1004. static void sae_cn_confirm_ecc(struct sae_data *sae, const u8 *sc,
  1005. const struct crypto_bignum *scalar1,
  1006. const struct crypto_ec_point *element1,
  1007. const struct crypto_bignum *scalar2,
  1008. const struct crypto_ec_point *element2,
  1009. u8 *confirm)
  1010. {
  1011. u8 element_b1[2 * SAE_MAX_ECC_PRIME_LEN];
  1012. u8 element_b2[2 * SAE_MAX_ECC_PRIME_LEN];
  1013. crypto_ec_point_to_bin(sae->tmp->ec, element1, element_b1,
  1014. element_b1 + sae->tmp->prime_len);
  1015. crypto_ec_point_to_bin(sae->tmp->ec, element2, element_b2,
  1016. element_b2 + sae->tmp->prime_len);
  1017. sae_cn_confirm(sae, sc, scalar1, element_b1, 2 * sae->tmp->prime_len,
  1018. scalar2, element_b2, 2 * sae->tmp->prime_len, confirm);
  1019. }
  1020. static void sae_cn_confirm_ffc(struct sae_data *sae, const u8 *sc,
  1021. const struct crypto_bignum *scalar1,
  1022. const struct crypto_bignum *element1,
  1023. const struct crypto_bignum *scalar2,
  1024. const struct crypto_bignum *element2,
  1025. u8 *confirm)
  1026. {
  1027. u8 element_b1[SAE_MAX_PRIME_LEN];
  1028. u8 element_b2[SAE_MAX_PRIME_LEN];
  1029. crypto_bignum_to_bin(element1, element_b1, sizeof(element_b1),
  1030. sae->tmp->prime_len);
  1031. crypto_bignum_to_bin(element2, element_b2, sizeof(element_b2),
  1032. sae->tmp->prime_len);
  1033. sae_cn_confirm(sae, sc, scalar1, element_b1, sae->tmp->prime_len,
  1034. scalar2, element_b2, sae->tmp->prime_len, confirm);
  1035. }
  1036. void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf)
  1037. {
  1038. const u8 *sc;
  1039. if (sae->tmp == NULL)
  1040. return;
  1041. /* Send-Confirm */
  1042. sc = wpabuf_put(buf, 0);
  1043. wpabuf_put_le16(buf, sae->send_confirm);
  1044. if (sae->send_confirm < 0xffff)
  1045. sae->send_confirm++;
  1046. if (sae->tmp->ec)
  1047. sae_cn_confirm_ecc(sae, sc, sae->tmp->own_commit_scalar,
  1048. sae->tmp->own_commit_element_ecc,
  1049. sae->peer_commit_scalar,
  1050. sae->tmp->peer_commit_element_ecc,
  1051. wpabuf_put(buf, SHA256_MAC_LEN));
  1052. else
  1053. sae_cn_confirm_ffc(sae, sc, sae->tmp->own_commit_scalar,
  1054. sae->tmp->own_commit_element_ffc,
  1055. sae->peer_commit_scalar,
  1056. sae->tmp->peer_commit_element_ffc,
  1057. wpabuf_put(buf, SHA256_MAC_LEN));
  1058. }
  1059. int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len)
  1060. {
  1061. u8 verifier[SHA256_MAC_LEN];
  1062. if (len < 2 + SHA256_MAC_LEN) {
  1063. wpa_printf(MSG_DEBUG, "SAE: Too short confirm message");
  1064. return -1;
  1065. }
  1066. wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", WPA_GET_LE16(data));
  1067. if (sae->tmp == NULL) {
  1068. wpa_printf(MSG_DEBUG, "SAE: Temporary data not yet available");
  1069. return -1;
  1070. }
  1071. if (sae->tmp->ec)
  1072. sae_cn_confirm_ecc(sae, data, sae->peer_commit_scalar,
  1073. sae->tmp->peer_commit_element_ecc,
  1074. sae->tmp->own_commit_scalar,
  1075. sae->tmp->own_commit_element_ecc,
  1076. verifier);
  1077. else
  1078. sae_cn_confirm_ffc(sae, data, sae->peer_commit_scalar,
  1079. sae->tmp->peer_commit_element_ffc,
  1080. sae->tmp->own_commit_scalar,
  1081. sae->tmp->own_commit_element_ffc,
  1082. verifier);
  1083. if (os_memcmp_const(verifier, data + 2, SHA256_MAC_LEN) != 0) {
  1084. wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch");
  1085. wpa_hexdump(MSG_DEBUG, "SAE: Received confirm",
  1086. data + 2, SHA256_MAC_LEN);
  1087. wpa_hexdump(MSG_DEBUG, "SAE: Calculated verifier",
  1088. verifier, SHA256_MAC_LEN);
  1089. return -1;
  1090. }
  1091. return 0;
  1092. }
  1093. const char * sae_state_txt(enum sae_state state)
  1094. {
  1095. switch (state) {
  1096. case SAE_NOTHING:
  1097. return "Nothing";
  1098. case SAE_COMMITTED:
  1099. return "Committed";
  1100. case SAE_CONFIRMED:
  1101. return "Confirmed";
  1102. case SAE_ACCEPTED:
  1103. return "Accepted";
  1104. }
  1105. return "?";
  1106. }