1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2023 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 * RSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <string.h> 17e1051a39Sopenharmony_ci#include <openssl/crypto.h> 18e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 19e1051a39Sopenharmony_ci#include <openssl/core_names.h> 20e1051a39Sopenharmony_ci#include <openssl/err.h> 21e1051a39Sopenharmony_ci#include <openssl/rsa.h> 22e1051a39Sopenharmony_ci#include <openssl/params.h> 23e1051a39Sopenharmony_ci#include <openssl/evp.h> 24e1051a39Sopenharmony_ci#include <openssl/proverr.h> 25e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 26e1051a39Sopenharmony_ci#include "internal/nelem.h" 27e1051a39Sopenharmony_ci#include "internal/sizes.h" 28e1051a39Sopenharmony_ci#include "crypto/rsa.h" 29e1051a39Sopenharmony_ci#include "prov/providercommon.h" 30e1051a39Sopenharmony_ci#include "prov/implementations.h" 31e1051a39Sopenharmony_ci#include "prov/provider_ctx.h" 32e1051a39Sopenharmony_ci#include "prov/der_rsa.h" 33e1051a39Sopenharmony_ci#include "prov/securitycheck.h" 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_ci#define RSA_DEFAULT_DIGEST_NAME OSSL_DIGEST_NAME_SHA1 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_newctx_fn rsa_newctx; 38e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_sign_init_fn rsa_sign_init; 39e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_verify_init_fn rsa_verify_init; 40e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_verify_recover_init_fn rsa_verify_recover_init; 41e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_sign_fn rsa_sign; 42e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_verify_fn rsa_verify; 43e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_verify_recover_fn rsa_verify_recover; 44e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_init_fn rsa_digest_sign_init; 45e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_update_fn rsa_digest_signverify_update; 46e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_final_fn rsa_digest_sign_final; 47e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_verify_init_fn rsa_digest_verify_init; 48e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_verify_update_fn rsa_digest_signverify_update; 49e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_verify_final_fn rsa_digest_verify_final; 50e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_freectx_fn rsa_freectx; 51e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_dupctx_fn rsa_dupctx; 52e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_get_ctx_params_fn rsa_get_ctx_params; 53e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_gettable_ctx_params_fn rsa_gettable_ctx_params; 54e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_set_ctx_params_fn rsa_set_ctx_params; 55e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_settable_ctx_params_fn rsa_settable_ctx_params; 56e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_get_ctx_md_params_fn rsa_get_ctx_md_params; 57e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_gettable_ctx_md_params_fn rsa_gettable_ctx_md_params; 58e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_set_ctx_md_params_fn rsa_set_ctx_md_params; 59e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_settable_ctx_md_params_fn rsa_settable_ctx_md_params; 60e1051a39Sopenharmony_ci 61e1051a39Sopenharmony_cistatic OSSL_ITEM padding_item[] = { 62e1051a39Sopenharmony_ci { RSA_PKCS1_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15 }, 63e1051a39Sopenharmony_ci { RSA_NO_PADDING, OSSL_PKEY_RSA_PAD_MODE_NONE }, 64e1051a39Sopenharmony_ci { RSA_X931_PADDING, OSSL_PKEY_RSA_PAD_MODE_X931 }, 65e1051a39Sopenharmony_ci { RSA_PKCS1_PSS_PADDING, OSSL_PKEY_RSA_PAD_MODE_PSS }, 66e1051a39Sopenharmony_ci { 0, NULL } 67e1051a39Sopenharmony_ci}; 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_ci/* 70e1051a39Sopenharmony_ci * What's passed as an actual key is defined by the KEYMGMT interface. 71e1051a39Sopenharmony_ci * We happen to know that our KEYMGMT simply passes RSA structures, so 72e1051a39Sopenharmony_ci * we use that here too. 73e1051a39Sopenharmony_ci */ 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_citypedef struct { 76e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; 77e1051a39Sopenharmony_ci char *propq; 78e1051a39Sopenharmony_ci RSA *rsa; 79e1051a39Sopenharmony_ci int operation; 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ci /* 82e1051a39Sopenharmony_ci * Flag to determine if the hash function can be changed (1) or not (0) 83e1051a39Sopenharmony_ci * Because it's dangerous to change during a DigestSign or DigestVerify 84e1051a39Sopenharmony_ci * operation, this flag is cleared by their Init function, and set again 85e1051a39Sopenharmony_ci * by their Final function. 86e1051a39Sopenharmony_ci */ 87e1051a39Sopenharmony_ci unsigned int flag_allow_md : 1; 88e1051a39Sopenharmony_ci unsigned int mgf1_md_set : 1; 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci /* main digest */ 91e1051a39Sopenharmony_ci EVP_MD *md; 92e1051a39Sopenharmony_ci EVP_MD_CTX *mdctx; 93e1051a39Sopenharmony_ci int mdnid; 94e1051a39Sopenharmony_ci char mdname[OSSL_MAX_NAME_SIZE]; /* Purely informational */ 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_ci /* RSA padding mode */ 97e1051a39Sopenharmony_ci int pad_mode; 98e1051a39Sopenharmony_ci /* message digest for MGF1 */ 99e1051a39Sopenharmony_ci EVP_MD *mgf1_md; 100e1051a39Sopenharmony_ci int mgf1_mdnid; 101e1051a39Sopenharmony_ci char mgf1_mdname[OSSL_MAX_NAME_SIZE]; /* Purely informational */ 102e1051a39Sopenharmony_ci /* PSS salt length */ 103e1051a39Sopenharmony_ci int saltlen; 104e1051a39Sopenharmony_ci /* Minimum salt length or -1 if no PSS parameter restriction */ 105e1051a39Sopenharmony_ci int min_saltlen; 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci /* Temp buffer */ 108e1051a39Sopenharmony_ci unsigned char *tbuf; 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_ci} PROV_RSA_CTX; 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ci/* True if PSS parameters are restricted */ 113e1051a39Sopenharmony_ci#define rsa_pss_restricted(prsactx) (prsactx->min_saltlen != -1) 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_cistatic size_t rsa_get_md_size(const PROV_RSA_CTX *prsactx) 116e1051a39Sopenharmony_ci{ 117e1051a39Sopenharmony_ci if (prsactx->md != NULL) 118e1051a39Sopenharmony_ci return EVP_MD_get_size(prsactx->md); 119e1051a39Sopenharmony_ci return 0; 120e1051a39Sopenharmony_ci} 121e1051a39Sopenharmony_ci 122e1051a39Sopenharmony_cistatic int rsa_check_padding(const PROV_RSA_CTX *prsactx, 123e1051a39Sopenharmony_ci const char *mdname, const char *mgf1_mdname, 124e1051a39Sopenharmony_ci int mdnid) 125e1051a39Sopenharmony_ci{ 126e1051a39Sopenharmony_ci switch(prsactx->pad_mode) { 127e1051a39Sopenharmony_ci case RSA_NO_PADDING: 128e1051a39Sopenharmony_ci if (mdname != NULL || mdnid != NID_undef) { 129e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE); 130e1051a39Sopenharmony_ci return 0; 131e1051a39Sopenharmony_ci } 132e1051a39Sopenharmony_ci break; 133e1051a39Sopenharmony_ci case RSA_X931_PADDING: 134e1051a39Sopenharmony_ci if (RSA_X931_hash_id(mdnid) == -1) { 135e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_X931_DIGEST); 136e1051a39Sopenharmony_ci return 0; 137e1051a39Sopenharmony_ci } 138e1051a39Sopenharmony_ci break; 139e1051a39Sopenharmony_ci case RSA_PKCS1_PSS_PADDING: 140e1051a39Sopenharmony_ci if (rsa_pss_restricted(prsactx)) 141e1051a39Sopenharmony_ci if ((mdname != NULL && !EVP_MD_is_a(prsactx->md, mdname)) 142e1051a39Sopenharmony_ci || (mgf1_mdname != NULL 143e1051a39Sopenharmony_ci && !EVP_MD_is_a(prsactx->mgf1_md, mgf1_mdname))) { 144e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED); 145e1051a39Sopenharmony_ci return 0; 146e1051a39Sopenharmony_ci } 147e1051a39Sopenharmony_ci break; 148e1051a39Sopenharmony_ci default: 149e1051a39Sopenharmony_ci break; 150e1051a39Sopenharmony_ci } 151e1051a39Sopenharmony_ci 152e1051a39Sopenharmony_ci return 1; 153e1051a39Sopenharmony_ci} 154e1051a39Sopenharmony_ci 155e1051a39Sopenharmony_cistatic int rsa_check_parameters(PROV_RSA_CTX *prsactx, int min_saltlen) 156e1051a39Sopenharmony_ci{ 157e1051a39Sopenharmony_ci if (prsactx->pad_mode == RSA_PKCS1_PSS_PADDING) { 158e1051a39Sopenharmony_ci int max_saltlen; 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ci /* See if minimum salt length exceeds maximum possible */ 161e1051a39Sopenharmony_ci max_saltlen = RSA_size(prsactx->rsa) - EVP_MD_get_size(prsactx->md); 162e1051a39Sopenharmony_ci if ((RSA_bits(prsactx->rsa) & 0x7) == 1) 163e1051a39Sopenharmony_ci max_saltlen--; 164e1051a39Sopenharmony_ci if (min_saltlen < 0 || min_saltlen > max_saltlen) { 165e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); 166e1051a39Sopenharmony_ci return 0; 167e1051a39Sopenharmony_ci } 168e1051a39Sopenharmony_ci prsactx->min_saltlen = min_saltlen; 169e1051a39Sopenharmony_ci } 170e1051a39Sopenharmony_ci return 1; 171e1051a39Sopenharmony_ci} 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_cistatic void *rsa_newctx(void *provctx, const char *propq) 174e1051a39Sopenharmony_ci{ 175e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = NULL; 176e1051a39Sopenharmony_ci char *propq_copy = NULL; 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 179e1051a39Sopenharmony_ci return NULL; 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ci if ((prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX))) == NULL 182e1051a39Sopenharmony_ci || (propq != NULL 183e1051a39Sopenharmony_ci && (propq_copy = OPENSSL_strdup(propq)) == NULL)) { 184e1051a39Sopenharmony_ci OPENSSL_free(prsactx); 185e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 186e1051a39Sopenharmony_ci return NULL; 187e1051a39Sopenharmony_ci } 188e1051a39Sopenharmony_ci 189e1051a39Sopenharmony_ci prsactx->libctx = PROV_LIBCTX_OF(provctx); 190e1051a39Sopenharmony_ci prsactx->flag_allow_md = 1; 191e1051a39Sopenharmony_ci prsactx->propq = propq_copy; 192e1051a39Sopenharmony_ci /* Maximum for sign, auto for verify */ 193e1051a39Sopenharmony_ci prsactx->saltlen = RSA_PSS_SALTLEN_AUTO; 194e1051a39Sopenharmony_ci prsactx->min_saltlen = -1; 195e1051a39Sopenharmony_ci return prsactx; 196e1051a39Sopenharmony_ci} 197e1051a39Sopenharmony_ci 198e1051a39Sopenharmony_cistatic int rsa_pss_compute_saltlen(PROV_RSA_CTX *ctx) 199e1051a39Sopenharmony_ci{ 200e1051a39Sopenharmony_ci int saltlen = ctx->saltlen; 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_ci if (saltlen == RSA_PSS_SALTLEN_DIGEST) { 203e1051a39Sopenharmony_ci saltlen = EVP_MD_get_size(ctx->md); 204e1051a39Sopenharmony_ci } else if (saltlen == RSA_PSS_SALTLEN_AUTO || saltlen == RSA_PSS_SALTLEN_MAX) { 205e1051a39Sopenharmony_ci saltlen = RSA_size(ctx->rsa) - EVP_MD_get_size(ctx->md) - 2; 206e1051a39Sopenharmony_ci if ((RSA_bits(ctx->rsa) & 0x7) == 1) 207e1051a39Sopenharmony_ci saltlen--; 208e1051a39Sopenharmony_ci } 209e1051a39Sopenharmony_ci if (saltlen < 0) { 210e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 211e1051a39Sopenharmony_ci return -1; 212e1051a39Sopenharmony_ci } else if (saltlen < ctx->min_saltlen) { 213e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL, 214e1051a39Sopenharmony_ci "minimum salt length: %d, actual salt length: %d", 215e1051a39Sopenharmony_ci ctx->min_saltlen, saltlen); 216e1051a39Sopenharmony_ci return -1; 217e1051a39Sopenharmony_ci } 218e1051a39Sopenharmony_ci return saltlen; 219e1051a39Sopenharmony_ci} 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_cistatic unsigned char *rsa_generate_signature_aid(PROV_RSA_CTX *ctx, 222e1051a39Sopenharmony_ci unsigned char *aid_buf, 223e1051a39Sopenharmony_ci size_t buf_len, 224e1051a39Sopenharmony_ci size_t *aid_len) 225e1051a39Sopenharmony_ci{ 226e1051a39Sopenharmony_ci WPACKET pkt; 227e1051a39Sopenharmony_ci unsigned char *aid = NULL; 228e1051a39Sopenharmony_ci int saltlen; 229e1051a39Sopenharmony_ci RSA_PSS_PARAMS_30 pss_params; 230e1051a39Sopenharmony_ci int ret; 231e1051a39Sopenharmony_ci 232e1051a39Sopenharmony_ci if (!WPACKET_init_der(&pkt, aid_buf, buf_len)) { 233e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 234e1051a39Sopenharmony_ci return NULL; 235e1051a39Sopenharmony_ci } 236e1051a39Sopenharmony_ci 237e1051a39Sopenharmony_ci switch(ctx->pad_mode) { 238e1051a39Sopenharmony_ci case RSA_PKCS1_PADDING: 239e1051a39Sopenharmony_ci ret = ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(&pkt, -1, 240e1051a39Sopenharmony_ci ctx->mdnid); 241e1051a39Sopenharmony_ci 242e1051a39Sopenharmony_ci if (ret > 0) { 243e1051a39Sopenharmony_ci break; 244e1051a39Sopenharmony_ci } else if (ret == 0) { 245e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 246e1051a39Sopenharmony_ci goto cleanup; 247e1051a39Sopenharmony_ci } 248e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, ERR_R_UNSUPPORTED, 249e1051a39Sopenharmony_ci "Algorithm ID generation - md NID: %d", 250e1051a39Sopenharmony_ci ctx->mdnid); 251e1051a39Sopenharmony_ci goto cleanup; 252e1051a39Sopenharmony_ci case RSA_PKCS1_PSS_PADDING: 253e1051a39Sopenharmony_ci saltlen = rsa_pss_compute_saltlen(ctx); 254e1051a39Sopenharmony_ci if (saltlen < 0) 255e1051a39Sopenharmony_ci goto cleanup; 256e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) 257e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, ctx->mdnid) 258e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, 259e1051a39Sopenharmony_ci ctx->mgf1_mdnid) 260e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) 261e1051a39Sopenharmony_ci || !ossl_DER_w_algorithmIdentifier_RSA_PSS(&pkt, -1, 262e1051a39Sopenharmony_ci RSA_FLAG_TYPE_RSASSAPSS, 263e1051a39Sopenharmony_ci &pss_params)) { 264e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 265e1051a39Sopenharmony_ci goto cleanup; 266e1051a39Sopenharmony_ci } 267e1051a39Sopenharmony_ci break; 268e1051a39Sopenharmony_ci default: 269e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, ERR_R_UNSUPPORTED, 270e1051a39Sopenharmony_ci "Algorithm ID generation - pad mode: %d", 271e1051a39Sopenharmony_ci ctx->pad_mode); 272e1051a39Sopenharmony_ci goto cleanup; 273e1051a39Sopenharmony_ci } 274e1051a39Sopenharmony_ci if (WPACKET_finish(&pkt)) { 275e1051a39Sopenharmony_ci WPACKET_get_total_written(&pkt, aid_len); 276e1051a39Sopenharmony_ci aid = WPACKET_get_curr(&pkt); 277e1051a39Sopenharmony_ci } 278e1051a39Sopenharmony_ci cleanup: 279e1051a39Sopenharmony_ci WPACKET_cleanup(&pkt); 280e1051a39Sopenharmony_ci return aid; 281e1051a39Sopenharmony_ci} 282e1051a39Sopenharmony_ci 283e1051a39Sopenharmony_cistatic int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, 284e1051a39Sopenharmony_ci const char *mdprops) 285e1051a39Sopenharmony_ci{ 286e1051a39Sopenharmony_ci if (mdprops == NULL) 287e1051a39Sopenharmony_ci mdprops = ctx->propq; 288e1051a39Sopenharmony_ci 289e1051a39Sopenharmony_ci if (mdname != NULL) { 290e1051a39Sopenharmony_ci EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); 291e1051a39Sopenharmony_ci int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); 292e1051a39Sopenharmony_ci int md_nid = ossl_digest_rsa_sign_get_md_nid(ctx->libctx, md, 293e1051a39Sopenharmony_ci sha1_allowed); 294e1051a39Sopenharmony_ci size_t mdname_len = strlen(mdname); 295e1051a39Sopenharmony_ci 296e1051a39Sopenharmony_ci if (md == NULL 297e1051a39Sopenharmony_ci || md_nid <= 0 298e1051a39Sopenharmony_ci || !rsa_check_padding(ctx, mdname, NULL, md_nid) 299e1051a39Sopenharmony_ci || mdname_len >= sizeof(ctx->mdname)) { 300e1051a39Sopenharmony_ci if (md == NULL) 301e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 302e1051a39Sopenharmony_ci "%s could not be fetched", mdname); 303e1051a39Sopenharmony_ci if (md_nid <= 0) 304e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 305e1051a39Sopenharmony_ci "digest=%s", mdname); 306e1051a39Sopenharmony_ci if (mdname_len >= sizeof(ctx->mdname)) 307e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 308e1051a39Sopenharmony_ci "%s exceeds name buffer length", mdname); 309e1051a39Sopenharmony_ci EVP_MD_free(md); 310e1051a39Sopenharmony_ci return 0; 311e1051a39Sopenharmony_ci } 312e1051a39Sopenharmony_ci 313e1051a39Sopenharmony_ci if (!ctx->flag_allow_md) { 314e1051a39Sopenharmony_ci if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) { 315e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 316e1051a39Sopenharmony_ci "digest %s != %s", mdname, ctx->mdname); 317e1051a39Sopenharmony_ci EVP_MD_free(md); 318e1051a39Sopenharmony_ci return 0; 319e1051a39Sopenharmony_ci } 320e1051a39Sopenharmony_ci EVP_MD_free(md); 321e1051a39Sopenharmony_ci return 1; 322e1051a39Sopenharmony_ci } 323e1051a39Sopenharmony_ci 324e1051a39Sopenharmony_ci if (!ctx->mgf1_md_set) { 325e1051a39Sopenharmony_ci if (!EVP_MD_up_ref(md)) { 326e1051a39Sopenharmony_ci EVP_MD_free(md); 327e1051a39Sopenharmony_ci return 0; 328e1051a39Sopenharmony_ci } 329e1051a39Sopenharmony_ci EVP_MD_free(ctx->mgf1_md); 330e1051a39Sopenharmony_ci ctx->mgf1_md = md; 331e1051a39Sopenharmony_ci ctx->mgf1_mdnid = md_nid; 332e1051a39Sopenharmony_ci OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); 333e1051a39Sopenharmony_ci } 334e1051a39Sopenharmony_ci 335e1051a39Sopenharmony_ci EVP_MD_CTX_free(ctx->mdctx); 336e1051a39Sopenharmony_ci EVP_MD_free(ctx->md); 337e1051a39Sopenharmony_ci 338e1051a39Sopenharmony_ci ctx->mdctx = NULL; 339e1051a39Sopenharmony_ci ctx->md = md; 340e1051a39Sopenharmony_ci ctx->mdnid = md_nid; 341e1051a39Sopenharmony_ci OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); 342e1051a39Sopenharmony_ci } 343e1051a39Sopenharmony_ci 344e1051a39Sopenharmony_ci return 1; 345e1051a39Sopenharmony_ci} 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_cistatic int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, 348e1051a39Sopenharmony_ci const char *mdprops) 349e1051a39Sopenharmony_ci{ 350e1051a39Sopenharmony_ci size_t len; 351e1051a39Sopenharmony_ci EVP_MD *md = NULL; 352e1051a39Sopenharmony_ci int mdnid; 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci if (mdprops == NULL) 355e1051a39Sopenharmony_ci mdprops = ctx->propq; 356e1051a39Sopenharmony_ci 357e1051a39Sopenharmony_ci if ((md = EVP_MD_fetch(ctx->libctx, mdname, mdprops)) == NULL) { 358e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 359e1051a39Sopenharmony_ci "%s could not be fetched", mdname); 360e1051a39Sopenharmony_ci return 0; 361e1051a39Sopenharmony_ci } 362e1051a39Sopenharmony_ci /* The default for mgf1 is SHA1 - so allow SHA1 */ 363e1051a39Sopenharmony_ci if ((mdnid = ossl_digest_rsa_sign_get_md_nid(ctx->libctx, md, 1)) <= 0 364e1051a39Sopenharmony_ci || !rsa_check_padding(ctx, NULL, mdname, mdnid)) { 365e1051a39Sopenharmony_ci if (mdnid <= 0) 366e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 367e1051a39Sopenharmony_ci "digest=%s", mdname); 368e1051a39Sopenharmony_ci EVP_MD_free(md); 369e1051a39Sopenharmony_ci return 0; 370e1051a39Sopenharmony_ci } 371e1051a39Sopenharmony_ci len = OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); 372e1051a39Sopenharmony_ci if (len >= sizeof(ctx->mgf1_mdname)) { 373e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 374e1051a39Sopenharmony_ci "%s exceeds name buffer length", mdname); 375e1051a39Sopenharmony_ci EVP_MD_free(md); 376e1051a39Sopenharmony_ci return 0; 377e1051a39Sopenharmony_ci } 378e1051a39Sopenharmony_ci 379e1051a39Sopenharmony_ci EVP_MD_free(ctx->mgf1_md); 380e1051a39Sopenharmony_ci ctx->mgf1_md = md; 381e1051a39Sopenharmony_ci ctx->mgf1_mdnid = mdnid; 382e1051a39Sopenharmony_ci ctx->mgf1_md_set = 1; 383e1051a39Sopenharmony_ci return 1; 384e1051a39Sopenharmony_ci} 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_cistatic int rsa_signverify_init(void *vprsactx, void *vrsa, 387e1051a39Sopenharmony_ci const OSSL_PARAM params[], int operation) 388e1051a39Sopenharmony_ci{ 389e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 390e1051a39Sopenharmony_ci 391e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || prsactx == NULL) 392e1051a39Sopenharmony_ci return 0; 393e1051a39Sopenharmony_ci 394e1051a39Sopenharmony_ci if (vrsa == NULL && prsactx->rsa == NULL) { 395e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 396e1051a39Sopenharmony_ci return 0; 397e1051a39Sopenharmony_ci } 398e1051a39Sopenharmony_ci 399e1051a39Sopenharmony_ci if (vrsa != NULL) { 400e1051a39Sopenharmony_ci if (!ossl_rsa_check_key(prsactx->libctx, vrsa, operation)) 401e1051a39Sopenharmony_ci return 0; 402e1051a39Sopenharmony_ci 403e1051a39Sopenharmony_ci if (!RSA_up_ref(vrsa)) 404e1051a39Sopenharmony_ci return 0; 405e1051a39Sopenharmony_ci RSA_free(prsactx->rsa); 406e1051a39Sopenharmony_ci prsactx->rsa = vrsa; 407e1051a39Sopenharmony_ci } 408e1051a39Sopenharmony_ci 409e1051a39Sopenharmony_ci prsactx->operation = operation; 410e1051a39Sopenharmony_ci 411e1051a39Sopenharmony_ci /* Maximum for sign, auto for verify */ 412e1051a39Sopenharmony_ci prsactx->saltlen = RSA_PSS_SALTLEN_AUTO; 413e1051a39Sopenharmony_ci prsactx->min_saltlen = -1; 414e1051a39Sopenharmony_ci 415e1051a39Sopenharmony_ci switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) { 416e1051a39Sopenharmony_ci case RSA_FLAG_TYPE_RSA: 417e1051a39Sopenharmony_ci prsactx->pad_mode = RSA_PKCS1_PADDING; 418e1051a39Sopenharmony_ci break; 419e1051a39Sopenharmony_ci case RSA_FLAG_TYPE_RSASSAPSS: 420e1051a39Sopenharmony_ci prsactx->pad_mode = RSA_PKCS1_PSS_PADDING; 421e1051a39Sopenharmony_ci 422e1051a39Sopenharmony_ci { 423e1051a39Sopenharmony_ci const RSA_PSS_PARAMS_30 *pss = 424e1051a39Sopenharmony_ci ossl_rsa_get0_pss_params_30(prsactx->rsa); 425e1051a39Sopenharmony_ci 426e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_is_unrestricted(pss)) { 427e1051a39Sopenharmony_ci int md_nid = ossl_rsa_pss_params_30_hashalg(pss); 428e1051a39Sopenharmony_ci int mgf1md_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss); 429e1051a39Sopenharmony_ci int min_saltlen = ossl_rsa_pss_params_30_saltlen(pss); 430e1051a39Sopenharmony_ci const char *mdname, *mgf1mdname; 431e1051a39Sopenharmony_ci size_t len; 432e1051a39Sopenharmony_ci 433e1051a39Sopenharmony_ci mdname = ossl_rsa_oaeppss_nid2name(md_nid); 434e1051a39Sopenharmony_ci mgf1mdname = ossl_rsa_oaeppss_nid2name(mgf1md_nid); 435e1051a39Sopenharmony_ci 436e1051a39Sopenharmony_ci if (mdname == NULL) { 437e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 438e1051a39Sopenharmony_ci "PSS restrictions lack hash algorithm"); 439e1051a39Sopenharmony_ci return 0; 440e1051a39Sopenharmony_ci } 441e1051a39Sopenharmony_ci if (mgf1mdname == NULL) { 442e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 443e1051a39Sopenharmony_ci "PSS restrictions lack MGF1 hash algorithm"); 444e1051a39Sopenharmony_ci return 0; 445e1051a39Sopenharmony_ci } 446e1051a39Sopenharmony_ci 447e1051a39Sopenharmony_ci len = OPENSSL_strlcpy(prsactx->mdname, mdname, 448e1051a39Sopenharmony_ci sizeof(prsactx->mdname)); 449e1051a39Sopenharmony_ci if (len >= sizeof(prsactx->mdname)) { 450e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 451e1051a39Sopenharmony_ci "hash algorithm name too long"); 452e1051a39Sopenharmony_ci return 0; 453e1051a39Sopenharmony_ci } 454e1051a39Sopenharmony_ci len = OPENSSL_strlcpy(prsactx->mgf1_mdname, mgf1mdname, 455e1051a39Sopenharmony_ci sizeof(prsactx->mgf1_mdname)); 456e1051a39Sopenharmony_ci if (len >= sizeof(prsactx->mgf1_mdname)) { 457e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 458e1051a39Sopenharmony_ci "MGF1 hash algorithm name too long"); 459e1051a39Sopenharmony_ci return 0; 460e1051a39Sopenharmony_ci } 461e1051a39Sopenharmony_ci prsactx->saltlen = min_saltlen; 462e1051a39Sopenharmony_ci 463e1051a39Sopenharmony_ci /* call rsa_setup_mgf1_md before rsa_setup_md to avoid duplication */ 464e1051a39Sopenharmony_ci if (!rsa_setup_mgf1_md(prsactx, mgf1mdname, prsactx->propq) 465e1051a39Sopenharmony_ci || !rsa_setup_md(prsactx, mdname, prsactx->propq) 466e1051a39Sopenharmony_ci || !rsa_check_parameters(prsactx, min_saltlen)) 467e1051a39Sopenharmony_ci return 0; 468e1051a39Sopenharmony_ci } 469e1051a39Sopenharmony_ci } 470e1051a39Sopenharmony_ci 471e1051a39Sopenharmony_ci break; 472e1051a39Sopenharmony_ci default: 473e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 474e1051a39Sopenharmony_ci return 0; 475e1051a39Sopenharmony_ci } 476e1051a39Sopenharmony_ci 477e1051a39Sopenharmony_ci if (!rsa_set_ctx_params(prsactx, params)) 478e1051a39Sopenharmony_ci return 0; 479e1051a39Sopenharmony_ci 480e1051a39Sopenharmony_ci return 1; 481e1051a39Sopenharmony_ci} 482e1051a39Sopenharmony_ci 483e1051a39Sopenharmony_cistatic int setup_tbuf(PROV_RSA_CTX *ctx) 484e1051a39Sopenharmony_ci{ 485e1051a39Sopenharmony_ci if (ctx->tbuf != NULL) 486e1051a39Sopenharmony_ci return 1; 487e1051a39Sopenharmony_ci if ((ctx->tbuf = OPENSSL_malloc(RSA_size(ctx->rsa))) == NULL) { 488e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 489e1051a39Sopenharmony_ci return 0; 490e1051a39Sopenharmony_ci } 491e1051a39Sopenharmony_ci return 1; 492e1051a39Sopenharmony_ci} 493e1051a39Sopenharmony_ci 494e1051a39Sopenharmony_cistatic void clean_tbuf(PROV_RSA_CTX *ctx) 495e1051a39Sopenharmony_ci{ 496e1051a39Sopenharmony_ci if (ctx->tbuf != NULL) 497e1051a39Sopenharmony_ci OPENSSL_cleanse(ctx->tbuf, RSA_size(ctx->rsa)); 498e1051a39Sopenharmony_ci} 499e1051a39Sopenharmony_ci 500e1051a39Sopenharmony_cistatic void free_tbuf(PROV_RSA_CTX *ctx) 501e1051a39Sopenharmony_ci{ 502e1051a39Sopenharmony_ci clean_tbuf(ctx); 503e1051a39Sopenharmony_ci OPENSSL_free(ctx->tbuf); 504e1051a39Sopenharmony_ci ctx->tbuf = NULL; 505e1051a39Sopenharmony_ci} 506e1051a39Sopenharmony_ci 507e1051a39Sopenharmony_cistatic int rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) 508e1051a39Sopenharmony_ci{ 509e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 510e1051a39Sopenharmony_ci return 0; 511e1051a39Sopenharmony_ci return rsa_signverify_init(vprsactx, vrsa, params, EVP_PKEY_OP_SIGN); 512e1051a39Sopenharmony_ci} 513e1051a39Sopenharmony_ci 514e1051a39Sopenharmony_cistatic int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, 515e1051a39Sopenharmony_ci size_t sigsize, const unsigned char *tbs, size_t tbslen) 516e1051a39Sopenharmony_ci{ 517e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 518e1051a39Sopenharmony_ci int ret; 519e1051a39Sopenharmony_ci size_t rsasize = RSA_size(prsactx->rsa); 520e1051a39Sopenharmony_ci size_t mdsize = rsa_get_md_size(prsactx); 521e1051a39Sopenharmony_ci 522e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 523e1051a39Sopenharmony_ci return 0; 524e1051a39Sopenharmony_ci 525e1051a39Sopenharmony_ci if (sig == NULL) { 526e1051a39Sopenharmony_ci *siglen = rsasize; 527e1051a39Sopenharmony_ci return 1; 528e1051a39Sopenharmony_ci } 529e1051a39Sopenharmony_ci 530e1051a39Sopenharmony_ci if (sigsize < rsasize) { 531e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE, 532e1051a39Sopenharmony_ci "is %zu, should be at least %zu", sigsize, rsasize); 533e1051a39Sopenharmony_ci return 0; 534e1051a39Sopenharmony_ci } 535e1051a39Sopenharmony_ci 536e1051a39Sopenharmony_ci if (mdsize != 0) { 537e1051a39Sopenharmony_ci if (tbslen != mdsize) { 538e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); 539e1051a39Sopenharmony_ci return 0; 540e1051a39Sopenharmony_ci } 541e1051a39Sopenharmony_ci 542e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 543e1051a39Sopenharmony_ci if (EVP_MD_is_a(prsactx->md, OSSL_DIGEST_NAME_MDC2)) { 544e1051a39Sopenharmony_ci unsigned int sltmp; 545e1051a39Sopenharmony_ci 546e1051a39Sopenharmony_ci if (prsactx->pad_mode != RSA_PKCS1_PADDING) { 547e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, 548e1051a39Sopenharmony_ci "only PKCS#1 padding supported with MDC2"); 549e1051a39Sopenharmony_ci return 0; 550e1051a39Sopenharmony_ci } 551e1051a39Sopenharmony_ci ret = RSA_sign_ASN1_OCTET_STRING(0, tbs, tbslen, sig, &sltmp, 552e1051a39Sopenharmony_ci prsactx->rsa); 553e1051a39Sopenharmony_ci 554e1051a39Sopenharmony_ci if (ret <= 0) { 555e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 556e1051a39Sopenharmony_ci return 0; 557e1051a39Sopenharmony_ci } 558e1051a39Sopenharmony_ci ret = sltmp; 559e1051a39Sopenharmony_ci goto end; 560e1051a39Sopenharmony_ci } 561e1051a39Sopenharmony_ci#endif 562e1051a39Sopenharmony_ci switch (prsactx->pad_mode) { 563e1051a39Sopenharmony_ci case RSA_X931_PADDING: 564e1051a39Sopenharmony_ci if ((size_t)RSA_size(prsactx->rsa) < tbslen + 1) { 565e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL, 566e1051a39Sopenharmony_ci "RSA key size = %d, expected minimum = %d", 567e1051a39Sopenharmony_ci RSA_size(prsactx->rsa), tbslen + 1); 568e1051a39Sopenharmony_ci return 0; 569e1051a39Sopenharmony_ci } 570e1051a39Sopenharmony_ci if (!setup_tbuf(prsactx)) { 571e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 572e1051a39Sopenharmony_ci return 0; 573e1051a39Sopenharmony_ci } 574e1051a39Sopenharmony_ci memcpy(prsactx->tbuf, tbs, tbslen); 575e1051a39Sopenharmony_ci prsactx->tbuf[tbslen] = RSA_X931_hash_id(prsactx->mdnid); 576e1051a39Sopenharmony_ci ret = RSA_private_encrypt(tbslen + 1, prsactx->tbuf, 577e1051a39Sopenharmony_ci sig, prsactx->rsa, RSA_X931_PADDING); 578e1051a39Sopenharmony_ci clean_tbuf(prsactx); 579e1051a39Sopenharmony_ci break; 580e1051a39Sopenharmony_ci 581e1051a39Sopenharmony_ci case RSA_PKCS1_PADDING: 582e1051a39Sopenharmony_ci { 583e1051a39Sopenharmony_ci unsigned int sltmp; 584e1051a39Sopenharmony_ci 585e1051a39Sopenharmony_ci ret = RSA_sign(prsactx->mdnid, tbs, tbslen, sig, &sltmp, 586e1051a39Sopenharmony_ci prsactx->rsa); 587e1051a39Sopenharmony_ci if (ret <= 0) { 588e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 589e1051a39Sopenharmony_ci return 0; 590e1051a39Sopenharmony_ci } 591e1051a39Sopenharmony_ci ret = sltmp; 592e1051a39Sopenharmony_ci } 593e1051a39Sopenharmony_ci break; 594e1051a39Sopenharmony_ci 595e1051a39Sopenharmony_ci case RSA_PKCS1_PSS_PADDING: 596e1051a39Sopenharmony_ci /* Check PSS restrictions */ 597e1051a39Sopenharmony_ci if (rsa_pss_restricted(prsactx)) { 598e1051a39Sopenharmony_ci switch (prsactx->saltlen) { 599e1051a39Sopenharmony_ci case RSA_PSS_SALTLEN_DIGEST: 600e1051a39Sopenharmony_ci if (prsactx->min_saltlen > EVP_MD_get_size(prsactx->md)) { 601e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, 602e1051a39Sopenharmony_ci PROV_R_PSS_SALTLEN_TOO_SMALL, 603e1051a39Sopenharmony_ci "minimum salt length set to %d, " 604e1051a39Sopenharmony_ci "but the digest only gives %d", 605e1051a39Sopenharmony_ci prsactx->min_saltlen, 606e1051a39Sopenharmony_ci EVP_MD_get_size(prsactx->md)); 607e1051a39Sopenharmony_ci return 0; 608e1051a39Sopenharmony_ci } 609e1051a39Sopenharmony_ci /* FALLTHRU */ 610e1051a39Sopenharmony_ci default: 611e1051a39Sopenharmony_ci if (prsactx->saltlen >= 0 612e1051a39Sopenharmony_ci && prsactx->saltlen < prsactx->min_saltlen) { 613e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, 614e1051a39Sopenharmony_ci PROV_R_PSS_SALTLEN_TOO_SMALL, 615e1051a39Sopenharmony_ci "minimum salt length set to %d, but the" 616e1051a39Sopenharmony_ci "actual salt length is only set to %d", 617e1051a39Sopenharmony_ci prsactx->min_saltlen, 618e1051a39Sopenharmony_ci prsactx->saltlen); 619e1051a39Sopenharmony_ci return 0; 620e1051a39Sopenharmony_ci } 621e1051a39Sopenharmony_ci break; 622e1051a39Sopenharmony_ci } 623e1051a39Sopenharmony_ci } 624e1051a39Sopenharmony_ci if (!setup_tbuf(prsactx)) 625e1051a39Sopenharmony_ci return 0; 626e1051a39Sopenharmony_ci if (!RSA_padding_add_PKCS1_PSS_mgf1(prsactx->rsa, 627e1051a39Sopenharmony_ci prsactx->tbuf, tbs, 628e1051a39Sopenharmony_ci prsactx->md, prsactx->mgf1_md, 629e1051a39Sopenharmony_ci prsactx->saltlen)) { 630e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 631e1051a39Sopenharmony_ci return 0; 632e1051a39Sopenharmony_ci } 633e1051a39Sopenharmony_ci ret = RSA_private_encrypt(RSA_size(prsactx->rsa), prsactx->tbuf, 634e1051a39Sopenharmony_ci sig, prsactx->rsa, RSA_NO_PADDING); 635e1051a39Sopenharmony_ci clean_tbuf(prsactx); 636e1051a39Sopenharmony_ci break; 637e1051a39Sopenharmony_ci 638e1051a39Sopenharmony_ci default: 639e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, 640e1051a39Sopenharmony_ci "Only X.931, PKCS#1 v1.5 or PSS padding allowed"); 641e1051a39Sopenharmony_ci return 0; 642e1051a39Sopenharmony_ci } 643e1051a39Sopenharmony_ci } else { 644e1051a39Sopenharmony_ci ret = RSA_private_encrypt(tbslen, tbs, sig, prsactx->rsa, 645e1051a39Sopenharmony_ci prsactx->pad_mode); 646e1051a39Sopenharmony_ci } 647e1051a39Sopenharmony_ci 648e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 649e1051a39Sopenharmony_ci end: 650e1051a39Sopenharmony_ci#endif 651e1051a39Sopenharmony_ci if (ret <= 0) { 652e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 653e1051a39Sopenharmony_ci return 0; 654e1051a39Sopenharmony_ci } 655e1051a39Sopenharmony_ci 656e1051a39Sopenharmony_ci *siglen = ret; 657e1051a39Sopenharmony_ci return 1; 658e1051a39Sopenharmony_ci} 659e1051a39Sopenharmony_ci 660e1051a39Sopenharmony_cistatic int rsa_verify_recover_init(void *vprsactx, void *vrsa, 661e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 662e1051a39Sopenharmony_ci{ 663e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 664e1051a39Sopenharmony_ci return 0; 665e1051a39Sopenharmony_ci return rsa_signverify_init(vprsactx, vrsa, params, 666e1051a39Sopenharmony_ci EVP_PKEY_OP_VERIFYRECOVER); 667e1051a39Sopenharmony_ci} 668e1051a39Sopenharmony_ci 669e1051a39Sopenharmony_cistatic int rsa_verify_recover(void *vprsactx, 670e1051a39Sopenharmony_ci unsigned char *rout, 671e1051a39Sopenharmony_ci size_t *routlen, 672e1051a39Sopenharmony_ci size_t routsize, 673e1051a39Sopenharmony_ci const unsigned char *sig, 674e1051a39Sopenharmony_ci size_t siglen) 675e1051a39Sopenharmony_ci{ 676e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 677e1051a39Sopenharmony_ci int ret; 678e1051a39Sopenharmony_ci 679e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 680e1051a39Sopenharmony_ci return 0; 681e1051a39Sopenharmony_ci 682e1051a39Sopenharmony_ci if (rout == NULL) { 683e1051a39Sopenharmony_ci *routlen = RSA_size(prsactx->rsa); 684e1051a39Sopenharmony_ci return 1; 685e1051a39Sopenharmony_ci } 686e1051a39Sopenharmony_ci 687e1051a39Sopenharmony_ci if (prsactx->md != NULL) { 688e1051a39Sopenharmony_ci switch (prsactx->pad_mode) { 689e1051a39Sopenharmony_ci case RSA_X931_PADDING: 690e1051a39Sopenharmony_ci if (!setup_tbuf(prsactx)) 691e1051a39Sopenharmony_ci return 0; 692e1051a39Sopenharmony_ci ret = RSA_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa, 693e1051a39Sopenharmony_ci RSA_X931_PADDING); 694e1051a39Sopenharmony_ci if (ret < 1) { 695e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 696e1051a39Sopenharmony_ci return 0; 697e1051a39Sopenharmony_ci } 698e1051a39Sopenharmony_ci ret--; 699e1051a39Sopenharmony_ci if (prsactx->tbuf[ret] != RSA_X931_hash_id(prsactx->mdnid)) { 700e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH); 701e1051a39Sopenharmony_ci return 0; 702e1051a39Sopenharmony_ci } 703e1051a39Sopenharmony_ci if (ret != EVP_MD_get_size(prsactx->md)) { 704e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH, 705e1051a39Sopenharmony_ci "Should be %d, but got %d", 706e1051a39Sopenharmony_ci EVP_MD_get_size(prsactx->md), ret); 707e1051a39Sopenharmony_ci return 0; 708e1051a39Sopenharmony_ci } 709e1051a39Sopenharmony_ci 710e1051a39Sopenharmony_ci *routlen = ret; 711e1051a39Sopenharmony_ci if (rout != prsactx->tbuf) { 712e1051a39Sopenharmony_ci if (routsize < (size_t)ret) { 713e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL, 714e1051a39Sopenharmony_ci "buffer size is %d, should be %d", 715e1051a39Sopenharmony_ci routsize, ret); 716e1051a39Sopenharmony_ci return 0; 717e1051a39Sopenharmony_ci } 718e1051a39Sopenharmony_ci memcpy(rout, prsactx->tbuf, ret); 719e1051a39Sopenharmony_ci } 720e1051a39Sopenharmony_ci break; 721e1051a39Sopenharmony_ci 722e1051a39Sopenharmony_ci case RSA_PKCS1_PADDING: 723e1051a39Sopenharmony_ci { 724e1051a39Sopenharmony_ci size_t sltmp; 725e1051a39Sopenharmony_ci 726e1051a39Sopenharmony_ci ret = ossl_rsa_verify(prsactx->mdnid, NULL, 0, rout, &sltmp, 727e1051a39Sopenharmony_ci sig, siglen, prsactx->rsa); 728e1051a39Sopenharmony_ci if (ret <= 0) { 729e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 730e1051a39Sopenharmony_ci return 0; 731e1051a39Sopenharmony_ci } 732e1051a39Sopenharmony_ci ret = sltmp; 733e1051a39Sopenharmony_ci } 734e1051a39Sopenharmony_ci break; 735e1051a39Sopenharmony_ci 736e1051a39Sopenharmony_ci default: 737e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, 738e1051a39Sopenharmony_ci "Only X.931 or PKCS#1 v1.5 padding allowed"); 739e1051a39Sopenharmony_ci return 0; 740e1051a39Sopenharmony_ci } 741e1051a39Sopenharmony_ci } else { 742e1051a39Sopenharmony_ci ret = RSA_public_decrypt(siglen, sig, rout, prsactx->rsa, 743e1051a39Sopenharmony_ci prsactx->pad_mode); 744e1051a39Sopenharmony_ci if (ret < 0) { 745e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 746e1051a39Sopenharmony_ci return 0; 747e1051a39Sopenharmony_ci } 748e1051a39Sopenharmony_ci } 749e1051a39Sopenharmony_ci *routlen = ret; 750e1051a39Sopenharmony_ci return 1; 751e1051a39Sopenharmony_ci} 752e1051a39Sopenharmony_ci 753e1051a39Sopenharmony_cistatic int rsa_verify_init(void *vprsactx, void *vrsa, 754e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 755e1051a39Sopenharmony_ci{ 756e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 757e1051a39Sopenharmony_ci return 0; 758e1051a39Sopenharmony_ci return rsa_signverify_init(vprsactx, vrsa, params, EVP_PKEY_OP_VERIFY); 759e1051a39Sopenharmony_ci} 760e1051a39Sopenharmony_ci 761e1051a39Sopenharmony_cistatic int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, 762e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen) 763e1051a39Sopenharmony_ci{ 764e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 765e1051a39Sopenharmony_ci size_t rslen; 766e1051a39Sopenharmony_ci 767e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 768e1051a39Sopenharmony_ci return 0; 769e1051a39Sopenharmony_ci if (prsactx->md != NULL) { 770e1051a39Sopenharmony_ci switch (prsactx->pad_mode) { 771e1051a39Sopenharmony_ci case RSA_PKCS1_PADDING: 772e1051a39Sopenharmony_ci if (!RSA_verify(prsactx->mdnid, tbs, tbslen, sig, siglen, 773e1051a39Sopenharmony_ci prsactx->rsa)) { 774e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 775e1051a39Sopenharmony_ci return 0; 776e1051a39Sopenharmony_ci } 777e1051a39Sopenharmony_ci return 1; 778e1051a39Sopenharmony_ci case RSA_X931_PADDING: 779e1051a39Sopenharmony_ci if (!setup_tbuf(prsactx)) 780e1051a39Sopenharmony_ci return 0; 781e1051a39Sopenharmony_ci if (rsa_verify_recover(prsactx, prsactx->tbuf, &rslen, 0, 782e1051a39Sopenharmony_ci sig, siglen) <= 0) 783e1051a39Sopenharmony_ci return 0; 784e1051a39Sopenharmony_ci break; 785e1051a39Sopenharmony_ci case RSA_PKCS1_PSS_PADDING: 786e1051a39Sopenharmony_ci { 787e1051a39Sopenharmony_ci int ret; 788e1051a39Sopenharmony_ci size_t mdsize; 789e1051a39Sopenharmony_ci 790e1051a39Sopenharmony_ci /* 791e1051a39Sopenharmony_ci * We need to check this for the RSA_verify_PKCS1_PSS_mgf1() 792e1051a39Sopenharmony_ci * call 793e1051a39Sopenharmony_ci */ 794e1051a39Sopenharmony_ci mdsize = rsa_get_md_size(prsactx); 795e1051a39Sopenharmony_ci if (tbslen != mdsize) { 796e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH, 797e1051a39Sopenharmony_ci "Should be %d, but got %d", 798e1051a39Sopenharmony_ci mdsize, tbslen); 799e1051a39Sopenharmony_ci return 0; 800e1051a39Sopenharmony_ci } 801e1051a39Sopenharmony_ci 802e1051a39Sopenharmony_ci if (!setup_tbuf(prsactx)) 803e1051a39Sopenharmony_ci return 0; 804e1051a39Sopenharmony_ci ret = RSA_public_decrypt(siglen, sig, prsactx->tbuf, 805e1051a39Sopenharmony_ci prsactx->rsa, RSA_NO_PADDING); 806e1051a39Sopenharmony_ci if (ret <= 0) { 807e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 808e1051a39Sopenharmony_ci return 0; 809e1051a39Sopenharmony_ci } 810e1051a39Sopenharmony_ci ret = RSA_verify_PKCS1_PSS_mgf1(prsactx->rsa, tbs, 811e1051a39Sopenharmony_ci prsactx->md, prsactx->mgf1_md, 812e1051a39Sopenharmony_ci prsactx->tbuf, 813e1051a39Sopenharmony_ci prsactx->saltlen); 814e1051a39Sopenharmony_ci if (ret <= 0) { 815e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 816e1051a39Sopenharmony_ci return 0; 817e1051a39Sopenharmony_ci } 818e1051a39Sopenharmony_ci return 1; 819e1051a39Sopenharmony_ci } 820e1051a39Sopenharmony_ci default: 821e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, 822e1051a39Sopenharmony_ci "Only X.931, PKCS#1 v1.5 or PSS padding allowed"); 823e1051a39Sopenharmony_ci return 0; 824e1051a39Sopenharmony_ci } 825e1051a39Sopenharmony_ci } else { 826e1051a39Sopenharmony_ci int ret; 827e1051a39Sopenharmony_ci 828e1051a39Sopenharmony_ci if (!setup_tbuf(prsactx)) 829e1051a39Sopenharmony_ci return 0; 830e1051a39Sopenharmony_ci ret = RSA_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa, 831e1051a39Sopenharmony_ci prsactx->pad_mode); 832e1051a39Sopenharmony_ci if (ret <= 0) { 833e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); 834e1051a39Sopenharmony_ci return 0; 835e1051a39Sopenharmony_ci } 836e1051a39Sopenharmony_ci rslen = (size_t)ret; 837e1051a39Sopenharmony_ci } 838e1051a39Sopenharmony_ci 839e1051a39Sopenharmony_ci if ((rslen != tbslen) || memcmp(tbs, prsactx->tbuf, rslen)) 840e1051a39Sopenharmony_ci return 0; 841e1051a39Sopenharmony_ci 842e1051a39Sopenharmony_ci return 1; 843e1051a39Sopenharmony_ci} 844e1051a39Sopenharmony_ci 845e1051a39Sopenharmony_cistatic int rsa_digest_signverify_init(void *vprsactx, const char *mdname, 846e1051a39Sopenharmony_ci void *vrsa, const OSSL_PARAM params[], 847e1051a39Sopenharmony_ci int operation) 848e1051a39Sopenharmony_ci{ 849e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 850e1051a39Sopenharmony_ci 851e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 852e1051a39Sopenharmony_ci return 0; 853e1051a39Sopenharmony_ci 854e1051a39Sopenharmony_ci if (!rsa_signverify_init(vprsactx, vrsa, params, operation)) 855e1051a39Sopenharmony_ci return 0; 856e1051a39Sopenharmony_ci 857e1051a39Sopenharmony_ci if (mdname != NULL 858e1051a39Sopenharmony_ci /* was rsa_setup_md already called in rsa_signverify_init()? */ 859e1051a39Sopenharmony_ci && (mdname[0] == '\0' || OPENSSL_strcasecmp(prsactx->mdname, mdname) != 0) 860e1051a39Sopenharmony_ci && !rsa_setup_md(prsactx, mdname, prsactx->propq)) 861e1051a39Sopenharmony_ci return 0; 862e1051a39Sopenharmony_ci 863e1051a39Sopenharmony_ci prsactx->flag_allow_md = 0; 864e1051a39Sopenharmony_ci 865e1051a39Sopenharmony_ci if (prsactx->mdctx == NULL) { 866e1051a39Sopenharmony_ci prsactx->mdctx = EVP_MD_CTX_new(); 867e1051a39Sopenharmony_ci if (prsactx->mdctx == NULL) 868e1051a39Sopenharmony_ci goto error; 869e1051a39Sopenharmony_ci } 870e1051a39Sopenharmony_ci 871e1051a39Sopenharmony_ci if (!EVP_DigestInit_ex2(prsactx->mdctx, prsactx->md, params)) 872e1051a39Sopenharmony_ci goto error; 873e1051a39Sopenharmony_ci 874e1051a39Sopenharmony_ci return 1; 875e1051a39Sopenharmony_ci 876e1051a39Sopenharmony_ci error: 877e1051a39Sopenharmony_ci EVP_MD_CTX_free(prsactx->mdctx); 878e1051a39Sopenharmony_ci prsactx->mdctx = NULL; 879e1051a39Sopenharmony_ci return 0; 880e1051a39Sopenharmony_ci} 881e1051a39Sopenharmony_ci 882e1051a39Sopenharmony_cistatic int rsa_digest_signverify_update(void *vprsactx, 883e1051a39Sopenharmony_ci const unsigned char *data, 884e1051a39Sopenharmony_ci size_t datalen) 885e1051a39Sopenharmony_ci{ 886e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 887e1051a39Sopenharmony_ci 888e1051a39Sopenharmony_ci if (prsactx == NULL || prsactx->mdctx == NULL) 889e1051a39Sopenharmony_ci return 0; 890e1051a39Sopenharmony_ci 891e1051a39Sopenharmony_ci return EVP_DigestUpdate(prsactx->mdctx, data, datalen); 892e1051a39Sopenharmony_ci} 893e1051a39Sopenharmony_ci 894e1051a39Sopenharmony_cistatic int rsa_digest_sign_init(void *vprsactx, const char *mdname, 895e1051a39Sopenharmony_ci void *vrsa, const OSSL_PARAM params[]) 896e1051a39Sopenharmony_ci{ 897e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 898e1051a39Sopenharmony_ci return 0; 899e1051a39Sopenharmony_ci return rsa_digest_signverify_init(vprsactx, mdname, vrsa, 900e1051a39Sopenharmony_ci params, EVP_PKEY_OP_SIGN); 901e1051a39Sopenharmony_ci} 902e1051a39Sopenharmony_ci 903e1051a39Sopenharmony_cistatic int rsa_digest_sign_final(void *vprsactx, unsigned char *sig, 904e1051a39Sopenharmony_ci size_t *siglen, size_t sigsize) 905e1051a39Sopenharmony_ci{ 906e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 907e1051a39Sopenharmony_ci unsigned char digest[EVP_MAX_MD_SIZE]; 908e1051a39Sopenharmony_ci unsigned int dlen = 0; 909e1051a39Sopenharmony_ci 910e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || prsactx == NULL) 911e1051a39Sopenharmony_ci return 0; 912e1051a39Sopenharmony_ci prsactx->flag_allow_md = 1; 913e1051a39Sopenharmony_ci if (prsactx->mdctx == NULL) 914e1051a39Sopenharmony_ci return 0; 915e1051a39Sopenharmony_ci /* 916e1051a39Sopenharmony_ci * If sig is NULL then we're just finding out the sig size. Other fields 917e1051a39Sopenharmony_ci * are ignored. Defer to rsa_sign. 918e1051a39Sopenharmony_ci */ 919e1051a39Sopenharmony_ci if (sig != NULL) { 920e1051a39Sopenharmony_ci /* 921e1051a39Sopenharmony_ci * The digests used here are all known (see rsa_get_md_nid()), so they 922e1051a39Sopenharmony_ci * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. 923e1051a39Sopenharmony_ci */ 924e1051a39Sopenharmony_ci if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) 925e1051a39Sopenharmony_ci return 0; 926e1051a39Sopenharmony_ci } 927e1051a39Sopenharmony_ci 928e1051a39Sopenharmony_ci return rsa_sign(vprsactx, sig, siglen, sigsize, digest, (size_t)dlen); 929e1051a39Sopenharmony_ci} 930e1051a39Sopenharmony_ci 931e1051a39Sopenharmony_cistatic int rsa_digest_verify_init(void *vprsactx, const char *mdname, 932e1051a39Sopenharmony_ci void *vrsa, const OSSL_PARAM params[]) 933e1051a39Sopenharmony_ci{ 934e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 935e1051a39Sopenharmony_ci return 0; 936e1051a39Sopenharmony_ci return rsa_digest_signverify_init(vprsactx, mdname, vrsa, 937e1051a39Sopenharmony_ci params, EVP_PKEY_OP_VERIFY); 938e1051a39Sopenharmony_ci} 939e1051a39Sopenharmony_ci 940e1051a39Sopenharmony_ciint rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, 941e1051a39Sopenharmony_ci size_t siglen) 942e1051a39Sopenharmony_ci{ 943e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 944e1051a39Sopenharmony_ci unsigned char digest[EVP_MAX_MD_SIZE]; 945e1051a39Sopenharmony_ci unsigned int dlen = 0; 946e1051a39Sopenharmony_ci 947e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 948e1051a39Sopenharmony_ci return 0; 949e1051a39Sopenharmony_ci 950e1051a39Sopenharmony_ci if (prsactx == NULL) 951e1051a39Sopenharmony_ci return 0; 952e1051a39Sopenharmony_ci prsactx->flag_allow_md = 1; 953e1051a39Sopenharmony_ci if (prsactx->mdctx == NULL) 954e1051a39Sopenharmony_ci return 0; 955e1051a39Sopenharmony_ci 956e1051a39Sopenharmony_ci /* 957e1051a39Sopenharmony_ci * The digests used here are all known (see rsa_get_md_nid()), so they 958e1051a39Sopenharmony_ci * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. 959e1051a39Sopenharmony_ci */ 960e1051a39Sopenharmony_ci if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) 961e1051a39Sopenharmony_ci return 0; 962e1051a39Sopenharmony_ci 963e1051a39Sopenharmony_ci return rsa_verify(vprsactx, sig, siglen, digest, (size_t)dlen); 964e1051a39Sopenharmony_ci} 965e1051a39Sopenharmony_ci 966e1051a39Sopenharmony_cistatic void rsa_freectx(void *vprsactx) 967e1051a39Sopenharmony_ci{ 968e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 969e1051a39Sopenharmony_ci 970e1051a39Sopenharmony_ci if (prsactx == NULL) 971e1051a39Sopenharmony_ci return; 972e1051a39Sopenharmony_ci 973e1051a39Sopenharmony_ci EVP_MD_CTX_free(prsactx->mdctx); 974e1051a39Sopenharmony_ci EVP_MD_free(prsactx->md); 975e1051a39Sopenharmony_ci EVP_MD_free(prsactx->mgf1_md); 976e1051a39Sopenharmony_ci OPENSSL_free(prsactx->propq); 977e1051a39Sopenharmony_ci free_tbuf(prsactx); 978e1051a39Sopenharmony_ci RSA_free(prsactx->rsa); 979e1051a39Sopenharmony_ci 980e1051a39Sopenharmony_ci OPENSSL_clear_free(prsactx, sizeof(*prsactx)); 981e1051a39Sopenharmony_ci} 982e1051a39Sopenharmony_ci 983e1051a39Sopenharmony_cistatic void *rsa_dupctx(void *vprsactx) 984e1051a39Sopenharmony_ci{ 985e1051a39Sopenharmony_ci PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx; 986e1051a39Sopenharmony_ci PROV_RSA_CTX *dstctx; 987e1051a39Sopenharmony_ci 988e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 989e1051a39Sopenharmony_ci return NULL; 990e1051a39Sopenharmony_ci 991e1051a39Sopenharmony_ci dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 992e1051a39Sopenharmony_ci if (dstctx == NULL) { 993e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 994e1051a39Sopenharmony_ci return NULL; 995e1051a39Sopenharmony_ci } 996e1051a39Sopenharmony_ci 997e1051a39Sopenharmony_ci *dstctx = *srcctx; 998e1051a39Sopenharmony_ci dstctx->rsa = NULL; 999e1051a39Sopenharmony_ci dstctx->md = NULL; 1000e1051a39Sopenharmony_ci dstctx->mdctx = NULL; 1001e1051a39Sopenharmony_ci dstctx->tbuf = NULL; 1002e1051a39Sopenharmony_ci dstctx->propq = NULL; 1003e1051a39Sopenharmony_ci 1004e1051a39Sopenharmony_ci if (srcctx->rsa != NULL && !RSA_up_ref(srcctx->rsa)) 1005e1051a39Sopenharmony_ci goto err; 1006e1051a39Sopenharmony_ci dstctx->rsa = srcctx->rsa; 1007e1051a39Sopenharmony_ci 1008e1051a39Sopenharmony_ci if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) 1009e1051a39Sopenharmony_ci goto err; 1010e1051a39Sopenharmony_ci dstctx->md = srcctx->md; 1011e1051a39Sopenharmony_ci 1012e1051a39Sopenharmony_ci if (srcctx->mgf1_md != NULL && !EVP_MD_up_ref(srcctx->mgf1_md)) 1013e1051a39Sopenharmony_ci goto err; 1014e1051a39Sopenharmony_ci dstctx->mgf1_md = srcctx->mgf1_md; 1015e1051a39Sopenharmony_ci 1016e1051a39Sopenharmony_ci if (srcctx->mdctx != NULL) { 1017e1051a39Sopenharmony_ci dstctx->mdctx = EVP_MD_CTX_new(); 1018e1051a39Sopenharmony_ci if (dstctx->mdctx == NULL 1019e1051a39Sopenharmony_ci || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) 1020e1051a39Sopenharmony_ci goto err; 1021e1051a39Sopenharmony_ci } 1022e1051a39Sopenharmony_ci 1023e1051a39Sopenharmony_ci if (srcctx->propq != NULL) { 1024e1051a39Sopenharmony_ci dstctx->propq = OPENSSL_strdup(srcctx->propq); 1025e1051a39Sopenharmony_ci if (dstctx->propq == NULL) 1026e1051a39Sopenharmony_ci goto err; 1027e1051a39Sopenharmony_ci } 1028e1051a39Sopenharmony_ci 1029e1051a39Sopenharmony_ci return dstctx; 1030e1051a39Sopenharmony_ci err: 1031e1051a39Sopenharmony_ci rsa_freectx(dstctx); 1032e1051a39Sopenharmony_ci return NULL; 1033e1051a39Sopenharmony_ci} 1034e1051a39Sopenharmony_ci 1035e1051a39Sopenharmony_cistatic int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) 1036e1051a39Sopenharmony_ci{ 1037e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 1038e1051a39Sopenharmony_ci OSSL_PARAM *p; 1039e1051a39Sopenharmony_ci 1040e1051a39Sopenharmony_ci if (prsactx == NULL) 1041e1051a39Sopenharmony_ci return 0; 1042e1051a39Sopenharmony_ci 1043e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); 1044e1051a39Sopenharmony_ci if (p != NULL) { 1045e1051a39Sopenharmony_ci /* The Algorithm Identifier of the combined signature algorithm */ 1046e1051a39Sopenharmony_ci unsigned char aid_buf[128]; 1047e1051a39Sopenharmony_ci unsigned char *aid; 1048e1051a39Sopenharmony_ci size_t aid_len; 1049e1051a39Sopenharmony_ci 1050e1051a39Sopenharmony_ci aid = rsa_generate_signature_aid(prsactx, aid_buf, 1051e1051a39Sopenharmony_ci sizeof(aid_buf), &aid_len); 1052e1051a39Sopenharmony_ci if (aid == NULL || !OSSL_PARAM_set_octet_string(p, aid, aid_len)) 1053e1051a39Sopenharmony_ci return 0; 1054e1051a39Sopenharmony_ci } 1055e1051a39Sopenharmony_ci 1056e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_PAD_MODE); 1057e1051a39Sopenharmony_ci if (p != NULL) 1058e1051a39Sopenharmony_ci switch (p->data_type) { 1059e1051a39Sopenharmony_ci case OSSL_PARAM_INTEGER: 1060e1051a39Sopenharmony_ci if (!OSSL_PARAM_set_int(p, prsactx->pad_mode)) 1061e1051a39Sopenharmony_ci return 0; 1062e1051a39Sopenharmony_ci break; 1063e1051a39Sopenharmony_ci case OSSL_PARAM_UTF8_STRING: 1064e1051a39Sopenharmony_ci { 1065e1051a39Sopenharmony_ci int i; 1066e1051a39Sopenharmony_ci const char *word = NULL; 1067e1051a39Sopenharmony_ci 1068e1051a39Sopenharmony_ci for (i = 0; padding_item[i].id != 0; i++) { 1069e1051a39Sopenharmony_ci if (prsactx->pad_mode == (int)padding_item[i].id) { 1070e1051a39Sopenharmony_ci word = padding_item[i].ptr; 1071e1051a39Sopenharmony_ci break; 1072e1051a39Sopenharmony_ci } 1073e1051a39Sopenharmony_ci } 1074e1051a39Sopenharmony_ci 1075e1051a39Sopenharmony_ci if (word != NULL) { 1076e1051a39Sopenharmony_ci if (!OSSL_PARAM_set_utf8_string(p, word)) 1077e1051a39Sopenharmony_ci return 0; 1078e1051a39Sopenharmony_ci } else { 1079e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 1080e1051a39Sopenharmony_ci } 1081e1051a39Sopenharmony_ci } 1082e1051a39Sopenharmony_ci break; 1083e1051a39Sopenharmony_ci default: 1084e1051a39Sopenharmony_ci return 0; 1085e1051a39Sopenharmony_ci } 1086e1051a39Sopenharmony_ci 1087e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST); 1088e1051a39Sopenharmony_ci if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->mdname)) 1089e1051a39Sopenharmony_ci return 0; 1090e1051a39Sopenharmony_ci 1091e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_MGF1_DIGEST); 1092e1051a39Sopenharmony_ci if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->mgf1_mdname)) 1093e1051a39Sopenharmony_ci return 0; 1094e1051a39Sopenharmony_ci 1095e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN); 1096e1051a39Sopenharmony_ci if (p != NULL) { 1097e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) { 1098e1051a39Sopenharmony_ci if (!OSSL_PARAM_set_int(p, prsactx->saltlen)) 1099e1051a39Sopenharmony_ci return 0; 1100e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_UTF8_STRING) { 1101e1051a39Sopenharmony_ci const char *value = NULL; 1102e1051a39Sopenharmony_ci 1103e1051a39Sopenharmony_ci switch (prsactx->saltlen) { 1104e1051a39Sopenharmony_ci case RSA_PSS_SALTLEN_DIGEST: 1105e1051a39Sopenharmony_ci value = OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST; 1106e1051a39Sopenharmony_ci break; 1107e1051a39Sopenharmony_ci case RSA_PSS_SALTLEN_MAX: 1108e1051a39Sopenharmony_ci value = OSSL_PKEY_RSA_PSS_SALT_LEN_MAX; 1109e1051a39Sopenharmony_ci break; 1110e1051a39Sopenharmony_ci case RSA_PSS_SALTLEN_AUTO: 1111e1051a39Sopenharmony_ci value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO; 1112e1051a39Sopenharmony_ci break; 1113e1051a39Sopenharmony_ci default: 1114e1051a39Sopenharmony_ci { 1115e1051a39Sopenharmony_ci int len = BIO_snprintf(p->data, p->data_size, "%d", 1116e1051a39Sopenharmony_ci prsactx->saltlen); 1117e1051a39Sopenharmony_ci 1118e1051a39Sopenharmony_ci if (len <= 0) 1119e1051a39Sopenharmony_ci return 0; 1120e1051a39Sopenharmony_ci p->return_size = len; 1121e1051a39Sopenharmony_ci break; 1122e1051a39Sopenharmony_ci } 1123e1051a39Sopenharmony_ci } 1124e1051a39Sopenharmony_ci if (value != NULL 1125e1051a39Sopenharmony_ci && !OSSL_PARAM_set_utf8_string(p, value)) 1126e1051a39Sopenharmony_ci return 0; 1127e1051a39Sopenharmony_ci } 1128e1051a39Sopenharmony_ci } 1129e1051a39Sopenharmony_ci 1130e1051a39Sopenharmony_ci return 1; 1131e1051a39Sopenharmony_ci} 1132e1051a39Sopenharmony_ci 1133e1051a39Sopenharmony_cistatic const OSSL_PARAM known_gettable_ctx_params[] = { 1134e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), 1135e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), 1136e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 1137e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), 1138e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), 1139e1051a39Sopenharmony_ci OSSL_PARAM_END 1140e1051a39Sopenharmony_ci}; 1141e1051a39Sopenharmony_ci 1142e1051a39Sopenharmony_cistatic const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vprsactx, 1143e1051a39Sopenharmony_ci ossl_unused void *provctx) 1144e1051a39Sopenharmony_ci{ 1145e1051a39Sopenharmony_ci return known_gettable_ctx_params; 1146e1051a39Sopenharmony_ci} 1147e1051a39Sopenharmony_ci 1148e1051a39Sopenharmony_cistatic int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) 1149e1051a39Sopenharmony_ci{ 1150e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 1151e1051a39Sopenharmony_ci const OSSL_PARAM *p; 1152e1051a39Sopenharmony_ci int pad_mode; 1153e1051a39Sopenharmony_ci int saltlen; 1154e1051a39Sopenharmony_ci char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = NULL; 1155e1051a39Sopenharmony_ci char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = NULL; 1156e1051a39Sopenharmony_ci char mgf1mdname[OSSL_MAX_NAME_SIZE] = "", *pmgf1mdname = NULL; 1157e1051a39Sopenharmony_ci char mgf1mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmgf1mdprops = NULL; 1158e1051a39Sopenharmony_ci 1159e1051a39Sopenharmony_ci if (prsactx == NULL) 1160e1051a39Sopenharmony_ci return 0; 1161e1051a39Sopenharmony_ci if (params == NULL) 1162e1051a39Sopenharmony_ci return 1; 1163e1051a39Sopenharmony_ci 1164e1051a39Sopenharmony_ci pad_mode = prsactx->pad_mode; 1165e1051a39Sopenharmony_ci saltlen = prsactx->saltlen; 1166e1051a39Sopenharmony_ci 1167e1051a39Sopenharmony_ci p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); 1168e1051a39Sopenharmony_ci if (p != NULL) { 1169e1051a39Sopenharmony_ci const OSSL_PARAM *propsp = 1170e1051a39Sopenharmony_ci OSSL_PARAM_locate_const(params, 1171e1051a39Sopenharmony_ci OSSL_SIGNATURE_PARAM_PROPERTIES); 1172e1051a39Sopenharmony_ci 1173e1051a39Sopenharmony_ci pmdname = mdname; 1174e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) 1175e1051a39Sopenharmony_ci return 0; 1176e1051a39Sopenharmony_ci 1177e1051a39Sopenharmony_ci if (propsp != NULL) { 1178e1051a39Sopenharmony_ci pmdprops = mdprops; 1179e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_utf8_string(propsp, 1180e1051a39Sopenharmony_ci &pmdprops, sizeof(mdprops))) 1181e1051a39Sopenharmony_ci return 0; 1182e1051a39Sopenharmony_ci } 1183e1051a39Sopenharmony_ci } 1184e1051a39Sopenharmony_ci 1185e1051a39Sopenharmony_ci p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PAD_MODE); 1186e1051a39Sopenharmony_ci if (p != NULL) { 1187e1051a39Sopenharmony_ci const char *err_extra_text = NULL; 1188e1051a39Sopenharmony_ci 1189e1051a39Sopenharmony_ci switch (p->data_type) { 1190e1051a39Sopenharmony_ci case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ 1191e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_int(p, &pad_mode)) 1192e1051a39Sopenharmony_ci return 0; 1193e1051a39Sopenharmony_ci break; 1194e1051a39Sopenharmony_ci case OSSL_PARAM_UTF8_STRING: 1195e1051a39Sopenharmony_ci { 1196e1051a39Sopenharmony_ci int i; 1197e1051a39Sopenharmony_ci 1198e1051a39Sopenharmony_ci if (p->data == NULL) 1199e1051a39Sopenharmony_ci return 0; 1200e1051a39Sopenharmony_ci 1201e1051a39Sopenharmony_ci for (i = 0; padding_item[i].id != 0; i++) { 1202e1051a39Sopenharmony_ci if (strcmp(p->data, padding_item[i].ptr) == 0) { 1203e1051a39Sopenharmony_ci pad_mode = padding_item[i].id; 1204e1051a39Sopenharmony_ci break; 1205e1051a39Sopenharmony_ci } 1206e1051a39Sopenharmony_ci } 1207e1051a39Sopenharmony_ci } 1208e1051a39Sopenharmony_ci break; 1209e1051a39Sopenharmony_ci default: 1210e1051a39Sopenharmony_ci return 0; 1211e1051a39Sopenharmony_ci } 1212e1051a39Sopenharmony_ci 1213e1051a39Sopenharmony_ci switch (pad_mode) { 1214e1051a39Sopenharmony_ci case RSA_PKCS1_OAEP_PADDING: 1215e1051a39Sopenharmony_ci /* 1216e1051a39Sopenharmony_ci * OAEP padding is for asymmetric cipher only so is not compatible 1217e1051a39Sopenharmony_ci * with signature use. 1218e1051a39Sopenharmony_ci */ 1219e1051a39Sopenharmony_ci err_extra_text = "OAEP padding not allowed for signing / verifying"; 1220e1051a39Sopenharmony_ci goto bad_pad; 1221e1051a39Sopenharmony_ci case RSA_PKCS1_PSS_PADDING: 1222e1051a39Sopenharmony_ci if ((prsactx->operation 1223e1051a39Sopenharmony_ci & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)) == 0) { 1224e1051a39Sopenharmony_ci err_extra_text = 1225e1051a39Sopenharmony_ci "PSS padding only allowed for sign and verify operations"; 1226e1051a39Sopenharmony_ci goto bad_pad; 1227e1051a39Sopenharmony_ci } 1228e1051a39Sopenharmony_ci break; 1229e1051a39Sopenharmony_ci case RSA_PKCS1_PADDING: 1230e1051a39Sopenharmony_ci err_extra_text = "PKCS#1 padding not allowed with RSA-PSS"; 1231e1051a39Sopenharmony_ci goto cont; 1232e1051a39Sopenharmony_ci case RSA_NO_PADDING: 1233e1051a39Sopenharmony_ci err_extra_text = "No padding not allowed with RSA-PSS"; 1234e1051a39Sopenharmony_ci goto cont; 1235e1051a39Sopenharmony_ci case RSA_X931_PADDING: 1236e1051a39Sopenharmony_ci err_extra_text = "X.931 padding not allowed with RSA-PSS"; 1237e1051a39Sopenharmony_ci cont: 1238e1051a39Sopenharmony_ci if (RSA_test_flags(prsactx->rsa, 1239e1051a39Sopenharmony_ci RSA_FLAG_TYPE_MASK) == RSA_FLAG_TYPE_RSA) 1240e1051a39Sopenharmony_ci break; 1241e1051a39Sopenharmony_ci /* FALLTHRU */ 1242e1051a39Sopenharmony_ci default: 1243e1051a39Sopenharmony_ci bad_pad: 1244e1051a39Sopenharmony_ci if (err_extra_text == NULL) 1245e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, 1246e1051a39Sopenharmony_ci PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); 1247e1051a39Sopenharmony_ci else 1248e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, 1249e1051a39Sopenharmony_ci PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE, 1250e1051a39Sopenharmony_ci err_extra_text); 1251e1051a39Sopenharmony_ci return 0; 1252e1051a39Sopenharmony_ci } 1253e1051a39Sopenharmony_ci } 1254e1051a39Sopenharmony_ci 1255e1051a39Sopenharmony_ci p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN); 1256e1051a39Sopenharmony_ci if (p != NULL) { 1257e1051a39Sopenharmony_ci if (pad_mode != RSA_PKCS1_PSS_PADDING) { 1258e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED, 1259e1051a39Sopenharmony_ci "PSS saltlen can only be specified if " 1260e1051a39Sopenharmony_ci "PSS padding has been specified first"); 1261e1051a39Sopenharmony_ci return 0; 1262e1051a39Sopenharmony_ci } 1263e1051a39Sopenharmony_ci 1264e1051a39Sopenharmony_ci switch (p->data_type) { 1265e1051a39Sopenharmony_ci case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ 1266e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_int(p, &saltlen)) 1267e1051a39Sopenharmony_ci return 0; 1268e1051a39Sopenharmony_ci break; 1269e1051a39Sopenharmony_ci case OSSL_PARAM_UTF8_STRING: 1270e1051a39Sopenharmony_ci if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST) == 0) 1271e1051a39Sopenharmony_ci saltlen = RSA_PSS_SALTLEN_DIGEST; 1272e1051a39Sopenharmony_ci else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_MAX) == 0) 1273e1051a39Sopenharmony_ci saltlen = RSA_PSS_SALTLEN_MAX; 1274e1051a39Sopenharmony_ci else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0) 1275e1051a39Sopenharmony_ci saltlen = RSA_PSS_SALTLEN_AUTO; 1276e1051a39Sopenharmony_ci else 1277e1051a39Sopenharmony_ci saltlen = atoi(p->data); 1278e1051a39Sopenharmony_ci break; 1279e1051a39Sopenharmony_ci default: 1280e1051a39Sopenharmony_ci return 0; 1281e1051a39Sopenharmony_ci } 1282e1051a39Sopenharmony_ci 1283e1051a39Sopenharmony_ci /* 1284e1051a39Sopenharmony_ci * RSA_PSS_SALTLEN_MAX seems curiously named in this check. 1285e1051a39Sopenharmony_ci * Contrary to what it's name suggests, it's the currently 1286e1051a39Sopenharmony_ci * lowest saltlen number possible. 1287e1051a39Sopenharmony_ci */ 1288e1051a39Sopenharmony_ci if (saltlen < RSA_PSS_SALTLEN_MAX) { 1289e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); 1290e1051a39Sopenharmony_ci return 0; 1291e1051a39Sopenharmony_ci } 1292e1051a39Sopenharmony_ci 1293e1051a39Sopenharmony_ci if (rsa_pss_restricted(prsactx)) { 1294e1051a39Sopenharmony_ci switch (saltlen) { 1295e1051a39Sopenharmony_ci case RSA_PSS_SALTLEN_AUTO: 1296e1051a39Sopenharmony_ci if (prsactx->operation == EVP_PKEY_OP_VERIFY) { 1297e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, 1298e1051a39Sopenharmony_ci "Cannot use autodetected salt length"); 1299e1051a39Sopenharmony_ci return 0; 1300e1051a39Sopenharmony_ci } 1301e1051a39Sopenharmony_ci break; 1302e1051a39Sopenharmony_ci case RSA_PSS_SALTLEN_DIGEST: 1303e1051a39Sopenharmony_ci if (prsactx->min_saltlen > EVP_MD_get_size(prsactx->md)) { 1304e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, 1305e1051a39Sopenharmony_ci PROV_R_PSS_SALTLEN_TOO_SMALL, 1306e1051a39Sopenharmony_ci "Should be more than %d, but would be " 1307e1051a39Sopenharmony_ci "set to match digest size (%d)", 1308e1051a39Sopenharmony_ci prsactx->min_saltlen, 1309e1051a39Sopenharmony_ci EVP_MD_get_size(prsactx->md)); 1310e1051a39Sopenharmony_ci return 0; 1311e1051a39Sopenharmony_ci } 1312e1051a39Sopenharmony_ci break; 1313e1051a39Sopenharmony_ci default: 1314e1051a39Sopenharmony_ci if (saltlen >= 0 && saltlen < prsactx->min_saltlen) { 1315e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PROV, 1316e1051a39Sopenharmony_ci PROV_R_PSS_SALTLEN_TOO_SMALL, 1317e1051a39Sopenharmony_ci "Should be more than %d, " 1318e1051a39Sopenharmony_ci "but would be set to %d", 1319e1051a39Sopenharmony_ci prsactx->min_saltlen, saltlen); 1320e1051a39Sopenharmony_ci return 0; 1321e1051a39Sopenharmony_ci } 1322e1051a39Sopenharmony_ci } 1323e1051a39Sopenharmony_ci } 1324e1051a39Sopenharmony_ci } 1325e1051a39Sopenharmony_ci 1326e1051a39Sopenharmony_ci p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_MGF1_DIGEST); 1327e1051a39Sopenharmony_ci if (p != NULL) { 1328e1051a39Sopenharmony_ci const OSSL_PARAM *propsp = 1329e1051a39Sopenharmony_ci OSSL_PARAM_locate_const(params, 1330e1051a39Sopenharmony_ci OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES); 1331e1051a39Sopenharmony_ci 1332e1051a39Sopenharmony_ci pmgf1mdname = mgf1mdname; 1333e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_utf8_string(p, &pmgf1mdname, sizeof(mgf1mdname))) 1334e1051a39Sopenharmony_ci return 0; 1335e1051a39Sopenharmony_ci 1336e1051a39Sopenharmony_ci if (propsp != NULL) { 1337e1051a39Sopenharmony_ci pmgf1mdprops = mgf1mdprops; 1338e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_utf8_string(propsp, 1339e1051a39Sopenharmony_ci &pmgf1mdprops, sizeof(mgf1mdprops))) 1340e1051a39Sopenharmony_ci return 0; 1341e1051a39Sopenharmony_ci } 1342e1051a39Sopenharmony_ci 1343e1051a39Sopenharmony_ci if (pad_mode != RSA_PKCS1_PSS_PADDING) { 1344e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MGF1_MD); 1345e1051a39Sopenharmony_ci return 0; 1346e1051a39Sopenharmony_ci } 1347e1051a39Sopenharmony_ci } 1348e1051a39Sopenharmony_ci 1349e1051a39Sopenharmony_ci prsactx->saltlen = saltlen; 1350e1051a39Sopenharmony_ci prsactx->pad_mode = pad_mode; 1351e1051a39Sopenharmony_ci 1352e1051a39Sopenharmony_ci if (prsactx->md == NULL && pmdname == NULL 1353e1051a39Sopenharmony_ci && pad_mode == RSA_PKCS1_PSS_PADDING) 1354e1051a39Sopenharmony_ci pmdname = RSA_DEFAULT_DIGEST_NAME; 1355e1051a39Sopenharmony_ci 1356e1051a39Sopenharmony_ci if (pmgf1mdname != NULL 1357e1051a39Sopenharmony_ci && !rsa_setup_mgf1_md(prsactx, pmgf1mdname, pmgf1mdprops)) 1358e1051a39Sopenharmony_ci return 0; 1359e1051a39Sopenharmony_ci 1360e1051a39Sopenharmony_ci if (pmdname != NULL) { 1361e1051a39Sopenharmony_ci if (!rsa_setup_md(prsactx, pmdname, pmdprops)) 1362e1051a39Sopenharmony_ci return 0; 1363e1051a39Sopenharmony_ci } else { 1364e1051a39Sopenharmony_ci if (!rsa_check_padding(prsactx, NULL, NULL, prsactx->mdnid)) 1365e1051a39Sopenharmony_ci return 0; 1366e1051a39Sopenharmony_ci } 1367e1051a39Sopenharmony_ci return 1; 1368e1051a39Sopenharmony_ci} 1369e1051a39Sopenharmony_ci 1370e1051a39Sopenharmony_cistatic const OSSL_PARAM settable_ctx_params[] = { 1371e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 1372e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), 1373e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), 1374e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), 1375e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), 1376e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), 1377e1051a39Sopenharmony_ci OSSL_PARAM_END 1378e1051a39Sopenharmony_ci}; 1379e1051a39Sopenharmony_ci 1380e1051a39Sopenharmony_cistatic const OSSL_PARAM settable_ctx_params_no_digest[] = { 1381e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), 1382e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), 1383e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), 1384e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), 1385e1051a39Sopenharmony_ci OSSL_PARAM_END 1386e1051a39Sopenharmony_ci}; 1387e1051a39Sopenharmony_ci 1388e1051a39Sopenharmony_cistatic const OSSL_PARAM *rsa_settable_ctx_params(void *vprsactx, 1389e1051a39Sopenharmony_ci ossl_unused void *provctx) 1390e1051a39Sopenharmony_ci{ 1391e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 1392e1051a39Sopenharmony_ci 1393e1051a39Sopenharmony_ci if (prsactx != NULL && !prsactx->flag_allow_md) 1394e1051a39Sopenharmony_ci return settable_ctx_params_no_digest; 1395e1051a39Sopenharmony_ci return settable_ctx_params; 1396e1051a39Sopenharmony_ci} 1397e1051a39Sopenharmony_ci 1398e1051a39Sopenharmony_cistatic int rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params) 1399e1051a39Sopenharmony_ci{ 1400e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 1401e1051a39Sopenharmony_ci 1402e1051a39Sopenharmony_ci if (prsactx->mdctx == NULL) 1403e1051a39Sopenharmony_ci return 0; 1404e1051a39Sopenharmony_ci 1405e1051a39Sopenharmony_ci return EVP_MD_CTX_get_params(prsactx->mdctx, params); 1406e1051a39Sopenharmony_ci} 1407e1051a39Sopenharmony_ci 1408e1051a39Sopenharmony_cistatic const OSSL_PARAM *rsa_gettable_ctx_md_params(void *vprsactx) 1409e1051a39Sopenharmony_ci{ 1410e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 1411e1051a39Sopenharmony_ci 1412e1051a39Sopenharmony_ci if (prsactx->md == NULL) 1413e1051a39Sopenharmony_ci return 0; 1414e1051a39Sopenharmony_ci 1415e1051a39Sopenharmony_ci return EVP_MD_gettable_ctx_params(prsactx->md); 1416e1051a39Sopenharmony_ci} 1417e1051a39Sopenharmony_ci 1418e1051a39Sopenharmony_cistatic int rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[]) 1419e1051a39Sopenharmony_ci{ 1420e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 1421e1051a39Sopenharmony_ci 1422e1051a39Sopenharmony_ci if (prsactx->mdctx == NULL) 1423e1051a39Sopenharmony_ci return 0; 1424e1051a39Sopenharmony_ci 1425e1051a39Sopenharmony_ci return EVP_MD_CTX_set_params(prsactx->mdctx, params); 1426e1051a39Sopenharmony_ci} 1427e1051a39Sopenharmony_ci 1428e1051a39Sopenharmony_cistatic const OSSL_PARAM *rsa_settable_ctx_md_params(void *vprsactx) 1429e1051a39Sopenharmony_ci{ 1430e1051a39Sopenharmony_ci PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; 1431e1051a39Sopenharmony_ci 1432e1051a39Sopenharmony_ci if (prsactx->md == NULL) 1433e1051a39Sopenharmony_ci return 0; 1434e1051a39Sopenharmony_ci 1435e1051a39Sopenharmony_ci return EVP_MD_settable_ctx_params(prsactx->md); 1436e1051a39Sopenharmony_ci} 1437e1051a39Sopenharmony_ci 1438e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_rsa_signature_functions[] = { 1439e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))rsa_newctx }, 1440e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))rsa_sign_init }, 1441e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))rsa_sign }, 1442e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))rsa_verify_init }, 1443e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))rsa_verify }, 1444e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, 1445e1051a39Sopenharmony_ci (void (*)(void))rsa_verify_recover_init }, 1446e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, 1447e1051a39Sopenharmony_ci (void (*)(void))rsa_verify_recover }, 1448e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, 1449e1051a39Sopenharmony_ci (void (*)(void))rsa_digest_sign_init }, 1450e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, 1451e1051a39Sopenharmony_ci (void (*)(void))rsa_digest_signverify_update }, 1452e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, 1453e1051a39Sopenharmony_ci (void (*)(void))rsa_digest_sign_final }, 1454e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, 1455e1051a39Sopenharmony_ci (void (*)(void))rsa_digest_verify_init }, 1456e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, 1457e1051a39Sopenharmony_ci (void (*)(void))rsa_digest_signverify_update }, 1458e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, 1459e1051a39Sopenharmony_ci (void (*)(void))rsa_digest_verify_final }, 1460e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))rsa_freectx }, 1461e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))rsa_dupctx }, 1462e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))rsa_get_ctx_params }, 1463e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, 1464e1051a39Sopenharmony_ci (void (*)(void))rsa_gettable_ctx_params }, 1465e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))rsa_set_ctx_params }, 1466e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, 1467e1051a39Sopenharmony_ci (void (*)(void))rsa_settable_ctx_params }, 1468e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, 1469e1051a39Sopenharmony_ci (void (*)(void))rsa_get_ctx_md_params }, 1470e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, 1471e1051a39Sopenharmony_ci (void (*)(void))rsa_gettable_ctx_md_params }, 1472e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, 1473e1051a39Sopenharmony_ci (void (*)(void))rsa_set_ctx_md_params }, 1474e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, 1475e1051a39Sopenharmony_ci (void (*)(void))rsa_settable_ctx_md_params }, 1476e1051a39Sopenharmony_ci { 0, NULL } 1477e1051a39Sopenharmony_ci}; 1478