From bebe112e079fd5edfae0bf995f1a226257de0d3c Mon Sep 17 00:00:00 2001 From: peng2285 Date: Wed, 21 Dec 2022 11:44:30 +0800 Subject: [PATCH 1/3] fix CVE-2022-41859 --- CVE-2022-41859.patch | 159 +++++++++++++++++++++++++++++++++++++++++++ freeradius.spec | 6 +- 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 CVE-2022-41859.patch diff --git a/CVE-2022-41859.patch b/CVE-2022-41859.patch new file mode 100644 index 0000000..9d5476e --- /dev/null +++ b/CVE-2022-41859.patch @@ -0,0 +1,159 @@ +From 9e5e8f2f912ad2da8ac6e176ac3a606333469937 Mon Sep 17 00:00:00 2001 +From: "Alan T. DeKok" +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; + } diff --git a/freeradius.spec b/freeradius.spec index 171b4b1..083bb4f 100644 --- a/freeradius.spec +++ b/freeradius.spec @@ -4,7 +4,7 @@ Name: freeradius Version: 3.0.25 -Release: 1 +Release: 2 Summary: Remote Authentication Dial-In User Service License: GPLv2+ and LGPLv2+ @@ -14,6 +14,7 @@ Source1: radiusd.service Source2: freeradius-logrotate Source3: freeradius-pam-conf Source4: freeradius-tmpfiles.conf +patch0000: CVE-2022-41859.patch BuildRequires: autoconf gdbm-devel openssl openssl-devel pam-devel zlib-devel net-snmp-devel BuildRequires: net-snmp-utils readline-devel libpcap-devel systemd-units libtalloc-devel @@ -489,6 +490,9 @@ exit 0 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-available/ldap %changelog +* Wed Dec 21 2022 jiangpeng - 3.0.25-2 +- Fix CVE-2022-41859 + * Thu Dec 30 2021 baizhonggui - 3.0.25-1 - update to 3.0.25 -- Gitee From 1340c74c286187406fcea91ffb883b87ffd34e7c Mon Sep 17 00:00:00 2001 From: peng2285 Date: Wed, 21 Dec 2022 18:52:26 +0800 Subject: [PATCH 2/3] fix CVE-2022-41860 new file: CVE-2022-41860.patch modified: freeradius.spec --- CVE-2022-41859.patch | 159 ------------------------------------------- CVE-2022-41860.patch | 109 +++++++++++++++++++++++++++++ freeradius.spec | 4 +- 3 files changed, 111 insertions(+), 161 deletions(-) delete mode 100644 CVE-2022-41859.patch create mode 100644 CVE-2022-41860.patch diff --git a/CVE-2022-41859.patch b/CVE-2022-41859.patch deleted file mode 100644 index 9d5476e..0000000 --- a/CVE-2022-41859.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 9e5e8f2f912ad2da8ac6e176ac3a606333469937 Mon Sep 17 00:00:00 2001 -From: "Alan T. DeKok" -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; - } diff --git a/CVE-2022-41860.patch b/CVE-2022-41860.patch new file mode 100644 index 0000000..421a0ce --- /dev/null +++ b/CVE-2022-41860.patch @@ -0,0 +1,109 @@ +From f1cdbb33ec61c4a64a32e107d4d02f936051c708 Mon Sep 17 00:00:00 2001 +From: "Alan T. DeKok" +Date: Mon, 7 Feb 2022 22:26:05 -0500 +Subject: [PATCH] it's probably wrong to be completely retarded. Let's fix + that. + +--- + src/modules/rlm_eap/libeap/eapsimlib.c | 69 +++++++++++++++++++------- + 1 file changed, 52 insertions(+), 17 deletions(-) + +diff --git a/src/modules/rlm_eap/libeap/eapsimlib.c b/src/modules/rlm_eap/libeap/eapsimlib.c +index cf1e8a7dd924..e438a844eab3 100644 +--- a/src/modules/rlm_eap/libeap/eapsimlib.c ++++ b/src/modules/rlm_eap/libeap/eapsimlib.c +@@ -307,42 +307,77 @@ int unmap_eapsim_basictypes(RADIUS_PACKET *r, + newvp->vp_length = 1; + fr_pair_add(&(r->vps), newvp); + ++ /* ++ * EAP-SIM has a 1 octet of subtype, and 2 octets ++ * reserved. ++ */ + attr += 3; + attrlen -= 3; + +- /* now, loop processing each attribute that we find */ +- while(attrlen > 0) { ++ /* ++ * Loop over each attribute. The format is: ++ * ++ * 1 octet of type ++ * 1 octet of length (value 1..255) ++ * ((4 * length) - 2) octets of data. ++ */ ++ while (attrlen > 0) { + uint8_t *p; + +- if(attrlen < 2) { ++ if (attrlen < 2) { + fr_strerror_printf("EAP-Sim attribute %d too short: %d < 2", es_attribute_count, attrlen); + return 0; + } + ++ if (!attr[1]) { ++ fr_strerror_printf("EAP-Sim attribute %d (no.%d) has no data", eapsim_attribute, ++ es_attribute_count); ++ return 0; ++ } ++ + eapsim_attribute = attr[0]; + eapsim_len = attr[1] * 4; + ++ /* ++ * The length includes the 2-byte header. ++ */ + if (eapsim_len > attrlen) { + fr_strerror_printf("EAP-Sim attribute %d (no.%d) has length longer than data (%d > %d)", + eapsim_attribute, es_attribute_count, eapsim_len, attrlen); + return 0; + } + +- if(eapsim_len > MAX_STRING_LEN) { +- eapsim_len = MAX_STRING_LEN; +- } +- if (eapsim_len < 2) { +- fr_strerror_printf("EAP-Sim attribute %d (no.%d) has length too small", eapsim_attribute, +- es_attribute_count); +- return 0; +- } ++ newvp = fr_pair_afrom_num(r, eapsim_attribute + PW_EAP_SIM_BASE, 0); ++ if (!newvp) { ++ /* ++ * RFC 4186 Section 8.1 says 0..127 are ++ * "non-skippable". If one such ++ * attribute is found and we don't ++ * understand it, the server has to send: ++ * ++ * EAP-Request/SIM/Notification packet with an ++ * (AT_NOTIFICATION code, which implies general failure ("General ++ * failure after authentication" (0), or "General failure" (16384), ++ * depending on the phase of the exchange), which terminates the ++ * authentication exchange. ++ */ ++ if (eapsim_attribute <= 127) { ++ fr_strerror_printf("Unknown mandatory attribute %d, failing", ++ eapsim_attribute); ++ return 0; ++ } + +- newvp = fr_pair_afrom_num(r, eapsim_attribute+PW_EAP_SIM_BASE, 0); +- newvp->vp_length = eapsim_len-2; +- newvp->vp_octets = p = talloc_array(newvp, uint8_t, newvp->vp_length); +- memcpy(p, &attr[2], eapsim_len-2); +- fr_pair_add(&(r->vps), newvp); +- newvp = NULL; ++ } else { ++ /* ++ * It's known, ccount for header, and ++ * copy the value over. ++ */ ++ newvp->vp_length = eapsim_len - 2; ++ ++ newvp->vp_octets = p = talloc_array(newvp, uint8_t, newvp->vp_length); ++ memcpy(p, &attr[2], newvp->vp_length); ++ fr_pair_add(&(r->vps), newvp); ++ } + + /* advance pointers, decrement length */ + attr += eapsim_len; diff --git a/freeradius.spec b/freeradius.spec index 083bb4f..f128731 100644 --- a/freeradius.spec +++ b/freeradius.spec @@ -14,7 +14,7 @@ Source1: radiusd.service Source2: freeradius-logrotate Source3: freeradius-pam-conf Source4: freeradius-tmpfiles.conf -patch0000: CVE-2022-41859.patch +patch0000: CVE-2022-41860.patch BuildRequires: autoconf gdbm-devel openssl openssl-devel pam-devel zlib-devel net-snmp-devel BuildRequires: net-snmp-utils readline-devel libpcap-devel systemd-units libtalloc-devel @@ -491,7 +491,7 @@ exit 0 %changelog * Wed Dec 21 2022 jiangpeng - 3.0.25-2 -- Fix CVE-2022-41859 +- Fix CVE-2022-41860 * Thu Dec 30 2021 baizhonggui - 3.0.25-1 - update to 3.0.25 -- Gitee From db7b8e218b10061171aa216c1554ff89d986e453 Mon Sep 17 00:00:00 2001 From: peng2285 Date: Thu, 22 Dec 2022 09:49:58 +0800 Subject: [PATCH 3/3] fix CVE-2022-41860 and CVE-2022-41861 new file: CVE-2022-41859-pre.patch new file: CVE-2022-41861.patch modified: freeradius.spec new file: CVE-2022-41859-pre.patch new file: CVE-2022-41859.patch new file: CVE-2022-41861.patch modified: freeradius.spec --- CVE-2022-41859-pre.patch | 94 +++++++++++++++++++++++ CVE-2022-41859.patch | 159 +++++++++++++++++++++++++++++++++++++++ CVE-2022-41861.patch | 44 +++++++++++ freeradius.spec | 7 +- 4 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 CVE-2022-41859-pre.patch create mode 100644 CVE-2022-41859.patch create mode 100644 CVE-2022-41861.patch diff --git a/CVE-2022-41859-pre.patch b/CVE-2022-41859-pre.patch new file mode 100644 index 0000000..bb8f564 --- /dev/null +++ b/CVE-2022-41859-pre.patch @@ -0,0 +1,94 @@ +From 1df6f266231816171d2662eacf0e528b8ad1d7d8 Mon Sep 17 00:00:00 2001 +From: "Alan T. DeKok" +Date: Sun, 26 Dec 2021 12:02:30 -0500 +Subject: [PATCH] switch to non-deprecated API + +--- + .../rlm_eap/types/rlm_eap_pwd/eap_pwd.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 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 cf7ab61816cb..d428644539ba 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 +@@ -141,7 +141,7 @@ static void do_equation(EC_GROUP *group, BIGNUM *y2, BIGNUM *x, BN_CTX *bnctx) + p = BN_new(); + a = BN_new(); + b = BN_new(); +- EC_GROUP_get_curve_GFp(group, p, a, b, bnctx); ++ EC_GROUP_get_curve(group, p, a, b, bnctx); + + BN_sub(pm1, p, BN_value_one()); + +@@ -308,7 +308,7 @@ int compute_password_element (REQUEST *request, pwd_session_t *session, uint16_t + goto fail; + } + +- if (!EC_GROUP_get_curve_GFp(session->group, session->prime, NULL, NULL, NULL)) { ++ if (!EC_GROUP_get_curve(session->group, session->prime, NULL, NULL, NULL)) { + DEBUG("unable to get prime for GFp curve"); + goto fail; + } +@@ -444,7 +444,7 @@ 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_GFp(session->group, session->pwe, ++ if (!EC_POINT_set_compressed_coordinates(session->group, session->pwe, + x_candidate, save_is_odd, NULL)) { + goto fail; + } +@@ -562,7 +562,7 @@ int process_peer_commit(REQUEST *request, pwd_session_t *session, uint8_t *in, s + goto finish; + } + +- if (!EC_POINT_set_affine_coordinates_GFp(session->group, session->peer_element, x, y, bn_ctx)) { ++ if (!EC_POINT_set_affine_coordinates(session->group, session->peer_element, x, y, bn_ctx)) { + REDEBUG("Unable to get coordinates of peer's element"); + goto finish; + } +@@ -621,7 +621,7 @@ int process_peer_commit(REQUEST *request, pwd_session_t *session, uint8_t *in, s + goto finish; + } + +- if (!EC_POINT_get_affine_coordinates_GFp(session->group, K, session->k, NULL, bn_ctx)) { ++ if (!EC_POINT_get_affine_coordinates(session->group, K, session->k, NULL, bn_ctx)) { + REDEBUG("Unable to get shared secret from K"); + goto finish; + } +@@ -671,7 +671,7 @@ int compute_server_confirm(REQUEST *request, pwd_session_t *session, uint8_t *ou + /* + * next is server element: x, y + */ +- if (!EC_POINT_get_affine_coordinates_GFp(session->group, session->my_element, x, y, bn_ctx)) { ++ if (!EC_POINT_get_affine_coordinates(session->group, session->my_element, x, y, bn_ctx)) { + REDEBUG("Unable to get coordinates of server element"); + goto finish; + } +@@ -696,7 +696,7 @@ int compute_server_confirm(REQUEST *request, pwd_session_t *session, uint8_t *ou + /* + * next is peer element: x, y + */ +- if (!EC_POINT_get_affine_coordinates_GFp(session->group, session->peer_element, x, y, bn_ctx)) { ++ if (!EC_POINT_get_affine_coordinates(session->group, session->peer_element, x, y, bn_ctx)) { + REDEBUG("Unable to get coordinates of peer's element"); + goto finish; + } +@@ -771,7 +771,7 @@ int compute_peer_confirm(REQUEST *request, pwd_session_t *session, uint8_t *out, + /* + * then peer element: x, y + */ +- if (!EC_POINT_get_affine_coordinates_GFp(session->group, session->peer_element, x, y, bn_ctx)) { ++ if (!EC_POINT_get_affine_coordinates(session->group, session->peer_element, x, y, bn_ctx)) { + REDEBUG("Unable to get coordinates of peer's element"); + goto finish; + } +@@ -797,7 +797,7 @@ int compute_peer_confirm(REQUEST *request, pwd_session_t *session, uint8_t *out, + /* + * then server element: x, y + */ +- if (!EC_POINT_get_affine_coordinates_GFp(session->group, session->my_element, x, y, bn_ctx)) { ++ if (!EC_POINT_get_affine_coordinates(session->group, session->my_element, x, y, bn_ctx)) { + REDEBUG("Unable to get coordinates of server element"); + goto finish; + } diff --git a/CVE-2022-41859.patch b/CVE-2022-41859.patch new file mode 100644 index 0000000..9d5476e --- /dev/null +++ b/CVE-2022-41859.patch @@ -0,0 +1,159 @@ +From 9e5e8f2f912ad2da8ac6e176ac3a606333469937 Mon Sep 17 00:00:00 2001 +From: "Alan T. DeKok" +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; + } diff --git a/CVE-2022-41861.patch b/CVE-2022-41861.patch new file mode 100644 index 0000000..edecbc3 --- /dev/null +++ b/CVE-2022-41861.patch @@ -0,0 +1,44 @@ +From 0ec2b39d260e08e4c3464f6b95005821dc559c62 Mon Sep 17 00:00:00 2001 +From: "Alan T. DeKok" +Date: Mon, 28 Feb 2022 10:34:15 -0500 +Subject: [PATCH] manual port of commit 5906bfa1 + +--- + src/lib/filters.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/lib/filters.c b/src/lib/filters.c +index 4868cd385d9f..3f3b63daeef3 100644 +--- a/src/lib/filters.c ++++ b/src/lib/filters.c +@@ -1205,13 +1205,19 @@ void print_abinary(char *out, size_t outlen, uint8_t const *data, size_t len, in + } + } + } else if (filter->type == RAD_FILTER_GENERIC) { +- int count; ++ size_t count, masklen; ++ ++ masklen = ntohs(filter->u.generic.len); ++ if (masklen >= sizeof(filter->u.generic.mask)) { ++ *p = '\0'; ++ return; ++ } + + i = snprintf(p, outlen, " %u ", (unsigned int) ntohs(filter->u.generic.offset)); + p += i; + + /* show the mask */ +- for (count = 0; count < ntohs(filter->u.generic.len); count++) { ++ for (count = 0; count < masklen; count++) { + i = snprintf(p, outlen, "%02x", filter->u.generic.mask[count]); + p += i; + outlen -= i; +@@ -1222,7 +1228,7 @@ void print_abinary(char *out, size_t outlen, uint8_t const *data, size_t len, in + outlen--; + + /* show the value */ +- for (count = 0; count < ntohs(filter->u.generic.len); count++) { ++ for (count = 0; count < masklen; count++) { + i = snprintf(p, outlen, "%02x", filter->u.generic.value[count]); + p += i; + outlen -= i; diff --git a/freeradius.spec b/freeradius.spec index f128731..c22ed8f 100644 --- a/freeradius.spec +++ b/freeradius.spec @@ -14,7 +14,10 @@ Source1: radiusd.service Source2: freeradius-logrotate Source3: freeradius-pam-conf Source4: freeradius-tmpfiles.conf -patch0000: CVE-2022-41860.patch +patch0000: CVE-2022-41859-pre.patch +patch0001: CVE-2022-41859.patch +patch0002: CVE-2022-41860.patch +patch0003: CVE-2022-41861.patch BuildRequires: autoconf gdbm-devel openssl openssl-devel pam-devel zlib-devel net-snmp-devel BuildRequires: net-snmp-utils readline-devel libpcap-devel systemd-units libtalloc-devel @@ -491,7 +494,7 @@ exit 0 %changelog * Wed Dec 21 2022 jiangpeng - 3.0.25-2 -- Fix CVE-2022-41860 +- Fix CVE-2022-41859 and CVE-2022-41860 and CVE-2022-41861 * Thu Dec 30 2021 baizhonggui - 3.0.25-1 - update to 3.0.25 -- Gitee