File openssh-fips-ensure-approved-moduli.patch of Package openssh.18131
commit 57c5454722a1dcaaa2d49090f471b70feb25d5bf
Author: Hans Petter Jansson <hpj@hpjansson.org>
Date: Mon Oct 26 21:46:49 2020 +0100
Ensure DHGs are approved in FIPS mode using OpenSSL's DH_check_params()
diff --git a/dh.c b/dh.c
index 8dd563a..d983a0d 100644
--- a/dh.c
+++ b/dh.c
@@ -142,6 +142,28 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
return 0;
}
+static int
+dhg_is_approved(const struct dhgroup *dhg)
+{
+ BIGNUM *g, *p;
+ DH *dh;
+ int dh_status;
+ int is_ok = 0;
+
+ /* DH_set0_pqg() transfers ownership of the bignums, so we
+ * make temporary copies here for simplicity. */
+ g = BN_dup(dhg->g);
+ p = BN_dup(dhg->p);
+ dh = dh_new_group(g, p);
+
+ if (dh) {
+ is_ok = DH_check_params(dh, &dh_status);
+ }
+
+ DH_free(dh);
+ return is_ok;
+}
+
DH *
choose_dh(int min, int wantbits, int max)
{
@@ -160,12 +182,20 @@ choose_dh(int min, int wantbits, int max)
linenum = 0;
best = bestcount = 0;
while (fgets(line, sizeof(line), f)) {
+ int dhg_is_ok;
+
linenum++;
if (!parse_prime(linenum, line, &dhg))
continue;
+
+ dhg_is_ok = dhg_is_approved(&dhg);
+
BN_clear_free(dhg.g);
BN_clear_free(dhg.p);
+ if (!dhg_is_ok)
+ continue;
+
if (dhg.size > max || dhg.size < min)
continue;
@@ -188,9 +218,15 @@ choose_dh(int min, int wantbits, int max)
linenum = 0;
which = arc4random_uniform(bestcount);
while (fgets(line, sizeof(line), f)) {
+ int dhg_is_ok;
+
if (!parse_prime(linenum, line, &dhg))
continue;
- if ((dhg.size > max || dhg.size < min) ||
+
+ dhg_is_ok = dhg_is_approved(&dhg);
+
+ if (!dhg_is_ok ||
+ (dhg.size > max || dhg.size < min) ||
dhg.size != best ||
linenum++ != which) {
BN_clear_free(dhg.g);