X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdh%2Fdh_check.c;h=0acd7753e9c206692c46691e2a1676504a299f3b;hp=8da8dc839390184b801acfdd8353d5ff904a0a54;hb=1d97c8435171a7af575f73c526d79e1ef0ee5960;hpb=d02b48c63a58ea4367a0e905979f140b7d090f86 diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index 8da8dc8393..0acd7753e9 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -1,5 +1,5 @@ /* crypto/dh/dh_check.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -58,11 +58,12 @@ #include #include "cryptlib.h" -#include "bn.h" -#include "dh.h" +#include +#include -/* Check that p is a strong prime and - * if g is 2, 3 or 5, check that is is a suitable generator +/*- + * Check that p is a safe prime and + * if g is 2, 3 or 5, check that it is a suitable generator * where * for 2, p mod 24 == 11 * for 3, p mod 12 == 5 @@ -70,31 +71,59 @@ * should hold. */ -int DH_check(dh,ret) -DH *dh; -int *ret; +int DH_check(const DH *dh, int *ret) { int ok=0; BN_CTX *ctx=NULL; BN_ULONG l; - BIGNUM *q=NULL; + BIGNUM *t1=NULL, *t2 = NULL; *ret=0; ctx=BN_CTX_new(); if (ctx == NULL) goto err; - q=BN_new(); - if (q == NULL) goto err; + BN_CTX_start(ctx); + t1=BN_CTX_get(ctx); + if (t1 == NULL) goto err; + t2=BN_CTX_get(ctx); + if (t2 == NULL) goto err; - if (BN_is_word(dh->g,DH_GENERATOR_2)) + 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; + if (!BN_is_one(t1)) + *ret|=DH_NOT_SUITABLE_GENERATOR; + } + if (!BN_is_prime_ex(dh->q,BN_prime_checks,ctx,NULL)) + *ret|=DH_CHECK_Q_NOT_PRIME; + /* Check p == 1 mod q i.e. q divides p - 1 */ + if (!BN_div(t1, t2, dh->p, dh->q, ctx)) + goto err; + if (!BN_is_one(t2)) + *ret|=DH_CHECK_INVALID_Q_VALUE; + 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 != 11) *ret|=DH_NOT_SUITABLE_GENERATOR; } -/* else if (BN_is_word(dh->g,DH_GENERATOR_3)) +#if 0 + else if (BN_is_word(dh->g,DH_GENERATOR_3)) { l=BN_mod_word(dh->p,12); if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR; - }*/ + } +#endif else if (BN_is_word(dh->g,DH_GENERATOR_5)) { l=BN_mod_word(dh->p,10); @@ -104,17 +133,42 @@ int *ret; else *ret|=DH_UNABLE_TO_CHECK_GENERATOR; - if (!BN_is_prime(dh->p,BN_prime_checks,NULL,ctx)) + if (!BN_is_prime_ex(dh->p,BN_prime_checks,ctx,NULL)) *ret|=DH_CHECK_P_NOT_PRIME; - else + else if (!dh->q) { - if (!BN_rshift1(q,dh->p)) goto err; - if (!BN_is_prime(q,BN_prime_checks,NULL,ctx)) - *ret|=DH_CHECK_P_NOT_STRONG_PRIME; + if (!BN_rshift1(t1,dh->p)) goto err; + if (!BN_is_prime_ex(t1,BN_prime_checks,ctx,NULL)) + *ret|=DH_CHECK_P_NOT_SAFE_PRIME; } ok=1; err: - if (ctx != NULL) BN_CTX_free(ctx); + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return(ok); + } + +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) + { + int ok=0; + BIGNUM *q=NULL; + + *ret=0; + q=BN_new(); + if (q == NULL) goto err; + BN_set_word(q,1); + if (BN_cmp(pub_key,q)<=0) + *ret|=DH_CHECK_PUBKEY_TOO_SMALL; + BN_copy(q,dh->p); + BN_sub_word(q,1); + if (BN_cmp(pub_key,q)>=0) + *ret|=DH_CHECK_PUBKEY_TOO_LARGE; + + ok = 1; +err: if (q != NULL) BN_free(q); return(ok); }