diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-02-16 04:03:46 +0100 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-02-16 04:03:46 +0100 |
commit | 8083fd3a183d4c881d6b15727cbc6cb7faeb3280 (patch) | |
tree | 82e998aa30cc9dc610b4f262df1f7ef73b23edad /crypto/dsa | |
parent | x86_64: Add endbranch at function entries for Intel CET (diff) | |
download | openssl-8083fd3a183d4c881d6b15727cbc6cb7faeb3280.tar.xz openssl-8083fd3a183d4c881d6b15727cbc6cb7faeb3280.zip |
Add FFC param/key validation
Embed libctx in dsa and dh objects and cleanup internal methods to not pass libctx (This makes it consistent with the rsa changes)
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10910)
Diffstat (limited to 'crypto/dsa')
-rw-r--r-- | crypto/dsa/dsa_check.c | 85 | ||||
-rw-r--r-- | crypto/dsa/dsa_gen.c | 30 | ||||
-rw-r--r-- | crypto/dsa/dsa_key.c | 49 | ||||
-rw-r--r-- | crypto/dsa/dsa_lib.c | 26 | ||||
-rw-r--r-- | crypto/dsa/dsa_local.h | 4 | ||||
-rw-r--r-- | crypto/dsa/dsa_ossl.c | 7 | ||||
-rw-r--r-- | crypto/dsa/dsa_sign.c | 8 |
7 files changed, 145 insertions, 64 deletions
diff --git a/crypto/dsa/dsa_check.c b/crypto/dsa/dsa_check.c new file mode 100644 index 0000000000..3b86d2dc7a --- /dev/null +++ b/crypto/dsa/dsa_check.c @@ -0,0 +1,85 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include "dsa_local.h" +#include "crypto/dsa.h" + +int dsa_check_params(const DSA *dsa, int *ret) +{ + int nid; + /* + * (2b) FFC domain params conform to FIPS-186-4 explicit domain param + * validity tests. + */ + return ffc_params_FIPS186_4_validate(&dsa->params, FFC_PARAM_TYPE_DSA, NULL, + FFC_PARAMS_VALIDATE_ALL, ret, NULL); +} + +/* + * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Full public key validation. + */ +int dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret) +{ + return ffc_validate_public_key(&dsa->params, pub_key, ret); +} + +/* + * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Partial public key validation. + * To only be used with ephemeral FFC public keys generated using the approved + * safe-prime groups. + */ +int dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, int *ret) +{ + return ffc_validate_public_key_partial(&dsa->params, pub_key, ret); +} + +int dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret) +{ + *ret = 0; + + return (dsa->params.q != NULL + && ffc_validate_private_key(dsa->params.q, priv_key, ret)); +} + +/* + * FFC pairwise check from SP800-56A R3. + * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency + */ +int dsa_check_pairwise(const DSA *dsa) +{ + int ret = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL; + + if (dsa->params.p == NULL + || dsa->params.g == NULL + || dsa->priv_key == NULL + || dsa->pub_key == NULL) + return 0; + + ctx = BN_CTX_new_ex(dsa->libctx); + if (ctx == NULL) + goto err; + pub_key = BN_new(); + if (pub_key == NULL) + goto err; + + /* recalculate the public key = (g ^ priv) mod p */ + if (!dsa_generate_public_key(ctx, dsa, dsa->priv_key, pub_key)) + goto err; + /* check it matches the existing pubic_key */ + ret = BN_cmp(pub_key, dsa->pub_key) == 0; +err: + BN_free(pub_key); + BN_CTX_free(ctx); + return ret; +} diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index ac5907c4f8..2148a1a487 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -23,7 +23,7 @@ #include "crypto/dsa.h" #include "dsa_local.h" -int dsa_generate_ffc_parameters(OPENSSL_CTX *libctx, DSA *dsa, int type, +int dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits, int gindex, BN_GENCB *cb) { @@ -37,12 +37,12 @@ int dsa_generate_ffc_parameters(OPENSSL_CTX *libctx, DSA *dsa, int type, dsa->params.gindex = gindex; #ifndef FIPS_MODE if (type == DSA_PARAMGEN_TYPE_FIPS_186_2) - ret = ffc_params_FIPS186_2_generate(libctx, &dsa->params, + ret = ffc_params_FIPS186_2_generate(dsa->libctx, &dsa->params, FFC_PARAM_TYPE_DSA, pbits, qbits, NULL, &res, cb); else #endif - ret = ffc_params_FIPS186_4_generate(libctx, &dsa->params, + ret = ffc_params_FIPS186_4_generate(dsa->libctx, &dsa->params, FFC_PARAM_TYPE_DSA, pbits, qbits, NULL, &res, cb); if (ret > 0) @@ -50,10 +50,10 @@ int dsa_generate_ffc_parameters(OPENSSL_CTX *libctx, DSA *dsa, int type, return ret; } -int dsa_generate_parameters_ctx(OPENSSL_CTX *libctx, DSA *dsa, int bits, - const unsigned char *seed_in, int seed_len, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb) +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb) { #ifndef FIPS_MODE if (dsa->meth->dsa_paramgen) @@ -67,15 +67,13 @@ int dsa_generate_parameters_ctx(OPENSSL_CTX *libctx, DSA *dsa, int bits, #ifndef FIPS_MODE /* The old code used FIPS 186-2 DSA Parameter generation */ if (bits <= 1024 && seed_len == 20) { - if (!dsa_generate_ffc_parameters(libctx, dsa, - DSA_PARAMGEN_TYPE_FIPS_186_2, + if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_2, bits, 160, -1, cb)) return 0; } else #endif { - if (!dsa_generate_ffc_parameters(libctx, dsa, - DSA_PARAMGEN_TYPE_FIPS_186_4, + if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_4, bits, -1, -1, cb)) return 0; } @@ -86,13 +84,3 @@ int dsa_generate_parameters_ctx(OPENSSL_CTX *libctx, DSA *dsa, int bits, *h_ret = dsa->params.h; return 1; } - -int DSA_generate_parameters_ex(DSA *dsa, int bits, - const unsigned char *seed_in, int seed_len, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb) -{ - return dsa_generate_parameters_ctx(NULL, dsa, bits, - seed_in, seed_len, - counter_ret, h_ret, cb); -} diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index 00e7213b97..c93ea15b76 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -20,31 +20,43 @@ #include "crypto/dsa.h" #include "dsa_local.h" -static int dsa_builtin_keygen(OPENSSL_CTX *libctx, DSA *dsa); +static int dsa_builtin_keygen(DSA *dsa); int DSA_generate_key(DSA *dsa) { +#ifndef FIPS_MODE if (dsa->meth->dsa_keygen != NULL) return dsa->meth->dsa_keygen(dsa); - return dsa_builtin_keygen(NULL, dsa); +#endif + return dsa_builtin_keygen(dsa); } -int dsa_generate_key_ctx(OPENSSL_CTX *libctx, DSA *dsa) +int dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, const BIGNUM *priv_key, + BIGNUM *pub_key) { -#ifndef FIPS_MODE - if (dsa->meth->dsa_keygen != NULL) - return dsa->meth->dsa_keygen(dsa); -#endif - return dsa_builtin_keygen(libctx, dsa); + int ret = 0; + BIGNUM *prk = BN_new(); + + if (prk == NULL) + return 0; + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + + /* pub_key = g ^ priv_key mod p */ + if (!BN_mod_exp(pub_key, dsa->params.g, prk, dsa->params.p, ctx)) + goto err; + ret = 1; +err: + BN_clear_free(prk); + return ret; } -static int dsa_builtin_keygen(OPENSSL_CTX *libctx, DSA *dsa) +static int dsa_builtin_keygen(DSA *dsa) { int ok = 0; BN_CTX *ctx = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; - if ((ctx = BN_CTX_new_ex(libctx)) == NULL) + if ((ctx = BN_CTX_new_ex(dsa->libctx)) == NULL) goto err; if (dsa->priv_key == NULL) { @@ -65,21 +77,8 @@ static int dsa_builtin_keygen(OPENSSL_CTX *libctx, DSA *dsa) pub_key = dsa->pub_key; } - { - BIGNUM *prk = BN_new(); - - if (prk == NULL) - goto err; - BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); - - /* pub_key = g ^ priv_key mod p */ - if (!BN_mod_exp(pub_key, dsa->params.g, prk, dsa->params.p, ctx)) { - BN_free(prk); - goto err; - } - /* We MUST free prk before any further use of priv_key */ - BN_free(prk); - } + if (!dsa_generate_public_key(ctx, dsa, priv_key, pub_key)) + goto err; dsa->priv_key = priv_key; dsa->pub_key = pub_key; diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 11f09891b2..4b048d48c5 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -23,6 +23,8 @@ #include "crypto/dsa.h" #include "crypto/dh.h" /* required by DSA_dup_DH() */ +static DSA *dsa_new_intern(ENGINE *engine, OPENSSL_CTX *libctx); + #ifndef FIPS_MODE int DSA_set_ex_data(DSA *d, int idx, void *arg) @@ -128,29 +130,30 @@ const DSA_METHOD *DSA_get_method(DSA *d) return d->meth; } -static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine) +static DSA *dsa_new_intern(ENGINE *engine, OPENSSL_CTX *libctx) { DSA *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + DSAerr(0, ERR_R_MALLOC_FAILURE); return NULL; } ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + DSAerr(0, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } + ret->libctx = libctx; ret->meth = DSA_get_default_method(); #if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE) ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */ if (engine) { if (!ENGINE_init(engine)) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + DSAerr(0, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; @@ -159,7 +162,7 @@ static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine) if (ret->engine) { ret->meth = ENGINE_get_DSA(ret->engine); if (ret->meth == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + DSAerr(0, ERR_R_ENGINE_LIB); goto err; } } @@ -173,7 +176,7 @@ static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine) #endif if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL); + DSAerr(0, ERR_R_INIT_FAIL); goto err; } @@ -186,13 +189,20 @@ static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine) DSA *DSA_new_method(ENGINE *engine) { - return dsa_new_method(NULL, engine); + return dsa_new_intern(engine, NULL); +} + +DSA *dsa_new_with_ctx(OPENSSL_CTX *libctx) +{ + return dsa_new_intern(NULL, libctx); } +#ifndef FIPS_MODE DSA *DSA_new(void) { - return DSA_new_method(NULL); + return dsa_new_intern(NULL, NULL); } +#endif void DSA_free(DSA *r) { diff --git a/crypto/dsa/dsa_local.h b/crypto/dsa/dsa_local.h index f01b0aae8c..f68ae2d05b 100644 --- a/crypto/dsa/dsa_local.h +++ b/crypto/dsa/dsa_local.h @@ -32,6 +32,7 @@ struct dsa_st { /* functional reference if 'meth' is ENGINE-provided */ ENGINE *engine; CRYPTO_RWLOCK *lock; + OPENSSL_CTX *libctx; /* Provider data */ size_t dirty_cnt; /* If any key material changes, increment this */ @@ -68,5 +69,4 @@ struct dsa_method { int (*dsa_keygen) (DSA *dsa); }; -DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst, - int dlen, DSA *dsa); +DSA_SIG *dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa); diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 6ff22e8c87..a87493a061 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -67,8 +67,7 @@ const DSA_METHOD *DSA_OpenSSL(void) return &openssl_dsa_meth; } -DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst, - int dlen, DSA *dsa) +DSA_SIG *dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa) { BIGNUM *kinv = NULL; BIGNUM *m, *blind, *blindm, *tmp; @@ -96,7 +95,7 @@ DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst, if (ret->r == NULL || ret->s == NULL) goto err; - ctx = BN_CTX_new_ex(libctx); + ctx = BN_CTX_new_ex(dsa->libctx); if (ctx == NULL) goto err; m = BN_CTX_get(ctx); @@ -186,7 +185,7 @@ DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst, static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { - return dsa_do_sign_int(NULL, dgst, dlen, dsa); + return dsa_do_sign_int(dgst, dlen, dsa); } static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index 1ee9272ced..9ef8f30f1e 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -148,16 +148,16 @@ int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) return 1; } -int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst, +int dsa_sign_int(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa) { DSA_SIG *s; /* legacy case uses the method table */ - if (libctx == NULL || dsa->meth != DSA_get_default_method()) + if (dsa->libctx == NULL || dsa->meth != DSA_get_default_method()) s = DSA_do_sign(dgst, dlen, dsa); else - s = dsa_do_sign_int(libctx, dgst, dlen, dsa); + s = dsa_do_sign_int(dgst, dlen, dsa); if (s == NULL) { *siglen = 0; return 0; @@ -170,7 +170,7 @@ int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst, int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa) { - return dsa_sign_int(NULL, type, dgst, dlen, sig, siglen, dsa); + return dsa_sign_int(type, dgst, dlen, sig, siglen, dsa); } /* data has already been hashed (probably with SHA or SHA-1). */ |