sae.c 27 KB

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