diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-02-10 18:44:00 +0100 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-02-18 11:02:26 +0100 |
commit | ba37b82045b1b2fbcbf7580b317de5e3b52c8035 (patch) | |
tree | 96e779b80c7c34adf8913f02bcc557cff6661042 /crypto/ffc | |
parent | ebcaf110b250cd55281500fa1debef806ab490f0 (diff) |
dsa_check: Perform simple parameter check if seed is not available
Added primality check on p and q in the ossl_ffc_params_simple_validate().
Checking for p and q sizes in the default provider is made more
lenient.
Added two testcases for invalid parameters.
Fixes #13950
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14148)
Diffstat (limited to 'crypto/ffc')
-rw-r--r-- | crypto/ffc/ffc_params_generate.c | 10 | ||||
-rw-r--r-- | crypto/ffc/ffc_params_validate.c | 98 |
2 files changed, 87 insertions, 21 deletions
diff --git a/crypto/ffc/ffc_params_generate.c b/crypto/ffc/ffc_params_generate.c index 9285f93c05..2e50c2b801 100644 --- a/crypto/ffc/ffc_params_generate.c +++ b/crypto/ffc/ffc_params_generate.c @@ -77,12 +77,12 @@ static int ffc_validate_LN(size_t L, size_t N, int type, int verify) ERR_raise(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS); # endif } else if (type == FFC_PARAM_TYPE_DSA) { - if (L == 1024 && N == 160) - return 80; - if (L == 2048 && (N == 224 || N == 256)) - return 112; - if (L == 3072 && N == 256) + if (L >= 3072 && N >= 256) return 128; + if (L >= 2048 && N >= 224) + return 112; + if (L >= 1024 && N >= 160) + return 80; # ifndef OPENSSL_NO_DSA ERR_raise(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS); # endif diff --git a/crypto/ffc/ffc_params_validate.c b/crypto/ffc/ffc_params_validate.c index 22983d62ef..a2bfe22da2 100644 --- a/crypto/ffc/ffc_params_validate.c +++ b/crypto/ffc/ffc_params_validate.c @@ -13,6 +13,10 @@ * It calls the same functions as the generation as the code is very similar. */ +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/dsaerr.h> +#include <openssl/dherr.h> #include "internal/ffc.h" /* FIPS186-4 A.2.2 Unverifiable partial validation of Generator g */ @@ -88,30 +92,92 @@ int ossl_ffc_params_FIPS186_2_validate(OSSL_LIB_CTX *libctx, * extra parameters such as the digest and seed, which may not be available for * this test. */ -int ossl_ffc_params_simple_validate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, - int type) +int ossl_ffc_params_simple_validate(OSSL_LIB_CTX *libctx, const FFC_PARAMS *params, + int paramstype, int *res) { - int ret, res = 0; - int save_gindex; - unsigned int save_flags; + int ret; + int tmpres = 0; + FFC_PARAMS tmpparams = {0}; if (params == NULL) return 0; - save_flags = params->flags; - save_gindex = params->gindex; - params->flags = FFC_PARAM_FLAG_VALIDATE_G; - params->gindex = FFC_UNVERIFIABLE_GINDEX; + if (res == NULL) + res = &tmpres; + + if (!ossl_ffc_params_copy(&tmpparams, params)) + return 0; + + tmpparams.flags = FFC_PARAM_FLAG_VALIDATE_G; + tmpparams.gindex = FFC_UNVERIFIABLE_GINDEX; #ifndef FIPS_MODULE - if (save_flags & FFC_PARAM_FLAG_VALIDATE_LEGACY) - ret = ossl_ffc_params_FIPS186_2_validate(libctx, params, type, &res, - NULL); + if (params->flags & FFC_PARAM_FLAG_VALIDATE_LEGACY) + ret = ossl_ffc_params_FIPS186_2_validate(libctx, &tmpparams, paramstype, + res, NULL); else #endif - ret = ossl_ffc_params_FIPS186_4_validate(libctx, params, type, &res, - NULL); - params->flags = save_flags; - params->gindex = save_gindex; + ret = ossl_ffc_params_FIPS186_4_validate(libctx, &tmpparams, paramstype, + res, NULL); +#ifndef OPENSSL_NO_DH + if (ret == FFC_PARAM_RET_STATUS_FAILED + && (*res & FFC_ERROR_NOT_SUITABLE_GENERATOR) != 0) { + ERR_raise(ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR); + } +#endif + + ossl_ffc_params_cleanup(&tmpparams); + return ret != FFC_PARAM_RET_STATUS_FAILED; } + +/* + * If possible (or always in FIPS_MODULE) do full FIPS 186-4 validation. + * Otherwise do simple check but in addition also check the primality of the + * p and q. + */ +int ossl_ffc_params_full_validate(OSSL_LIB_CTX *libctx, const FFC_PARAMS *params, + int paramstype, int *res) +{ + int tmpres = 0; + + if (params == NULL) + return 0; + + if (res == NULL) + res = &tmpres; + +#ifdef FIPS_MODULE + return ossl_ffc_params_FIPS186_4_validate(libctx, params, paramstype, + res, NULL); +#else + if (params->seed != NULL) { + return ossl_ffc_params_FIPS186_4_validate(libctx, params, paramstype, + res, NULL); + } else { + int ret = 0; + + ret = ossl_ffc_params_simple_validate(libctx, params, paramstype, res); + if (ret) { + BN_CTX *ctx; + + if ((ctx = BN_CTX_new_ex(libctx)) == NULL) + return 0; + if (BN_check_prime(params->q, ctx, NULL) != 1) { +# ifndef OPENSSL_NO_DSA + ERR_raise(ERR_LIB_DSA, DSA_R_Q_NOT_PRIME); +# endif + ret = 0; + } + if (ret && BN_check_prime(params->p, ctx, NULL) != 1) { +# ifndef OPENSSL_NO_DSA + ERR_raise(ERR_LIB_DSA, DSA_R_P_NOT_PRIME); +# endif + ret = 0; + } + BN_CTX_free(ctx); + } + return ret; + } +#endif +} |