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 DEBUG(
"unable to compute y");
492 size_t y1_pad = primebytelen - BN_num_bytes(y1);
493 size_t y2_pad = primebytelen - BN_num_bytes(y2);
495 memset(y1buf, 0, y1_pad);
496 memset(y2buf, 0, y2_pad);
497 if ((BN_bn2bin(y1, y1buf + y1_pad) < 0) ||
498 (BN_bn2bin(y2, y2buf + y2_pad) < 0)) {
499 DEBUG(
"unable to write y to buffer");
505 if (BN_bin2bn(ybuf, primebytelen, y) == NULL ||
506 !EC_POINT_set_affine_coordinates(session->
group, session->
pwe, x_candidate, y, bnctx)) {
507 DEBUG(
"unable to set point coordinate");
518 BN_clear_free(x_candidate);
519 BN_clear_free(y_sqrd);
535 EVP_MD_CTX_free(hmac_ctx);
536 EVP_PKEY_free(hmac_pkey);
585 BIGNUM *x = NULL, *y = NULL, *cofactor = NULL;
586 EC_POINT *K = NULL, *point = NULL;
590 MEM(session->
k = BN_new());
592 MEM(point = EC_POINT_new(session->
group));
593 MEM(K = EC_POINT_new(session->
group));
595 MEM(cofactor = BN_new());
599 if (!EC_GROUP_get_cofactor(session->
group, cofactor, NULL)) {
600 REDEBUG(
"Unable to get group co-factor");
606 data_len = BN_num_bytes(session->
prime);
611 if (in_len < (2 * data_len + BN_num_bytes(session->
order))) {
612 REDEBUG(
"Invalid commit packet");
616 BN_bin2bn(ptr, data_len, x);
618 BN_bin2bn(ptr, data_len, y);
621 data_len = BN_num_bytes(session->
order);
628 REDEBUG(
"Peer's scalar is not within the allowed range");
632 if (!EC_POINT_set_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
633 REDEBUG(
"Unable to get coordinates of peer's element");
640 REDEBUG(
"Peer's element is not a point on the elliptic curve");
645 if (BN_cmp(cofactor, BN_value_one())) {
646 if (!EC_POINT_mul(session->
group, point, NULL, session->
peer_element, cofactor, NULL)) {
647 REDEBUG(
"Unable to multiply element by co-factor");
651 if (EC_POINT_is_at_infinity(session->
group, point)) {
652 REDEBUG(
"Peer's element is in small sub-group");
660 REDEBUG(
"Reflection attack detected");
665 if ((!EC_POINT_mul(session->
group, K, NULL, session->
pwe, session->
peer_scalar, bn_ctx)) ||
668 REDEBUG(
"Unable to compute shared key, k");
673 if (BN_cmp(cofactor, BN_value_one())) {
674 if (!EC_POINT_mul(session->
group, K, NULL, K, cofactor, NULL)) {
675 REDEBUG(
"Unable to multiply k by co-factor");
686 if (EC_POINT_is_at_infinity(session->
group, K)) {
687 REDEBUG(
"K is point-at-infinity");
691 if (!EC_POINT_get_affine_coordinates(session->
group, K, session->
k, NULL, bn_ctx)) {
692 REDEBUG(
"Unable to get shared secret from K");
698 EC_POINT_clear_free(K);
699 EC_POINT_clear_free(point);
700 BN_clear_free(cofactor);
709 BIGNUM *x = NULL, *y = NULL;
710 EVP_MD_CTX *hmac_ctx;
713 int offset, req = -1;
718 MEM(cruft = talloc_zero_array(session,
uint8_t, BN_num_bytes(session->
prime)));
726 MEM(hmac_ctx = EVP_MD_CTX_new());
727 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
728 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
736 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
737 BN_bn2bin(session->
k, cruft + offset);
738 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
743 if (!EC_POINT_get_affine_coordinates(session->
group, session->
my_element, x, y, bn_ctx)) {
744 REDEBUG(
"Unable to get coordinates of server element");
747 memset(cruft, 0, BN_num_bytes(session->
prime));
748 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
749 BN_bn2bin(x, cruft + offset);
750 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
752 memset(cruft, 0, BN_num_bytes(session->
prime));
753 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
754 BN_bn2bin(y, cruft + offset);
755 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
760 memset(cruft, 0, BN_num_bytes(session->
prime));
761 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
762 BN_bn2bin(session->
my_scalar, cruft + offset);
763 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
768 if (!EC_POINT_get_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
769 REDEBUG(
"Unable to get coordinates of peer's element");
773 memset(cruft, 0, BN_num_bytes(session->
prime));
774 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
775 BN_bn2bin(x, cruft + offset);
776 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
778 memset(cruft, 0, BN_num_bytes(session->
prime));
779 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
780 BN_bn2bin(y, cruft + offset);
781 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
786 memset(cruft, 0, BN_num_bytes(session->
prime));
789 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
801 EVP_MD_CTX_free(hmac_ctx);
802 EVP_PKEY_free(hmac_pkey);
812 BIGNUM *x = NULL, *y = NULL;
813 EVP_MD_CTX *hmac_ctx;
816 int offset, req = -1;
821 MEM(cruft = talloc_zero_array(session,
uint8_t, BN_num_bytes(session->
prime)));
829 MEM(hmac_ctx = EVP_MD_CTX_new());
830 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
831 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
839 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
840 BN_bn2bin(session->
k, cruft + offset);
841 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
846 if (!EC_POINT_get_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
847 REDEBUG(
"Unable to get coordinates of peer's element");
851 memset(cruft, 0, BN_num_bytes(session->
prime));
852 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
853 BN_bn2bin(x, cruft + offset);
854 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
856 memset(cruft, 0, BN_num_bytes(session->
prime));
857 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
858 BN_bn2bin(y, cruft + offset);
859 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
864 memset(cruft, 0, BN_num_bytes(session->
prime));
867 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
872 if (!EC_POINT_get_affine_coordinates(session->
group, session->
my_element, x, y, bn_ctx)) {
873 REDEBUG(
"Unable to get coordinates of server element");
876 memset(cruft, 0, BN_num_bytes(session->
prime));
877 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
878 BN_bn2bin(x, cruft + offset);
879 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
881 memset(cruft, 0, BN_num_bytes(session->
prime));
882 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
883 BN_bn2bin(y, cruft + offset);
884 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
889 memset(cruft, 0, BN_num_bytes(session->
prime));
890 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
891 BN_bn2bin(session->
my_scalar, cruft + offset);
892 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
903 EVP_MD_CTX_free(hmac_ctx);
904 EVP_PKEY_free(hmac_pkey);
914 EVP_MD_CTX *hmac_ctx;
916 uint8_t mk[SHA256_DIGEST_LENGTH], *cruft;
917 uint8_t session_id[SHA256_DIGEST_LENGTH + 1];
921 MEM(cruft = talloc_array(session,
uint8_t, BN_num_bytes(session->
prime)));
922 MEM(hmac_ctx = EVP_MD_CTX_new());
923 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
930 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
933 memset(cruft, 0, BN_num_bytes(session->
prime));
935 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
936 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
937 memset(cruft, 0, BN_num_bytes(session->
prime));
938 BN_bn2bin(session->
my_scalar, cruft + offset);
939 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
943 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
945 memset(cruft, 0, BN_num_bytes(session->
prime));
946 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
947 BN_bn2bin(session->
k, cruft + offset);
948 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
950 EVP_DigestSignUpdate(hmac_ctx, peer_confirm, SHA256_DIGEST_LENGTH);
952 EVP_DigestSignUpdate(hmac_ctx, session->
my_confirm, SHA256_DIGEST_LENGTH);
957 eap_pwd_kdf(mk, SHA256_DIGEST_LENGTH, (
char const *)session_id,
958 SHA256_DIGEST_LENGTH + 1, msk_emsk, 1024);
960 memcpy(msk, msk_emsk, 64);
961 memcpy(emsk, msk_emsk + 64, 64);
963 EVP_MD_CTX_free(hmac_ctx);
964 EVP_PKEY_free(hmac_pkey);