1b077aed3SPierre Pronchery /* 2*e7be843bSPierre Pronchery * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. 3b077aed3SPierre Pronchery * 4b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use 5b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy 6b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at 7b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html 8b077aed3SPierre Pronchery */ 9b077aed3SPierre Pronchery 10b077aed3SPierre Pronchery /* 11b077aed3SPierre Pronchery * ECDSA low level APIs are deprecated for public use, but still ok for 12b077aed3SPierre Pronchery * internal use. 13b077aed3SPierre Pronchery */ 14b077aed3SPierre Pronchery #include "internal/deprecated.h" 15b077aed3SPierre Pronchery 16b077aed3SPierre Pronchery #include <string.h> /* memcpy */ 17b077aed3SPierre Pronchery #include <openssl/crypto.h> 18b077aed3SPierre Pronchery #include <openssl/core_dispatch.h> 19b077aed3SPierre Pronchery #include <openssl/core_names.h> 20b077aed3SPierre Pronchery #include <openssl/dsa.h> 21b077aed3SPierre Pronchery #include <openssl/params.h> 22b077aed3SPierre Pronchery #include <openssl/evp.h> 23b077aed3SPierre Pronchery #include <openssl/err.h> 24b077aed3SPierre Pronchery #include <openssl/proverr.h> 25b077aed3SPierre Pronchery #include "internal/nelem.h" 26b077aed3SPierre Pronchery #include "internal/sizes.h" 27b077aed3SPierre Pronchery #include "internal/cryptlib.h" 28*e7be843bSPierre Pronchery #include "internal/deterministic_nonce.h" 29b077aed3SPierre Pronchery #include "prov/providercommon.h" 30b077aed3SPierre Pronchery #include "prov/implementations.h" 31b077aed3SPierre Pronchery #include "prov/provider_ctx.h" 32b077aed3SPierre Pronchery #include "prov/securitycheck.h" 33b077aed3SPierre Pronchery #include "prov/der_ec.h" 34*e7be843bSPierre Pronchery #include "crypto/ec.h" 35b077aed3SPierre Pronchery 36b077aed3SPierre Pronchery static OSSL_FUNC_signature_newctx_fn ecdsa_newctx; 37b077aed3SPierre Pronchery static OSSL_FUNC_signature_sign_init_fn ecdsa_sign_init; 38b077aed3SPierre Pronchery static OSSL_FUNC_signature_verify_init_fn ecdsa_verify_init; 39b077aed3SPierre Pronchery static OSSL_FUNC_signature_sign_fn ecdsa_sign; 40*e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_message_update_fn ecdsa_signverify_message_update; 41*e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_message_final_fn ecdsa_sign_message_final; 42b077aed3SPierre Pronchery static OSSL_FUNC_signature_verify_fn ecdsa_verify; 43*e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_message_update_fn ecdsa_signverify_message_update; 44*e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_message_final_fn ecdsa_verify_message_final; 45b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_init_fn ecdsa_digest_sign_init; 46b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_update_fn ecdsa_digest_signverify_update; 47b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_final_fn ecdsa_digest_sign_final; 48b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_init_fn ecdsa_digest_verify_init; 49b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_update_fn ecdsa_digest_signverify_update; 50b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_final_fn ecdsa_digest_verify_final; 51b077aed3SPierre Pronchery static OSSL_FUNC_signature_freectx_fn ecdsa_freectx; 52b077aed3SPierre Pronchery static OSSL_FUNC_signature_dupctx_fn ecdsa_dupctx; 53*e7be843bSPierre Pronchery static OSSL_FUNC_signature_query_key_types_fn ecdsa_sigalg_query_key_types; 54b077aed3SPierre Pronchery static OSSL_FUNC_signature_get_ctx_params_fn ecdsa_get_ctx_params; 55b077aed3SPierre Pronchery static OSSL_FUNC_signature_gettable_ctx_params_fn ecdsa_gettable_ctx_params; 56b077aed3SPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_set_ctx_params; 57b077aed3SPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_settable_ctx_params; 58b077aed3SPierre Pronchery static OSSL_FUNC_signature_get_ctx_md_params_fn ecdsa_get_ctx_md_params; 59b077aed3SPierre Pronchery static OSSL_FUNC_signature_gettable_ctx_md_params_fn ecdsa_gettable_ctx_md_params; 60b077aed3SPierre Pronchery static OSSL_FUNC_signature_set_ctx_md_params_fn ecdsa_set_ctx_md_params; 61b077aed3SPierre Pronchery static OSSL_FUNC_signature_settable_ctx_md_params_fn ecdsa_settable_ctx_md_params; 62*e7be843bSPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_sigalg_set_ctx_params; 63*e7be843bSPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_sigalg_settable_ctx_params; 64b077aed3SPierre Pronchery 65b077aed3SPierre Pronchery /* 66b077aed3SPierre Pronchery * What's passed as an actual key is defined by the KEYMGMT interface. 67b077aed3SPierre Pronchery * We happen to know that our KEYMGMT simply passes DSA structures, so 68b077aed3SPierre Pronchery * we use that here too. 69b077aed3SPierre Pronchery */ 70b077aed3SPierre Pronchery 71b077aed3SPierre Pronchery typedef struct { 72b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx; 73b077aed3SPierre Pronchery char *propq; 74b077aed3SPierre Pronchery EC_KEY *ec; 75*e7be843bSPierre Pronchery /* |operation| reuses EVP's operation bitfield */ 76*e7be843bSPierre Pronchery int operation; 77b077aed3SPierre Pronchery 78b077aed3SPierre Pronchery /* 79*e7be843bSPierre Pronchery * Flag to determine if a full sigalg is run (1) or if a composable 80*e7be843bSPierre Pronchery * signature algorithm is run (0). 81*e7be843bSPierre Pronchery * 82*e7be843bSPierre Pronchery * When a full sigalg is run (1), this currently affects the following 83*e7be843bSPierre Pronchery * other flags, which are to remain untouched after their initialization: 84*e7be843bSPierre Pronchery * 85*e7be843bSPierre Pronchery * - flag_allow_md (initialized to 0) 86*e7be843bSPierre Pronchery */ 87*e7be843bSPierre Pronchery unsigned int flag_sigalg : 1; 88*e7be843bSPierre Pronchery /* 89b077aed3SPierre Pronchery * Flag to determine if the hash function can be changed (1) or not (0) 90b077aed3SPierre Pronchery * Because it's dangerous to change during a DigestSign or DigestVerify 91b077aed3SPierre Pronchery * operation, this flag is cleared by their Init function, and set again 92b077aed3SPierre Pronchery * by their Final function. 93b077aed3SPierre Pronchery */ 94b077aed3SPierre Pronchery unsigned int flag_allow_md : 1; 95b077aed3SPierre Pronchery 96b077aed3SPierre Pronchery /* The Algorithm Identifier of the combined signature algorithm */ 97b077aed3SPierre Pronchery unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; 98b077aed3SPierre Pronchery size_t aid_len; 99b077aed3SPierre Pronchery 100*e7be843bSPierre Pronchery /* main digest */ 101*e7be843bSPierre Pronchery char mdname[OSSL_MAX_NAME_SIZE]; 102b077aed3SPierre Pronchery EVP_MD *md; 103b077aed3SPierre Pronchery EVP_MD_CTX *mdctx; 104*e7be843bSPierre Pronchery size_t mdsize; 105*e7be843bSPierre Pronchery 106*e7be843bSPierre Pronchery /* Signature, for verification */ 107*e7be843bSPierre Pronchery unsigned char *sig; 108*e7be843bSPierre Pronchery size_t siglen; 109*e7be843bSPierre Pronchery 110b077aed3SPierre Pronchery /* 111b077aed3SPierre Pronchery * Internally used to cache the results of calling the EC group 112b077aed3SPierre Pronchery * sign_setup() methods which are then passed to the sign operation. 113b077aed3SPierre Pronchery * This is used by CAVS failure tests to terminate a loop if the signature 114b077aed3SPierre Pronchery * is not valid. 115b077aed3SPierre Pronchery * This could of also been done with a simple flag. 116b077aed3SPierre Pronchery */ 117b077aed3SPierre Pronchery BIGNUM *kinv; 118b077aed3SPierre Pronchery BIGNUM *r; 119b077aed3SPierre Pronchery #if !defined(OPENSSL_NO_ACVP_TESTS) 120b077aed3SPierre Pronchery /* 121b077aed3SPierre Pronchery * This indicates that KAT (CAVS) test is running. Externally an app will 122b077aed3SPierre Pronchery * override the random callback such that the generated private key and k 123b077aed3SPierre Pronchery * are known. 124b077aed3SPierre Pronchery * Normal operation will loop to choose a new k if the signature is not 125b077aed3SPierre Pronchery * valid - but for this mode of operation it forces a failure instead. 126b077aed3SPierre Pronchery */ 127b077aed3SPierre Pronchery unsigned int kattest; 128b077aed3SPierre Pronchery #endif 129*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 130*e7be843bSPierre Pronchery /* 131*e7be843bSPierre Pronchery * FIPS 140-3 IG 2.4.B mandates that verification based on a digest of a 132*e7be843bSPierre Pronchery * message is not permitted. However, signing based on a digest is still 133*e7be843bSPierre Pronchery * permitted. 134*e7be843bSPierre Pronchery */ 135*e7be843bSPierre Pronchery int verify_message; 136*e7be843bSPierre Pronchery #endif 137*e7be843bSPierre Pronchery /* If this is set then the generated k is not random */ 138*e7be843bSPierre Pronchery unsigned int nonce_type; 139*e7be843bSPierre Pronchery OSSL_FIPS_IND_DECLARE 140b077aed3SPierre Pronchery } PROV_ECDSA_CTX; 141b077aed3SPierre Pronchery 142b077aed3SPierre Pronchery static void *ecdsa_newctx(void *provctx, const char *propq) 143b077aed3SPierre Pronchery { 144b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx; 145b077aed3SPierre Pronchery 146b077aed3SPierre Pronchery if (!ossl_prov_is_running()) 147b077aed3SPierre Pronchery return NULL; 148b077aed3SPierre Pronchery 149b077aed3SPierre Pronchery ctx = OPENSSL_zalloc(sizeof(PROV_ECDSA_CTX)); 150b077aed3SPierre Pronchery if (ctx == NULL) 151b077aed3SPierre Pronchery return NULL; 152b077aed3SPierre Pronchery 153*e7be843bSPierre Pronchery OSSL_FIPS_IND_INIT(ctx) 154b077aed3SPierre Pronchery ctx->flag_allow_md = 1; 155*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 156*e7be843bSPierre Pronchery ctx->verify_message = 1; 157*e7be843bSPierre Pronchery #endif 158b077aed3SPierre Pronchery ctx->libctx = PROV_LIBCTX_OF(provctx); 159b077aed3SPierre Pronchery if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { 160b077aed3SPierre Pronchery OPENSSL_free(ctx); 161b077aed3SPierre Pronchery ctx = NULL; 162b077aed3SPierre Pronchery } 163b077aed3SPierre Pronchery return ctx; 164b077aed3SPierre Pronchery } 165b077aed3SPierre Pronchery 166*e7be843bSPierre Pronchery static int ecdsa_setup_md(PROV_ECDSA_CTX *ctx, 167*e7be843bSPierre Pronchery const char *mdname, const char *mdprops, 168*e7be843bSPierre Pronchery const char *desc) 169b077aed3SPierre Pronchery { 170*e7be843bSPierre Pronchery EVP_MD *md = NULL; 171*e7be843bSPierre Pronchery size_t mdname_len; 172*e7be843bSPierre Pronchery int md_nid, md_size; 173*e7be843bSPierre Pronchery WPACKET pkt; 174*e7be843bSPierre Pronchery unsigned char *aid = NULL; 175b077aed3SPierre Pronchery 176*e7be843bSPierre Pronchery if (mdname == NULL) 177*e7be843bSPierre Pronchery return 1; 178*e7be843bSPierre Pronchery 179*e7be843bSPierre Pronchery mdname_len = strlen(mdname); 180*e7be843bSPierre Pronchery if (mdname_len >= sizeof(ctx->mdname)) { 181*e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 182*e7be843bSPierre Pronchery "%s exceeds name buffer length", mdname); 183*e7be843bSPierre Pronchery return 0; 184*e7be843bSPierre Pronchery } 185*e7be843bSPierre Pronchery if (mdprops == NULL) 186*e7be843bSPierre Pronchery mdprops = ctx->propq; 187*e7be843bSPierre Pronchery md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); 188*e7be843bSPierre Pronchery if (md == NULL) { 189*e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 190*e7be843bSPierre Pronchery "%s could not be fetched", mdname); 191*e7be843bSPierre Pronchery return 0; 192*e7be843bSPierre Pronchery } 193*e7be843bSPierre Pronchery md_size = EVP_MD_get_size(md); 194*e7be843bSPierre Pronchery if (md_size <= 0) { 195*e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 196*e7be843bSPierre Pronchery "%s has invalid md size %d", mdname, md_size); 197*e7be843bSPierre Pronchery goto err; 198*e7be843bSPierre Pronchery } 199*e7be843bSPierre Pronchery md_nid = ossl_digest_get_approved_nid(md); 200*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 201*e7be843bSPierre Pronchery if (md_nid == NID_undef) { 202*e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 203*e7be843bSPierre Pronchery "digest=%s", mdname); 204*e7be843bSPierre Pronchery goto err; 205*e7be843bSPierre Pronchery } 206*e7be843bSPierre Pronchery #endif 207*e7be843bSPierre Pronchery /* XOF digests don't work */ 208*e7be843bSPierre Pronchery if (EVP_MD_xof(md)) { 209*e7be843bSPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED); 210*e7be843bSPierre Pronchery goto err; 211*e7be843bSPierre Pronchery } 212*e7be843bSPierre Pronchery 213*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 214*e7be843bSPierre Pronchery { 215*e7be843bSPierre Pronchery int sha1_allowed 216*e7be843bSPierre Pronchery = ((ctx->operation 217*e7be843bSPierre Pronchery & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG)) == 0); 218*e7be843bSPierre Pronchery 219*e7be843bSPierre Pronchery if (!ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND_GET(ctx), 220*e7be843bSPierre Pronchery OSSL_FIPS_IND_SETTABLE1, 221*e7be843bSPierre Pronchery ctx->libctx, 222*e7be843bSPierre Pronchery md_nid, sha1_allowed, desc, 223*e7be843bSPierre Pronchery ossl_fips_config_signature_digest_check)) 224*e7be843bSPierre Pronchery goto err; 225*e7be843bSPierre Pronchery } 226*e7be843bSPierre Pronchery #endif 227*e7be843bSPierre Pronchery 228*e7be843bSPierre Pronchery if (!ctx->flag_allow_md) { 229*e7be843bSPierre Pronchery if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) { 230*e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 231*e7be843bSPierre Pronchery "digest %s != %s", mdname, ctx->mdname); 232*e7be843bSPierre Pronchery goto err; 233*e7be843bSPierre Pronchery } 234*e7be843bSPierre Pronchery EVP_MD_free(md); 235*e7be843bSPierre Pronchery return 1; 236*e7be843bSPierre Pronchery } 237*e7be843bSPierre Pronchery 238*e7be843bSPierre Pronchery EVP_MD_CTX_free(ctx->mdctx); 239*e7be843bSPierre Pronchery EVP_MD_free(ctx->md); 240*e7be843bSPierre Pronchery 241*e7be843bSPierre Pronchery ctx->aid_len = 0; 242*e7be843bSPierre Pronchery #ifndef FIPS_MODULE 243*e7be843bSPierre Pronchery if (md_nid != NID_undef) { 244*e7be843bSPierre Pronchery #else 245*e7be843bSPierre Pronchery { 246*e7be843bSPierre Pronchery #endif 247*e7be843bSPierre Pronchery if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) 248*e7be843bSPierre Pronchery && ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec, 249*e7be843bSPierre Pronchery md_nid) 250*e7be843bSPierre Pronchery && WPACKET_finish(&pkt)) { 251*e7be843bSPierre Pronchery WPACKET_get_total_written(&pkt, &ctx->aid_len); 252*e7be843bSPierre Pronchery aid = WPACKET_get_curr(&pkt); 253*e7be843bSPierre Pronchery } 254*e7be843bSPierre Pronchery WPACKET_cleanup(&pkt); 255*e7be843bSPierre Pronchery if (aid != NULL && ctx->aid_len != 0) 256*e7be843bSPierre Pronchery memmove(ctx->aid_buf, aid, ctx->aid_len); 257*e7be843bSPierre Pronchery } 258*e7be843bSPierre Pronchery 259*e7be843bSPierre Pronchery ctx->mdctx = NULL; 260*e7be843bSPierre Pronchery ctx->md = md; 261*e7be843bSPierre Pronchery ctx->mdsize = (size_t)md_size; 262*e7be843bSPierre Pronchery OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); 263*e7be843bSPierre Pronchery 264*e7be843bSPierre Pronchery return 1; 265*e7be843bSPierre Pronchery err: 266*e7be843bSPierre Pronchery EVP_MD_free(md); 267*e7be843bSPierre Pronchery return 0; 268*e7be843bSPierre Pronchery } 269*e7be843bSPierre Pronchery 270*e7be843bSPierre Pronchery static int 271*e7be843bSPierre Pronchery ecdsa_signverify_init(PROV_ECDSA_CTX *ctx, void *ec, 272*e7be843bSPierre Pronchery OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params, 273*e7be843bSPierre Pronchery const OSSL_PARAM params[], int operation, 274*e7be843bSPierre Pronchery const char *desc) 275*e7be843bSPierre Pronchery { 276b077aed3SPierre Pronchery if (!ossl_prov_is_running() 277b077aed3SPierre Pronchery || ctx == NULL) 278b077aed3SPierre Pronchery return 0; 279b077aed3SPierre Pronchery 280b077aed3SPierre Pronchery if (ec == NULL && ctx->ec == NULL) { 281b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 282b077aed3SPierre Pronchery return 0; 283b077aed3SPierre Pronchery } 284b077aed3SPierre Pronchery 285b077aed3SPierre Pronchery if (ec != NULL) { 286b077aed3SPierre Pronchery if (!EC_KEY_up_ref(ec)) 287b077aed3SPierre Pronchery return 0; 288b077aed3SPierre Pronchery EC_KEY_free(ctx->ec); 289b077aed3SPierre Pronchery ctx->ec = ec; 290b077aed3SPierre Pronchery } 291b077aed3SPierre Pronchery 292b077aed3SPierre Pronchery ctx->operation = operation; 293b077aed3SPierre Pronchery 294*e7be843bSPierre Pronchery OSSL_FIPS_IND_SET_APPROVED(ctx) 295*e7be843bSPierre Pronchery if (!set_ctx_params(ctx, params)) 296b077aed3SPierre Pronchery return 0; 297*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 298*e7be843bSPierre Pronchery if (!ossl_fips_ind_ec_key_check(OSSL_FIPS_IND_GET(ctx), 299*e7be843bSPierre Pronchery OSSL_FIPS_IND_SETTABLE0, ctx->libctx, 300*e7be843bSPierre Pronchery EC_KEY_get0_group(ctx->ec), desc, 301*e7be843bSPierre Pronchery (operation & (EVP_PKEY_OP_SIGN 302*e7be843bSPierre Pronchery | EVP_PKEY_OP_SIGNMSG)) != 0)) 303*e7be843bSPierre Pronchery return 0; 304*e7be843bSPierre Pronchery #endif 305b077aed3SPierre Pronchery return 1; 306b077aed3SPierre Pronchery } 307b077aed3SPierre Pronchery 308b077aed3SPierre Pronchery static int ecdsa_sign_init(void *vctx, void *ec, const OSSL_PARAM params[]) 309b077aed3SPierre Pronchery { 310*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 311*e7be843bSPierre Pronchery 312*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 313*e7be843bSPierre Pronchery ctx->verify_message = 1; 314*e7be843bSPierre Pronchery #endif 315*e7be843bSPierre Pronchery return ecdsa_signverify_init(ctx, ec, ecdsa_set_ctx_params, params, 316*e7be843bSPierre Pronchery EVP_PKEY_OP_SIGN, "ECDSA Sign Init"); 317b077aed3SPierre Pronchery } 318b077aed3SPierre Pronchery 319*e7be843bSPierre Pronchery /* 320*e7be843bSPierre Pronchery * Sign tbs without digesting it first. This is suitable for "primitive" 321*e7be843bSPierre Pronchery * signing and signing the digest of a message. 322*e7be843bSPierre Pronchery */ 323*e7be843bSPierre Pronchery static int ecdsa_sign_directly(void *vctx, 324*e7be843bSPierre Pronchery unsigned char *sig, size_t *siglen, size_t sigsize, 325*e7be843bSPierre Pronchery const unsigned char *tbs, size_t tbslen) 326b077aed3SPierre Pronchery { 327b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 328b077aed3SPierre Pronchery int ret; 329b077aed3SPierre Pronchery unsigned int sltmp; 330b077aed3SPierre Pronchery size_t ecsize = ECDSA_size(ctx->ec); 331b077aed3SPierre Pronchery 332b077aed3SPierre Pronchery if (!ossl_prov_is_running()) 333b077aed3SPierre Pronchery return 0; 334b077aed3SPierre Pronchery 335b077aed3SPierre Pronchery if (sig == NULL) { 336b077aed3SPierre Pronchery *siglen = ecsize; 337b077aed3SPierre Pronchery return 1; 338b077aed3SPierre Pronchery } 339b077aed3SPierre Pronchery 340b077aed3SPierre Pronchery #if !defined(OPENSSL_NO_ACVP_TESTS) 341b077aed3SPierre Pronchery if (ctx->kattest && !ECDSA_sign_setup(ctx->ec, NULL, &ctx->kinv, &ctx->r)) 342b077aed3SPierre Pronchery return 0; 343b077aed3SPierre Pronchery #endif 344b077aed3SPierre Pronchery 345b077aed3SPierre Pronchery if (sigsize < (size_t)ecsize) 346b077aed3SPierre Pronchery return 0; 347b077aed3SPierre Pronchery 348b077aed3SPierre Pronchery if (ctx->mdsize != 0 && tbslen != ctx->mdsize) 349b077aed3SPierre Pronchery return 0; 350b077aed3SPierre Pronchery 351*e7be843bSPierre Pronchery if (ctx->nonce_type != 0) { 352*e7be843bSPierre Pronchery const char *mdname = NULL; 353*e7be843bSPierre Pronchery 354*e7be843bSPierre Pronchery if (ctx->mdname[0] != '\0') 355*e7be843bSPierre Pronchery mdname = ctx->mdname; 356*e7be843bSPierre Pronchery ret = ossl_ecdsa_deterministic_sign(tbs, tbslen, sig, &sltmp, 357*e7be843bSPierre Pronchery ctx->ec, ctx->nonce_type, 358*e7be843bSPierre Pronchery mdname, 359*e7be843bSPierre Pronchery ctx->libctx, ctx->propq); 360*e7be843bSPierre Pronchery } else { 361*e7be843bSPierre Pronchery ret = ECDSA_sign_ex(0, tbs, tbslen, sig, &sltmp, ctx->kinv, ctx->r, 362*e7be843bSPierre Pronchery ctx->ec); 363*e7be843bSPierre Pronchery } 364b077aed3SPierre Pronchery if (ret <= 0) 365b077aed3SPierre Pronchery return 0; 366b077aed3SPierre Pronchery 367b077aed3SPierre Pronchery *siglen = sltmp; 368b077aed3SPierre Pronchery return 1; 369b077aed3SPierre Pronchery } 370b077aed3SPierre Pronchery 371*e7be843bSPierre Pronchery static int ecdsa_signverify_message_update(void *vctx, 372*e7be843bSPierre Pronchery const unsigned char *data, 373*e7be843bSPierre Pronchery size_t datalen) 374*e7be843bSPierre Pronchery { 375*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 376*e7be843bSPierre Pronchery 377*e7be843bSPierre Pronchery if (ctx == NULL) 378*e7be843bSPierre Pronchery return 0; 379*e7be843bSPierre Pronchery 380*e7be843bSPierre Pronchery return EVP_DigestUpdate(ctx->mdctx, data, datalen); 381*e7be843bSPierre Pronchery } 382*e7be843bSPierre Pronchery 383*e7be843bSPierre Pronchery static int ecdsa_sign_message_final(void *vctx, unsigned char *sig, 384*e7be843bSPierre Pronchery size_t *siglen, size_t sigsize) 385*e7be843bSPierre Pronchery { 386*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 387*e7be843bSPierre Pronchery unsigned char digest[EVP_MAX_MD_SIZE]; 388*e7be843bSPierre Pronchery unsigned int dlen = 0; 389*e7be843bSPierre Pronchery 390*e7be843bSPierre Pronchery if (!ossl_prov_is_running() || ctx == NULL) 391*e7be843bSPierre Pronchery return 0; 392*e7be843bSPierre Pronchery if (ctx->mdctx == NULL) 393*e7be843bSPierre Pronchery return 0; 394*e7be843bSPierre Pronchery /* 395*e7be843bSPierre Pronchery * If sig is NULL then we're just finding out the sig size. Other fields 396*e7be843bSPierre Pronchery * are ignored. Defer to ecdsa_sign. 397*e7be843bSPierre Pronchery */ 398*e7be843bSPierre Pronchery if (sig != NULL 399*e7be843bSPierre Pronchery && !EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen)) 400*e7be843bSPierre Pronchery return 0; 401*e7be843bSPierre Pronchery return ecdsa_sign_directly(vctx, sig, siglen, sigsize, digest, dlen); 402*e7be843bSPierre Pronchery } 403*e7be843bSPierre Pronchery 404*e7be843bSPierre Pronchery /* 405*e7be843bSPierre Pronchery * If signing a message, digest tbs and sign the result. 406*e7be843bSPierre Pronchery * Otherwise, sign tbs directly. 407*e7be843bSPierre Pronchery */ 408*e7be843bSPierre Pronchery static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen, 409*e7be843bSPierre Pronchery size_t sigsize, const unsigned char *tbs, size_t tbslen) 410*e7be843bSPierre Pronchery { 411*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 412*e7be843bSPierre Pronchery 413*e7be843bSPierre Pronchery if (ctx->operation == EVP_PKEY_OP_SIGNMSG) { 414*e7be843bSPierre Pronchery /* 415*e7be843bSPierre Pronchery * If |sig| is NULL, the caller is only looking for the sig length. 416*e7be843bSPierre Pronchery * DO NOT update the input in this case. 417*e7be843bSPierre Pronchery */ 418*e7be843bSPierre Pronchery if (sig == NULL) 419*e7be843bSPierre Pronchery return ecdsa_sign_message_final(ctx, sig, siglen, sigsize); 420*e7be843bSPierre Pronchery 421*e7be843bSPierre Pronchery if (ecdsa_signverify_message_update(ctx, tbs, tbslen) <= 0) 422*e7be843bSPierre Pronchery return 0; 423*e7be843bSPierre Pronchery return ecdsa_sign_message_final(ctx, sig, siglen, sigsize); 424*e7be843bSPierre Pronchery } 425*e7be843bSPierre Pronchery return ecdsa_sign_directly(ctx, sig, siglen, sigsize, tbs, tbslen); 426*e7be843bSPierre Pronchery } 427*e7be843bSPierre Pronchery 428*e7be843bSPierre Pronchery static int ecdsa_verify_init(void *vctx, void *ec, const OSSL_PARAM params[]) 429*e7be843bSPierre Pronchery { 430*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 431*e7be843bSPierre Pronchery 432*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 433*e7be843bSPierre Pronchery ctx->verify_message = 0; 434*e7be843bSPierre Pronchery #endif 435*e7be843bSPierre Pronchery return ecdsa_signverify_init(ctx, ec, ecdsa_set_ctx_params, params, 436*e7be843bSPierre Pronchery EVP_PKEY_OP_VERIFY, "ECDSA Verify Init"); 437*e7be843bSPierre Pronchery } 438*e7be843bSPierre Pronchery 439*e7be843bSPierre Pronchery static int ecdsa_verify_directly(void *vctx, 440*e7be843bSPierre Pronchery const unsigned char *sig, size_t siglen, 441b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen) 442b077aed3SPierre Pronchery { 443b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 444b077aed3SPierre Pronchery 445b077aed3SPierre Pronchery if (!ossl_prov_is_running() || (ctx->mdsize != 0 && tbslen != ctx->mdsize)) 446b077aed3SPierre Pronchery return 0; 447b077aed3SPierre Pronchery 448b077aed3SPierre Pronchery return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->ec); 449b077aed3SPierre Pronchery } 450b077aed3SPierre Pronchery 451*e7be843bSPierre Pronchery static int ecdsa_verify_set_sig(void *vctx, 452*e7be843bSPierre Pronchery const unsigned char *sig, size_t siglen) 453b077aed3SPierre Pronchery { 454*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 455*e7be843bSPierre Pronchery OSSL_PARAM params[2]; 456b077aed3SPierre Pronchery 457*e7be843bSPierre Pronchery params[0] = 458*e7be843bSPierre Pronchery OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, 459*e7be843bSPierre Pronchery (unsigned char *)sig, siglen); 460*e7be843bSPierre Pronchery params[1] = OSSL_PARAM_construct_end(); 461*e7be843bSPierre Pronchery return ecdsa_sigalg_set_ctx_params(ctx, params); 462*e7be843bSPierre Pronchery } 463b077aed3SPierre Pronchery 464*e7be843bSPierre Pronchery static int ecdsa_verify_message_final(void *vctx) 465*e7be843bSPierre Pronchery { 466*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 467*e7be843bSPierre Pronchery unsigned char digest[EVP_MAX_MD_SIZE]; 468*e7be843bSPierre Pronchery unsigned int dlen = 0; 469*e7be843bSPierre Pronchery 470*e7be843bSPierre Pronchery if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL) 471b077aed3SPierre Pronchery return 0; 472*e7be843bSPierre Pronchery 473*e7be843bSPierre Pronchery /* 474*e7be843bSPierre Pronchery * The digests used here are all known (see ecdsa_get_md_nid()), so they 475*e7be843bSPierre Pronchery * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. 476*e7be843bSPierre Pronchery */ 477*e7be843bSPierre Pronchery if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen)) 478b077aed3SPierre Pronchery return 0; 479*e7be843bSPierre Pronchery 480*e7be843bSPierre Pronchery return ecdsa_verify_directly(vctx, ctx->sig, ctx->siglen, 481*e7be843bSPierre Pronchery digest, dlen); 482b077aed3SPierre Pronchery } 483*e7be843bSPierre Pronchery 484*e7be843bSPierre Pronchery /* 485*e7be843bSPierre Pronchery * If verifying a message, digest tbs and verify the result. 486*e7be843bSPierre Pronchery * Otherwise, verify tbs directly. 487*e7be843bSPierre Pronchery */ 488*e7be843bSPierre Pronchery static int ecdsa_verify(void *vctx, 489*e7be843bSPierre Pronchery const unsigned char *sig, size_t siglen, 490*e7be843bSPierre Pronchery const unsigned char *tbs, size_t tbslen) 491*e7be843bSPierre Pronchery { 492*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 493*e7be843bSPierre Pronchery 494*e7be843bSPierre Pronchery if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) { 495*e7be843bSPierre Pronchery if (ecdsa_verify_set_sig(ctx, sig, siglen) <= 0) 496b077aed3SPierre Pronchery return 0; 497*e7be843bSPierre Pronchery if (ecdsa_signverify_message_update(ctx, tbs, tbslen) <= 0) 498b077aed3SPierre Pronchery return 0; 499*e7be843bSPierre Pronchery return ecdsa_verify_message_final(ctx); 500b077aed3SPierre Pronchery } 501*e7be843bSPierre Pronchery return ecdsa_verify_directly(ctx, sig, siglen, tbs, tbslen); 502b077aed3SPierre Pronchery } 503b077aed3SPierre Pronchery 504*e7be843bSPierre Pronchery /* DigestSign/DigestVerify wrappers */ 505b077aed3SPierre Pronchery 506b077aed3SPierre Pronchery static int ecdsa_digest_signverify_init(void *vctx, const char *mdname, 507b077aed3SPierre Pronchery void *ec, const OSSL_PARAM params[], 508*e7be843bSPierre Pronchery int operation, const char *desc) 509b077aed3SPierre Pronchery { 510b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 511b077aed3SPierre Pronchery 512b077aed3SPierre Pronchery if (!ossl_prov_is_running()) 513b077aed3SPierre Pronchery return 0; 514b077aed3SPierre Pronchery 515*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 516*e7be843bSPierre Pronchery ctx->verify_message = 1; 517*e7be843bSPierre Pronchery #endif 518*e7be843bSPierre Pronchery if (!ecdsa_signverify_init(vctx, ec, ecdsa_set_ctx_params, params, 519*e7be843bSPierre Pronchery operation, desc)) 520*e7be843bSPierre Pronchery return 0; 521*e7be843bSPierre Pronchery 522*e7be843bSPierre Pronchery if (mdname != NULL 523*e7be843bSPierre Pronchery /* was ecdsa_setup_md already called in ecdsa_signverify_init()? */ 524*e7be843bSPierre Pronchery && (mdname[0] == '\0' || OPENSSL_strcasecmp(ctx->mdname, mdname) != 0) 525*e7be843bSPierre Pronchery && !ecdsa_setup_md(ctx, mdname, NULL, desc)) 526b077aed3SPierre Pronchery return 0; 527b077aed3SPierre Pronchery 528b077aed3SPierre Pronchery ctx->flag_allow_md = 0; 529b077aed3SPierre Pronchery 530b077aed3SPierre Pronchery if (ctx->mdctx == NULL) { 531b077aed3SPierre Pronchery ctx->mdctx = EVP_MD_CTX_new(); 532b077aed3SPierre Pronchery if (ctx->mdctx == NULL) 533b077aed3SPierre Pronchery goto error; 534b077aed3SPierre Pronchery } 535b077aed3SPierre Pronchery 536b077aed3SPierre Pronchery if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params)) 537b077aed3SPierre Pronchery goto error; 538b077aed3SPierre Pronchery return 1; 539b077aed3SPierre Pronchery error: 540b077aed3SPierre Pronchery EVP_MD_CTX_free(ctx->mdctx); 541b077aed3SPierre Pronchery ctx->mdctx = NULL; 542b077aed3SPierre Pronchery return 0; 543b077aed3SPierre Pronchery } 544b077aed3SPierre Pronchery 545b077aed3SPierre Pronchery static int ecdsa_digest_sign_init(void *vctx, const char *mdname, void *ec, 546b077aed3SPierre Pronchery const OSSL_PARAM params[]) 547b077aed3SPierre Pronchery { 548b077aed3SPierre Pronchery return ecdsa_digest_signverify_init(vctx, mdname, ec, params, 549*e7be843bSPierre Pronchery EVP_PKEY_OP_SIGNMSG, 550*e7be843bSPierre Pronchery "ECDSA Digest Sign Init"); 551b077aed3SPierre Pronchery } 552b077aed3SPierre Pronchery 553*e7be843bSPierre Pronchery static int ecdsa_digest_signverify_update(void *vctx, const unsigned char *data, 554b077aed3SPierre Pronchery size_t datalen) 555b077aed3SPierre Pronchery { 556b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 557b077aed3SPierre Pronchery 558b077aed3SPierre Pronchery if (ctx == NULL || ctx->mdctx == NULL) 559b077aed3SPierre Pronchery return 0; 560*e7be843bSPierre Pronchery /* Sigalg implementations shouldn't do digest_sign */ 561*e7be843bSPierre Pronchery if (ctx->flag_sigalg) 562*e7be843bSPierre Pronchery return 0; 563b077aed3SPierre Pronchery 564*e7be843bSPierre Pronchery return ecdsa_signverify_message_update(vctx, data, datalen); 565b077aed3SPierre Pronchery } 566b077aed3SPierre Pronchery 567b077aed3SPierre Pronchery int ecdsa_digest_sign_final(void *vctx, unsigned char *sig, size_t *siglen, 568b077aed3SPierre Pronchery size_t sigsize) 569b077aed3SPierre Pronchery { 570b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 571*e7be843bSPierre Pronchery int ok = 0; 572b077aed3SPierre Pronchery 573*e7be843bSPierre Pronchery if (ctx == NULL) 574*e7be843bSPierre Pronchery return 0; 575*e7be843bSPierre Pronchery /* Sigalg implementations shouldn't do digest_sign */ 576*e7be843bSPierre Pronchery if (ctx->flag_sigalg) 577b077aed3SPierre Pronchery return 0; 578b077aed3SPierre Pronchery 579*e7be843bSPierre Pronchery ok = ecdsa_sign_message_final(ctx, sig, siglen, sigsize); 580*e7be843bSPierre Pronchery 581b077aed3SPierre Pronchery ctx->flag_allow_md = 1; 582*e7be843bSPierre Pronchery 583*e7be843bSPierre Pronchery return ok; 584*e7be843bSPierre Pronchery } 585*e7be843bSPierre Pronchery 586*e7be843bSPierre Pronchery static int ecdsa_digest_verify_init(void *vctx, const char *mdname, void *ec, 587*e7be843bSPierre Pronchery const OSSL_PARAM params[]) 588*e7be843bSPierre Pronchery { 589*e7be843bSPierre Pronchery return ecdsa_digest_signverify_init(vctx, mdname, ec, params, 590*e7be843bSPierre Pronchery EVP_PKEY_OP_VERIFYMSG, 591*e7be843bSPierre Pronchery "ECDSA Digest Verify Init"); 592b077aed3SPierre Pronchery } 593b077aed3SPierre Pronchery 594b077aed3SPierre Pronchery int ecdsa_digest_verify_final(void *vctx, const unsigned char *sig, 595b077aed3SPierre Pronchery size_t siglen) 596b077aed3SPierre Pronchery { 597b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 598*e7be843bSPierre Pronchery int ok = 0; 599b077aed3SPierre Pronchery 600b077aed3SPierre Pronchery if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL) 601b077aed3SPierre Pronchery return 0; 602b077aed3SPierre Pronchery 603*e7be843bSPierre Pronchery /* Sigalg implementations shouldn't do digest_verify */ 604*e7be843bSPierre Pronchery if (ctx->flag_sigalg) 605b077aed3SPierre Pronchery return 0; 606*e7be843bSPierre Pronchery 607*e7be843bSPierre Pronchery if (ecdsa_verify_set_sig(ctx, sig, siglen)) 608*e7be843bSPierre Pronchery ok = ecdsa_verify_message_final(ctx); 609*e7be843bSPierre Pronchery 610b077aed3SPierre Pronchery ctx->flag_allow_md = 1; 611*e7be843bSPierre Pronchery 612*e7be843bSPierre Pronchery return ok; 613b077aed3SPierre Pronchery } 614b077aed3SPierre Pronchery 615b077aed3SPierre Pronchery static void ecdsa_freectx(void *vctx) 616b077aed3SPierre Pronchery { 617b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 618b077aed3SPierre Pronchery 619b077aed3SPierre Pronchery EVP_MD_CTX_free(ctx->mdctx); 620b077aed3SPierre Pronchery EVP_MD_free(ctx->md); 621*e7be843bSPierre Pronchery OPENSSL_free(ctx->propq); 622*e7be843bSPierre Pronchery OPENSSL_free(ctx->sig); 623b077aed3SPierre Pronchery EC_KEY_free(ctx->ec); 624b077aed3SPierre Pronchery BN_clear_free(ctx->kinv); 625b077aed3SPierre Pronchery BN_clear_free(ctx->r); 626b077aed3SPierre Pronchery OPENSSL_free(ctx); 627b077aed3SPierre Pronchery } 628b077aed3SPierre Pronchery 629b077aed3SPierre Pronchery static void *ecdsa_dupctx(void *vctx) 630b077aed3SPierre Pronchery { 631b077aed3SPierre Pronchery PROV_ECDSA_CTX *srcctx = (PROV_ECDSA_CTX *)vctx; 632b077aed3SPierre Pronchery PROV_ECDSA_CTX *dstctx; 633b077aed3SPierre Pronchery 634b077aed3SPierre Pronchery if (!ossl_prov_is_running()) 635b077aed3SPierre Pronchery return NULL; 636b077aed3SPierre Pronchery 637b077aed3SPierre Pronchery dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 638b077aed3SPierre Pronchery if (dstctx == NULL) 639b077aed3SPierre Pronchery return NULL; 640b077aed3SPierre Pronchery 641b077aed3SPierre Pronchery *dstctx = *srcctx; 642b077aed3SPierre Pronchery dstctx->ec = NULL; 643b077aed3SPierre Pronchery dstctx->propq = NULL; 644b077aed3SPierre Pronchery 645b077aed3SPierre Pronchery if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec)) 646b077aed3SPierre Pronchery goto err; 647b077aed3SPierre Pronchery /* Test KATS should not need to be supported */ 648b077aed3SPierre Pronchery if (srcctx->kinv != NULL || srcctx->r != NULL) 649b077aed3SPierre Pronchery goto err; 650b077aed3SPierre Pronchery dstctx->ec = srcctx->ec; 651b077aed3SPierre Pronchery 652b077aed3SPierre Pronchery if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) 653b077aed3SPierre Pronchery goto err; 654b077aed3SPierre Pronchery dstctx->md = srcctx->md; 655b077aed3SPierre Pronchery 656b077aed3SPierre Pronchery if (srcctx->mdctx != NULL) { 657b077aed3SPierre Pronchery dstctx->mdctx = EVP_MD_CTX_new(); 658b077aed3SPierre Pronchery if (dstctx->mdctx == NULL 659b077aed3SPierre Pronchery || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) 660b077aed3SPierre Pronchery goto err; 661b077aed3SPierre Pronchery } 662b077aed3SPierre Pronchery 663b077aed3SPierre Pronchery if (srcctx->propq != NULL) { 664b077aed3SPierre Pronchery dstctx->propq = OPENSSL_strdup(srcctx->propq); 665b077aed3SPierre Pronchery if (dstctx->propq == NULL) 666b077aed3SPierre Pronchery goto err; 667b077aed3SPierre Pronchery } 668b077aed3SPierre Pronchery 669b077aed3SPierre Pronchery return dstctx; 670b077aed3SPierre Pronchery err: 671b077aed3SPierre Pronchery ecdsa_freectx(dstctx); 672b077aed3SPierre Pronchery return NULL; 673b077aed3SPierre Pronchery } 674b077aed3SPierre Pronchery 675b077aed3SPierre Pronchery static int ecdsa_get_ctx_params(void *vctx, OSSL_PARAM *params) 676b077aed3SPierre Pronchery { 677b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 678b077aed3SPierre Pronchery OSSL_PARAM *p; 679b077aed3SPierre Pronchery 680b077aed3SPierre Pronchery if (ctx == NULL) 681b077aed3SPierre Pronchery return 0; 682b077aed3SPierre Pronchery 683b077aed3SPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); 684*e7be843bSPierre Pronchery if (p != NULL && !OSSL_PARAM_set_octet_string(p, 685*e7be843bSPierre Pronchery ctx->aid_len == 0 ? NULL : ctx->aid_buf, 686*e7be843bSPierre Pronchery ctx->aid_len)) 687b077aed3SPierre Pronchery return 0; 688b077aed3SPierre Pronchery 689b077aed3SPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); 690b077aed3SPierre Pronchery if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->mdsize)) 691b077aed3SPierre Pronchery return 0; 692b077aed3SPierre Pronchery 693b077aed3SPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST); 694b077aed3SPierre Pronchery if (p != NULL && !OSSL_PARAM_set_utf8_string(p, ctx->md == NULL 695b077aed3SPierre Pronchery ? ctx->mdname 696b077aed3SPierre Pronchery : EVP_MD_get0_name(ctx->md))) 697b077aed3SPierre Pronchery return 0; 698b077aed3SPierre Pronchery 699*e7be843bSPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE); 700*e7be843bSPierre Pronchery if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->nonce_type)) 701*e7be843bSPierre Pronchery return 0; 702*e7be843bSPierre Pronchery 703*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 704*e7be843bSPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE); 705*e7be843bSPierre Pronchery if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->verify_message)) 706*e7be843bSPierre Pronchery return 0; 707*e7be843bSPierre Pronchery #endif 708*e7be843bSPierre Pronchery 709*e7be843bSPierre Pronchery if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params)) 710*e7be843bSPierre Pronchery return 0; 711b077aed3SPierre Pronchery return 1; 712b077aed3SPierre Pronchery } 713b077aed3SPierre Pronchery 714b077aed3SPierre Pronchery static const OSSL_PARAM known_gettable_ctx_params[] = { 715b077aed3SPierre Pronchery OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), 716b077aed3SPierre Pronchery OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), 717b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 718*e7be843bSPierre Pronchery OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), 719*e7be843bSPierre Pronchery #ifdef FIPS_MODULE 720*e7be843bSPierre Pronchery OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE, NULL), 721*e7be843bSPierre Pronchery #endif 722*e7be843bSPierre Pronchery OSSL_FIPS_IND_GETTABLE_CTX_PARAM() 723b077aed3SPierre Pronchery OSSL_PARAM_END 724b077aed3SPierre Pronchery }; 725b077aed3SPierre Pronchery 726b077aed3SPierre Pronchery static const OSSL_PARAM *ecdsa_gettable_ctx_params(ossl_unused void *vctx, 727b077aed3SPierre Pronchery ossl_unused void *provctx) 728b077aed3SPierre Pronchery { 729b077aed3SPierre Pronchery return known_gettable_ctx_params; 730b077aed3SPierre Pronchery } 731b077aed3SPierre Pronchery 732*e7be843bSPierre Pronchery /** 733*e7be843bSPierre Pronchery * @brief Set up common params for ecdsa_set_ctx_params and 734*e7be843bSPierre Pronchery * ecdsa_sigalg_set_ctx_params. The caller is responsible for checking |vctx| is 735*e7be843bSPierre Pronchery * not NULL and |params| is not empty. 736*e7be843bSPierre Pronchery */ 737*e7be843bSPierre Pronchery static int ecdsa_common_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 738b077aed3SPierre Pronchery { 739b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 740b077aed3SPierre Pronchery const OSSL_PARAM *p; 741b077aed3SPierre Pronchery 742*e7be843bSPierre Pronchery if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params, 743*e7be843bSPierre Pronchery OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK)) 744b077aed3SPierre Pronchery return 0; 745*e7be843bSPierre Pronchery if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params, 746*e7be843bSPierre Pronchery OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK)) 747*e7be843bSPierre Pronchery return 0; 748b077aed3SPierre Pronchery 749b077aed3SPierre Pronchery #if !defined(OPENSSL_NO_ACVP_TESTS) 750b077aed3SPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_KAT); 751b077aed3SPierre Pronchery if (p != NULL && !OSSL_PARAM_get_uint(p, &ctx->kattest)) 752b077aed3SPierre Pronchery return 0; 753b077aed3SPierre Pronchery #endif 754b077aed3SPierre Pronchery 755*e7be843bSPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE); 756*e7be843bSPierre Pronchery if (p != NULL 757*e7be843bSPierre Pronchery && !OSSL_PARAM_get_uint(p, &ctx->nonce_type)) 758*e7be843bSPierre Pronchery return 0; 759*e7be843bSPierre Pronchery return 1; 760*e7be843bSPierre Pronchery } 761*e7be843bSPierre Pronchery 762*e7be843bSPierre Pronchery #define ECDSA_COMMON_SETTABLE_CTX_PARAMS \ 763*e7be843bSPierre Pronchery OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL), \ 764*e7be843bSPierre Pronchery OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), \ 765*e7be843bSPierre Pronchery OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK) \ 766*e7be843bSPierre Pronchery OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK) \ 767*e7be843bSPierre Pronchery OSSL_PARAM_END 768*e7be843bSPierre Pronchery 769*e7be843bSPierre Pronchery static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 770*e7be843bSPierre Pronchery { 771*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 772*e7be843bSPierre Pronchery const OSSL_PARAM *p; 773*e7be843bSPierre Pronchery size_t mdsize = 0; 774*e7be843bSPierre Pronchery int ret; 775*e7be843bSPierre Pronchery 776*e7be843bSPierre Pronchery if (ctx == NULL) 777*e7be843bSPierre Pronchery return 0; 778*e7be843bSPierre Pronchery if (ossl_param_is_empty(params)) 779*e7be843bSPierre Pronchery return 1; 780*e7be843bSPierre Pronchery 781*e7be843bSPierre Pronchery if ((ret = ecdsa_common_set_ctx_params(ctx, params)) <= 0) 782*e7be843bSPierre Pronchery return ret; 783*e7be843bSPierre Pronchery 784b077aed3SPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); 785b077aed3SPierre Pronchery if (p != NULL) { 786b077aed3SPierre Pronchery char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname; 787b077aed3SPierre Pronchery char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops; 788b077aed3SPierre Pronchery const OSSL_PARAM *propsp = 789b077aed3SPierre Pronchery OSSL_PARAM_locate_const(params, 790b077aed3SPierre Pronchery OSSL_SIGNATURE_PARAM_PROPERTIES); 791b077aed3SPierre Pronchery 792b077aed3SPierre Pronchery if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) 793b077aed3SPierre Pronchery return 0; 794b077aed3SPierre Pronchery if (propsp != NULL 795b077aed3SPierre Pronchery && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) 796b077aed3SPierre Pronchery return 0; 797*e7be843bSPierre Pronchery if (!ecdsa_setup_md(ctx, mdname, mdprops, "ECDSA Set Ctx")) 798b077aed3SPierre Pronchery return 0; 799b077aed3SPierre Pronchery } 800b077aed3SPierre Pronchery 801b077aed3SPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); 802b077aed3SPierre Pronchery if (p != NULL) { 803b077aed3SPierre Pronchery if (!OSSL_PARAM_get_size_t(p, &mdsize) 804b077aed3SPierre Pronchery || (!ctx->flag_allow_md && mdsize != ctx->mdsize)) 805b077aed3SPierre Pronchery return 0; 806b077aed3SPierre Pronchery ctx->mdsize = mdsize; 807b077aed3SPierre Pronchery } 808b077aed3SPierre Pronchery return 1; 809b077aed3SPierre Pronchery } 810b077aed3SPierre Pronchery 811b077aed3SPierre Pronchery static const OSSL_PARAM settable_ctx_params[] = { 812b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 813b077aed3SPierre Pronchery OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), 814b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), 815*e7be843bSPierre Pronchery ECDSA_COMMON_SETTABLE_CTX_PARAMS 816b077aed3SPierre Pronchery }; 817b077aed3SPierre Pronchery 818b077aed3SPierre Pronchery static const OSSL_PARAM *ecdsa_settable_ctx_params(void *vctx, 819b077aed3SPierre Pronchery ossl_unused void *provctx) 820b077aed3SPierre Pronchery { 821b077aed3SPierre Pronchery return settable_ctx_params; 822b077aed3SPierre Pronchery } 823b077aed3SPierre Pronchery 824b077aed3SPierre Pronchery static int ecdsa_get_ctx_md_params(void *vctx, OSSL_PARAM *params) 825b077aed3SPierre Pronchery { 826b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 827b077aed3SPierre Pronchery 828b077aed3SPierre Pronchery if (ctx->mdctx == NULL) 829b077aed3SPierre Pronchery return 0; 830b077aed3SPierre Pronchery 831b077aed3SPierre Pronchery return EVP_MD_CTX_get_params(ctx->mdctx, params); 832b077aed3SPierre Pronchery } 833b077aed3SPierre Pronchery 834b077aed3SPierre Pronchery static const OSSL_PARAM *ecdsa_gettable_ctx_md_params(void *vctx) 835b077aed3SPierre Pronchery { 836b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 837b077aed3SPierre Pronchery 838b077aed3SPierre Pronchery if (ctx->md == NULL) 839b077aed3SPierre Pronchery return 0; 840b077aed3SPierre Pronchery 841b077aed3SPierre Pronchery return EVP_MD_gettable_ctx_params(ctx->md); 842b077aed3SPierre Pronchery } 843b077aed3SPierre Pronchery 844b077aed3SPierre Pronchery static int ecdsa_set_ctx_md_params(void *vctx, const OSSL_PARAM params[]) 845b077aed3SPierre Pronchery { 846b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 847b077aed3SPierre Pronchery 848b077aed3SPierre Pronchery if (ctx->mdctx == NULL) 849b077aed3SPierre Pronchery return 0; 850b077aed3SPierre Pronchery 851b077aed3SPierre Pronchery return EVP_MD_CTX_set_params(ctx->mdctx, params); 852b077aed3SPierre Pronchery } 853b077aed3SPierre Pronchery 854b077aed3SPierre Pronchery static const OSSL_PARAM *ecdsa_settable_ctx_md_params(void *vctx) 855b077aed3SPierre Pronchery { 856b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 857b077aed3SPierre Pronchery 858b077aed3SPierre Pronchery if (ctx->md == NULL) 859b077aed3SPierre Pronchery return 0; 860b077aed3SPierre Pronchery 861b077aed3SPierre Pronchery return EVP_MD_settable_ctx_params(ctx->md); 862b077aed3SPierre Pronchery } 863b077aed3SPierre Pronchery 864b077aed3SPierre Pronchery const OSSL_DISPATCH ossl_ecdsa_signature_functions[] = { 865b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx }, 866b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_sign_init }, 867b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign }, 868b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))ecdsa_verify_init }, 869b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))ecdsa_verify }, 870b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, 871b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_sign_init }, 872b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, 873b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_signverify_update }, 874b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, 875b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_sign_final }, 876b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, 877b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_verify_init }, 878b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, 879b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_signverify_update }, 880b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, 881b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_verify_final }, 882b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx }, 883b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx }, 884b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))ecdsa_get_ctx_params }, 885b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, 886b077aed3SPierre Pronchery (void (*)(void))ecdsa_gettable_ctx_params }, 887b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))ecdsa_set_ctx_params }, 888b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, 889b077aed3SPierre Pronchery (void (*)(void))ecdsa_settable_ctx_params }, 890b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, 891b077aed3SPierre Pronchery (void (*)(void))ecdsa_get_ctx_md_params }, 892b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, 893b077aed3SPierre Pronchery (void (*)(void))ecdsa_gettable_ctx_md_params }, 894b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, 895b077aed3SPierre Pronchery (void (*)(void))ecdsa_set_ctx_md_params }, 896b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, 897b077aed3SPierre Pronchery (void (*)(void))ecdsa_settable_ctx_md_params }, 898*e7be843bSPierre Pronchery OSSL_DISPATCH_END 899b077aed3SPierre Pronchery }; 900*e7be843bSPierre Pronchery 901*e7be843bSPierre Pronchery /* ------------------------------------------------------------------ */ 902*e7be843bSPierre Pronchery 903*e7be843bSPierre Pronchery /* 904*e7be843bSPierre Pronchery * So called sigalgs (composite ECDSA+hash) implemented below. They 905*e7be843bSPierre Pronchery * are pretty much hard coded. 906*e7be843bSPierre Pronchery */ 907*e7be843bSPierre Pronchery 908*e7be843bSPierre Pronchery static OSSL_FUNC_signature_query_key_types_fn ecdsa_sigalg_query_key_types; 909*e7be843bSPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_sigalg_settable_ctx_params; 910*e7be843bSPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_sigalg_set_ctx_params; 911*e7be843bSPierre Pronchery 912*e7be843bSPierre Pronchery /* 913*e7be843bSPierre Pronchery * ecdsa_sigalg_signverify_init() is almost like ecdsa_digest_signverify_init(), 914*e7be843bSPierre Pronchery * just doesn't allow fetching an MD from whatever the user chooses. 915*e7be843bSPierre Pronchery */ 916*e7be843bSPierre Pronchery static int ecdsa_sigalg_signverify_init(void *vctx, void *vec, 917*e7be843bSPierre Pronchery OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params, 918*e7be843bSPierre Pronchery const OSSL_PARAM params[], 919*e7be843bSPierre Pronchery const char *mdname, 920*e7be843bSPierre Pronchery int operation, const char *desc) 921*e7be843bSPierre Pronchery { 922*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 923*e7be843bSPierre Pronchery 924*e7be843bSPierre Pronchery if (!ossl_prov_is_running()) 925*e7be843bSPierre Pronchery return 0; 926*e7be843bSPierre Pronchery 927*e7be843bSPierre Pronchery if (!ecdsa_signverify_init(vctx, vec, set_ctx_params, params, operation, 928*e7be843bSPierre Pronchery desc)) 929*e7be843bSPierre Pronchery return 0; 930*e7be843bSPierre Pronchery 931*e7be843bSPierre Pronchery if (!ecdsa_setup_md(ctx, mdname, NULL, desc)) 932*e7be843bSPierre Pronchery return 0; 933*e7be843bSPierre Pronchery 934*e7be843bSPierre Pronchery ctx->flag_sigalg = 1; 935*e7be843bSPierre Pronchery ctx->flag_allow_md = 0; 936*e7be843bSPierre Pronchery 937*e7be843bSPierre Pronchery if (ctx->mdctx == NULL) { 938*e7be843bSPierre Pronchery ctx->mdctx = EVP_MD_CTX_new(); 939*e7be843bSPierre Pronchery if (ctx->mdctx == NULL) 940*e7be843bSPierre Pronchery goto error; 941*e7be843bSPierre Pronchery } 942*e7be843bSPierre Pronchery 943*e7be843bSPierre Pronchery if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params)) 944*e7be843bSPierre Pronchery goto error; 945*e7be843bSPierre Pronchery 946*e7be843bSPierre Pronchery return 1; 947*e7be843bSPierre Pronchery 948*e7be843bSPierre Pronchery error: 949*e7be843bSPierre Pronchery EVP_MD_CTX_free(ctx->mdctx); 950*e7be843bSPierre Pronchery ctx->mdctx = NULL; 951*e7be843bSPierre Pronchery return 0; 952*e7be843bSPierre Pronchery } 953*e7be843bSPierre Pronchery 954*e7be843bSPierre Pronchery static const char **ecdsa_sigalg_query_key_types(void) 955*e7be843bSPierre Pronchery { 956*e7be843bSPierre Pronchery static const char *keytypes[] = { "EC", NULL }; 957*e7be843bSPierre Pronchery 958*e7be843bSPierre Pronchery return keytypes; 959*e7be843bSPierre Pronchery } 960*e7be843bSPierre Pronchery 961*e7be843bSPierre Pronchery static const OSSL_PARAM settable_sigalg_ctx_params[] = { 962*e7be843bSPierre Pronchery OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0), 963*e7be843bSPierre Pronchery ECDSA_COMMON_SETTABLE_CTX_PARAMS 964*e7be843bSPierre Pronchery }; 965*e7be843bSPierre Pronchery 966*e7be843bSPierre Pronchery static const OSSL_PARAM *ecdsa_sigalg_settable_ctx_params(void *vctx, 967*e7be843bSPierre Pronchery ossl_unused void *provctx) 968*e7be843bSPierre Pronchery { 969*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 970*e7be843bSPierre Pronchery 971*e7be843bSPierre Pronchery if (ctx != NULL && ctx->operation == EVP_PKEY_OP_VERIFYMSG) 972*e7be843bSPierre Pronchery return settable_sigalg_ctx_params; 973*e7be843bSPierre Pronchery return NULL; 974*e7be843bSPierre Pronchery } 975*e7be843bSPierre Pronchery 976*e7be843bSPierre Pronchery static int ecdsa_sigalg_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 977*e7be843bSPierre Pronchery { 978*e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; 979*e7be843bSPierre Pronchery const OSSL_PARAM *p; 980*e7be843bSPierre Pronchery int ret; 981*e7be843bSPierre Pronchery 982*e7be843bSPierre Pronchery if (ctx == NULL) 983*e7be843bSPierre Pronchery return 0; 984*e7be843bSPierre Pronchery if (ossl_param_is_empty(params)) 985*e7be843bSPierre Pronchery return 1; 986*e7be843bSPierre Pronchery 987*e7be843bSPierre Pronchery if ((ret = ecdsa_common_set_ctx_params(ctx, params)) <= 0) 988*e7be843bSPierre Pronchery return ret; 989*e7be843bSPierre Pronchery 990*e7be843bSPierre Pronchery if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) { 991*e7be843bSPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE); 992*e7be843bSPierre Pronchery if (p != NULL) { 993*e7be843bSPierre Pronchery OPENSSL_free(ctx->sig); 994*e7be843bSPierre Pronchery ctx->sig = NULL; 995*e7be843bSPierre Pronchery ctx->siglen = 0; 996*e7be843bSPierre Pronchery if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->sig, 997*e7be843bSPierre Pronchery 0, &ctx->siglen)) 998*e7be843bSPierre Pronchery return 0; 999*e7be843bSPierre Pronchery } 1000*e7be843bSPierre Pronchery } 1001*e7be843bSPierre Pronchery return 1; 1002*e7be843bSPierre Pronchery } 1003*e7be843bSPierre Pronchery 1004*e7be843bSPierre Pronchery #define IMPL_ECDSA_SIGALG(md, MD) \ 1005*e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_init_fn ecdsa_##md##_sign_init; \ 1006*e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_message_init_fn \ 1007*e7be843bSPierre Pronchery ecdsa_##md##_sign_message_init; \ 1008*e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_init_fn ecdsa_##md##_verify_init; \ 1009*e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_message_init_fn \ 1010*e7be843bSPierre Pronchery ecdsa_##md##_verify_message_init; \ 1011*e7be843bSPierre Pronchery \ 1012*e7be843bSPierre Pronchery static int \ 1013*e7be843bSPierre Pronchery ecdsa_##md##_sign_init(void *vctx, void *vec, \ 1014*e7be843bSPierre Pronchery const OSSL_PARAM params[]) \ 1015*e7be843bSPierre Pronchery { \ 1016*e7be843bSPierre Pronchery static const char desc[] = "ECDSA-" #MD " Sign Init"; \ 1017*e7be843bSPierre Pronchery \ 1018*e7be843bSPierre Pronchery return ecdsa_sigalg_signverify_init(vctx, vec, \ 1019*e7be843bSPierre Pronchery ecdsa_sigalg_set_ctx_params, \ 1020*e7be843bSPierre Pronchery params, #MD, \ 1021*e7be843bSPierre Pronchery EVP_PKEY_OP_SIGN, \ 1022*e7be843bSPierre Pronchery desc); \ 1023*e7be843bSPierre Pronchery } \ 1024*e7be843bSPierre Pronchery \ 1025*e7be843bSPierre Pronchery static int \ 1026*e7be843bSPierre Pronchery ecdsa_##md##_sign_message_init(void *vctx, void *vec, \ 1027*e7be843bSPierre Pronchery const OSSL_PARAM params[]) \ 1028*e7be843bSPierre Pronchery { \ 1029*e7be843bSPierre Pronchery static const char desc[] = "ECDSA-" #MD " Sign Message Init"; \ 1030*e7be843bSPierre Pronchery \ 1031*e7be843bSPierre Pronchery return ecdsa_sigalg_signverify_init(vctx, vec, \ 1032*e7be843bSPierre Pronchery ecdsa_sigalg_set_ctx_params, \ 1033*e7be843bSPierre Pronchery params, #MD, \ 1034*e7be843bSPierre Pronchery EVP_PKEY_OP_SIGNMSG, \ 1035*e7be843bSPierre Pronchery desc); \ 1036*e7be843bSPierre Pronchery } \ 1037*e7be843bSPierre Pronchery \ 1038*e7be843bSPierre Pronchery static int \ 1039*e7be843bSPierre Pronchery ecdsa_##md##_verify_init(void *vctx, void *vec, \ 1040*e7be843bSPierre Pronchery const OSSL_PARAM params[]) \ 1041*e7be843bSPierre Pronchery { \ 1042*e7be843bSPierre Pronchery static const char desc[] = "ECDSA-" #MD " Verify Init"; \ 1043*e7be843bSPierre Pronchery \ 1044*e7be843bSPierre Pronchery return ecdsa_sigalg_signverify_init(vctx, vec, \ 1045*e7be843bSPierre Pronchery ecdsa_sigalg_set_ctx_params, \ 1046*e7be843bSPierre Pronchery params, #MD, \ 1047*e7be843bSPierre Pronchery EVP_PKEY_OP_VERIFY, \ 1048*e7be843bSPierre Pronchery desc); \ 1049*e7be843bSPierre Pronchery } \ 1050*e7be843bSPierre Pronchery \ 1051*e7be843bSPierre Pronchery static int \ 1052*e7be843bSPierre Pronchery ecdsa_##md##_verify_message_init(void *vctx, void *vec, \ 1053*e7be843bSPierre Pronchery const OSSL_PARAM params[]) \ 1054*e7be843bSPierre Pronchery { \ 1055*e7be843bSPierre Pronchery static const char desc[] = "ECDSA-" #MD " Verify Message Init"; \ 1056*e7be843bSPierre Pronchery \ 1057*e7be843bSPierre Pronchery return ecdsa_sigalg_signverify_init(vctx, vec, \ 1058*e7be843bSPierre Pronchery ecdsa_sigalg_set_ctx_params, \ 1059*e7be843bSPierre Pronchery params, #MD, \ 1060*e7be843bSPierre Pronchery EVP_PKEY_OP_VERIFYMSG, \ 1061*e7be843bSPierre Pronchery desc); \ 1062*e7be843bSPierre Pronchery } \ 1063*e7be843bSPierre Pronchery \ 1064*e7be843bSPierre Pronchery const OSSL_DISPATCH ossl_ecdsa_##md##_signature_functions[] = { \ 1065*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx }, \ 1066*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_INIT, \ 1067*e7be843bSPierre Pronchery (void (*)(void))ecdsa_##md##_sign_init }, \ 1068*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign }, \ 1069*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \ 1070*e7be843bSPierre Pronchery (void (*)(void))ecdsa_##md##_sign_message_init }, \ 1071*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, \ 1072*e7be843bSPierre Pronchery (void (*)(void))ecdsa_signverify_message_update }, \ 1073*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, \ 1074*e7be843bSPierre Pronchery (void (*)(void))ecdsa_sign_message_final }, \ 1075*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \ 1076*e7be843bSPierre Pronchery (void (*)(void))ecdsa_##md##_verify_init }, \ 1077*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY, \ 1078*e7be843bSPierre Pronchery (void (*)(void))ecdsa_verify }, \ 1079*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \ 1080*e7be843bSPierre Pronchery (void (*)(void))ecdsa_##md##_verify_message_init }, \ 1081*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE, \ 1082*e7be843bSPierre Pronchery (void (*)(void))ecdsa_signverify_message_update }, \ 1083*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, \ 1084*e7be843bSPierre Pronchery (void (*)(void))ecdsa_verify_message_final }, \ 1085*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx }, \ 1086*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx }, \ 1087*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \ 1088*e7be843bSPierre Pronchery (void (*)(void))ecdsa_sigalg_query_key_types }, \ 1089*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \ 1090*e7be843bSPierre Pronchery (void (*)(void))ecdsa_get_ctx_params }, \ 1091*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \ 1092*e7be843bSPierre Pronchery (void (*)(void))ecdsa_gettable_ctx_params }, \ 1093*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ 1094*e7be843bSPierre Pronchery (void (*)(void))ecdsa_sigalg_set_ctx_params }, \ 1095*e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ 1096*e7be843bSPierre Pronchery (void (*)(void))ecdsa_sigalg_settable_ctx_params }, \ 1097*e7be843bSPierre Pronchery OSSL_DISPATCH_END \ 1098*e7be843bSPierre Pronchery } 1099*e7be843bSPierre Pronchery 1100*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha1, SHA1); 1101*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha224, SHA2-224); 1102*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha256, SHA2-256); 1103*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha384, SHA2-384); 1104*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha512, SHA2-512); 1105*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha3_224, SHA3-224); 1106*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha3_256, SHA3-256); 1107*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha3_384, SHA3-384); 1108*e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha3_512, SHA3-512); 1109