sae.c 28 KB

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