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);
143static void do_equation(EC_GROUP *group, BIGNUM *y2, BIGNUM *x, BN_CTX *bnctx)
145 BIGNUM *p, *a, *b, *tmp1, *pm1;
152 EC_GROUP_get_curve(group, p, a, b, bnctx);
154 BN_sub(pm1, p, BN_value_one());
159 BN_mod_sqr(tmp1, x, p, bnctx);
160 BN_mod_mul(y2, tmp1, x, p, bnctx);
161 BN_mod_mul(tmp1, a, x, p, bnctx);
162 BN_mod_add_quick(y2, y2, tmp1, p);
163 BN_mod_add_quick(y2, y2, b, p);
176 int offset,
check, ret = 0;
177 BIGNUM *r = NULL, *pm1 = NULL, *res = NULL, *qr_or_qnr = NULL;
179 unsigned char *qr_bin = NULL, *qnr_bin = NULL, *qr_or_qnr_bin = NULL;
189 if (((qr_bin = (
unsigned char *)malloc(BN_num_bytes(p))) == NULL) ||
190 ((qnr_bin = (
unsigned char *)malloc(BN_num_bytes(p))) == NULL) ||
191 ((qr_or_qnr_bin = (
unsigned char *)malloc(BN_num_bytes(p))) == NULL)) {
199 memset(qr_bin, 0, BN_num_bytes(p));
200 memset(qnr_bin, 0, BN_num_bytes(p));
201 memset(qr_or_qnr_bin, 0, BN_num_bytes(p));
203 offset = BN_num_bytes(p) - BN_num_bytes(qr);
204 BN_bn2bin(qr, qr_bin + offset);
206 offset = BN_num_bytes(p) - BN_num_bytes(qnr);
207 BN_bn2bin(qnr, qnr_bin + offset);
212 BN_sub(pm1, p, BN_value_one());
213 BN_rand_range(r, pm1);
214 BN_add(r, r, BN_value_one());
221 BN_mod_mul(res, res, r, p, bnctx);
222 BN_mod_mul(res, res, r, p, bnctx);
230 BN_bin2bn(qr_or_qnr_bin, BN_num_bytes(p), qr_or_qnr);
231 BN_mod_mul(res, res, qr_or_qnr, p, bnctx);
234 if ((ret =
legendre(res, p, bnctx)) == -2) {
242 if (qr_bin != NULL)
free(qr_bin);
243 if (qnr_bin != NULL)
free(qnr_bin);
244 if (qr_or_qnr_bin != NULL)
free(qr_or_qnr_bin);
254 char const *password,
int password_len,
255 char const *id_server,
int id_server_len,
256 char const *id_peer,
int id_peer_len,
259 BIGNUM *x_candidate = NULL, *rnd = NULL, *y_sqrd = NULL, *qr = NULL, *qnr = NULL, *y1 = NULL, *y2 = NULL, *y = NULL, *exp = NULL;
260 EVP_MD_CTX *hmac_ctx;
262 uint8_t pwe_digest[SHA256_DIGEST_LENGTH], *prfbuf = NULL, *xbuf = NULL, *pm1buf = NULL, *y1buf = NULL, *y2buf = NULL, *ybuf = NULL, ctr;
263 int nid, is_odd, primebitlen, primebytelen, ret = 0, found = 0,
mask;
264 int save, i, rbits, qr_or_qnr, save_is_odd = 0, cmp;
267 MEM(hmac_ctx = EVP_MD_CTX_new());
268 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
272 nid = NID_X9_62_prime256v1;
284 nid = NID_X9_62_prime192v1;
292 DEBUG(
"unknown group %d", grp_num);
297 session->
order = NULL;
298 session->
prime = NULL;
300 if ((session->
group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
301 DEBUG(
"unable to create EC_GROUP");
306 ((session->
pwe = EC_POINT_new(session->
group)) == NULL) ||
317 DEBUG(
"unable to create bignums");
321 if (!EC_GROUP_get_curve(session->
group, session->
prime, NULL, NULL, NULL)) {
322 DEBUG(
"unable to get prime for GFp curve");
326 if (!EC_GROUP_get_order(session->
group, session->
order, NULL)) {
327 DEBUG(
"unable to get order for curve");
331 primebitlen = BN_num_bits(session->
prime);
332 primebytelen = BN_num_bytes(session->
prime);
333 if ((prfbuf = talloc_zero_array(session,
uint8_t, primebytelen)) == NULL) {
334 DEBUG(
"unable to alloc space for prf buffer");
337 if ((xbuf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
338 DEBUG(
"unable to alloc space for x buffer");
341 if ((pm1buf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
342 DEBUG(
"unable to alloc space for pm1 buffer");
345 if ((y1buf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
346 DEBUG(
"unable to alloc space for y1 buffer");
349 if ((y2buf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
350 DEBUG(
"unable to alloc space for y2 buffer");
353 if ((ybuf = talloc_zero_array(request,
uint8_t, primebytelen)) == NULL) {
354 DEBUG(
"unable to alloc space for y buffer");
363 BN_rand_range(qr, session->
prime);
367 BN_rand_range(qnr, session->
prime);
370 if (!BN_sub(rnd, session->
prime, BN_value_one())) {
373 BN_bn2bin(rnd, pm1buf);
377 memset(xbuf, 0, primebytelen);
387 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
388 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t *)token,
sizeof(*token));
389 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t const *)id_peer, id_peer_len);
390 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t const *)id_server, id_server_len);
391 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t const *)password, password_len);
392 EVP_DigestSignUpdate(hmac_ctx, (
uint8_t *)&ctr,
sizeof(ctr));
395 BN_bin2bn(pwe_digest, SHA256_DIGEST_LENGTH, rnd);
396 eap_pwd_kdf(pwe_digest, SHA256_DIGEST_LENGTH,
"EAP-pwd Hunting And Pecking",
397 strlen(
"EAP-pwd Hunting And Pecking"), prfbuf, primebitlen);
406 if (primebitlen % 8) {
407 rbits = 8 - (primebitlen % 8);
408 for (i = primebytelen - 1; i > 0; i--) {
409 prfbuf[i] = (prfbuf[i - 1] << (8 - rbits)) | (prfbuf[i] >> rbits);
413 BN_bin2bn(prfbuf, primebytelen, x_candidate);
427 is_odd = BN_is_odd(rnd);
469 BN_bin2bn(xbuf, primebytelen, x_candidate);
471 if ( !BN_add(exp, session->
prime, BN_value_one()) ||
472 !BN_rshift(exp, exp, 2) ||
473 !BN_mod_exp_mont_consttime(y1, y_sqrd, exp, session->
prime, bnctx, NULL) ||
474 !BN_sub(y2, session->
prime, y1) ||
475 !BN_bn2bin(y1, y1buf) ||
476 !BN_bn2bin(y2, y2buf)) {
477 DEBUG(
"unable to compute y");
482 if (BN_bin2bn(ybuf, primebytelen, y) == NULL ||
483 !EC_POINT_set_affine_coordinates(session->
group, session->
pwe, x_candidate, y, bnctx)) {
484 DEBUG(
"unable to set point coordinate");
495 BN_clear_free(x_candidate);
496 BN_clear_free(y_sqrd);
512 EVP_MD_CTX_free(hmac_ctx);
513 EVP_PKEY_free(hmac_pkey);
562 BIGNUM *x = NULL, *y = NULL, *cofactor = NULL;
563 EC_POINT *K = NULL, *point = NULL;
567 MEM(session->
k = BN_new());
569 MEM(point = EC_POINT_new(session->
group));
570 MEM(K = EC_POINT_new(session->
group));
572 MEM(cofactor = BN_new());
576 if (!EC_GROUP_get_cofactor(session->
group, cofactor, NULL)) {
577 REDEBUG(
"Unable to get group co-factor");
583 data_len = BN_num_bytes(session->
prime);
588 if (in_len < (2 * data_len + BN_num_bytes(session->
order))) {
589 REDEBUG(
"Invalid commit packet");
593 BN_bin2bn(ptr, data_len, x);
595 BN_bin2bn(ptr, data_len, y);
598 data_len = BN_num_bytes(session->
order);
605 REDEBUG(
"Peer's scalar is not within the allowed range");
609 if (!EC_POINT_set_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
610 REDEBUG(
"Unable to get coordinates of peer's element");
617 REDEBUG(
"Peer's element is not a point on the elliptic curve");
622 if (BN_cmp(cofactor, BN_value_one())) {
623 if (!EC_POINT_mul(session->
group, point, NULL, session->
peer_element, cofactor, NULL)) {
624 REDEBUG(
"Unable to multiply element by co-factor");
628 if (EC_POINT_is_at_infinity(session->
group, point)) {
629 REDEBUG(
"Peer's element is in small sub-group");
637 REDEBUG(
"Reflection attack detected");
642 if ((!EC_POINT_mul(session->
group, K, NULL, session->
pwe, session->
peer_scalar, bn_ctx)) ||
645 REDEBUG(
"Unable to compute shared key, k");
650 if (BN_cmp(cofactor, BN_value_one())) {
651 if (!EC_POINT_mul(session->
group, K, NULL, K, cofactor, NULL)) {
652 REDEBUG(
"Unable to multiply k by co-factor");
663 if (EC_POINT_is_at_infinity(session->
group, K)) {
664 REDEBUG(
"K is point-at-infinity");
668 if (!EC_POINT_get_affine_coordinates(session->
group, K, session->
k, NULL, bn_ctx)) {
669 REDEBUG(
"Unable to get shared secret from K");
675 EC_POINT_clear_free(K);
676 EC_POINT_clear_free(point);
677 BN_clear_free(cofactor);
686 BIGNUM *x = NULL, *y = NULL;
687 EVP_MD_CTX *hmac_ctx;
690 int offset, req = -1;
695 MEM(cruft = talloc_zero_array(session,
uint8_t, BN_num_bytes(session->
prime)));
703 MEM(hmac_ctx = EVP_MD_CTX_new());
704 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
705 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
713 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
714 BN_bn2bin(session->
k, cruft + offset);
715 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
720 if (!EC_POINT_get_affine_coordinates(session->
group, session->
my_element, x, y, bn_ctx)) {
721 REDEBUG(
"Unable to get coordinates of server element");
724 memset(cruft, 0, BN_num_bytes(session->
prime));
725 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
726 BN_bn2bin(x, cruft + offset);
727 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
729 memset(cruft, 0, BN_num_bytes(session->
prime));
730 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
731 BN_bn2bin(y, cruft + offset);
732 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
737 memset(cruft, 0, BN_num_bytes(session->
prime));
738 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
739 BN_bn2bin(session->
my_scalar, cruft + offset);
740 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
745 if (!EC_POINT_get_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
746 REDEBUG(
"Unable to get coordinates of peer's element");
750 memset(cruft, 0, BN_num_bytes(session->
prime));
751 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
752 BN_bn2bin(x, cruft + offset);
753 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
755 memset(cruft, 0, BN_num_bytes(session->
prime));
756 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
757 BN_bn2bin(y, cruft + offset);
758 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
763 memset(cruft, 0, BN_num_bytes(session->
prime));
766 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
778 EVP_MD_CTX_free(hmac_ctx);
779 EVP_PKEY_free(hmac_pkey);
789 BIGNUM *x = NULL, *y = NULL;
790 EVP_MD_CTX *hmac_ctx;
793 int offset, req = -1;
798 MEM(cruft = talloc_zero_array(session,
uint8_t, BN_num_bytes(session->
prime)));
806 MEM(hmac_ctx = EVP_MD_CTX_new());
807 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
808 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
816 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
817 BN_bn2bin(session->
k, cruft + offset);
818 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
823 if (!EC_POINT_get_affine_coordinates(session->
group, session->
peer_element, x, y, bn_ctx)) {
824 REDEBUG(
"Unable to get coordinates of peer's element");
828 memset(cruft, 0, BN_num_bytes(session->
prime));
829 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
830 BN_bn2bin(x, cruft + offset);
831 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
833 memset(cruft, 0, BN_num_bytes(session->
prime));
834 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
835 BN_bn2bin(y, cruft + offset);
836 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
841 memset(cruft, 0, BN_num_bytes(session->
prime));
844 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
849 if (!EC_POINT_get_affine_coordinates(session->
group, session->
my_element, x, y, bn_ctx)) {
850 REDEBUG(
"Unable to get coordinates of server element");
853 memset(cruft, 0, BN_num_bytes(session->
prime));
854 offset = BN_num_bytes(session->
prime) - BN_num_bytes(x);
855 BN_bn2bin(x, cruft + offset);
856 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
858 memset(cruft, 0, BN_num_bytes(session->
prime));
859 offset = BN_num_bytes(session->
prime) - BN_num_bytes(y);
860 BN_bn2bin(y, cruft + offset);
861 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
866 memset(cruft, 0, BN_num_bytes(session->
prime));
867 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
868 BN_bn2bin(session->
my_scalar, cruft + offset);
869 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
880 EVP_MD_CTX_free(hmac_ctx);
881 EVP_PKEY_free(hmac_pkey);
891 EVP_MD_CTX *hmac_ctx;
893 uint8_t mk[SHA256_DIGEST_LENGTH], *cruft;
894 uint8_t session_id[SHA256_DIGEST_LENGTH + 1];
898 MEM(cruft = talloc_array(session,
uint8_t, BN_num_bytes(session->
prime)));
899 MEM(hmac_ctx = EVP_MD_CTX_new());
900 MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
allzero,
sizeof(
allzero)));
907 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
910 memset(cruft, 0, BN_num_bytes(session->
prime));
912 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
913 offset = BN_num_bytes(session->
order) - BN_num_bytes(session->
my_scalar);
914 memset(cruft, 0, BN_num_bytes(session->
prime));
915 BN_bn2bin(session->
my_scalar, cruft + offset);
916 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
order));
920 EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
922 memset(cruft, 0, BN_num_bytes(session->
prime));
923 offset = BN_num_bytes(session->
prime) - BN_num_bytes(session->
k);
924 BN_bn2bin(session->
k, cruft + offset);
925 EVP_DigestSignUpdate(hmac_ctx, cruft, BN_num_bytes(session->
prime));
927 EVP_DigestSignUpdate(hmac_ctx, peer_confirm, SHA256_DIGEST_LENGTH);
929 EVP_DigestSignUpdate(hmac_ctx, session->
my_confirm, SHA256_DIGEST_LENGTH);
934 eap_pwd_kdf(mk, SHA256_DIGEST_LENGTH, (
char const *)session_id,
935 SHA256_DIGEST_LENGTH + 1, msk_emsk, 1024);
937 memcpy(msk, msk_emsk, 64);
938 memcpy(emsk, msk_emsk + 64, 64);
940 EVP_MD_CTX_free(hmac_ctx);
941 EVP_PKEY_free(hmac_pkey);