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