sae.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. /*
  2. * Simultaneous authentication of equals
  3. * Copyright (c) 2012-2013, 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)
  107. return NULL;
  108. if (random_get_bytes(val, order_len) < 0)
  109. return NULL;
  110. if (order_len_bits % 8)
  111. buf_shift_right(val, order_len, 8 - order_len_bits % 8);
  112. bn = crypto_bignum_init_set(val, order_len);
  113. if (bn == NULL)
  114. return NULL;
  115. if (crypto_bignum_is_zero(bn) ||
  116. crypto_bignum_is_one(bn) ||
  117. crypto_bignum_cmp(bn, sae->tmp->order) >= 0) {
  118. crypto_bignum_deinit(bn, 0);
  119. continue;
  120. }
  121. break;
  122. }
  123. os_memset(val, 0, order_len);
  124. return bn;
  125. }
  126. static struct crypto_bignum * sae_get_rand_and_mask(struct sae_data *sae)
  127. {
  128. crypto_bignum_deinit(sae->tmp->sae_rand, 1);
  129. sae->tmp->sae_rand = sae_get_rand(sae);
  130. if (sae->tmp->sae_rand == NULL)
  131. return NULL;
  132. return sae_get_rand(sae);
  133. }
  134. static void sae_pwd_seed_key(const u8 *addr1, const u8 *addr2, u8 *key)
  135. {
  136. wpa_printf(MSG_DEBUG, "SAE: PWE derivation - addr1=" MACSTR
  137. " addr2=" MACSTR, MAC2STR(addr1), MAC2STR(addr2));
  138. if (os_memcmp(addr1, addr2, ETH_ALEN) > 0) {
  139. os_memcpy(key, addr1, ETH_ALEN);
  140. os_memcpy(key + ETH_ALEN, addr2, ETH_ALEN);
  141. } else {
  142. os_memcpy(key, addr2, ETH_ALEN);
  143. os_memcpy(key + ETH_ALEN, addr1, ETH_ALEN);
  144. }
  145. }
  146. static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed,
  147. struct crypto_ec_point *pwe)
  148. {
  149. u8 pwd_value[SAE_MAX_ECC_PRIME_LEN], prime[SAE_MAX_ECC_PRIME_LEN];
  150. struct crypto_bignum *x;
  151. int y_bit;
  152. size_t bits;
  153. if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
  154. sae->tmp->prime_len) < 0)
  155. return -1;
  156. wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
  157. /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
  158. bits = crypto_ec_prime_len_bits(sae->tmp->ec);
  159. sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
  160. prime, sae->tmp->prime_len, pwd_value, bits);
  161. if (bits % 8)
  162. buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8);
  163. wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
  164. pwd_value, sae->tmp->prime_len);
  165. if (os_memcmp(pwd_value, prime, sae->tmp->prime_len) >= 0)
  166. return 0;
  167. y_bit = pwd_seed[SHA256_MAC_LEN - 1] & 0x01;
  168. x = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
  169. if (x == NULL)
  170. return -1;
  171. if (crypto_ec_point_solve_y_coord(sae->tmp->ec, pwe, x, y_bit) < 0) {
  172. crypto_bignum_deinit(x, 0);
  173. wpa_printf(MSG_DEBUG, "SAE: No solution found");
  174. return 0;
  175. }
  176. crypto_bignum_deinit(x, 0);
  177. wpa_printf(MSG_DEBUG, "SAE: PWE found");
  178. return 1;
  179. }
  180. static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed,
  181. struct crypto_bignum *pwe)
  182. {
  183. u8 pwd_value[SAE_MAX_PRIME_LEN];
  184. size_t bits = sae->tmp->prime_len * 8;
  185. u8 exp[1];
  186. struct crypto_bignum *a, *b;
  187. int res;
  188. wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
  189. /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
  190. sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
  191. sae->tmp->dh->prime, sae->tmp->prime_len, pwd_value,
  192. bits);
  193. if (bits % 8)
  194. buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8);
  195. wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", pwd_value,
  196. sae->tmp->prime_len);
  197. if (os_memcmp(pwd_value, sae->tmp->dh->prime, sae->tmp->prime_len) >= 0)
  198. {
  199. wpa_printf(MSG_DEBUG, "SAE: pwd-value >= p");
  200. return 0;
  201. }
  202. /* PWE = pwd-value^((p-1)/r) modulo p */
  203. a = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
  204. if (sae->tmp->dh->safe_prime) {
  205. /*
  206. * r = (p-1)/2 for the group used here, so this becomes:
  207. * PWE = pwd-value^2 modulo p
  208. */
  209. exp[0] = 2;
  210. b = crypto_bignum_init_set(exp, sizeof(exp));
  211. } else {
  212. /* Calculate exponent: (p-1)/r */
  213. exp[0] = 1;
  214. b = crypto_bignum_init_set(exp, sizeof(exp));
  215. if (b == NULL ||
  216. crypto_bignum_sub(sae->tmp->prime, b, b) < 0 ||
  217. crypto_bignum_div(b, sae->tmp->order, b) < 0) {
  218. crypto_bignum_deinit(b, 0);
  219. b = NULL;
  220. }
  221. }
  222. if (a == NULL || b == NULL)
  223. res = -1;
  224. else
  225. res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
  226. crypto_bignum_deinit(a, 0);
  227. crypto_bignum_deinit(b, 0);
  228. if (res < 0) {
  229. wpa_printf(MSG_DEBUG, "SAE: Failed to calculate PWE");
  230. return -1;
  231. }
  232. /* if (PWE > 1) --> found */
  233. if (crypto_bignum_is_zero(pwe) || crypto_bignum_is_one(pwe)) {
  234. wpa_printf(MSG_DEBUG, "SAE: PWE <= 1");
  235. return 0;
  236. }
  237. wpa_printf(MSG_DEBUG, "SAE: PWE found");
  238. return 1;
  239. }
  240. static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
  241. const u8 *addr2, const u8 *password,
  242. size_t password_len)
  243. {
  244. u8 counter, k = 4;
  245. u8 addrs[2 * ETH_ALEN];
  246. const u8 *addr[2];
  247. size_t len[2];
  248. int found = 0;
  249. struct crypto_ec_point *pwe_tmp;
  250. if (sae->tmp->pwe_ecc == NULL) {
  251. sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec);
  252. if (sae->tmp->pwe_ecc == NULL)
  253. return -1;
  254. }
  255. pwe_tmp = crypto_ec_point_init(sae->tmp->ec);
  256. if (pwe_tmp == NULL)
  257. return -1;
  258. wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
  259. password, password_len);
  260. /*
  261. * H(salt, ikm) = HMAC-SHA256(salt, ikm)
  262. * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
  263. * password || counter)
  264. */
  265. sae_pwd_seed_key(addr1, addr2, addrs);
  266. addr[0] = password;
  267. len[0] = password_len;
  268. addr[1] = &counter;
  269. len[1] = sizeof(counter);
  270. /*
  271. * Continue for at least k iterations to protect against side-channel
  272. * attacks that attempt to determine the number of iterations required
  273. * in the loop.
  274. */
  275. for (counter = 1; counter < k || !found; counter++) {
  276. u8 pwd_seed[SHA256_MAC_LEN];
  277. int res;
  278. if (counter > 200) {
  279. /* This should not happen in practice */
  280. wpa_printf(MSG_DEBUG, "SAE: Failed to derive PWE");
  281. break;
  282. }
  283. wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
  284. if (hmac_sha256_vector(addrs, sizeof(addrs), 2, addr, len,
  285. pwd_seed) < 0)
  286. break;
  287. res = sae_test_pwd_seed_ecc(sae, pwd_seed,
  288. found ? pwe_tmp :
  289. sae->tmp->pwe_ecc);
  290. if (res < 0)
  291. break;
  292. if (res == 0)
  293. continue;
  294. if (found) {
  295. wpa_printf(MSG_DEBUG, "SAE: Ignore this PWE (one was "
  296. "already selected)");
  297. } else {
  298. wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
  299. found = 1;
  300. }
  301. }
  302. crypto_ec_point_deinit(pwe_tmp, 1);
  303. return found ? 0 : -1;
  304. }
  305. static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
  306. const u8 *addr2, const u8 *password,
  307. size_t password_len)
  308. {
  309. u8 counter;
  310. u8 addrs[2 * ETH_ALEN];
  311. const u8 *addr[2];
  312. size_t len[2];
  313. int found = 0;
  314. if (sae->tmp->pwe_ffc == NULL) {
  315. sae->tmp->pwe_ffc = crypto_bignum_init();
  316. if (sae->tmp->pwe_ffc == NULL)
  317. return -1;
  318. }
  319. wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
  320. password, password_len);
  321. /*
  322. * H(salt, ikm) = HMAC-SHA256(salt, ikm)
  323. * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
  324. * password || counter)
  325. */
  326. sae_pwd_seed_key(addr1, addr2, addrs);
  327. addr[0] = password;
  328. len[0] = password_len;
  329. addr[1] = &counter;
  330. len[1] = sizeof(counter);
  331. for (counter = 1; !found; counter++) {
  332. u8 pwd_seed[SHA256_MAC_LEN];
  333. int res;
  334. if (counter > 200) {
  335. /* This should not happen in practice */
  336. wpa_printf(MSG_DEBUG, "SAE: Failed to derive PWE");
  337. break;
  338. }
  339. wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
  340. if (hmac_sha256_vector(addrs, sizeof(addrs), 2, addr, len,
  341. pwd_seed) < 0)
  342. break;
  343. res = sae_test_pwd_seed_ffc(sae, pwd_seed, sae->tmp->pwe_ffc);
  344. if (res < 0)
  345. break;
  346. if (res > 0) {
  347. wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
  348. found = 1;
  349. }
  350. }
  351. return found ? 0 : -1;
  352. }
  353. static int sae_derive_commit_element_ecc(struct sae_data *sae,
  354. struct crypto_bignum *mask)
  355. {
  356. /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */
  357. if (!sae->tmp->own_commit_element_ecc) {
  358. sae->tmp->own_commit_element_ecc =
  359. crypto_ec_point_init(sae->tmp->ec);
  360. if (!sae->tmp->own_commit_element_ecc)
  361. return -1;
  362. }
  363. if (crypto_ec_point_mul(sae->tmp->ec, sae->tmp->pwe_ecc, mask,
  364. sae->tmp->own_commit_element_ecc) < 0 ||
  365. crypto_ec_point_invert(sae->tmp->ec,
  366. sae->tmp->own_commit_element_ecc) < 0) {
  367. wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element");
  368. return -1;
  369. }
  370. return 0;
  371. }
  372. static int sae_derive_commit_element_ffc(struct sae_data *sae,
  373. struct crypto_bignum *mask)
  374. {
  375. /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */
  376. if (!sae->tmp->own_commit_element_ffc) {
  377. sae->tmp->own_commit_element_ffc = crypto_bignum_init();
  378. if (!sae->tmp->own_commit_element_ffc)
  379. return -1;
  380. }
  381. if (crypto_bignum_exptmod(sae->tmp->pwe_ffc, mask, sae->tmp->prime,
  382. sae->tmp->own_commit_element_ffc) < 0 ||
  383. crypto_bignum_inverse(sae->tmp->own_commit_element_ffc,
  384. sae->tmp->prime,
  385. sae->tmp->own_commit_element_ffc) < 0) {
  386. wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element");
  387. return -1;
  388. }
  389. return 0;
  390. }
  391. static int sae_derive_commit(struct sae_data *sae)
  392. {
  393. struct crypto_bignum *mask;
  394. int ret = -1;
  395. mask = sae_get_rand_and_mask(sae);
  396. if (mask == NULL) {
  397. wpa_printf(MSG_DEBUG, "SAE: Could not get rand/mask");
  398. return -1;
  399. }
  400. /* commit-scalar = (rand + mask) modulo r */
  401. if (!sae->tmp->own_commit_scalar) {
  402. sae->tmp->own_commit_scalar = crypto_bignum_init();
  403. if (!sae->tmp->own_commit_scalar)
  404. goto fail;
  405. }
  406. crypto_bignum_add(sae->tmp->sae_rand, mask,
  407. sae->tmp->own_commit_scalar);
  408. crypto_bignum_mod(sae->tmp->own_commit_scalar, sae->tmp->order,
  409. sae->tmp->own_commit_scalar);
  410. if (sae->tmp->ec && sae_derive_commit_element_ecc(sae, mask) < 0)
  411. goto fail;
  412. if (sae->tmp->dh && sae_derive_commit_element_ffc(sae, mask) < 0)
  413. goto fail;
  414. ret = 0;
  415. fail:
  416. crypto_bignum_deinit(mask, 1);
  417. return ret;
  418. }
  419. int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
  420. const u8 *password, size_t password_len,
  421. struct sae_data *sae)
  422. {
  423. if (sae->tmp == NULL)
  424. return -1;
  425. if (sae->tmp->ec && sae_derive_pwe_ecc(sae, addr1, addr2, password,
  426. password_len) < 0)
  427. return -1;
  428. if (sae->tmp->dh && sae_derive_pwe_ffc(sae, addr1, addr2, password,
  429. password_len) < 0)
  430. return -1;
  431. if (sae_derive_commit(sae) < 0)
  432. return -1;
  433. return 0;
  434. }
  435. static int sae_derive_k_ecc(struct sae_data *sae, u8 *k)
  436. {
  437. struct crypto_ec_point *K;
  438. int ret = -1;
  439. K = crypto_ec_point_init(sae->tmp->ec);
  440. if (K == NULL)
  441. goto fail;
  442. /*
  443. * K = scalar-op(rand, (elem-op(scalar-op(peer-commit-scalar, PWE),
  444. * PEER-COMMIT-ELEMENT)))
  445. * If K is identity element (point-at-infinity), reject
  446. * k = F(K) (= x coordinate)
  447. */
  448. if (crypto_ec_point_mul(sae->tmp->ec, sae->tmp->pwe_ecc,
  449. sae->peer_commit_scalar, K) < 0 ||
  450. crypto_ec_point_add(sae->tmp->ec, K,
  451. sae->tmp->peer_commit_element_ecc, K) < 0 ||
  452. crypto_ec_point_mul(sae->tmp->ec, K, sae->tmp->sae_rand, K) < 0 ||
  453. crypto_ec_point_is_at_infinity(sae->tmp->ec, K) ||
  454. crypto_ec_point_to_bin(sae->tmp->ec, K, k, NULL) < 0) {
  455. wpa_printf(MSG_DEBUG, "SAE: Failed to calculate K and k");
  456. goto fail;
  457. }
  458. wpa_hexdump_key(MSG_DEBUG, "SAE: k", k, sae->tmp->prime_len);
  459. ret = 0;
  460. fail:
  461. crypto_ec_point_deinit(K, 1);
  462. return ret;
  463. }
  464. static int sae_derive_k_ffc(struct sae_data *sae, u8 *k)
  465. {
  466. struct crypto_bignum *K;
  467. int ret = -1;
  468. K = crypto_bignum_init();
  469. if (K == NULL)
  470. goto fail;
  471. /*
  472. * K = scalar-op(rand, (elem-op(scalar-op(peer-commit-scalar, PWE),
  473. * PEER-COMMIT-ELEMENT)))
  474. * If K is identity element (one), reject.
  475. * k = F(K) (= x coordinate)
  476. */
  477. if (crypto_bignum_exptmod(sae->tmp->pwe_ffc, sae->peer_commit_scalar,
  478. sae->tmp->prime, K) < 0 ||
  479. crypto_bignum_mulmod(K, sae->tmp->peer_commit_element_ffc,
  480. sae->tmp->prime, K) < 0 ||
  481. crypto_bignum_exptmod(K, sae->tmp->sae_rand, sae->tmp->prime, K) < 0
  482. ||
  483. crypto_bignum_is_one(K) ||
  484. crypto_bignum_to_bin(K, k, SAE_MAX_PRIME_LEN, sae->tmp->prime_len) <
  485. 0) {
  486. wpa_printf(MSG_DEBUG, "SAE: Failed to calculate K and k");
  487. goto fail;
  488. }
  489. wpa_hexdump_key(MSG_DEBUG, "SAE: k", k, sae->tmp->prime_len);
  490. ret = 0;
  491. fail:
  492. crypto_bignum_deinit(K, 1);
  493. return ret;
  494. }
  495. static int sae_derive_keys(struct sae_data *sae, const u8 *k)
  496. {
  497. u8 null_key[SAE_KEYSEED_KEY_LEN], val[SAE_MAX_PRIME_LEN];
  498. u8 keyseed[SHA256_MAC_LEN];
  499. u8 keys[SAE_KCK_LEN + SAE_PMK_LEN];
  500. struct crypto_bignum *tmp;
  501. int ret = -1;
  502. tmp = crypto_bignum_init();
  503. if (tmp == NULL)
  504. goto fail;
  505. /* keyseed = H(<0>32, k)
  506. * KCK || PMK = KDF-512(keyseed, "SAE KCK and PMK",
  507. * (commit-scalar + peer-commit-scalar) modulo r)
  508. * PMKID = L((commit-scalar + peer-commit-scalar) modulo r, 0, 128)
  509. */
  510. os_memset(null_key, 0, sizeof(null_key));
  511. hmac_sha256(null_key, sizeof(null_key), k, sae->tmp->prime_len,
  512. keyseed);
  513. wpa_hexdump_key(MSG_DEBUG, "SAE: keyseed", keyseed, sizeof(keyseed));
  514. crypto_bignum_add(sae->tmp->own_commit_scalar, sae->peer_commit_scalar,
  515. tmp);
  516. crypto_bignum_mod(tmp, sae->tmp->order, tmp);
  517. crypto_bignum_to_bin(tmp, val, sizeof(val), sae->tmp->prime_len);
  518. wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN);
  519. sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK",
  520. val, sae->tmp->prime_len, keys, sizeof(keys));
  521. os_memset(keyseed, 0, sizeof(keyseed));
  522. os_memcpy(sae->tmp->kck, keys, SAE_KCK_LEN);
  523. os_memcpy(sae->pmk, keys + SAE_KCK_LEN, SAE_PMK_LEN);
  524. os_memset(keys, 0, sizeof(keys));
  525. wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", sae->tmp->kck, SAE_KCK_LEN);
  526. wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, SAE_PMK_LEN);
  527. ret = 0;
  528. fail:
  529. crypto_bignum_deinit(tmp, 0);
  530. return ret;
  531. }
  532. int sae_process_commit(struct sae_data *sae)
  533. {
  534. u8 k[SAE_MAX_PRIME_LEN];
  535. if (sae->tmp == NULL ||
  536. (sae->tmp->ec && sae_derive_k_ecc(sae, k) < 0) ||
  537. (sae->tmp->dh && sae_derive_k_ffc(sae, k) < 0) ||
  538. sae_derive_keys(sae, k) < 0)
  539. return -1;
  540. return 0;
  541. }
  542. void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
  543. const struct wpabuf *token)
  544. {
  545. u8 *pos;
  546. if (sae->tmp == NULL)
  547. return;
  548. wpabuf_put_le16(buf, sae->group); /* Finite Cyclic Group */
  549. if (token) {
  550. wpabuf_put_buf(buf, token);
  551. wpa_hexdump(MSG_DEBUG, "SAE: Anti-clogging token",
  552. wpabuf_head(token), wpabuf_len(token));
  553. }
  554. pos = wpabuf_put(buf, sae->tmp->prime_len);
  555. crypto_bignum_to_bin(sae->tmp->own_commit_scalar, pos,
  556. sae->tmp->prime_len, sae->tmp->prime_len);
  557. wpa_hexdump(MSG_DEBUG, "SAE: own commit-scalar",
  558. pos, sae->tmp->prime_len);
  559. if (sae->tmp->ec) {
  560. pos = wpabuf_put(buf, 2 * sae->tmp->prime_len);
  561. crypto_ec_point_to_bin(sae->tmp->ec,
  562. sae->tmp->own_commit_element_ecc,
  563. pos, pos + sae->tmp->prime_len);
  564. wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(x)",
  565. pos, sae->tmp->prime_len);
  566. wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(y)",
  567. pos + sae->tmp->prime_len, sae->tmp->prime_len);
  568. } else {
  569. pos = wpabuf_put(buf, sae->tmp->prime_len);
  570. crypto_bignum_to_bin(sae->tmp->own_commit_element_ffc, pos,
  571. sae->tmp->prime_len, sae->tmp->prime_len);
  572. wpa_hexdump(MSG_DEBUG, "SAE: own commit-element",
  573. pos, sae->tmp->prime_len);
  574. }
  575. }
  576. u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group)
  577. {
  578. if (allowed_groups) {
  579. int i;
  580. for (i = 0; allowed_groups[i] > 0; i++) {
  581. if (allowed_groups[i] == group)
  582. break;
  583. }
  584. if (allowed_groups[i] != group) {
  585. wpa_printf(MSG_DEBUG, "SAE: Proposed group %u not "
  586. "enabled in the current configuration",
  587. group);
  588. return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
  589. }
  590. }
  591. if (sae->state == SAE_COMMITTED && group != sae->group) {
  592. wpa_printf(MSG_DEBUG, "SAE: Do not allow group to be changed");
  593. return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
  594. }
  595. if (group != sae->group && sae_set_group(sae, group) < 0) {
  596. wpa_printf(MSG_DEBUG, "SAE: Unsupported Finite Cyclic Group %u",
  597. group);
  598. return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
  599. }
  600. if (sae->tmp == NULL) {
  601. wpa_printf(MSG_DEBUG, "SAE: Group information not yet initialized");
  602. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  603. }
  604. if (sae->tmp->dh && !allowed_groups) {
  605. wpa_printf(MSG_DEBUG, "SAE: Do not allow FFC group %u without "
  606. "explicit configuration enabling it", group);
  607. return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
  608. }
  609. return WLAN_STATUS_SUCCESS;
  610. }
  611. static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos,
  612. const u8 *end, const u8 **token,
  613. size_t *token_len)
  614. {
  615. if (*pos + (sae->tmp->ec ? 3 : 2) * sae->tmp->prime_len < end) {
  616. size_t tlen = end - (*pos + (sae->tmp->ec ? 3 : 2) *
  617. sae->tmp->prime_len);
  618. wpa_hexdump(MSG_DEBUG, "SAE: Anti-Clogging Token", *pos, tlen);
  619. if (token)
  620. *token = *pos;
  621. if (token_len)
  622. *token_len = tlen;
  623. *pos += tlen;
  624. } else {
  625. if (token)
  626. *token = NULL;
  627. if (token_len)
  628. *token_len = 0;
  629. }
  630. }
  631. static u16 sae_parse_commit_scalar(struct sae_data *sae, const u8 **pos,
  632. const u8 *end)
  633. {
  634. struct crypto_bignum *peer_scalar;
  635. if (*pos + sae->tmp->prime_len > end) {
  636. wpa_printf(MSG_DEBUG, "SAE: Not enough data for scalar");
  637. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  638. }
  639. peer_scalar = crypto_bignum_init_set(*pos, sae->tmp->prime_len);
  640. if (peer_scalar == NULL)
  641. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  642. /*
  643. * IEEE Std 802.11-2012, 11.3.8.6.1: If there is a protocol instance for
  644. * the peer and it is in Authenticated state, the new Commit Message
  645. * shall be dropped if the peer-scalar is identical to the one used in
  646. * the existing protocol instance.
  647. */
  648. if (sae->state == SAE_ACCEPTED && sae->peer_commit_scalar &&
  649. crypto_bignum_cmp(sae->peer_commit_scalar, peer_scalar) == 0) {
  650. wpa_printf(MSG_DEBUG, "SAE: Do not accept re-use of previous "
  651. "peer-commit-scalar");
  652. crypto_bignum_deinit(peer_scalar, 0);
  653. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  654. }
  655. /* 0 < scalar < r */
  656. if (crypto_bignum_is_zero(peer_scalar) ||
  657. crypto_bignum_cmp(peer_scalar, sae->tmp->order) >= 0) {
  658. wpa_printf(MSG_DEBUG, "SAE: Invalid peer scalar");
  659. crypto_bignum_deinit(peer_scalar, 0);
  660. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  661. }
  662. crypto_bignum_deinit(sae->peer_commit_scalar, 0);
  663. sae->peer_commit_scalar = peer_scalar;
  664. wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-scalar",
  665. *pos, sae->tmp->prime_len);
  666. *pos += sae->tmp->prime_len;
  667. return WLAN_STATUS_SUCCESS;
  668. }
  669. static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 *pos,
  670. const u8 *end)
  671. {
  672. u8 prime[SAE_MAX_ECC_PRIME_LEN];
  673. if (pos + 2 * sae->tmp->prime_len > end) {
  674. wpa_printf(MSG_DEBUG, "SAE: Not enough data for "
  675. "commit-element");
  676. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  677. }
  678. if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
  679. sae->tmp->prime_len) < 0)
  680. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  681. /* element x and y coordinates < p */
  682. if (os_memcmp(pos, prime, sae->tmp->prime_len) >= 0 ||
  683. os_memcmp(pos + sae->tmp->prime_len, prime,
  684. sae->tmp->prime_len) >= 0) {
  685. wpa_printf(MSG_DEBUG, "SAE: Invalid coordinates in peer "
  686. "element");
  687. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  688. }
  689. wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(x)",
  690. pos, sae->tmp->prime_len);
  691. wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(y)",
  692. pos + sae->tmp->prime_len, sae->tmp->prime_len);
  693. crypto_ec_point_deinit(sae->tmp->peer_commit_element_ecc, 0);
  694. sae->tmp->peer_commit_element_ecc =
  695. crypto_ec_point_from_bin(sae->tmp->ec, pos);
  696. if (sae->tmp->peer_commit_element_ecc == NULL)
  697. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  698. if (!crypto_ec_point_is_on_curve(sae->tmp->ec,
  699. sae->tmp->peer_commit_element_ecc)) {
  700. wpa_printf(MSG_DEBUG, "SAE: Peer element is not on curve");
  701. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  702. }
  703. return WLAN_STATUS_SUCCESS;
  704. }
  705. static u16 sae_parse_commit_element_ffc(struct sae_data *sae, const u8 *pos,
  706. const u8 *end)
  707. {
  708. struct crypto_bignum *res;
  709. if (pos + sae->tmp->prime_len > end) {
  710. wpa_printf(MSG_DEBUG, "SAE: Not enough data for "
  711. "commit-element");
  712. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  713. }
  714. wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element", pos,
  715. sae->tmp->prime_len);
  716. crypto_bignum_deinit(sae->tmp->peer_commit_element_ffc, 0);
  717. sae->tmp->peer_commit_element_ffc =
  718. crypto_bignum_init_set(pos, sae->tmp->prime_len);
  719. if (sae->tmp->peer_commit_element_ffc == NULL)
  720. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  721. if (crypto_bignum_is_zero(sae->tmp->peer_commit_element_ffc) ||
  722. crypto_bignum_is_one(sae->tmp->peer_commit_element_ffc) ||
  723. crypto_bignum_cmp(sae->tmp->peer_commit_element_ffc,
  724. sae->tmp->prime) >= 0) {
  725. wpa_printf(MSG_DEBUG, "SAE: Invalid peer element");
  726. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  727. }
  728. /* scalar-op(r, ELEMENT) = 1 modulo p */
  729. res = crypto_bignum_init();
  730. if (res == NULL ||
  731. crypto_bignum_exptmod(sae->tmp->peer_commit_element_ffc,
  732. sae->tmp->order, sae->tmp->prime, res) < 0 ||
  733. !crypto_bignum_is_one(res)) {
  734. wpa_printf(MSG_DEBUG, "SAE: Invalid peer element (scalar-op)");
  735. crypto_bignum_deinit(res, 0);
  736. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  737. }
  738. crypto_bignum_deinit(res, 0);
  739. return WLAN_STATUS_SUCCESS;
  740. }
  741. static u16 sae_parse_commit_element(struct sae_data *sae, const u8 *pos,
  742. const u8 *end)
  743. {
  744. if (sae->tmp->dh)
  745. return sae_parse_commit_element_ffc(sae, pos, end);
  746. return sae_parse_commit_element_ecc(sae, pos, end);
  747. }
  748. u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
  749. const u8 **token, size_t *token_len, int *allowed_groups)
  750. {
  751. const u8 *pos = data, *end = data + len;
  752. u16 res;
  753. /* Check Finite Cyclic Group */
  754. if (pos + 2 > end)
  755. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  756. res = sae_group_allowed(sae, allowed_groups, WPA_GET_LE16(pos));
  757. if (res != WLAN_STATUS_SUCCESS)
  758. return res;
  759. pos += 2;
  760. /* Optional Anti-Clogging Token */
  761. sae_parse_commit_token(sae, &pos, end, token, token_len);
  762. /* commit-scalar */
  763. res = sae_parse_commit_scalar(sae, &pos, end);
  764. if (res != WLAN_STATUS_SUCCESS)
  765. return res;
  766. /* commit-element */
  767. return sae_parse_commit_element(sae, pos, end);
  768. }
  769. static void sae_cn_confirm(struct sae_data *sae, const u8 *sc,
  770. const struct crypto_bignum *scalar1,
  771. const u8 *element1, size_t element1_len,
  772. const struct crypto_bignum *scalar2,
  773. const u8 *element2, size_t element2_len,
  774. u8 *confirm)
  775. {
  776. const u8 *addr[5];
  777. size_t len[5];
  778. u8 scalar_b1[SAE_MAX_PRIME_LEN], scalar_b2[SAE_MAX_PRIME_LEN];
  779. /* Confirm
  780. * CN(key, X, Y, Z, ...) =
  781. * HMAC-SHA256(key, D2OS(X) || D2OS(Y) || D2OS(Z) | ...)
  782. * confirm = CN(KCK, send-confirm, commit-scalar, COMMIT-ELEMENT,
  783. * peer-commit-scalar, PEER-COMMIT-ELEMENT)
  784. * verifier = CN(KCK, peer-send-confirm, peer-commit-scalar,
  785. * PEER-COMMIT-ELEMENT, commit-scalar, COMMIT-ELEMENT)
  786. */
  787. addr[0] = sc;
  788. len[0] = 2;
  789. crypto_bignum_to_bin(scalar1, scalar_b1, sizeof(scalar_b1),
  790. sae->tmp->prime_len);
  791. addr[1] = scalar_b1;
  792. len[1] = sae->tmp->prime_len;
  793. addr[2] = element1;
  794. len[2] = element1_len;
  795. crypto_bignum_to_bin(scalar2, scalar_b2, sizeof(scalar_b2),
  796. sae->tmp->prime_len);
  797. addr[3] = scalar_b2;
  798. len[3] = sae->tmp->prime_len;
  799. addr[4] = element2;
  800. len[4] = element2_len;
  801. hmac_sha256_vector(sae->tmp->kck, sizeof(sae->tmp->kck), 5, addr, len,
  802. confirm);
  803. }
  804. static void sae_cn_confirm_ecc(struct sae_data *sae, const u8 *sc,
  805. const struct crypto_bignum *scalar1,
  806. const struct crypto_ec_point *element1,
  807. const struct crypto_bignum *scalar2,
  808. const struct crypto_ec_point *element2,
  809. u8 *confirm)
  810. {
  811. u8 element_b1[2 * SAE_MAX_ECC_PRIME_LEN];
  812. u8 element_b2[2 * SAE_MAX_ECC_PRIME_LEN];
  813. crypto_ec_point_to_bin(sae->tmp->ec, element1, element_b1,
  814. element_b1 + sae->tmp->prime_len);
  815. crypto_ec_point_to_bin(sae->tmp->ec, element2, element_b2,
  816. element_b2 + sae->tmp->prime_len);
  817. sae_cn_confirm(sae, sc, scalar1, element_b1, 2 * sae->tmp->prime_len,
  818. scalar2, element_b2, 2 * sae->tmp->prime_len, confirm);
  819. }
  820. static void sae_cn_confirm_ffc(struct sae_data *sae, const u8 *sc,
  821. const struct crypto_bignum *scalar1,
  822. const struct crypto_bignum *element1,
  823. const struct crypto_bignum *scalar2,
  824. const struct crypto_bignum *element2,
  825. u8 *confirm)
  826. {
  827. u8 element_b1[SAE_MAX_PRIME_LEN];
  828. u8 element_b2[SAE_MAX_PRIME_LEN];
  829. crypto_bignum_to_bin(element1, element_b1, sizeof(element_b1),
  830. sae->tmp->prime_len);
  831. crypto_bignum_to_bin(element2, element_b2, sizeof(element_b2),
  832. sae->tmp->prime_len);
  833. sae_cn_confirm(sae, sc, scalar1, element_b1, sae->tmp->prime_len,
  834. scalar2, element_b2, sae->tmp->prime_len, confirm);
  835. }
  836. void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf)
  837. {
  838. const u8 *sc;
  839. if (sae->tmp == NULL)
  840. return;
  841. /* Send-Confirm */
  842. sc = wpabuf_put(buf, 0);
  843. wpabuf_put_le16(buf, sae->send_confirm);
  844. sae->send_confirm++;
  845. if (sae->tmp->ec)
  846. sae_cn_confirm_ecc(sae, sc, sae->tmp->own_commit_scalar,
  847. sae->tmp->own_commit_element_ecc,
  848. sae->peer_commit_scalar,
  849. sae->tmp->peer_commit_element_ecc,
  850. wpabuf_put(buf, SHA256_MAC_LEN));
  851. else
  852. sae_cn_confirm_ffc(sae, sc, sae->tmp->own_commit_scalar,
  853. sae->tmp->own_commit_element_ffc,
  854. sae->peer_commit_scalar,
  855. sae->tmp->peer_commit_element_ffc,
  856. wpabuf_put(buf, SHA256_MAC_LEN));
  857. }
  858. int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len)
  859. {
  860. u8 verifier[SHA256_MAC_LEN];
  861. if (len < 2 + SHA256_MAC_LEN) {
  862. wpa_printf(MSG_DEBUG, "SAE: Too short confirm message");
  863. return -1;
  864. }
  865. wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", WPA_GET_LE16(data));
  866. if (sae->tmp == NULL) {
  867. wpa_printf(MSG_DEBUG, "SAE: Temporary data not yet available");
  868. return -1;
  869. }
  870. if (sae->tmp->ec)
  871. sae_cn_confirm_ecc(sae, data, sae->peer_commit_scalar,
  872. sae->tmp->peer_commit_element_ecc,
  873. sae->tmp->own_commit_scalar,
  874. sae->tmp->own_commit_element_ecc,
  875. verifier);
  876. else
  877. sae_cn_confirm_ffc(sae, data, sae->peer_commit_scalar,
  878. sae->tmp->peer_commit_element_ffc,
  879. sae->tmp->own_commit_scalar,
  880. sae->tmp->own_commit_element_ffc,
  881. verifier);
  882. if (os_memcmp_const(verifier, data + 2, SHA256_MAC_LEN) != 0) {
  883. wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch");
  884. wpa_hexdump(MSG_DEBUG, "SAE: Received confirm",
  885. data + 2, SHA256_MAC_LEN);
  886. wpa_hexdump(MSG_DEBUG, "SAE: Calculated verifier",
  887. verifier, SHA256_MAC_LEN);
  888. return -1;
  889. }
  890. return 0;
  891. }