X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdsa%2Fdsa_lib.c;h=034300fc7ea4a3fda430d45034930a9829709769;hp=caaa65c1f53bb40b95b5d4818042827cd8690067;hb=HEAD;hpb=cd420b0b1f2336972e386eba1cccf23b47d99538 diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index caaa65c1f5..7997c2ac25 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -1,26 +1,106 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ -/* Original version from Steven Schoch */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" -#include +#include +#ifndef FIPS_MODULE +# include +#endif #include "internal/cryptlib.h" #include "internal/refcount.h" -#include -#include "dsa_locl.h" -#include -#include -#include +#include "crypto/dsa.h" +#include "crypto/dh.h" /* required by DSA_dup_DH() */ +#include "dsa_local.h" -DSA *DSA_new(void) +static DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); + +#ifndef FIPS_MODULE + +int DSA_set_ex_data(DSA *d, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&d->ex_data, idx, arg); +} + +void *DSA_get_ex_data(const DSA *d, int idx) { - return DSA_new_method(NULL); + return CRYPTO_get_ex_data(&d->ex_data, idx); +} + +# ifndef OPENSSL_NO_DH +DH *DSA_dup_DH(const DSA *r) +{ + /* + * DSA has p, q, g, optional pub_key, optional priv_key. + * DH has p, optional length, g, optional pub_key, + * optional priv_key, optional q. + */ + DH *ret = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if (r == NULL) + goto err; + ret = DH_new(); + if (ret == NULL) + goto err; + + if (!ossl_ffc_params_copy(ossl_dh_get0_params(ret), &r->params)) + goto err; + + if (r->pub_key != NULL) { + pub_key = BN_dup(r->pub_key); + if (pub_key == NULL) + goto err; + if (r->priv_key != NULL) { + priv_key = BN_dup(r->priv_key); + if (priv_key == NULL) + goto err; + } + if (!DH_set0_key(ret, pub_key, priv_key)) + goto err; + } else if (r->priv_key != NULL) { + /* Shouldn't happen */ + goto err; + } + + return ret; + + err: + BN_free(pub_key); + BN_free(priv_key); + DH_free(ret); + return NULL; +} +# endif /* OPENSSL_NO_DH */ + +void DSA_clear_flags(DSA *d, int flags) +{ + d->flags &= ~flags; +} + +int DSA_test_flags(const DSA *d, int flags) +{ + return d->flags & flags; +} + +void DSA_set_flags(DSA *d, int flags) +{ + d->flags |= flags; +} + +ENGINE *DSA_get0_engine(DSA *d) +{ + return d->engine; } int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) @@ -42,35 +122,41 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) meth->init(dsa); return 1; } +#endif /* FIPS_MODULE */ + const DSA_METHOD *DSA_get_method(DSA *d) { return d->meth; } -DSA *DSA_new_method(ENGINE *engine) +static DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { DSA *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + if (ret == NULL) 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); + ERR_raise(ERR_LIB_DSA, ERR_R_CRYPTO_LIB); + OPENSSL_free(ret); + return NULL; + } + + if (!CRYPTO_NEW_REF(&ret->references, 1)) { + CRYPTO_THREAD_lock_free(ret->lock); OPENSSL_free(ret); return NULL; } + ret->libctx = libctx; ret->meth = DSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE +#if !defined(FIPS_MODULE) && !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); + ERR_raise(ERR_LIB_DSA, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; @@ -79,7 +165,7 @@ DSA *DSA_new_method(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); + ERR_raise(ERR_LIB_DSA, ERR_R_ENGINE_LIB); goto err; } } @@ -87,19 +173,43 @@ DSA *DSA_new_method(ENGINE *engine) ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data)) +#ifndef FIPS_MODULE + if (!ossl_crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret, + &ret->ex_data)) goto err; +#endif + + ossl_ffc_params_init(&ret->params); if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL); -err: - DSA_free(ret); - ret = NULL; + ERR_raise(ERR_LIB_DSA, ERR_R_INIT_FAIL); + goto err; } return ret; + + err: + DSA_free(ret); + return NULL; +} + +DSA *DSA_new_method(ENGINE *engine) +{ + return dsa_new_intern(engine, NULL); +} + +DSA *ossl_dsa_new(OSSL_LIB_CTX *libctx) +{ + return dsa_new_intern(NULL, libctx); } +#ifndef FIPS_MODULE +DSA *DSA_new(void) +{ + return dsa_new_intern(NULL, NULL); +} +#endif + void DSA_free(DSA *r) { int i; @@ -107,25 +217,26 @@ void DSA_free(DSA *r) if (r == NULL) return; - CRYPTO_DOWN_REF(&r->references, &i, r->lock); + CRYPTO_DOWN_REF(&r->references, &i); REF_PRINT_COUNT("DSA", r); if (i > 0) return; REF_ASSERT_ISNT(i < 0); - if (r->meth->finish) + if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE +#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) ENGINE_finish(r->engine); #endif +#ifndef FIPS_MODULE CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); +#endif CRYPTO_THREAD_lock_free(r->lock); + CRYPTO_FREE_REF(&r->references); - BN_clear_free(r->p); - BN_clear_free(r->q); - BN_clear_free(r->g); + ossl_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r); @@ -135,7 +246,7 @@ int DSA_up_ref(DSA *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) + if (CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; REF_PRINT_COUNT("DSA", r); @@ -143,138 +254,56 @@ int DSA_up_ref(DSA *r) return ((i > 1) ? 1 : 0); } -int DSA_size(const DSA *r) +void ossl_dsa_set0_libctx(DSA *d, OSSL_LIB_CTX *libctx) { - int ret, i; - ASN1_INTEGER bs; - unsigned char buf[4]; /* 4 bytes looks really small. However, - * i2d_ASN1_INTEGER() will not look beyond - * the first byte, as long as the second - * parameter is NULL. */ - - i = BN_num_bits(r->q); - bs.length = (i + 7) / 8; - bs.data = buf; - bs.type = V_ASN1_INTEGER; - /* If the top bit is set the asn1 encoding is 1 larger. */ - buf[0] = 0xff; - - i = i2d_ASN1_INTEGER(&bs, NULL); - i += i; /* r and s */ - ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); - return (ret); + d->libctx = libctx; } -int DSA_set_ex_data(DSA *d, int idx, void *arg) +void DSA_get0_pqg(const DSA *d, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { - return (CRYPTO_set_ex_data(&d->ex_data, idx, arg)); + ossl_ffc_params_get0_pqg(&d->params, p, q, g); } -void *DSA_get_ex_data(DSA *d, int idx) +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { - return (CRYPTO_get_ex_data(&d->ex_data, idx)); + /* If the fields p, q and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((d->params.p == NULL && p == NULL) + || (d->params.q == NULL && q == NULL) + || (d->params.g == NULL && g == NULL)) + return 0; + + ossl_ffc_params_set0_pqg(&d->params, p, q, g); + d->dirty_cnt++; + + return 1; } -int DSA_security_bits(const DSA *d) +const BIGNUM *DSA_get0_p(const DSA *d) { - if (d->p && d->q) - return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q)); - return -1; + return d->params.p; } -#ifndef OPENSSL_NO_DH -DH *DSA_dup_DH(const DSA *r) +const BIGNUM *DSA_get0_q(const DSA *d) { - /* - * DSA has p, q, g, optional pub_key, optional priv_key. DH has p, - * optional length, g, optional pub_key, optional priv_key, optional q. - */ - - DH *ret = NULL; - BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL; - - if (r == NULL) - goto err; - ret = DH_new(); - if (ret == NULL) - goto err; - if (r->p != NULL || r->g != NULL || r->q != NULL) { - if (r->p == NULL || r->g == NULL || r->q == NULL) { - /* Shouldn't happen */ - goto err; - } - p = BN_dup(r->p); - g = BN_dup(r->g); - q = BN_dup(r->q); - if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g)) - goto err; - p = g = q = NULL; - } - - if (r->pub_key != NULL) { - pub_key = BN_dup(r->pub_key); - if (pub_key == NULL) - goto err; - if (r->priv_key != NULL) { - priv_key = BN_dup(r->priv_key); - if (priv_key == NULL) - goto err; - } - if (!DH_set0_key(ret, pub_key, priv_key)) - goto err; - } else if (r->priv_key != NULL) { - /* Shouldn't happen */ - goto err; - } - - return ret; - - err: - BN_free(p); - BN_free(g); - BN_free(q); - BN_free(pub_key); - BN_free(priv_key); - DH_free(ret); - return NULL; + return d->params.q; } -#endif -void DSA_get0_pqg(const DSA *d, - const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +const BIGNUM *DSA_get0_g(const DSA *d) { - if (p != NULL) - *p = d->p; - if (q != NULL) - *q = d->q; - if (g != NULL) - *g = d->g; + return d->params.g; } -int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +const BIGNUM *DSA_get0_pub_key(const DSA *d) { - /* If the fields p, q and g in d are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((d->p == NULL && p == NULL) - || (d->q == NULL && q == NULL) - || (d->g == NULL && g == NULL)) - return 0; - - if (p != NULL) { - BN_free(d->p); - d->p = p; - } - if (q != NULL) { - BN_free(d->q); - d->q = q; - } - if (g != NULL) { - BN_free(d->g); - d->g = g; - } + return d->pub_key; +} - return 1; +const BIGNUM *DSA_get0_priv_key(const DSA *d) +{ + return d->priv_key; } void DSA_get0_key(const DSA *d, @@ -288,13 +317,6 @@ void DSA_get0_key(const DSA *d, int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) { - /* If the field pub_key in d is NULL, the corresponding input - * parameters MUST be non-NULL. The priv_key field may - * be left NULL. - */ - if (d->pub_key == NULL && pub_key == NULL) - return 0; - if (pub_key != NULL) { BN_free(d->pub_key); d->pub_key = pub_key; @@ -303,31 +325,38 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) BN_free(d->priv_key); d->priv_key = priv_key; } + d->dirty_cnt++; return 1; } -void DSA_clear_flags(DSA *d, int flags) +int DSA_security_bits(const DSA *d) { - d->flags &= ~flags; + if (d->params.p != NULL && d->params.q != NULL) + return BN_security_bits(BN_num_bits(d->params.p), + BN_num_bits(d->params.q)); + return -1; } -int DSA_test_flags(const DSA *d, int flags) +int DSA_bits(const DSA *dsa) { - return d->flags & flags; + if (dsa->params.p != NULL) + return BN_num_bits(dsa->params.p); + return -1; } -void DSA_set_flags(DSA *d, int flags) +FFC_PARAMS *ossl_dsa_get0_params(DSA *dsa) { - d->flags |= flags; + return &dsa->params; } -ENGINE *DSA_get0_engine(DSA *d) +int ossl_dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]) { - return d->engine; -} + int ret; + FFC_PARAMS *ffc = ossl_dsa_get0_params(dsa); -int DSA_bits(const DSA *dsa) -{ - return BN_num_bits(dsa->p); + ret = ossl_ffc_params_fromdata(ffc, params); + if (ret) + dsa->dirty_cnt++; + return ret; }