1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-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 <string.h> 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_ci#include <openssl/crypto.h> 19e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 20e1051a39Sopenharmony_ci#include <openssl/core_names.h> 21e1051a39Sopenharmony_ci#include <openssl/err.h> 22e1051a39Sopenharmony_ci#include <openssl/dsa.h> 23e1051a39Sopenharmony_ci#include <openssl/params.h> 24e1051a39Sopenharmony_ci#include <openssl/evp.h> 25e1051a39Sopenharmony_ci#include <openssl/err.h> 26e1051a39Sopenharmony_ci#include <openssl/proverr.h> 27e1051a39Sopenharmony_ci#include "internal/nelem.h" 28e1051a39Sopenharmony_ci#include "internal/sizes.h" 29e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 30e1051a39Sopenharmony_ci#include "prov/providercommon.h" 31e1051a39Sopenharmony_ci#include "prov/implementations.h" 32e1051a39Sopenharmony_ci#include "prov/provider_ctx.h" 33e1051a39Sopenharmony_ci#include "prov/securitycheck.h" 34e1051a39Sopenharmony_ci#include "crypto/dsa.h" 35e1051a39Sopenharmony_ci#include "prov/der_dsa.h" 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_newctx_fn dsa_newctx; 38e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_sign_init_fn dsa_sign_init; 39e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_verify_init_fn dsa_verify_init; 40e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_sign_fn dsa_sign; 41e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_verify_fn dsa_verify; 42e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_init_fn dsa_digest_sign_init; 43e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_update_fn dsa_digest_signverify_update; 44e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_final_fn dsa_digest_sign_final; 45e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_verify_init_fn dsa_digest_verify_init; 46e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_verify_update_fn dsa_digest_signverify_update; 47e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_verify_final_fn dsa_digest_verify_final; 48e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_freectx_fn dsa_freectx; 49e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_dupctx_fn dsa_dupctx; 50e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_get_ctx_params_fn dsa_get_ctx_params; 51e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_gettable_ctx_params_fn dsa_gettable_ctx_params; 52e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_set_ctx_params_fn dsa_set_ctx_params; 53e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_settable_ctx_params_fn dsa_settable_ctx_params; 54e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_get_ctx_md_params_fn dsa_get_ctx_md_params; 55e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_gettable_ctx_md_params_fn dsa_gettable_ctx_md_params; 56e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_set_ctx_md_params_fn dsa_set_ctx_md_params; 57e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_settable_ctx_md_params_fn dsa_settable_ctx_md_params; 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ci/* 60e1051a39Sopenharmony_ci * What's passed as an actual key is defined by the KEYMGMT interface. 61e1051a39Sopenharmony_ci * We happen to know that our KEYMGMT simply passes DSA structures, so 62e1051a39Sopenharmony_ci * we use that here too. 63e1051a39Sopenharmony_ci */ 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_citypedef struct { 66e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; 67e1051a39Sopenharmony_ci char *propq; 68e1051a39Sopenharmony_ci DSA *dsa; 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci /* 71e1051a39Sopenharmony_ci * Flag to determine if the hash function can be changed (1) or not (0) 72e1051a39Sopenharmony_ci * Because it's dangerous to change during a DigestSign or DigestVerify 73e1051a39Sopenharmony_ci * operation, this flag is cleared by their Init function, and set again 74e1051a39Sopenharmony_ci * by their Final function. 75e1051a39Sopenharmony_ci */ 76e1051a39Sopenharmony_ci unsigned int flag_allow_md : 1; 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ci char mdname[OSSL_MAX_NAME_SIZE]; 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci /* The Algorithm Identifier of the combined signature algorithm */ 81e1051a39Sopenharmony_ci unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; 82e1051a39Sopenharmony_ci unsigned char *aid; 83e1051a39Sopenharmony_ci size_t aid_len; 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ci /* main digest */ 86e1051a39Sopenharmony_ci EVP_MD *md; 87e1051a39Sopenharmony_ci EVP_MD_CTX *mdctx; 88e1051a39Sopenharmony_ci int operation; 89e1051a39Sopenharmony_ci} PROV_DSA_CTX; 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_cistatic size_t dsa_get_md_size(const PROV_DSA_CTX *pdsactx) 93e1051a39Sopenharmony_ci{ 94e1051a39Sopenharmony_ci if (pdsactx->md != NULL) 95e1051a39Sopenharmony_ci return EVP_MD_get_size(pdsactx->md); 96e1051a39Sopenharmony_ci return 0; 97e1051a39Sopenharmony_ci} 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_cistatic void *dsa_newctx(void *provctx, const char *propq) 100e1051a39Sopenharmony_ci{ 101e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx; 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 104e1051a39Sopenharmony_ci return NULL; 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX)); 107e1051a39Sopenharmony_ci if (pdsactx == NULL) 108e1051a39Sopenharmony_ci return NULL; 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_ci pdsactx->libctx = PROV_LIBCTX_OF(provctx); 111e1051a39Sopenharmony_ci pdsactx->flag_allow_md = 1; 112e1051a39Sopenharmony_ci if (propq != NULL && (pdsactx->propq = OPENSSL_strdup(propq)) == NULL) { 113e1051a39Sopenharmony_ci OPENSSL_free(pdsactx); 114e1051a39Sopenharmony_ci pdsactx = NULL; 115e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 116e1051a39Sopenharmony_ci } 117e1051a39Sopenharmony_ci return pdsactx; 118e1051a39Sopenharmony_ci} 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_cistatic int dsa_setup_md(PROV_DSA_CTX *ctx, 121e1051a39Sopenharmony_ci const char *mdname, const char *mdprops) 122e1051a39Sopenharmony_ci{ 123e1051a39Sopenharmony_ci if (mdprops == NULL) 124e1051a39Sopenharmony_ci mdprops = ctx->propq; 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_ci if (mdname != NULL) { 127e1051a39Sopenharmony_ci int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); 128e1051a39Sopenharmony_ci WPACKET pkt; 129e1051a39Sopenharmony_ci EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); 130e1051a39Sopenharmony_ci int md_nid = ossl_digest_get_approved_nid_with_sha1(ctx->libctx, md, 131e1051a39Sopenharmony_ci sha1_allowed); 132e1051a39Sopenharmony_ci size_t mdname_len = strlen(mdname); 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci if (md == NULL || md_nid < 0) { 135e1051a39Sopenharmony_ci if (md == NULL) 136e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 137e1051a39Sopenharmony_ci "%s could not be fetched", mdname); 138e1051a39Sopenharmony_ci if (md_nid < 0) 139e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 140e1051a39Sopenharmony_ci "digest=%s", mdname); 141e1051a39Sopenharmony_ci if (mdname_len >= sizeof(ctx->mdname)) 142e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 143e1051a39Sopenharmony_ci "%s exceeds name buffer length", mdname); 144e1051a39Sopenharmony_ci EVP_MD_free(md); 145e1051a39Sopenharmony_ci return 0; 146e1051a39Sopenharmony_ci } 147e1051a39Sopenharmony_ci 148e1051a39Sopenharmony_ci if (!ctx->flag_allow_md) { 149e1051a39Sopenharmony_ci if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) { 150e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 151e1051a39Sopenharmony_ci "digest %s != %s", mdname, ctx->mdname); 152e1051a39Sopenharmony_ci EVP_MD_free(md); 153e1051a39Sopenharmony_ci return 0; 154e1051a39Sopenharmony_ci } 155e1051a39Sopenharmony_ci EVP_MD_free(md); 156e1051a39Sopenharmony_ci return 1; 157e1051a39Sopenharmony_ci } 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ci EVP_MD_CTX_free(ctx->mdctx); 160e1051a39Sopenharmony_ci EVP_MD_free(ctx->md); 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_ci /* 163e1051a39Sopenharmony_ci * We do not care about DER writing errors. 164e1051a39Sopenharmony_ci * All it really means is that for some reason, there's no 165e1051a39Sopenharmony_ci * AlgorithmIdentifier to be had, but the operation itself is 166e1051a39Sopenharmony_ci * still valid, just as long as it's not used to construct 167e1051a39Sopenharmony_ci * anything that needs an AlgorithmIdentifier. 168e1051a39Sopenharmony_ci */ 169e1051a39Sopenharmony_ci ctx->aid_len = 0; 170e1051a39Sopenharmony_ci if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) 171e1051a39Sopenharmony_ci && ossl_DER_w_algorithmIdentifier_DSA_with_MD(&pkt, -1, ctx->dsa, 172e1051a39Sopenharmony_ci md_nid) 173e1051a39Sopenharmony_ci && WPACKET_finish(&pkt)) { 174e1051a39Sopenharmony_ci WPACKET_get_total_written(&pkt, &ctx->aid_len); 175e1051a39Sopenharmony_ci ctx->aid = WPACKET_get_curr(&pkt); 176e1051a39Sopenharmony_ci } 177e1051a39Sopenharmony_ci WPACKET_cleanup(&pkt); 178e1051a39Sopenharmony_ci 179e1051a39Sopenharmony_ci ctx->mdctx = NULL; 180e1051a39Sopenharmony_ci ctx->md = md; 181e1051a39Sopenharmony_ci OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); 182e1051a39Sopenharmony_ci } 183e1051a39Sopenharmony_ci return 1; 184e1051a39Sopenharmony_ci} 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_cistatic int dsa_signverify_init(void *vpdsactx, void *vdsa, 187e1051a39Sopenharmony_ci const OSSL_PARAM params[], int operation) 188e1051a39Sopenharmony_ci{ 189e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 190e1051a39Sopenharmony_ci 191e1051a39Sopenharmony_ci if (!ossl_prov_is_running() 192e1051a39Sopenharmony_ci || pdsactx == NULL) 193e1051a39Sopenharmony_ci return 0; 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci if (vdsa == NULL && pdsactx->dsa == NULL) { 196e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 197e1051a39Sopenharmony_ci return 0; 198e1051a39Sopenharmony_ci } 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_ci if (vdsa != NULL) { 201e1051a39Sopenharmony_ci if (!ossl_dsa_check_key(pdsactx->libctx, vdsa, 202e1051a39Sopenharmony_ci operation == EVP_PKEY_OP_SIGN)) { 203e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 204e1051a39Sopenharmony_ci return 0; 205e1051a39Sopenharmony_ci } 206e1051a39Sopenharmony_ci if (!DSA_up_ref(vdsa)) 207e1051a39Sopenharmony_ci return 0; 208e1051a39Sopenharmony_ci DSA_free(pdsactx->dsa); 209e1051a39Sopenharmony_ci pdsactx->dsa = vdsa; 210e1051a39Sopenharmony_ci } 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_ci pdsactx->operation = operation; 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci if (!dsa_set_ctx_params(pdsactx, params)) 215e1051a39Sopenharmony_ci return 0; 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_ci return 1; 218e1051a39Sopenharmony_ci} 219e1051a39Sopenharmony_ci 220e1051a39Sopenharmony_cistatic int dsa_sign_init(void *vpdsactx, void *vdsa, const OSSL_PARAM params[]) 221e1051a39Sopenharmony_ci{ 222e1051a39Sopenharmony_ci return dsa_signverify_init(vpdsactx, vdsa, params, EVP_PKEY_OP_SIGN); 223e1051a39Sopenharmony_ci} 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_cistatic int dsa_verify_init(void *vpdsactx, void *vdsa, 226e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 227e1051a39Sopenharmony_ci{ 228e1051a39Sopenharmony_ci return dsa_signverify_init(vpdsactx, vdsa, params, EVP_PKEY_OP_VERIFY); 229e1051a39Sopenharmony_ci} 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_cistatic int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen, 232e1051a39Sopenharmony_ci size_t sigsize, const unsigned char *tbs, size_t tbslen) 233e1051a39Sopenharmony_ci{ 234e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 235e1051a39Sopenharmony_ci int ret; 236e1051a39Sopenharmony_ci unsigned int sltmp; 237e1051a39Sopenharmony_ci size_t dsasize = DSA_size(pdsactx->dsa); 238e1051a39Sopenharmony_ci size_t mdsize = dsa_get_md_size(pdsactx); 239e1051a39Sopenharmony_ci 240e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 241e1051a39Sopenharmony_ci return 0; 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ci if (sig == NULL) { 244e1051a39Sopenharmony_ci *siglen = dsasize; 245e1051a39Sopenharmony_ci return 1; 246e1051a39Sopenharmony_ci } 247e1051a39Sopenharmony_ci 248e1051a39Sopenharmony_ci if (sigsize < (size_t)dsasize) 249e1051a39Sopenharmony_ci return 0; 250e1051a39Sopenharmony_ci 251e1051a39Sopenharmony_ci if (mdsize != 0 && tbslen != mdsize) 252e1051a39Sopenharmony_ci return 0; 253e1051a39Sopenharmony_ci 254e1051a39Sopenharmony_ci ret = ossl_dsa_sign_int(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa); 255e1051a39Sopenharmony_ci if (ret <= 0) 256e1051a39Sopenharmony_ci return 0; 257e1051a39Sopenharmony_ci 258e1051a39Sopenharmony_ci *siglen = sltmp; 259e1051a39Sopenharmony_ci return 1; 260e1051a39Sopenharmony_ci} 261e1051a39Sopenharmony_ci 262e1051a39Sopenharmony_cistatic int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen, 263e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen) 264e1051a39Sopenharmony_ci{ 265e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 266e1051a39Sopenharmony_ci size_t mdsize = dsa_get_md_size(pdsactx); 267e1051a39Sopenharmony_ci 268e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || (mdsize != 0 && tbslen != mdsize)) 269e1051a39Sopenharmony_ci return 0; 270e1051a39Sopenharmony_ci 271e1051a39Sopenharmony_ci return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa); 272e1051a39Sopenharmony_ci} 273e1051a39Sopenharmony_ci 274e1051a39Sopenharmony_cistatic int dsa_digest_signverify_init(void *vpdsactx, const char *mdname, 275e1051a39Sopenharmony_ci void *vdsa, const OSSL_PARAM params[], 276e1051a39Sopenharmony_ci int operation) 277e1051a39Sopenharmony_ci{ 278e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 279e1051a39Sopenharmony_ci 280e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 281e1051a39Sopenharmony_ci return 0; 282e1051a39Sopenharmony_ci 283e1051a39Sopenharmony_ci if (!dsa_signverify_init(vpdsactx, vdsa, params, operation)) 284e1051a39Sopenharmony_ci return 0; 285e1051a39Sopenharmony_ci 286e1051a39Sopenharmony_ci if (!dsa_setup_md(pdsactx, mdname, NULL)) 287e1051a39Sopenharmony_ci return 0; 288e1051a39Sopenharmony_ci 289e1051a39Sopenharmony_ci pdsactx->flag_allow_md = 0; 290e1051a39Sopenharmony_ci 291e1051a39Sopenharmony_ci if (pdsactx->mdctx == NULL) { 292e1051a39Sopenharmony_ci pdsactx->mdctx = EVP_MD_CTX_new(); 293e1051a39Sopenharmony_ci if (pdsactx->mdctx == NULL) 294e1051a39Sopenharmony_ci goto error; 295e1051a39Sopenharmony_ci } 296e1051a39Sopenharmony_ci 297e1051a39Sopenharmony_ci if (!EVP_DigestInit_ex2(pdsactx->mdctx, pdsactx->md, params)) 298e1051a39Sopenharmony_ci goto error; 299e1051a39Sopenharmony_ci 300e1051a39Sopenharmony_ci return 1; 301e1051a39Sopenharmony_ci 302e1051a39Sopenharmony_ci error: 303e1051a39Sopenharmony_ci EVP_MD_CTX_free(pdsactx->mdctx); 304e1051a39Sopenharmony_ci pdsactx->mdctx = NULL; 305e1051a39Sopenharmony_ci return 0; 306e1051a39Sopenharmony_ci} 307e1051a39Sopenharmony_ci 308e1051a39Sopenharmony_cistatic int dsa_digest_sign_init(void *vpdsactx, const char *mdname, 309e1051a39Sopenharmony_ci void *vdsa, const OSSL_PARAM params[]) 310e1051a39Sopenharmony_ci{ 311e1051a39Sopenharmony_ci return dsa_digest_signverify_init(vpdsactx, mdname, vdsa, params, 312e1051a39Sopenharmony_ci EVP_PKEY_OP_SIGN); 313e1051a39Sopenharmony_ci} 314e1051a39Sopenharmony_ci 315e1051a39Sopenharmony_cistatic int dsa_digest_verify_init(void *vpdsactx, const char *mdname, 316e1051a39Sopenharmony_ci void *vdsa, const OSSL_PARAM params[]) 317e1051a39Sopenharmony_ci{ 318e1051a39Sopenharmony_ci return dsa_digest_signverify_init(vpdsactx, mdname, vdsa, params, 319e1051a39Sopenharmony_ci EVP_PKEY_OP_VERIFY); 320e1051a39Sopenharmony_ci} 321e1051a39Sopenharmony_ci 322e1051a39Sopenharmony_ciint dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data, 323e1051a39Sopenharmony_ci size_t datalen) 324e1051a39Sopenharmony_ci{ 325e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 326e1051a39Sopenharmony_ci 327e1051a39Sopenharmony_ci if (pdsactx == NULL || pdsactx->mdctx == NULL) 328e1051a39Sopenharmony_ci return 0; 329e1051a39Sopenharmony_ci 330e1051a39Sopenharmony_ci return EVP_DigestUpdate(pdsactx->mdctx, data, datalen); 331e1051a39Sopenharmony_ci} 332e1051a39Sopenharmony_ci 333e1051a39Sopenharmony_ciint dsa_digest_sign_final(void *vpdsactx, unsigned char *sig, size_t *siglen, 334e1051a39Sopenharmony_ci size_t sigsize) 335e1051a39Sopenharmony_ci{ 336e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 337e1051a39Sopenharmony_ci unsigned char digest[EVP_MAX_MD_SIZE]; 338e1051a39Sopenharmony_ci unsigned int dlen = 0; 339e1051a39Sopenharmony_ci 340e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL) 341e1051a39Sopenharmony_ci return 0; 342e1051a39Sopenharmony_ci 343e1051a39Sopenharmony_ci /* 344e1051a39Sopenharmony_ci * If sig is NULL then we're just finding out the sig size. Other fields 345e1051a39Sopenharmony_ci * are ignored. Defer to dsa_sign. 346e1051a39Sopenharmony_ci */ 347e1051a39Sopenharmony_ci if (sig != NULL) { 348e1051a39Sopenharmony_ci /* 349e1051a39Sopenharmony_ci * There is the possibility that some externally provided 350e1051a39Sopenharmony_ci * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - 351e1051a39Sopenharmony_ci * but that problem is much larger than just in DSA. 352e1051a39Sopenharmony_ci */ 353e1051a39Sopenharmony_ci if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen)) 354e1051a39Sopenharmony_ci return 0; 355e1051a39Sopenharmony_ci } 356e1051a39Sopenharmony_ci 357e1051a39Sopenharmony_ci pdsactx->flag_allow_md = 1; 358e1051a39Sopenharmony_ci 359e1051a39Sopenharmony_ci return dsa_sign(vpdsactx, sig, siglen, sigsize, digest, (size_t)dlen); 360e1051a39Sopenharmony_ci} 361e1051a39Sopenharmony_ci 362e1051a39Sopenharmony_ci 363e1051a39Sopenharmony_ciint dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig, 364e1051a39Sopenharmony_ci size_t siglen) 365e1051a39Sopenharmony_ci{ 366e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 367e1051a39Sopenharmony_ci unsigned char digest[EVP_MAX_MD_SIZE]; 368e1051a39Sopenharmony_ci unsigned int dlen = 0; 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL) 371e1051a39Sopenharmony_ci return 0; 372e1051a39Sopenharmony_ci 373e1051a39Sopenharmony_ci /* 374e1051a39Sopenharmony_ci * There is the possibility that some externally provided 375e1051a39Sopenharmony_ci * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - 376e1051a39Sopenharmony_ci * but that problem is much larger than just in DSA. 377e1051a39Sopenharmony_ci */ 378e1051a39Sopenharmony_ci if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen)) 379e1051a39Sopenharmony_ci return 0; 380e1051a39Sopenharmony_ci 381e1051a39Sopenharmony_ci pdsactx->flag_allow_md = 1; 382e1051a39Sopenharmony_ci 383e1051a39Sopenharmony_ci return dsa_verify(vpdsactx, sig, siglen, digest, (size_t)dlen); 384e1051a39Sopenharmony_ci} 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_cistatic void dsa_freectx(void *vpdsactx) 387e1051a39Sopenharmony_ci{ 388e1051a39Sopenharmony_ci PROV_DSA_CTX *ctx = (PROV_DSA_CTX *)vpdsactx; 389e1051a39Sopenharmony_ci 390e1051a39Sopenharmony_ci OPENSSL_free(ctx->propq); 391e1051a39Sopenharmony_ci EVP_MD_CTX_free(ctx->mdctx); 392e1051a39Sopenharmony_ci EVP_MD_free(ctx->md); 393e1051a39Sopenharmony_ci ctx->propq = NULL; 394e1051a39Sopenharmony_ci ctx->mdctx = NULL; 395e1051a39Sopenharmony_ci ctx->md = NULL; 396e1051a39Sopenharmony_ci DSA_free(ctx->dsa); 397e1051a39Sopenharmony_ci OPENSSL_free(ctx); 398e1051a39Sopenharmony_ci} 399e1051a39Sopenharmony_ci 400e1051a39Sopenharmony_cistatic void *dsa_dupctx(void *vpdsactx) 401e1051a39Sopenharmony_ci{ 402e1051a39Sopenharmony_ci PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx; 403e1051a39Sopenharmony_ci PROV_DSA_CTX *dstctx; 404e1051a39Sopenharmony_ci 405e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 406e1051a39Sopenharmony_ci return NULL; 407e1051a39Sopenharmony_ci 408e1051a39Sopenharmony_ci dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 409e1051a39Sopenharmony_ci if (dstctx == NULL) 410e1051a39Sopenharmony_ci return NULL; 411e1051a39Sopenharmony_ci 412e1051a39Sopenharmony_ci *dstctx = *srcctx; 413e1051a39Sopenharmony_ci dstctx->dsa = NULL; 414e1051a39Sopenharmony_ci dstctx->md = NULL; 415e1051a39Sopenharmony_ci dstctx->mdctx = NULL; 416e1051a39Sopenharmony_ci dstctx->propq = NULL; 417e1051a39Sopenharmony_ci 418e1051a39Sopenharmony_ci if (srcctx->dsa != NULL && !DSA_up_ref(srcctx->dsa)) 419e1051a39Sopenharmony_ci goto err; 420e1051a39Sopenharmony_ci dstctx->dsa = srcctx->dsa; 421e1051a39Sopenharmony_ci 422e1051a39Sopenharmony_ci if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) 423e1051a39Sopenharmony_ci goto err; 424e1051a39Sopenharmony_ci dstctx->md = srcctx->md; 425e1051a39Sopenharmony_ci 426e1051a39Sopenharmony_ci if (srcctx->mdctx != NULL) { 427e1051a39Sopenharmony_ci dstctx->mdctx = EVP_MD_CTX_new(); 428e1051a39Sopenharmony_ci if (dstctx->mdctx == NULL 429e1051a39Sopenharmony_ci || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) 430e1051a39Sopenharmony_ci goto err; 431e1051a39Sopenharmony_ci } 432e1051a39Sopenharmony_ci if (srcctx->propq != NULL) { 433e1051a39Sopenharmony_ci dstctx->propq = OPENSSL_strdup(srcctx->propq); 434e1051a39Sopenharmony_ci if (dstctx->propq == NULL) 435e1051a39Sopenharmony_ci goto err; 436e1051a39Sopenharmony_ci } 437e1051a39Sopenharmony_ci 438e1051a39Sopenharmony_ci return dstctx; 439e1051a39Sopenharmony_ci err: 440e1051a39Sopenharmony_ci dsa_freectx(dstctx); 441e1051a39Sopenharmony_ci return NULL; 442e1051a39Sopenharmony_ci} 443e1051a39Sopenharmony_ci 444e1051a39Sopenharmony_cistatic int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params) 445e1051a39Sopenharmony_ci{ 446e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 447e1051a39Sopenharmony_ci OSSL_PARAM *p; 448e1051a39Sopenharmony_ci 449e1051a39Sopenharmony_ci if (pdsactx == NULL) 450e1051a39Sopenharmony_ci return 0; 451e1051a39Sopenharmony_ci 452e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); 453e1051a39Sopenharmony_ci if (p != NULL 454e1051a39Sopenharmony_ci && !OSSL_PARAM_set_octet_string(p, pdsactx->aid, pdsactx->aid_len)) 455e1051a39Sopenharmony_ci return 0; 456e1051a39Sopenharmony_ci 457e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST); 458e1051a39Sopenharmony_ci if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->mdname)) 459e1051a39Sopenharmony_ci return 0; 460e1051a39Sopenharmony_ci 461e1051a39Sopenharmony_ci return 1; 462e1051a39Sopenharmony_ci} 463e1051a39Sopenharmony_ci 464e1051a39Sopenharmony_cistatic const OSSL_PARAM known_gettable_ctx_params[] = { 465e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), 466e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 467e1051a39Sopenharmony_ci OSSL_PARAM_END 468e1051a39Sopenharmony_ci}; 469e1051a39Sopenharmony_ci 470e1051a39Sopenharmony_cistatic const OSSL_PARAM *dsa_gettable_ctx_params(ossl_unused void *ctx, 471e1051a39Sopenharmony_ci ossl_unused void *provctx) 472e1051a39Sopenharmony_ci{ 473e1051a39Sopenharmony_ci return known_gettable_ctx_params; 474e1051a39Sopenharmony_ci} 475e1051a39Sopenharmony_ci 476e1051a39Sopenharmony_cistatic int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[]) 477e1051a39Sopenharmony_ci{ 478e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 479e1051a39Sopenharmony_ci const OSSL_PARAM *p; 480e1051a39Sopenharmony_ci 481e1051a39Sopenharmony_ci if (pdsactx == NULL) 482e1051a39Sopenharmony_ci return 0; 483e1051a39Sopenharmony_ci if (params == NULL) 484e1051a39Sopenharmony_ci return 1; 485e1051a39Sopenharmony_ci 486e1051a39Sopenharmony_ci p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); 487e1051a39Sopenharmony_ci if (p != NULL) { 488e1051a39Sopenharmony_ci char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname; 489e1051a39Sopenharmony_ci char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops; 490e1051a39Sopenharmony_ci const OSSL_PARAM *propsp = 491e1051a39Sopenharmony_ci OSSL_PARAM_locate_const(params, 492e1051a39Sopenharmony_ci OSSL_SIGNATURE_PARAM_PROPERTIES); 493e1051a39Sopenharmony_ci 494e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) 495e1051a39Sopenharmony_ci return 0; 496e1051a39Sopenharmony_ci if (propsp != NULL 497e1051a39Sopenharmony_ci && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) 498e1051a39Sopenharmony_ci return 0; 499e1051a39Sopenharmony_ci if (!dsa_setup_md(pdsactx, mdname, mdprops)) 500e1051a39Sopenharmony_ci return 0; 501e1051a39Sopenharmony_ci } 502e1051a39Sopenharmony_ci 503e1051a39Sopenharmony_ci return 1; 504e1051a39Sopenharmony_ci} 505e1051a39Sopenharmony_ci 506e1051a39Sopenharmony_cistatic const OSSL_PARAM settable_ctx_params[] = { 507e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 508e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), 509e1051a39Sopenharmony_ci OSSL_PARAM_END 510e1051a39Sopenharmony_ci}; 511e1051a39Sopenharmony_ci 512e1051a39Sopenharmony_cistatic const OSSL_PARAM settable_ctx_params_no_digest[] = { 513e1051a39Sopenharmony_ci OSSL_PARAM_END 514e1051a39Sopenharmony_ci}; 515e1051a39Sopenharmony_ci 516e1051a39Sopenharmony_cistatic const OSSL_PARAM *dsa_settable_ctx_params(void *vpdsactx, 517e1051a39Sopenharmony_ci ossl_unused void *provctx) 518e1051a39Sopenharmony_ci{ 519e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 520e1051a39Sopenharmony_ci 521e1051a39Sopenharmony_ci if (pdsactx != NULL && !pdsactx->flag_allow_md) 522e1051a39Sopenharmony_ci return settable_ctx_params_no_digest; 523e1051a39Sopenharmony_ci return settable_ctx_params; 524e1051a39Sopenharmony_ci} 525e1051a39Sopenharmony_ci 526e1051a39Sopenharmony_cistatic int dsa_get_ctx_md_params(void *vpdsactx, OSSL_PARAM *params) 527e1051a39Sopenharmony_ci{ 528e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 529e1051a39Sopenharmony_ci 530e1051a39Sopenharmony_ci if (pdsactx->mdctx == NULL) 531e1051a39Sopenharmony_ci return 0; 532e1051a39Sopenharmony_ci 533e1051a39Sopenharmony_ci return EVP_MD_CTX_get_params(pdsactx->mdctx, params); 534e1051a39Sopenharmony_ci} 535e1051a39Sopenharmony_ci 536e1051a39Sopenharmony_cistatic const OSSL_PARAM *dsa_gettable_ctx_md_params(void *vpdsactx) 537e1051a39Sopenharmony_ci{ 538e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 539e1051a39Sopenharmony_ci 540e1051a39Sopenharmony_ci if (pdsactx->md == NULL) 541e1051a39Sopenharmony_ci return 0; 542e1051a39Sopenharmony_ci 543e1051a39Sopenharmony_ci return EVP_MD_gettable_ctx_params(pdsactx->md); 544e1051a39Sopenharmony_ci} 545e1051a39Sopenharmony_ci 546e1051a39Sopenharmony_cistatic int dsa_set_ctx_md_params(void *vpdsactx, const OSSL_PARAM params[]) 547e1051a39Sopenharmony_ci{ 548e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 549e1051a39Sopenharmony_ci 550e1051a39Sopenharmony_ci if (pdsactx->mdctx == NULL) 551e1051a39Sopenharmony_ci return 0; 552e1051a39Sopenharmony_ci 553e1051a39Sopenharmony_ci return EVP_MD_CTX_set_params(pdsactx->mdctx, params); 554e1051a39Sopenharmony_ci} 555e1051a39Sopenharmony_ci 556e1051a39Sopenharmony_cistatic const OSSL_PARAM *dsa_settable_ctx_md_params(void *vpdsactx) 557e1051a39Sopenharmony_ci{ 558e1051a39Sopenharmony_ci PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 559e1051a39Sopenharmony_ci 560e1051a39Sopenharmony_ci if (pdsactx->md == NULL) 561e1051a39Sopenharmony_ci return 0; 562e1051a39Sopenharmony_ci 563e1051a39Sopenharmony_ci return EVP_MD_settable_ctx_params(pdsactx->md); 564e1051a39Sopenharmony_ci} 565e1051a39Sopenharmony_ci 566e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_dsa_signature_functions[] = { 567e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx }, 568e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_sign_init }, 569e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign }, 570e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))dsa_verify_init }, 571e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify }, 572e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, 573e1051a39Sopenharmony_ci (void (*)(void))dsa_digest_sign_init }, 574e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, 575e1051a39Sopenharmony_ci (void (*)(void))dsa_digest_signverify_update }, 576e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, 577e1051a39Sopenharmony_ci (void (*)(void))dsa_digest_sign_final }, 578e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, 579e1051a39Sopenharmony_ci (void (*)(void))dsa_digest_verify_init }, 580e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, 581e1051a39Sopenharmony_ci (void (*)(void))dsa_digest_signverify_update }, 582e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, 583e1051a39Sopenharmony_ci (void (*)(void))dsa_digest_verify_final }, 584e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx }, 585e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx }, 586e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))dsa_get_ctx_params }, 587e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, 588e1051a39Sopenharmony_ci (void (*)(void))dsa_gettable_ctx_params }, 589e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))dsa_set_ctx_params }, 590e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, 591e1051a39Sopenharmony_ci (void (*)(void))dsa_settable_ctx_params }, 592e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, 593e1051a39Sopenharmony_ci (void (*)(void))dsa_get_ctx_md_params }, 594e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, 595e1051a39Sopenharmony_ci (void (*)(void))dsa_gettable_ctx_md_params }, 596e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, 597e1051a39Sopenharmony_ci (void (*)(void))dsa_set_ctx_md_params }, 598e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, 599e1051a39Sopenharmony_ci (void (*)(void))dsa_settable_ctx_md_params }, 600e1051a39Sopenharmony_ci { 0, NULL } 601e1051a39Sopenharmony_ci}; 602