diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-01-23 20:33:28 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-01-23 20:33:28 +1000 |
commit | 62f49b90d7e88d3c36fc1f5e4d677997aeb97b0a (patch) | |
tree | fbe5f7df9b658d87f2975923703942033ff020d2 /crypto/dh | |
parent | f10048301390283523d3d1623880be7518cf46ac (diff) |
Add DH key exchange to fips provider
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10826)
Diffstat (limited to 'crypto/dh')
-rw-r--r-- | crypto/dh/build.info | 9 | ||||
-rw-r--r-- | crypto/dh/dh_key.c | 200 | ||||
-rw-r--r-- | crypto/dh/dh_lib.c | 17 | ||||
-rw-r--r-- | crypto/dh/dh_local.h | 2 |
4 files changed, 134 insertions, 94 deletions
diff --git a/crypto/dh/build.info b/crypto/dh/build.info index b19ff6dbac..924ca8f92f 100644 --- a/crypto/dh/build.info +++ b/crypto/dh/build.info @@ -1,5 +1,10 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \ + +$COMMON=dh_lib.c dh_key.c + +SOURCE[../../libcrypto]=$COMMON\ + dh_asn1.c dh_gen.c dh_check.c dh_err.c dh_depr.c \ dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c \ dh_rfc7919.c + +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index a8a9dbe764..bd9b5c824b 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -11,29 +11,94 @@ #include "internal/cryptlib.h" #include "dh_local.h" #include "crypto/bn.h" +#include "crypto/dh.h" +#ifndef FIPS_MODE static int generate_key(DH *dh); -static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +#endif /* FIPS_MODE */ + static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); static int dh_init(DH *dh); static int dh_finish(DH *dh); -int DH_generate_key(DH *dh) +int dh_compute_key(OPENSSL_CTX *libctx, unsigned char *key, + const BIGNUM *pub_key, DH *dh) { - return dh->meth->generate_key(dh); + BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *tmp; + int ret = -1; +#ifndef FIPS_MODE + int check_result; +#endif + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(0, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) { + DHerr(0, DH_R_MODULUS_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new_ex(libctx); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + if (dh->priv_key == NULL) { + DHerr(0, DH_R_NO_PRIVATE_VALUE); + goto err; + } + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, + dh->lock, dh->p, ctx); + BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); + if (!mont) + goto err; + } +/* TODO(3.0) : Solve in a PR related to Key validation for DH */ +#ifndef FIPS_MODE + if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) { + DHerr(0, DH_R_INVALID_PUBKEY); + goto err; + } +#endif + if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, + mont)) { + DHerr(0, ERR_R_BN_LIB); + goto err; + } + + ret = BN_bn2bin(tmp, key); + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; } -int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) { - return dh->meth->compute_key(key, pub_key, dh); + return dh_compute_key(NULL, key, pub_key, dh); } -int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) +int dh_compute_key_padded(OPENSSL_CTX *libctx, unsigned char *key, + const BIGNUM *pub_key, DH *dh) { int rv, pad; + +#ifdef FIPS_MODE + rv = dh_compute_key(libctx, key, pub_key, dh); +#else rv = dh->meth->compute_key(key, pub_key, dh); +#endif if (rv <= 0) return rv; pad = BN_num_bytes(dh->p) - rv; @@ -44,9 +109,25 @@ int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) return rv + pad; } +#ifndef FIPS_MODE +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + return dh->meth->compute_key(key, pub_key, dh); +} + +int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + return dh_compute_key_padded(NULL, key, pub_key, dh); +} +#endif + static DH_METHOD dh_ossl = { "OpenSSL DH Method", +#ifndef FIPS_MODE generate_key, +#else + NULL, /* TODO(3.0) : solve this in a keygen related PR */ +#endif compute_key, dh_bn_mod_exp, dh_init, @@ -63,14 +144,40 @@ const DH_METHOD *DH_OpenSSL(void) return &dh_ossl; } +const DH_METHOD *DH_get_default_method(void) +{ + return default_DH_method; +} + +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); +} + +static int dh_init(DH *dh) +{ + dh->flags |= DH_FLAG_CACHE_MONT_P; + return 1; +} + +static int dh_finish(DH *dh) +{ + BN_MONT_CTX_free(dh->method_mont_p); + return 1; +} + +#ifndef FIPS_MODE + void DH_set_default_method(const DH_METHOD *meth) { default_DH_method = meth; } -const DH_METHOD *DH_get_default_method(void) +int DH_generate_key(DH *dh) { - return default_DH_method; + return dh->meth->generate_key(dh); } static int generate_key(DH *dh) @@ -173,82 +280,6 @@ static int generate_key(DH *dh) return ok; } -static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) -{ - BN_CTX *ctx = NULL; - BN_MONT_CTX *mont = NULL; - BIGNUM *tmp; - int ret = -1; - int check_result; - - if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { - DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); - goto err; - } - - if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) { - DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_SMALL); - return 0; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - if (tmp == NULL) - goto err; - - if (dh->priv_key == NULL) { - DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE); - goto err; - } - - if (dh->flags & DH_FLAG_CACHE_MONT_P) { - mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, - dh->lock, dh->p, ctx); - BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); - if (!mont) - goto err; - } - - if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) { - DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY); - goto err; - } - - if (!dh-> - meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) { - DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB); - goto err; - } - - ret = BN_bn2bin(tmp, key); - err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ret; -} - -static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); -} - -static int dh_init(DH *dh) -{ - dh->flags |= DH_FLAG_CACHE_MONT_P; - return 1; -} - -static int dh_finish(DH *dh) -{ - BN_MONT_CTX_free(dh->method_mont_p); - return 1; -} - int dh_buf2key(DH *dh, const unsigned char *buf, size_t len) { int err_reason = DH_R_BN_ERROR; @@ -311,3 +342,4 @@ size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out) *pbuf_out = pbuf; return p_size; } +#endif /* FIPS_MODE */ diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index 65c2154c26..c9679d7e52 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -12,8 +12,10 @@ #include "internal/refcount.h" #include <openssl/bn.h> #include "dh_local.h" +#include "crypto/dh.h" #include <openssl/engine.h> +#ifndef FIPS_MODE int DH_set_method(DH *dh, const DH_METHOD *meth) { /* @@ -33,6 +35,7 @@ int DH_set_method(DH *dh, const DH_METHOD *meth) meth->init(dh); return 1; } +#endif /* !FIPS_MODE */ DH *DH_new(void) { @@ -57,7 +60,7 @@ DH *DH_new_method(ENGINE *engine) } ret->meth = DH_get_default_method(); -#ifndef OPENSSL_NO_ENGINE +#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE) ret->flags = ret->meth->flags; /* early default init */ if (engine) { if (!ENGINE_init(engine)) { @@ -81,7 +84,7 @@ DH *DH_new_method(ENGINE *engine) #ifndef FIPS_MODE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data)) goto err; -#endif +#endif /* FIPS_MODE */ if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { DHerr(DH_F_DH_NEW_METHOD, ERR_R_INIT_FAIL); @@ -110,11 +113,10 @@ void DH_free(DH *r) if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE +#if !defined(FIPS_MODE) +# if !defined(OPENSSL_NO_ENGINE) ENGINE_finish(r->engine); -#endif - -#ifndef FIPS_MODE +# endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); #endif @@ -177,7 +179,6 @@ int DH_security_bits(const DH *dh) return BN_security_bits(BN_num_bits(dh->p), N); } - void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { @@ -293,7 +294,9 @@ void DH_set_flags(DH *dh, int flags) dh->flags |= flags; } +#ifndef FIPS_MODE ENGINE *DH_get0_engine(DH *dh) { return dh->engine; } +#endif /*FIPS_MODE */ diff --git a/crypto/dh/dh_local.h b/crypto/dh/dh_local.h index 378cf5c957..2a200c748e 100644 --- a/crypto/dh/dh_local.h +++ b/crypto/dh/dh_local.h @@ -35,9 +35,9 @@ struct dh_st { CRYPTO_REF_COUNT references; #ifndef FIPS_MODE CRYPTO_EX_DATA ex_data; + ENGINE *engine; #endif const DH_METHOD *meth; - ENGINE *engine; CRYPTO_RWLOCK *lock; /* Provider data */ |