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 <stdio.h> 17e1051a39Sopenharmony_ci#include <time.h> 18e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 19e1051a39Sopenharmony_ci#include <openssl/bn.h> 20e1051a39Sopenharmony_ci#include <openssl/self_test.h> 21e1051a39Sopenharmony_ci#include "prov/providercommon.h" 22e1051a39Sopenharmony_ci#include "crypto/dsa.h" 23e1051a39Sopenharmony_ci#include "dsa_local.h" 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 26e1051a39Sopenharmony_ci# define MIN_STRENGTH 112 27e1051a39Sopenharmony_ci#else 28e1051a39Sopenharmony_ci# define MIN_STRENGTH 80 29e1051a39Sopenharmony_ci#endif 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_cistatic int dsa_keygen(DSA *dsa, int pairwise_test); 32e1051a39Sopenharmony_cistatic int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg); 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ciint DSA_generate_key(DSA *dsa) 35e1051a39Sopenharmony_ci{ 36e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 37e1051a39Sopenharmony_ci if (dsa->meth->dsa_keygen != NULL) 38e1051a39Sopenharmony_ci return dsa->meth->dsa_keygen(dsa); 39e1051a39Sopenharmony_ci#endif 40e1051a39Sopenharmony_ci return dsa_keygen(dsa, 0); 41e1051a39Sopenharmony_ci} 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ciint ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, 44e1051a39Sopenharmony_ci const BIGNUM *priv_key, BIGNUM *pub_key) 45e1051a39Sopenharmony_ci{ 46e1051a39Sopenharmony_ci int ret = 0; 47e1051a39Sopenharmony_ci BIGNUM *prk = BN_new(); 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ci if (prk == NULL) 50e1051a39Sopenharmony_ci return 0; 51e1051a39Sopenharmony_ci BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ci /* pub_key = g ^ priv_key mod p */ 54e1051a39Sopenharmony_ci if (!BN_mod_exp(pub_key, dsa->params.g, prk, dsa->params.p, ctx)) 55e1051a39Sopenharmony_ci goto err; 56e1051a39Sopenharmony_ci ret = 1; 57e1051a39Sopenharmony_cierr: 58e1051a39Sopenharmony_ci BN_clear_free(prk); 59e1051a39Sopenharmony_ci return ret; 60e1051a39Sopenharmony_ci} 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_cistatic int dsa_keygen(DSA *dsa, int pairwise_test) 63e1051a39Sopenharmony_ci{ 64e1051a39Sopenharmony_ci int ok = 0; 65e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 66e1051a39Sopenharmony_ci BIGNUM *pub_key = NULL, *priv_key = NULL; 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci if ((ctx = BN_CTX_new_ex(dsa->libctx)) == NULL) 69e1051a39Sopenharmony_ci goto err; 70e1051a39Sopenharmony_ci 71e1051a39Sopenharmony_ci if (dsa->priv_key == NULL) { 72e1051a39Sopenharmony_ci if ((priv_key = BN_secure_new()) == NULL) 73e1051a39Sopenharmony_ci goto err; 74e1051a39Sopenharmony_ci } else { 75e1051a39Sopenharmony_ci priv_key = dsa->priv_key; 76e1051a39Sopenharmony_ci } 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ci /* Do a partial check for invalid p, q, g */ 79e1051a39Sopenharmony_ci if (!ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params, 80e1051a39Sopenharmony_ci FFC_PARAM_TYPE_DSA, NULL)) 81e1051a39Sopenharmony_ci goto err; 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci /* 84e1051a39Sopenharmony_ci * For FFC FIPS 186-4 keygen 85e1051a39Sopenharmony_ci * security strength s = 112, 86e1051a39Sopenharmony_ci * Max Private key size N = len(q) 87e1051a39Sopenharmony_ci */ 88e1051a39Sopenharmony_ci if (!ossl_ffc_generate_private_key(ctx, &dsa->params, 89e1051a39Sopenharmony_ci BN_num_bits(dsa->params.q), 90e1051a39Sopenharmony_ci MIN_STRENGTH, priv_key)) 91e1051a39Sopenharmony_ci goto err; 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_ci if (dsa->pub_key == NULL) { 94e1051a39Sopenharmony_ci if ((pub_key = BN_new()) == NULL) 95e1051a39Sopenharmony_ci goto err; 96e1051a39Sopenharmony_ci } else { 97e1051a39Sopenharmony_ci pub_key = dsa->pub_key; 98e1051a39Sopenharmony_ci } 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci if (!ossl_dsa_generate_public_key(ctx, dsa, priv_key, pub_key)) 101e1051a39Sopenharmony_ci goto err; 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_ci dsa->priv_key = priv_key; 104e1051a39Sopenharmony_ci dsa->pub_key = pub_key; 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 107e1051a39Sopenharmony_ci pairwise_test = 1; 108e1051a39Sopenharmony_ci#endif /* FIPS_MODULE */ 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_ci ok = 1; 111e1051a39Sopenharmony_ci if (pairwise_test) { 112e1051a39Sopenharmony_ci OSSL_CALLBACK *cb = NULL; 113e1051a39Sopenharmony_ci void *cbarg = NULL; 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ci OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg); 116e1051a39Sopenharmony_ci ok = dsa_keygen_pairwise_test(dsa, cb, cbarg); 117e1051a39Sopenharmony_ci if (!ok) { 118e1051a39Sopenharmony_ci ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); 119e1051a39Sopenharmony_ci BN_free(dsa->pub_key); 120e1051a39Sopenharmony_ci BN_clear_free(dsa->priv_key); 121e1051a39Sopenharmony_ci dsa->pub_key = NULL; 122e1051a39Sopenharmony_ci dsa->priv_key = NULL; 123e1051a39Sopenharmony_ci BN_CTX_free(ctx); 124e1051a39Sopenharmony_ci return ok; 125e1051a39Sopenharmony_ci } 126e1051a39Sopenharmony_ci } 127e1051a39Sopenharmony_ci dsa->dirty_cnt++; 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci err: 130e1051a39Sopenharmony_ci if (pub_key != dsa->pub_key) 131e1051a39Sopenharmony_ci BN_free(pub_key); 132e1051a39Sopenharmony_ci if (priv_key != dsa->priv_key) 133e1051a39Sopenharmony_ci BN_free(priv_key); 134e1051a39Sopenharmony_ci BN_CTX_free(ctx); 135e1051a39Sopenharmony_ci 136e1051a39Sopenharmony_ci return ok; 137e1051a39Sopenharmony_ci} 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci/* 140e1051a39Sopenharmony_ci * FIPS 140-2 IG 9.9 AS09.33 141e1051a39Sopenharmony_ci * Perform a sign/verify operation. 142e1051a39Sopenharmony_ci */ 143e1051a39Sopenharmony_cistatic int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg) 144e1051a39Sopenharmony_ci{ 145e1051a39Sopenharmony_ci int ret = 0; 146e1051a39Sopenharmony_ci unsigned char dgst[16] = {0}; 147e1051a39Sopenharmony_ci unsigned int dgst_len = (unsigned int)sizeof(dgst); 148e1051a39Sopenharmony_ci DSA_SIG *sig = NULL; 149e1051a39Sopenharmony_ci OSSL_SELF_TEST *st = NULL; 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_ci st = OSSL_SELF_TEST_new(cb, cbarg); 152e1051a39Sopenharmony_ci if (st == NULL) 153e1051a39Sopenharmony_ci goto err; 154e1051a39Sopenharmony_ci 155e1051a39Sopenharmony_ci OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, 156e1051a39Sopenharmony_ci OSSL_SELF_TEST_DESC_PCT_DSA); 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci sig = DSA_do_sign(dgst, (int)dgst_len, dsa); 159e1051a39Sopenharmony_ci if (sig == NULL) 160e1051a39Sopenharmony_ci goto err; 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_ci OSSL_SELF_TEST_oncorrupt_byte(st, dgst); 163e1051a39Sopenharmony_ci 164e1051a39Sopenharmony_ci if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1) 165e1051a39Sopenharmony_ci goto err; 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ci ret = 1; 168e1051a39Sopenharmony_cierr: 169e1051a39Sopenharmony_ci OSSL_SELF_TEST_onend(st, ret); 170e1051a39Sopenharmony_ci OSSL_SELF_TEST_free(st); 171e1051a39Sopenharmony_ci DSA_SIG_free(sig); 172e1051a39Sopenharmony_ci return ret; 173e1051a39Sopenharmony_ci} 174