On Jan 3, 2019, at 3:18 PM, Andy Schmidt <andrewrobertschmidt@xxxxxxxxx> wrote: > I am adding the RFC 7919 Diffie-Hellman parameters to our TLS > servers, and I've found that these parameters won't pass OpenSSL's > Diffie Hellman parameter check function DH_check(). The return code > is DH_NOT_SUITABLE_GENERATOR. Looking at the source code, it appears > to fail because the remainder of the prime divided by 24 is not 11. > That its, p mod 24 != 11. I have a couple of questions: > > What relationship between the prime p and the generator g is this checking > for? I thought that since p was a safe prime, as long as the generator g > wasn't 1 the only choice is between the full group and the subgroup of the > squares? For a safe prime $p = 2q + 1$ with $q$ also prime, the order of $2$ is $q$ provided $2$ is quadratic residue mod $p$, which, by quadratic reciprocity, considering that $q$ is odd and not a multiple of 3 for any primes of interest, gives $p \cong 23 mod 24$, which then gives $q \cong 11 mod 12$. The order of $2$ is $2q$ when $2$ is not a quadratic residue mod $p$, which then gives $p \cong 3 mod 8$ and so taking mod 3 into account $p \cong 11 mod 24$. So it seems that the check in question wants $2$ to generates the full multiplicative group of order $2q$, rather than the prime-order subgroup of quadratic residues of order $q$. > I would like to use DH_check() to attempt to ensure that Diffie Hellman > parameters haven't been tampered on operating systems that don't have > digital signatures for executable binaries. > > The OpenSSL version in use is 1.0.2q. The primes in RFC7919 are all 23 mod 24, which has $o(2) = q$ rather than $o(2) = 2q$. This is actually fine, perhaps even better, and the code in DH_check() is too strict in wanting the generator to generate the full multiplicative group mod $p$, rather than just the subgroup of of quadratic residues of order $q$. So a pull request for OpenSSL would be welcome. Given that we should not care whether the order of $g$ is $q$ or $2q$, it suffices to just check that $p$ is plausibly prime and $q = (p-1)/2 == (p >> 1)$ is plausibly prime. The special checks for $g == 2, 3 and 5$ should be removed. For 1.1.1 the patch would be something like: --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -88,8 +88,6 @@ int DH_check_ex(const DH *dh) DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_INVALID_Q_VALUE); if ((errflags & DH_CHECK_INVALID_J_VALUE) != 0) DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_INVALID_J_VALUE); - if ((errflags & DH_UNABLE_TO_CHECK_GENERATOR) != 0) - DHerr(DH_F_DH_CHECK_EX, DH_R_UNABLE_TO_CHECK_GENERATOR); if ((errflags & DH_CHECK_P_NOT_PRIME) != 0) DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_PRIME); if ((errflags & DH_CHECK_P_NOT_SAFE_PRIME) != 0) @@ -140,20 +138,7 @@ int DH_check(const DH *dh, int *ret) if (dh->j && BN_cmp(dh->j, t1)) *ret |= DH_CHECK_INVALID_J_VALUE; - } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { - l = BN_mod_word(dh->p, 24); - if (l == (BN_ULONG)-1) - goto err; - if (l != 11) - *ret |= DH_NOT_SUITABLE_GENERATOR; - } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { - l = BN_mod_word(dh->p, 10); - if (l == (BN_ULONG)-1) - goto err; - if ((l != 3) && (l != 7)) - *ret |= DH_NOT_SUITABLE_GENERATOR; - } else - *ret |= DH_UNABLE_TO_CHECK_GENERATOR; + } r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL); if (r < 0) -- Viktor. -- openssl-users mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users