57 int label_len,
uint8_t *result,
int result_bit_len)
61 uint8_t digest[SHA256_DIGEST_LENGTH];
63 int result_byte_len, len = 0;
64 size_t mdlen = SHA256_DIGEST_LENGTH;
67 result_byte_len = (result_bit_len + 7) / 8;
70 L = htons(result_bit_len);
72 MEM(hmac_ctx = EVP_MD_CTX_new());
73 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, keylen));
74 while (len < result_byte_len) {
75 ctr++; i = htons(ctr);
77 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
78 if (ctr > 1) EVP_DigestSignUpdate(hmac_ctx, digest, mdlen);
80 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t const *)label, label_len);
82 EVP_DigestSignFinal(hmac_ctx, digest, &mdlen);
83 if ((len + (
int) mdlen) > result_byte_len) {
84 memcpy(result + len, digest, result_byte_len - len);
86 memcpy(result + len, digest, mdlen);
89 EVP_MD_CTX_reset(hmac_ctx);
93 if (result_bit_len % 8) {
94 mask <<= (8 - (result_bit_len % 8));
95 result[result_byte_len - 1] &=
mask;
98 EVP_MD_CTX_free(hmac_ctx);
99 EVP_PKEY_free(hmac_pkey);
145static void do_equation(EC_GROUP *group, BIGNUM *y2, BIGNUM *x, BN_CTX *bnctx)
147 BIGNUM *p, *a, *b, *tmp1, *pm1;
149 MEM(tmp1 = BN_new());
154 EC_GROUP_get_curve(group, p, a, b, bnctx);
156 BN_sub(pm1, p, BN_value_one());
161 BN_mod_sqr(tmp1, x, p, bnctx);
162 BN_mod_mul(y2, tmp1, x, p, bnctx);
163 BN_mod_mul(tmp1, a, x, p, bnctx);
164 BN_mod_add_quick(y2, y2, tmp1, p);
165 BN_mod_add_quick(y2, y2, b, p);
178 int offset, check, ret = 0;
180 BIGNUM *r = NULL, *pm1 = NULL, *res = NULL, *qr_or_qnr = NULL;
182 unsigned char *qr_bin = NULL, *qnr_bin = NULL, *qr_or_qnr_bin = NULL;
192 if (((qr_bin = (
unsigned char *)malloc(BN_num_bytes(p))) == NULL) ||
193 ((qnr_bin = (
unsigned char *)malloc(BN_num_bytes(p))) == NULL) ||
194 ((qr_or_qnr_bin = (
unsigned char *)malloc(BN_num_bytes(p))) == NULL)) {
202 memset(qr_bin, 0, BN_num_bytes(p));
203 memset(qnr_bin, 0, BN_num_bytes(p));
204 memset(qr_or_qnr_bin, 0, BN_num_bytes(p));
206 offset = BN_num_bytes(p) - BN_num_bytes(qr);
207 BN_bn2bin(qr, qr_bin + offset);
209 offset = BN_num_bytes(p) - BN_num_bytes(qnr);
210 BN_bn2bin(qnr, qnr_bin + offset);
215 BN_sub(pm1, p, BN_value_one());
216 BN_rand_range(r, pm1);
217 BN_add(r, r, BN_value_one());
224 BN_mod_mul(res, res, r, p, bnctx);
225 BN_mod_mul(res, res, r, p, bnctx);
233 BN_bin2bn(qr_or_qnr_bin, BN_num_bytes(p), qr_or_qnr);
234 BN_mod_mul(res, res, qr_or_qnr, p, bnctx);
237 if ((ret =
legendre(&fail, res, p, bnctx)) == -2) {
245 if (qr_bin != NULL)
free(qr_bin);
246 if (qnr_bin != NULL)
free(qnr_bin);
247 if (qr_or_qnr_bin != NULL)
free(qr_or_qnr_bin);
257 char const *password,
int password_len,
258 char const *id_server,
int id_server_len,
259 char const *id_peer,
int id_peer_len,
262 BIGNUM *x_candidate = NULL, *rnd = NULL, *y_sqrd = NULL, *qr = NULL, *qnr = NULL, *y1 = NULL, *y2 = NULL, *y = NULL, *exp = NULL;
263 EVP_MD_CTX *hmac_ctx;
265 uint8_t pwe_digest[SHA256_DIGEST_LENGTH], *prfbuf = NULL, *xbuf = NULL, *pm1buf = NULL, *y1buf = NULL, *y2buf = NULL, *ybuf = NULL, ctr;
266 int nid, is_odd, primebitlen, primebytelen, ret = 0, found = 0,
mask;
267 int save, i, rbits, qr_or_qnr, save_is_odd = 0, cmp;
271 MEM(hmac_ctx = EVP_MD_CTX_new());
272 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
276 nid = NID_X9_62_prime256v1;
288 nid = NID_X9_62_prime192v1;
296 DEBUG(
"unknown group %d", grp_num);
301 session->
order = NULL;
302 session->
prime = NULL;
304 if ((session->
group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
305 DEBUG(
"unable to create EC_GROUP");
310 ((session->
pwe = EC_POINT_new(session->
group)) == NULL) ||
321 DEBUG(
"unable to create bignums");
325 if (!EC_GROUP_get_curve(session->
group, session->
prime, NULL, NULL, NULL)) {
326 DEBUG(
"unable to get prime for GFp curve");
330 if (!EC_GROUP_get_order(session->
group, session->
order, NULL)) {
331 DEBUG(
"unable to get order for curve");
335 primebitlen = BN_num_bits(session->
prime);
336 primebytelen = BN_num_bytes(session->
prime);
337 if ((prfbuf = talloc_zero_array(session,
uint8_t, primebytelen)) == NULL) {
338 DEBUG(
"unable to alloc space for prf buffer");
341 if ((xbuf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
342 DEBUG(
"unable to alloc space for x buffer");
345 if ((pm1buf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
346 DEBUG(
"unable to alloc space for pm1 buffer");
349 if ((y1buf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
350 DEBUG(
"unable to alloc space for y1 buffer");
353 if ((y2buf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
354 DEBUG(
"unable to alloc space for y2 buffer");
357 if ((ybuf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
358 DEBUG(
"unable to alloc space for y buffer");
367 BN_rand_range(qr, session->
prime);
368 }
while ((
legendre(&error, qr, session->
prime, bnctx) != 1) && !error);
369 if (error)
goto fail;
372 BN_rand_range(qnr, session->
prime);
373 }
while ((
legendre(&error, qnr, session->
prime, bnctx) != -1) && !error);
374 if (error)
goto fail;
376 if (!BN_sub(rnd, session->
prime, BN_value_one())) {
379 BN_bn2bin(rnd, pm1buf);
383 memset(xbuf, 0, primebytelen);
393 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
394 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t *)token,
sizeof(*token));
395 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t const *)id_peer, id_peer_len);
396 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t const *)id_server, id_server_len);
397 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t const *)password, password_len);
398 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t *)&ctr,
sizeof(ctr));
401 BN_bin2bn(pwe_digest, SHA256_DIGEST_LENGTH, rnd);
402 eap_pwd_kdf(pwe_digest, SHA256_DIGEST_LENGTH,
"EAP-pwd Hunting And Pecking",
403 strlen(
"EAP-pwd Hunting And Pecking"), prfbuf, primebitlen);
412 if (primebitlen % 8) {
413 rbits = 8 - (primebitlen % 8);
414 for (i = primebytelen - 1; i > 0; i--) {
415 prfbuf[i] = (prfbuf[i - 1] << (8 - rbits)) | (prfbuf[i] >> rbits);
419 BN_bin2bn(prfbuf, primebytelen, x_candidate);
433 is_odd = BN_is_odd(rnd);
475 BN_bin2bn(xbuf, primebytelen, x_candidate);
477 if ( !BN_add(exp, session->
prime, BN_value_one()) ||
478 !BN_rshift(exp, exp, 2) ||
479 !BN_mod_exp_mont_consttime(y1, y_sqrd, exp, session->
prime, bnctx, NULL) ||
480 !BN_sub(y2, session->
prime, y1) ||
481 !BN_bn2bin(y1, y1buf) ||
482 !BN_bn2bin(y2, y2buf)) {
483 DEBUG(
"unable to compute y");
488 if (BN_bin2bn(ybuf, primebytelen, y) == NULL ||
489 !EC_POINT_set_affine_coordinates(session->
group, session->
pwe, x_candidate, y, bnctx)) {
490 DEBUG(
"unable to set point coordinate");
501 BN_clear_free(x_candidate);
502 BN_clear_free(y_sqrd);
518 EVP_MD_CTX_free(hmac_ctx);
519 EVP_PKEY_free(hmac_pkey);
568 BIGNUM *x = NULL, *y = NULL, *cofactor = NULL;
569 EC_POINT *K = NULL, *point = NULL;
573 MEM(session->
k = BN_new());
575 MEM(point = EC_POINT_new(session->
group));
576 MEM(K = EC_POINT_new(session->
group));
578 MEM(cofactor = BN_new());
582 if (!EC_GROUP_get_cofactor(session->
group, cofactor, NULL)) {
583 REDEBUG(
"Unable to get group co-factor");
589 data_len = BN_num_bytes(session->
prime);
594 if (in_len < (2 * data_len + BN_num_bytes(session->
order))) {
595 REDEBUG(
"Invalid commit packet");
599 BN_bin2bn(ptr, data_len, x);
601 BN_bin2bn(ptr, data_len, y);
604 data_len = BN_num_bytes(session->
order);
611 REDEBUG(
"Peer's scalar is not within the allowed range");
615 if (!EC_POINT_set_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
616 REDEBUG(
"Unable to get coordinates of peer's element");
623 REDEBUG(
"Peer's element is not a point on the elliptic curve");
628 if (BN_cmp(cofactor, BN_value_one())) {
629 if (!EC_POINT_mul(session->
group, point, NULL, session->
peer_element, cofactor, NULL)) {
630 REDEBUG(
"Unable to multiply element by co-factor");
634 if (EC_POINT_is_at_infinity(session->
group, point)) {
635 REDEBUG(
"Peer's element is in small sub-group");
643 REDEBUG(
"Reflection attack detected");
648 if ((!EC_POINT_mul(session->
group, K, NULL, session->
pwe, session->
peer_scalar, bn_ctx)) ||
651 REDEBUG(
"Unable to compute shared key, k");
656 if (BN_cmp(cofactor, BN_value_one())) {
657 if (!EC_POINT_mul(session->
group, K, NULL, K, cofactor, NULL)) {
658 REDEBUG(
"Unable to multiply k by co-factor");
669 if (EC_POINT_is_at_infinity(session->
group, K)) {
670 REDEBUG(
"K is point-at-infinity");
674 if (!EC_POINT_get_affine_coordinates(session->
group, K, session->
k, NULL, bn_ctx)) {
675 REDEBUG(
"Unable to get shared secret from K");
681 EC_POINT_clear_free(K);
682 EC_POINT_clear_free(point);
683 BN_clear_free(cofactor);
692 BIGNUM *x = NULL, *y = NULL;
693 EVP_MD_CTX *hmac_ctx;
696 int offset, req = -1;
701 MEM(cruft = talloc_zero_array(session,
uint8_t, BN_num_bytes(session->
prime)));
709 MEM(hmac_ctx = EVP_MD_CTX_new());
710 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
711 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
719 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
720 BN_bn2bin(session->
k, cruft + offset);
721 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
726 if (!EC_POINT_get_affine_coordinates(session->
group, session->
my_element, x, y, bn_ctx)) {
727 REDEBUG(
"Unable to get coordinates of server element");
730 memset(cruft, 0, BN_num_bytes(session->
prime));
731 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
732 BN_bn2bin(x, cruft + offset);
733 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
735 memset(cruft, 0, BN_num_bytes(session->
prime));
736 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
737 BN_bn2bin(y, cruft + offset);
738 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
743 memset(cruft, 0, BN_num_bytes(session->
prime));
744 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
745 BN_bn2bin(session->
my_scalar, cruft + offset);
746 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
751 if (!EC_POINT_get_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
752 REDEBUG(
"Unable to get coordinates of peer's element");
756 memset(cruft, 0, BN_num_bytes(session->
prime));
757 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
758 BN_bn2bin(x, cruft + offset);
759 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
761 memset(cruft, 0, BN_num_bytes(session->
prime));
762 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
763 BN_bn2bin(y, cruft + offset);
764 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
769 memset(cruft, 0, BN_num_bytes(session->
prime));
772 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
784 EVP_MD_CTX_free(hmac_ctx);
785 EVP_PKEY_free(hmac_pkey);
795 BIGNUM *x = NULL, *y = NULL;
796 EVP_MD_CTX *hmac_ctx;
799 int offset, req = -1;
804 MEM(cruft = talloc_zero_array(session,
uint8_t, BN_num_bytes(session->
prime)));
812 MEM(hmac_ctx = EVP_MD_CTX_new());
813 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
814 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
822 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
823 BN_bn2bin(session->
k, cruft + offset);
824 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
829 if (!EC_POINT_get_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
830 REDEBUG(
"Unable to get coordinates of peer's element");
834 memset(cruft, 0, BN_num_bytes(session->
prime));
835 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
836 BN_bn2bin(x, cruft + offset);
837 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
839 memset(cruft, 0, BN_num_bytes(session->
prime));
840 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
841 BN_bn2bin(y, cruft + offset);
842 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
847 memset(cruft, 0, BN_num_bytes(session->
prime));
850 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
855 if (!EC_POINT_get_affine_coordinates(session->
group, session->
my_element, x, y, bn_ctx)) {
856 REDEBUG(
"Unable to get coordinates of server element");
859 memset(cruft, 0, BN_num_bytes(session->
prime));
860 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
861 BN_bn2bin(x, cruft + offset);
862 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
864 memset(cruft, 0, BN_num_bytes(session->
prime));
865 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
866 BN_bn2bin(y, cruft + offset);
867 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
872 memset(cruft, 0, BN_num_bytes(session->
prime));
873 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
874 BN_bn2bin(session->
my_scalar, cruft + offset);
875 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
886 EVP_MD_CTX_free(hmac_ctx);
887 EVP_PKEY_free(hmac_pkey);
897 EVP_MD_CTX *hmac_ctx;
899 uint8_t mk[SHA256_DIGEST_LENGTH], *cruft;
900 uint8_t session_id[SHA256_DIGEST_LENGTH + 1];
904 MEM(cruft = talloc_array(session,
uint8_t, BN_num_bytes(session->
prime)));
905 MEM(hmac_ctx = EVP_MD_CTX_new());
906 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
913 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
916 memset(cruft, 0, BN_num_bytes(session->
prime));
918 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
919 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
920 memset(cruft, 0, BN_num_bytes(session->
prime));
921 BN_bn2bin(session->
my_scalar, cruft + offset);
922 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
926 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
928 memset(cruft, 0, BN_num_bytes(session->
prime));
929 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
930 BN_bn2bin(session->
k, cruft + offset);
931 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
933 EVP_DigestSignUpdate(hmac_ctx, peer_confirm, SHA256_DIGEST_LENGTH);
935 EVP_DigestSignUpdate(hmac_ctx, session->
my_confirm, SHA256_DIGEST_LENGTH);
940 eap_pwd_kdf(mk, SHA256_DIGEST_LENGTH, (
char const *)session_id,
941 SHA256_DIGEST_LENGTH + 1, msk_emsk, 1024);
943 memcpy(msk, msk_emsk, 64);
944 memcpy(emsk, msk_emsk + 64, 64);
946 EVP_MD_CTX_free(hmac_ctx);
947 EVP_PKEY_free(hmac_pkey);