1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * DSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <openssl/bn.h> 17e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 18e1051a39Sopenharmony_ci# include <openssl/engine.h> 19e1051a39Sopenharmony_ci#endif 20e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 21e1051a39Sopenharmony_ci#include "internal/refcount.h" 22e1051a39Sopenharmony_ci#include "crypto/dsa.h" 23e1051a39Sopenharmony_ci#include "crypto/dh.h" /* required by DSA_dup_DH() */ 24e1051a39Sopenharmony_ci#include "dsa_local.h" 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_cistatic DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ciint DSA_set_ex_data(DSA *d, int idx, void *arg) 31e1051a39Sopenharmony_ci{ 32e1051a39Sopenharmony_ci return CRYPTO_set_ex_data(&d->ex_data, idx, arg); 33e1051a39Sopenharmony_ci} 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_civoid *DSA_get_ex_data(const DSA *d, int idx) 36e1051a39Sopenharmony_ci{ 37e1051a39Sopenharmony_ci return CRYPTO_get_ex_data(&d->ex_data, idx); 38e1051a39Sopenharmony_ci} 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_DH 41e1051a39Sopenharmony_ciDH *DSA_dup_DH(const DSA *r) 42e1051a39Sopenharmony_ci{ 43e1051a39Sopenharmony_ci /* 44e1051a39Sopenharmony_ci * DSA has p, q, g, optional pub_key, optional priv_key. 45e1051a39Sopenharmony_ci * DH has p, optional length, g, optional pub_key, 46e1051a39Sopenharmony_ci * optional priv_key, optional q. 47e1051a39Sopenharmony_ci */ 48e1051a39Sopenharmony_ci DH *ret = NULL; 49e1051a39Sopenharmony_ci BIGNUM *pub_key = NULL, *priv_key = NULL; 50e1051a39Sopenharmony_ci 51e1051a39Sopenharmony_ci if (r == NULL) 52e1051a39Sopenharmony_ci goto err; 53e1051a39Sopenharmony_ci ret = DH_new(); 54e1051a39Sopenharmony_ci if (ret == NULL) 55e1051a39Sopenharmony_ci goto err; 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_ci if (!ossl_ffc_params_copy(ossl_dh_get0_params(ret), &r->params)) 58e1051a39Sopenharmony_ci goto err; 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_ci if (r->pub_key != NULL) { 61e1051a39Sopenharmony_ci pub_key = BN_dup(r->pub_key); 62e1051a39Sopenharmony_ci if (pub_key == NULL) 63e1051a39Sopenharmony_ci goto err; 64e1051a39Sopenharmony_ci if (r->priv_key != NULL) { 65e1051a39Sopenharmony_ci priv_key = BN_dup(r->priv_key); 66e1051a39Sopenharmony_ci if (priv_key == NULL) 67e1051a39Sopenharmony_ci goto err; 68e1051a39Sopenharmony_ci } 69e1051a39Sopenharmony_ci if (!DH_set0_key(ret, pub_key, priv_key)) 70e1051a39Sopenharmony_ci goto err; 71e1051a39Sopenharmony_ci } else if (r->priv_key != NULL) { 72e1051a39Sopenharmony_ci /* Shouldn't happen */ 73e1051a39Sopenharmony_ci goto err; 74e1051a39Sopenharmony_ci } 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci return ret; 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ci err: 79e1051a39Sopenharmony_ci BN_free(pub_key); 80e1051a39Sopenharmony_ci BN_free(priv_key); 81e1051a39Sopenharmony_ci DH_free(ret); 82e1051a39Sopenharmony_ci return NULL; 83e1051a39Sopenharmony_ci} 84e1051a39Sopenharmony_ci# endif /* OPENSSL_NO_DH */ 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_civoid DSA_clear_flags(DSA *d, int flags) 87e1051a39Sopenharmony_ci{ 88e1051a39Sopenharmony_ci d->flags &= ~flags; 89e1051a39Sopenharmony_ci} 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ciint DSA_test_flags(const DSA *d, int flags) 92e1051a39Sopenharmony_ci{ 93e1051a39Sopenharmony_ci return d->flags & flags; 94e1051a39Sopenharmony_ci} 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_civoid DSA_set_flags(DSA *d, int flags) 97e1051a39Sopenharmony_ci{ 98e1051a39Sopenharmony_ci d->flags |= flags; 99e1051a39Sopenharmony_ci} 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ciENGINE *DSA_get0_engine(DSA *d) 102e1051a39Sopenharmony_ci{ 103e1051a39Sopenharmony_ci return d->engine; 104e1051a39Sopenharmony_ci} 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ciint DSA_set_method(DSA *dsa, const DSA_METHOD *meth) 107e1051a39Sopenharmony_ci{ 108e1051a39Sopenharmony_ci /* 109e1051a39Sopenharmony_ci * NB: The caller is specifically setting a method, so it's not up to us 110e1051a39Sopenharmony_ci * to deal with which ENGINE it comes from. 111e1051a39Sopenharmony_ci */ 112e1051a39Sopenharmony_ci const DSA_METHOD *mtmp; 113e1051a39Sopenharmony_ci mtmp = dsa->meth; 114e1051a39Sopenharmony_ci if (mtmp->finish) 115e1051a39Sopenharmony_ci mtmp->finish(dsa); 116e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 117e1051a39Sopenharmony_ci ENGINE_finish(dsa->engine); 118e1051a39Sopenharmony_ci dsa->engine = NULL; 119e1051a39Sopenharmony_ci#endif 120e1051a39Sopenharmony_ci dsa->meth = meth; 121e1051a39Sopenharmony_ci if (meth->init) 122e1051a39Sopenharmony_ci meth->init(dsa); 123e1051a39Sopenharmony_ci return 1; 124e1051a39Sopenharmony_ci} 125e1051a39Sopenharmony_ci#endif /* FIPS_MODULE */ 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci 128e1051a39Sopenharmony_ciconst DSA_METHOD *DSA_get_method(DSA *d) 129e1051a39Sopenharmony_ci{ 130e1051a39Sopenharmony_ci return d->meth; 131e1051a39Sopenharmony_ci} 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_cistatic DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) 134e1051a39Sopenharmony_ci{ 135e1051a39Sopenharmony_ci DSA *ret = OPENSSL_zalloc(sizeof(*ret)); 136e1051a39Sopenharmony_ci 137e1051a39Sopenharmony_ci if (ret == NULL) { 138e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 139e1051a39Sopenharmony_ci return NULL; 140e1051a39Sopenharmony_ci } 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci ret->references = 1; 143e1051a39Sopenharmony_ci ret->lock = CRYPTO_THREAD_lock_new(); 144e1051a39Sopenharmony_ci if (ret->lock == NULL) { 145e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 146e1051a39Sopenharmony_ci OPENSSL_free(ret); 147e1051a39Sopenharmony_ci return NULL; 148e1051a39Sopenharmony_ci } 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ci ret->libctx = libctx; 151e1051a39Sopenharmony_ci ret->meth = DSA_get_default_method(); 152e1051a39Sopenharmony_ci#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) 153e1051a39Sopenharmony_ci ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */ 154e1051a39Sopenharmony_ci if (engine) { 155e1051a39Sopenharmony_ci if (!ENGINE_init(engine)) { 156e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_ENGINE_LIB); 157e1051a39Sopenharmony_ci goto err; 158e1051a39Sopenharmony_ci } 159e1051a39Sopenharmony_ci ret->engine = engine; 160e1051a39Sopenharmony_ci } else 161e1051a39Sopenharmony_ci ret->engine = ENGINE_get_default_DSA(); 162e1051a39Sopenharmony_ci if (ret->engine) { 163e1051a39Sopenharmony_ci ret->meth = ENGINE_get_DSA(ret->engine); 164e1051a39Sopenharmony_ci if (ret->meth == NULL) { 165e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_ENGINE_LIB); 166e1051a39Sopenharmony_ci goto err; 167e1051a39Sopenharmony_ci } 168e1051a39Sopenharmony_ci } 169e1051a39Sopenharmony_ci#endif 170e1051a39Sopenharmony_ci 171e1051a39Sopenharmony_ci ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 174e1051a39Sopenharmony_ci if (!ossl_crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret, 175e1051a39Sopenharmony_ci &ret->ex_data)) 176e1051a39Sopenharmony_ci goto err; 177e1051a39Sopenharmony_ci#endif 178e1051a39Sopenharmony_ci 179e1051a39Sopenharmony_ci if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { 180e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_INIT_FAIL); 181e1051a39Sopenharmony_ci goto err; 182e1051a39Sopenharmony_ci } 183e1051a39Sopenharmony_ci 184e1051a39Sopenharmony_ci return ret; 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_ci err: 187e1051a39Sopenharmony_ci DSA_free(ret); 188e1051a39Sopenharmony_ci return NULL; 189e1051a39Sopenharmony_ci} 190e1051a39Sopenharmony_ci 191e1051a39Sopenharmony_ciDSA *DSA_new_method(ENGINE *engine) 192e1051a39Sopenharmony_ci{ 193e1051a39Sopenharmony_ci return dsa_new_intern(engine, NULL); 194e1051a39Sopenharmony_ci} 195e1051a39Sopenharmony_ci 196e1051a39Sopenharmony_ciDSA *ossl_dsa_new(OSSL_LIB_CTX *libctx) 197e1051a39Sopenharmony_ci{ 198e1051a39Sopenharmony_ci return dsa_new_intern(NULL, libctx); 199e1051a39Sopenharmony_ci} 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 202e1051a39Sopenharmony_ciDSA *DSA_new(void) 203e1051a39Sopenharmony_ci{ 204e1051a39Sopenharmony_ci return dsa_new_intern(NULL, NULL); 205e1051a39Sopenharmony_ci} 206e1051a39Sopenharmony_ci#endif 207e1051a39Sopenharmony_ci 208e1051a39Sopenharmony_civoid DSA_free(DSA *r) 209e1051a39Sopenharmony_ci{ 210e1051a39Sopenharmony_ci int i; 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_ci if (r == NULL) 213e1051a39Sopenharmony_ci return; 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_ci CRYPTO_DOWN_REF(&r->references, &i, r->lock); 216e1051a39Sopenharmony_ci REF_PRINT_COUNT("DSA", r); 217e1051a39Sopenharmony_ci if (i > 0) 218e1051a39Sopenharmony_ci return; 219e1051a39Sopenharmony_ci REF_ASSERT_ISNT(i < 0); 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_ci if (r->meth != NULL && r->meth->finish != NULL) 222e1051a39Sopenharmony_ci r->meth->finish(r); 223e1051a39Sopenharmony_ci#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) 224e1051a39Sopenharmony_ci ENGINE_finish(r->engine); 225e1051a39Sopenharmony_ci#endif 226e1051a39Sopenharmony_ci 227e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 228e1051a39Sopenharmony_ci CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); 229e1051a39Sopenharmony_ci#endif 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(r->lock); 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_ci ossl_ffc_params_cleanup(&r->params); 234e1051a39Sopenharmony_ci BN_clear_free(r->pub_key); 235e1051a39Sopenharmony_ci BN_clear_free(r->priv_key); 236e1051a39Sopenharmony_ci OPENSSL_free(r); 237e1051a39Sopenharmony_ci} 238e1051a39Sopenharmony_ci 239e1051a39Sopenharmony_ciint DSA_up_ref(DSA *r) 240e1051a39Sopenharmony_ci{ 241e1051a39Sopenharmony_ci int i; 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ci if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) 244e1051a39Sopenharmony_ci return 0; 245e1051a39Sopenharmony_ci 246e1051a39Sopenharmony_ci REF_PRINT_COUNT("DSA", r); 247e1051a39Sopenharmony_ci REF_ASSERT_ISNT(i < 2); 248e1051a39Sopenharmony_ci return ((i > 1) ? 1 : 0); 249e1051a39Sopenharmony_ci} 250e1051a39Sopenharmony_ci 251e1051a39Sopenharmony_civoid ossl_dsa_set0_libctx(DSA *d, OSSL_LIB_CTX *libctx) 252e1051a39Sopenharmony_ci{ 253e1051a39Sopenharmony_ci d->libctx = libctx; 254e1051a39Sopenharmony_ci} 255e1051a39Sopenharmony_ci 256e1051a39Sopenharmony_civoid DSA_get0_pqg(const DSA *d, 257e1051a39Sopenharmony_ci const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) 258e1051a39Sopenharmony_ci{ 259e1051a39Sopenharmony_ci ossl_ffc_params_get0_pqg(&d->params, p, q, g); 260e1051a39Sopenharmony_ci} 261e1051a39Sopenharmony_ci 262e1051a39Sopenharmony_ciint DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) 263e1051a39Sopenharmony_ci{ 264e1051a39Sopenharmony_ci /* If the fields p, q and g in d are NULL, the corresponding input 265e1051a39Sopenharmony_ci * parameters MUST be non-NULL. 266e1051a39Sopenharmony_ci */ 267e1051a39Sopenharmony_ci if ((d->params.p == NULL && p == NULL) 268e1051a39Sopenharmony_ci || (d->params.q == NULL && q == NULL) 269e1051a39Sopenharmony_ci || (d->params.g == NULL && g == NULL)) 270e1051a39Sopenharmony_ci return 0; 271e1051a39Sopenharmony_ci 272e1051a39Sopenharmony_ci ossl_ffc_params_set0_pqg(&d->params, p, q, g); 273e1051a39Sopenharmony_ci d->dirty_cnt++; 274e1051a39Sopenharmony_ci 275e1051a39Sopenharmony_ci return 1; 276e1051a39Sopenharmony_ci} 277e1051a39Sopenharmony_ci 278e1051a39Sopenharmony_ciconst BIGNUM *DSA_get0_p(const DSA *d) 279e1051a39Sopenharmony_ci{ 280e1051a39Sopenharmony_ci return d->params.p; 281e1051a39Sopenharmony_ci} 282e1051a39Sopenharmony_ci 283e1051a39Sopenharmony_ciconst BIGNUM *DSA_get0_q(const DSA *d) 284e1051a39Sopenharmony_ci{ 285e1051a39Sopenharmony_ci return d->params.q; 286e1051a39Sopenharmony_ci} 287e1051a39Sopenharmony_ci 288e1051a39Sopenharmony_ciconst BIGNUM *DSA_get0_g(const DSA *d) 289e1051a39Sopenharmony_ci{ 290e1051a39Sopenharmony_ci return d->params.g; 291e1051a39Sopenharmony_ci} 292e1051a39Sopenharmony_ci 293e1051a39Sopenharmony_ciconst BIGNUM *DSA_get0_pub_key(const DSA *d) 294e1051a39Sopenharmony_ci{ 295e1051a39Sopenharmony_ci return d->pub_key; 296e1051a39Sopenharmony_ci} 297e1051a39Sopenharmony_ci 298e1051a39Sopenharmony_ciconst BIGNUM *DSA_get0_priv_key(const DSA *d) 299e1051a39Sopenharmony_ci{ 300e1051a39Sopenharmony_ci return d->priv_key; 301e1051a39Sopenharmony_ci} 302e1051a39Sopenharmony_ci 303e1051a39Sopenharmony_civoid DSA_get0_key(const DSA *d, 304e1051a39Sopenharmony_ci const BIGNUM **pub_key, const BIGNUM **priv_key) 305e1051a39Sopenharmony_ci{ 306e1051a39Sopenharmony_ci if (pub_key != NULL) 307e1051a39Sopenharmony_ci *pub_key = d->pub_key; 308e1051a39Sopenharmony_ci if (priv_key != NULL) 309e1051a39Sopenharmony_ci *priv_key = d->priv_key; 310e1051a39Sopenharmony_ci} 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ciint DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) 313e1051a39Sopenharmony_ci{ 314e1051a39Sopenharmony_ci if (pub_key != NULL) { 315e1051a39Sopenharmony_ci BN_free(d->pub_key); 316e1051a39Sopenharmony_ci d->pub_key = pub_key; 317e1051a39Sopenharmony_ci } 318e1051a39Sopenharmony_ci if (priv_key != NULL) { 319e1051a39Sopenharmony_ci BN_free(d->priv_key); 320e1051a39Sopenharmony_ci d->priv_key = priv_key; 321e1051a39Sopenharmony_ci } 322e1051a39Sopenharmony_ci d->dirty_cnt++; 323e1051a39Sopenharmony_ci 324e1051a39Sopenharmony_ci return 1; 325e1051a39Sopenharmony_ci} 326e1051a39Sopenharmony_ci 327e1051a39Sopenharmony_ciint DSA_security_bits(const DSA *d) 328e1051a39Sopenharmony_ci{ 329e1051a39Sopenharmony_ci if (d->params.p != NULL && d->params.q != NULL) 330e1051a39Sopenharmony_ci return BN_security_bits(BN_num_bits(d->params.p), 331e1051a39Sopenharmony_ci BN_num_bits(d->params.q)); 332e1051a39Sopenharmony_ci return -1; 333e1051a39Sopenharmony_ci} 334e1051a39Sopenharmony_ci 335e1051a39Sopenharmony_ciint DSA_bits(const DSA *dsa) 336e1051a39Sopenharmony_ci{ 337e1051a39Sopenharmony_ci if (dsa->params.p != NULL) 338e1051a39Sopenharmony_ci return BN_num_bits(dsa->params.p); 339e1051a39Sopenharmony_ci return -1; 340e1051a39Sopenharmony_ci} 341e1051a39Sopenharmony_ci 342e1051a39Sopenharmony_ciFFC_PARAMS *ossl_dsa_get0_params(DSA *dsa) 343e1051a39Sopenharmony_ci{ 344e1051a39Sopenharmony_ci return &dsa->params; 345e1051a39Sopenharmony_ci} 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_ciint ossl_dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]) 348e1051a39Sopenharmony_ci{ 349e1051a39Sopenharmony_ci int ret; 350e1051a39Sopenharmony_ci FFC_PARAMS *ffc; 351e1051a39Sopenharmony_ci 352e1051a39Sopenharmony_ci if (dsa == NULL) 353e1051a39Sopenharmony_ci return 0; 354e1051a39Sopenharmony_ci ffc = ossl_dsa_get0_params(dsa); 355e1051a39Sopenharmony_ci if (ffc == NULL) 356e1051a39Sopenharmony_ci return 0; 357e1051a39Sopenharmony_ci 358e1051a39Sopenharmony_ci ret = ossl_ffc_params_fromdata(ffc, params); 359e1051a39Sopenharmony_ci if (ret) 360e1051a39Sopenharmony_ci dsa->dirty_cnt++; 361e1051a39Sopenharmony_ci return ret; 362e1051a39Sopenharmony_ci} 363