On 31 May 2013 16:42, Jakob Bohm <[email protected]> wrote:
> Interesting, I don't seem to be able to find code that calls dh_check
> or equivalent on received DH group parameters, but then the check in
> that function is too strict in its criteria (for instance, some
> standards (such as X9.42 and NIST SP 800-56A) require a subgroup of a
> smaller order than ((large prime minus 1) divided by 2), which would
> fail the obsolete test for "safe primes" (primes of the form large
> prime=one plus two times subgroup prime), which was motivated by a
> property of now obsolete factorization and discrete logarithm methods.
As I understand it there isn't full support for X9.42 in the current
released versions. There are some X9.42 parameters in the DH
structure. See the following from 1.0.1:
struct dh_st
{
/* This first argument is used to pick up errors when
* a DH is passed instead of a EVP_PKEY */
int pad;
int version;
BIGNUM *p;
BIGNUM *g;
long length; /* optional */
BIGNUM *pub_key; /* g^x */
BIGNUM *priv_key; /* x */
int flags;
BN_MONT_CTX *method_mont_p;
/* Place holders if we want to do X9.42 DH */
BIGNUM *q;
BIGNUM *j;
unsigned char *seed;
int seedlen;
BIGNUM *counter;
int references;
CRYPTO_EX_DATA ex_data;
const DH_METHOD *meth;
ENGINE *engine;
};
However the ASN1 structures for X9.42 are not present. We only have
the following:
ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
ASN1_SIMPLE(DH, p, BIGNUM),
ASN1_SIMPLE(DH, g, BIGNUM),
ASN1_OPT(DH, length, ZLONG),
} ASN1_SEQUENCE_END_cb(DH, DHparams)
However in the as yet unreleased 1.0.2 (and 1.1.0) we additionally get:
ASN1_SEQUENCE(DHxparams) = {
ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM),
ASN1_OPT(int_dhx942_dh, j, BIGNUM),
ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
} ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
>
> As for the DH_check_pub_key() function, checking if pubkey is in the
> range "two to large prime minus 2, inclusive" is an insufficient check
> against accepting degenerate keys. For instance NIST SP 800-56A
> requires the following check for most FIPS certified implementations
> (they also allow some less practical checks that typically work only
> for static DH keys or your own keys):
>
> Verify that (public key raised to subgroup prime) equals 1 modulo
> large prime. Note that checking if (public key raised to (large prime minus
> 1)) equals 1 modulo large prime is pointless, we need the actual
> subgroup prime for this.
>
This check exists in 1.0.2 but not earlier (in DH_check):
if (dh->q)
{
if (BN_cmp(dh->g, BN_value_one()) <= 0)
*ret|=DH_NOT_SUITABLE_GENERATOR;
else if (BN_cmp(dh->g, dh->p) >= 0)
*ret|=DH_NOT_SUITABLE_GENERATOR;
else
{
/* Check g^q == 1 mod p */
if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
goto err;
Matt
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]