160 lines
6.3 KiB
Diff
160 lines
6.3 KiB
Diff
|
|
From 9e5e8f2f912ad2da8ac6e176ac3a606333469937 Mon Sep 17 00:00:00 2001
|
||
|
|
From: "Alan T. DeKok" <aland@freeradius.org>
|
||
|
|
Date: Fri, 4 Feb 2022 09:36:26 -0500
|
||
|
|
Subject: [PATCH] port fixes from master
|
||
|
|
|
||
|
|
via the simple expedient of copying the entire function, with
|
||
|
|
some minor changes to work in v3
|
||
|
|
---
|
||
|
|
.../rlm_eap/types/rlm_eap_pwd/eap_pwd.c | 90 ++++++++++++++-----
|
||
|
|
1 file changed, 66 insertions(+), 24 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c b/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c
|
||
|
|
index d428644539ba..26260527a536 100644
|
||
|
|
--- a/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c
|
||
|
|
+++ b/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c
|
||
|
|
@@ -248,18 +248,16 @@ int compute_password_element (REQUEST *request, pwd_session_t *session, uint16_t
|
||
|
|
char const *id_peer, int id_peer_len,
|
||
|
|
uint32_t *token)
|
||
|
|
{
|
||
|
|
- BIGNUM *x_candidate = NULL, *rnd = NULL, *y_sqrd = NULL, *qr = NULL, *qnr = NULL;
|
||
|
|
- HMAC_CTX *ctx = NULL;
|
||
|
|
- uint8_t pwe_digest[SHA256_DIGEST_LENGTH], *prfbuf = NULL, *xbuf = NULL, *pm1buf = NULL, ctr;
|
||
|
|
- int nid, is_odd, primebitlen, primebytelen, ret = 0, found = 0, mask;
|
||
|
|
- int save, i, rbits, qr_or_qnr, save_is_odd = 0, cmp;
|
||
|
|
- unsigned int skip;
|
||
|
|
-
|
||
|
|
- ctx = HMAC_CTX_new();
|
||
|
|
- if (ctx == NULL) {
|
||
|
|
- DEBUG("failed allocating HMAC context");
|
||
|
|
- goto fail;
|
||
|
|
- }
|
||
|
|
+ BIGNUM *x_candidate = NULL, *rnd = NULL, *y_sqrd = NULL, *qr = NULL, *qnr = NULL, *y1 = NULL, *y2 = NULL, *y = NULL, *exp = NULL;
|
||
|
|
+ EVP_MD_CTX *hmac_ctx;
|
||
|
|
+ EVP_PKEY *hmac_pkey;
|
||
|
|
+ uint8_t pwe_digest[SHA256_DIGEST_LENGTH], *prfbuf = NULL, *xbuf = NULL, *pm1buf = NULL, *y1buf = NULL, *y2buf = NULL, *ybuf = NULL, ctr;
|
||
|
|
+ int nid, is_odd, primebitlen, primebytelen, ret = 0, found = 0, mask;
|
||
|
|
+ int save, i, rbits, qr_or_qnr, save_is_odd = 0, cmp;
|
||
|
|
+ unsigned int skip;
|
||
|
|
+
|
||
|
|
+ MEM(hmac_ctx = EVP_MD_CTX_new());
|
||
|
|
+ MEM(hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, allzero, sizeof(allzero)));
|
||
|
|
|
||
|
|
switch (grp_num) { /* from IANA registry for IKE D-H groups */
|
||
|
|
case 19:
|
||
|
|
@@ -303,7 +301,11 @@ int compute_password_element (REQUEST *request, pwd_session_t *session, uint16_t
|
||
|
|
((qr = consttime_BN()) == NULL) ||
|
||
|
|
((qnr = consttime_BN()) == NULL) ||
|
||
|
|
((x_candidate = consttime_BN()) == NULL) ||
|
||
|
|
- ((y_sqrd = consttime_BN()) == NULL)) {
|
||
|
|
+ ((y_sqrd = consttime_BN()) == NULL) ||
|
||
|
|
+ ((y1 = consttime_BN()) == NULL) ||
|
||
|
|
+ ((y2 = consttime_BN()) == NULL) ||
|
||
|
|
+ ((y = consttime_BN()) == NULL) ||
|
||
|
|
+ ((exp = consttime_BN()) == NULL)) {
|
||
|
|
DEBUG("unable to create bignums");
|
||
|
|
goto fail;
|
||
|
|
}
|
||
|
|
@@ -332,6 +334,19 @@ int compute_password_element (REQUEST *request, pwd_session_t *session, uint16_t
|
||
|
|
DEBUG("unable to alloc space for pm1 buffer");
|
||
|
|
goto fail;
|
||
|
|
}
|
||
|
|
+ if ((y1buf = talloc_zero_array(request, uint8_t, primebytelen)) == NULL) {
|
||
|
|
+ DEBUG("unable to alloc space for y1 buffer");
|
||
|
|
+ goto fail;
|
||
|
|
+ }
|
||
|
|
+ if ((y2buf = talloc_zero_array(request, uint8_t, primebytelen)) == NULL) {
|
||
|
|
+ DEBUG("unable to alloc space for y2 buffer");
|
||
|
|
+ goto fail;
|
||
|
|
+ }
|
||
|
|
+ if ((ybuf = talloc_zero_array(request, uint8_t, primebytelen)) == NULL) {
|
||
|
|
+ DEBUG("unable to alloc space for y buffer");
|
||
|
|
+ goto fail;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
|
||
|
|
/*
|
||
|
|
* derive random quadradic residue and quadratic non-residue
|
||
|
|
@@ -361,13 +376,19 @@ int compute_password_element (REQUEST *request, pwd_session_t *session, uint16_t
|
||
|
|
* pwd-seed = H(token | peer-id | server-id | password |
|
||
|
|
* counter)
|
||
|
|
*/
|
||
|
|
- HMAC_Init_ex(ctx, allzero, SHA256_DIGEST_LENGTH, EVP_sha256(),NULL);
|
||
|
|
- HMAC_Update(ctx, (uint8_t *)token, sizeof(*token));
|
||
|
|
- HMAC_Update(ctx, (uint8_t const *)id_peer, id_peer_len);
|
||
|
|
- HMAC_Update(ctx, (uint8_t const *)id_server, id_server_len);
|
||
|
|
- HMAC_Update(ctx, (uint8_t const *)password, password_len);
|
||
|
|
- HMAC_Update(ctx, (uint8_t *)&ctr, sizeof(ctr));
|
||
|
|
- pwd_hmac_final(ctx, pwe_digest);
|
||
|
|
+ EVP_DigestSignInit(hmac_ctx, NULL, EVP_sha256(), NULL, hmac_pkey);
|
||
|
|
+ EVP_DigestSignUpdate(hmac_ctx, (uint8_t *)token, sizeof(*token));
|
||
|
|
+ EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *)id_peer, id_peer_len);
|
||
|
|
+ EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *)id_server, id_server_len);
|
||
|
|
+ EVP_DigestSignUpdate(hmac_ctx, (uint8_t const *)password, password_len);
|
||
|
|
+ EVP_DigestSignUpdate(hmac_ctx, (uint8_t *)&ctr, sizeof(ctr));
|
||
|
|
+
|
||
|
|
+ {
|
||
|
|
+ size_t mdlen = SHA256_DIGEST_LENGTH;
|
||
|
|
+
|
||
|
|
+ EVP_DigestSignFinal(hmac_ctx, pwe_digest, &mdlen);
|
||
|
|
+ EVP_MD_CTX_reset(hmac_ctx);
|
||
|
|
+ }
|
||
|
|
|
||
|
|
BN_bin2bn(pwe_digest, SHA256_DIGEST_LENGTH, rnd);
|
||
|
|
eap_pwd_kdf(pwe_digest, SHA256_DIGEST_LENGTH, "EAP-pwd Hunting And Pecking",
|
||
|
|
@@ -401,7 +422,7 @@ int compute_password_element (REQUEST *request, pwd_session_t *session, uint16_t
|
||
|
|
* need to unambiguously identify the solution, if there is
|
||
|
|
* one..
|
||
|
|
*/
|
||
|
|
- is_odd = BN_is_odd(rnd) ? 1 : 0;
|
||
|
|
+ is_odd = BN_is_odd(rnd);
|
||
|
|
|
||
|
|
/*
|
||
|
|
* check whether x^3 + a*x + b is a quadratic residue
|
||
|
|
@@ -444,8 +465,21 @@ int compute_password_element (REQUEST *request, pwd_session_t *session, uint16_t
|
||
|
|
* now we can savely construct PWE
|
||
|
|
*/
|
||
|
|
BN_bin2bn(xbuf, primebytelen, x_candidate);
|
||
|
|
- if (!EC_POINT_set_compressed_coordinates(session->group, session->pwe,
|
||
|
|
- x_candidate, save_is_odd, NULL)) {
|
||
|
|
+ do_equation(session->group, y_sqrd, x_candidate, session->bnctx);
|
||
|
|
+ if ( !BN_add(exp, session->prime, BN_value_one()) ||
|
||
|
|
+ !BN_rshift(exp, exp, 2) ||
|
||
|
|
+ !BN_mod_exp_mont_consttime(y1, y_sqrd, exp, session->prime, session->bnctx, NULL) ||
|
||
|
|
+ !BN_sub(y2, session->prime, y1) ||
|
||
|
|
+ !BN_bn2bin(y1, y1buf) ||
|
||
|
|
+ !BN_bn2bin(y2, y2buf)) {
|
||
|
|
+ DEBUG("unable to compute y");
|
||
|
|
+ goto fail;
|
||
|
|
+ }
|
||
|
|
+ mask = const_time_eq(save_is_odd, BN_is_odd(y1));
|
||
|
|
+ const_time_select_bin(mask, y1buf, y2buf, primebytelen, ybuf);
|
||
|
|
+ if (BN_bin2bn(ybuf, primebytelen, y) == NULL ||
|
||
|
|
+ !EC_POINT_set_affine_coordinates(session->group, session->pwe, x_candidate, y, session->bnctx)) {
|
||
|
|
+ DEBUG("unable to set point coordinate");
|
||
|
|
goto fail;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -461,12 +495,20 @@ int compute_password_element (REQUEST *request, pwd_session_t *session, uint16_t
|
||
|
|
BN_clear_free(qr);
|
||
|
|
BN_clear_free(qnr);
|
||
|
|
BN_clear_free(rnd);
|
||
|
|
+ BN_clear_free(y1);
|
||
|
|
+ BN_clear_free(y2);
|
||
|
|
+ BN_clear_free(y);
|
||
|
|
+ BN_clear_free(exp);
|
||
|
|
|
||
|
|
if (prfbuf) talloc_free(prfbuf);
|
||
|
|
if (xbuf) talloc_free(xbuf);
|
||
|
|
if (pm1buf) talloc_free(pm1buf);
|
||
|
|
+ if (y1buf) talloc_free(y1buf);
|
||
|
|
+ if (y2buf) talloc_free(y2buf);
|
||
|
|
+ if (ybuf) talloc_free(ybuf);
|
||
|
|
|
||
|
|
- HMAC_CTX_free(ctx);
|
||
|
|
+ EVP_MD_CTX_free(hmac_ctx);
|
||
|
|
+ EVP_PKEY_free(hmac_pkey);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|