1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * 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 "internal/constant_time.h" 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_ci#include <stdio.h> 19e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 20e1051a39Sopenharmony_ci#include <openssl/asn1t.h> 21e1051a39Sopenharmony_ci#include <openssl/x509.h> 22e1051a39Sopenharmony_ci#include <openssl/rsa.h> 23e1051a39Sopenharmony_ci#include <openssl/bn.h> 24e1051a39Sopenharmony_ci#include <openssl/evp.h> 25e1051a39Sopenharmony_ci#include <openssl/x509v3.h> 26e1051a39Sopenharmony_ci#include <openssl/cms.h> 27e1051a39Sopenharmony_ci#include "crypto/evp.h" 28e1051a39Sopenharmony_ci#include "crypto/rsa.h" 29e1051a39Sopenharmony_ci#include "rsa_local.h" 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_ci/* RSA pkey context structure */ 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_citypedef struct { 34e1051a39Sopenharmony_ci /* Key gen parameters */ 35e1051a39Sopenharmony_ci int nbits; 36e1051a39Sopenharmony_ci BIGNUM *pub_exp; 37e1051a39Sopenharmony_ci int primes; 38e1051a39Sopenharmony_ci /* Keygen callback info */ 39e1051a39Sopenharmony_ci int gentmp[2]; 40e1051a39Sopenharmony_ci /* RSA padding mode */ 41e1051a39Sopenharmony_ci int pad_mode; 42e1051a39Sopenharmony_ci /* message digest */ 43e1051a39Sopenharmony_ci const EVP_MD *md; 44e1051a39Sopenharmony_ci /* message digest for MGF1 */ 45e1051a39Sopenharmony_ci const EVP_MD *mgf1md; 46e1051a39Sopenharmony_ci /* PSS salt length */ 47e1051a39Sopenharmony_ci int saltlen; 48e1051a39Sopenharmony_ci /* Minimum salt length or -1 if no PSS parameter restriction */ 49e1051a39Sopenharmony_ci int min_saltlen; 50e1051a39Sopenharmony_ci /* Temp buffer */ 51e1051a39Sopenharmony_ci unsigned char *tbuf; 52e1051a39Sopenharmony_ci /* OAEP label */ 53e1051a39Sopenharmony_ci unsigned char *oaep_label; 54e1051a39Sopenharmony_ci size_t oaep_labellen; 55e1051a39Sopenharmony_ci} RSA_PKEY_CTX; 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_ci/* True if PSS parameters are restricted */ 58e1051a39Sopenharmony_ci#define rsa_pss_restricted(rctx) (rctx->min_saltlen != -1) 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_cistatic int pkey_rsa_init(EVP_PKEY_CTX *ctx) 61e1051a39Sopenharmony_ci{ 62e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx)); 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ci if (rctx == NULL) 65e1051a39Sopenharmony_ci return 0; 66e1051a39Sopenharmony_ci rctx->nbits = 2048; 67e1051a39Sopenharmony_ci rctx->primes = RSA_DEFAULT_PRIME_NUM; 68e1051a39Sopenharmony_ci if (pkey_ctx_is_pss(ctx)) 69e1051a39Sopenharmony_ci rctx->pad_mode = RSA_PKCS1_PSS_PADDING; 70e1051a39Sopenharmony_ci else 71e1051a39Sopenharmony_ci rctx->pad_mode = RSA_PKCS1_PADDING; 72e1051a39Sopenharmony_ci /* Maximum for sign, auto for verify */ 73e1051a39Sopenharmony_ci rctx->saltlen = RSA_PSS_SALTLEN_AUTO; 74e1051a39Sopenharmony_ci rctx->min_saltlen = -1; 75e1051a39Sopenharmony_ci ctx->data = rctx; 76e1051a39Sopenharmony_ci ctx->keygen_info = rctx->gentmp; 77e1051a39Sopenharmony_ci ctx->keygen_info_count = 2; 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ci return 1; 80e1051a39Sopenharmony_ci} 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_cistatic int pkey_rsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) 83e1051a39Sopenharmony_ci{ 84e1051a39Sopenharmony_ci RSA_PKEY_CTX *dctx, *sctx; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci if (!pkey_rsa_init(dst)) 87e1051a39Sopenharmony_ci return 0; 88e1051a39Sopenharmony_ci sctx = src->data; 89e1051a39Sopenharmony_ci dctx = dst->data; 90e1051a39Sopenharmony_ci dctx->nbits = sctx->nbits; 91e1051a39Sopenharmony_ci if (sctx->pub_exp) { 92e1051a39Sopenharmony_ci dctx->pub_exp = BN_dup(sctx->pub_exp); 93e1051a39Sopenharmony_ci if (!dctx->pub_exp) 94e1051a39Sopenharmony_ci return 0; 95e1051a39Sopenharmony_ci } 96e1051a39Sopenharmony_ci dctx->pad_mode = sctx->pad_mode; 97e1051a39Sopenharmony_ci dctx->md = sctx->md; 98e1051a39Sopenharmony_ci dctx->mgf1md = sctx->mgf1md; 99e1051a39Sopenharmony_ci dctx->saltlen = sctx->saltlen; 100e1051a39Sopenharmony_ci if (sctx->oaep_label) { 101e1051a39Sopenharmony_ci OPENSSL_free(dctx->oaep_label); 102e1051a39Sopenharmony_ci dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen); 103e1051a39Sopenharmony_ci if (!dctx->oaep_label) 104e1051a39Sopenharmony_ci return 0; 105e1051a39Sopenharmony_ci dctx->oaep_labellen = sctx->oaep_labellen; 106e1051a39Sopenharmony_ci } 107e1051a39Sopenharmony_ci return 1; 108e1051a39Sopenharmony_ci} 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_cistatic int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) 111e1051a39Sopenharmony_ci{ 112e1051a39Sopenharmony_ci if (ctx->tbuf != NULL) 113e1051a39Sopenharmony_ci return 1; 114e1051a39Sopenharmony_ci if ((ctx->tbuf = 115e1051a39Sopenharmony_ci OPENSSL_malloc(RSA_size(EVP_PKEY_get0_RSA(pk->pkey)))) == NULL) { 116e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); 117e1051a39Sopenharmony_ci return 0; 118e1051a39Sopenharmony_ci } 119e1051a39Sopenharmony_ci return 1; 120e1051a39Sopenharmony_ci} 121e1051a39Sopenharmony_ci 122e1051a39Sopenharmony_cistatic void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) 123e1051a39Sopenharmony_ci{ 124e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 125e1051a39Sopenharmony_ci if (rctx) { 126e1051a39Sopenharmony_ci BN_free(rctx->pub_exp); 127e1051a39Sopenharmony_ci OPENSSL_free(rctx->tbuf); 128e1051a39Sopenharmony_ci OPENSSL_free(rctx->oaep_label); 129e1051a39Sopenharmony_ci OPENSSL_free(rctx); 130e1051a39Sopenharmony_ci } 131e1051a39Sopenharmony_ci} 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_cistatic int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, 134e1051a39Sopenharmony_ci size_t *siglen, const unsigned char *tbs, 135e1051a39Sopenharmony_ci size_t tbslen) 136e1051a39Sopenharmony_ci{ 137e1051a39Sopenharmony_ci int ret; 138e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 139e1051a39Sopenharmony_ci /* 140e1051a39Sopenharmony_ci * Discard const. Its marked as const because this may be a cached copy of 141e1051a39Sopenharmony_ci * the "real" key. These calls don't make any modifications that need to 142e1051a39Sopenharmony_ci * be reflected back in the "original" key. 143e1051a39Sopenharmony_ci */ 144e1051a39Sopenharmony_ci RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci if (rctx->md) { 147e1051a39Sopenharmony_ci if (tbslen != (size_t)EVP_MD_get_size(rctx->md)) { 148e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH); 149e1051a39Sopenharmony_ci return -1; 150e1051a39Sopenharmony_ci } 151e1051a39Sopenharmony_ci 152e1051a39Sopenharmony_ci if (EVP_MD_get_type(rctx->md) == NID_mdc2) { 153e1051a39Sopenharmony_ci unsigned int sltmp; 154e1051a39Sopenharmony_ci if (rctx->pad_mode != RSA_PKCS1_PADDING) 155e1051a39Sopenharmony_ci return -1; 156e1051a39Sopenharmony_ci ret = RSA_sign_ASN1_OCTET_STRING(0, tbs, tbslen, sig, &sltmp, rsa); 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci if (ret <= 0) 159e1051a39Sopenharmony_ci return ret; 160e1051a39Sopenharmony_ci ret = sltmp; 161e1051a39Sopenharmony_ci } else if (rctx->pad_mode == RSA_X931_PADDING) { 162e1051a39Sopenharmony_ci if ((size_t)RSA_size(rsa) < tbslen + 1) { 163e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); 164e1051a39Sopenharmony_ci return -1; 165e1051a39Sopenharmony_ci } 166e1051a39Sopenharmony_ci if (!setup_tbuf(rctx, ctx)) { 167e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); 168e1051a39Sopenharmony_ci return -1; 169e1051a39Sopenharmony_ci } 170e1051a39Sopenharmony_ci memcpy(rctx->tbuf, tbs, tbslen); 171e1051a39Sopenharmony_ci rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_get_type(rctx->md)); 172e1051a39Sopenharmony_ci ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, 173e1051a39Sopenharmony_ci sig, rsa, RSA_X931_PADDING); 174e1051a39Sopenharmony_ci } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { 175e1051a39Sopenharmony_ci unsigned int sltmp; 176e1051a39Sopenharmony_ci ret = RSA_sign(EVP_MD_get_type(rctx->md), 177e1051a39Sopenharmony_ci tbs, tbslen, sig, &sltmp, rsa); 178e1051a39Sopenharmony_ci if (ret <= 0) 179e1051a39Sopenharmony_ci return ret; 180e1051a39Sopenharmony_ci ret = sltmp; 181e1051a39Sopenharmony_ci } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { 182e1051a39Sopenharmony_ci if (!setup_tbuf(rctx, ctx)) 183e1051a39Sopenharmony_ci return -1; 184e1051a39Sopenharmony_ci if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, 185e1051a39Sopenharmony_ci rctx->tbuf, tbs, 186e1051a39Sopenharmony_ci rctx->md, rctx->mgf1md, 187e1051a39Sopenharmony_ci rctx->saltlen)) 188e1051a39Sopenharmony_ci return -1; 189e1051a39Sopenharmony_ci ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, 190e1051a39Sopenharmony_ci sig, rsa, RSA_NO_PADDING); 191e1051a39Sopenharmony_ci } else { 192e1051a39Sopenharmony_ci return -1; 193e1051a39Sopenharmony_ci } 194e1051a39Sopenharmony_ci } else { 195e1051a39Sopenharmony_ci ret = RSA_private_encrypt(tbslen, tbs, sig, rsa, rctx->pad_mode); 196e1051a39Sopenharmony_ci } 197e1051a39Sopenharmony_ci if (ret < 0) 198e1051a39Sopenharmony_ci return ret; 199e1051a39Sopenharmony_ci *siglen = ret; 200e1051a39Sopenharmony_ci return 1; 201e1051a39Sopenharmony_ci} 202e1051a39Sopenharmony_ci 203e1051a39Sopenharmony_cistatic int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, 204e1051a39Sopenharmony_ci unsigned char *rout, size_t *routlen, 205e1051a39Sopenharmony_ci const unsigned char *sig, size_t siglen) 206e1051a39Sopenharmony_ci{ 207e1051a39Sopenharmony_ci int ret; 208e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 209e1051a39Sopenharmony_ci /* 210e1051a39Sopenharmony_ci * Discard const. Its marked as const because this may be a cached copy of 211e1051a39Sopenharmony_ci * the "real" key. These calls don't make any modifications that need to 212e1051a39Sopenharmony_ci * be reflected back in the "original" key. 213e1051a39Sopenharmony_ci */ 214e1051a39Sopenharmony_ci RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); 215e1051a39Sopenharmony_ci 216e1051a39Sopenharmony_ci if (rctx->md) { 217e1051a39Sopenharmony_ci if (rctx->pad_mode == RSA_X931_PADDING) { 218e1051a39Sopenharmony_ci if (!setup_tbuf(rctx, ctx)) 219e1051a39Sopenharmony_ci return -1; 220e1051a39Sopenharmony_ci ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, rsa, 221e1051a39Sopenharmony_ci RSA_X931_PADDING); 222e1051a39Sopenharmony_ci if (ret < 1) 223e1051a39Sopenharmony_ci return 0; 224e1051a39Sopenharmony_ci ret--; 225e1051a39Sopenharmony_ci if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_get_type(rctx->md))) { 226e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_ALGORITHM_MISMATCH); 227e1051a39Sopenharmony_ci return 0; 228e1051a39Sopenharmony_ci } 229e1051a39Sopenharmony_ci if (ret != EVP_MD_get_size(rctx->md)) { 230e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH); 231e1051a39Sopenharmony_ci return 0; 232e1051a39Sopenharmony_ci } 233e1051a39Sopenharmony_ci if (rout) 234e1051a39Sopenharmony_ci memcpy(rout, rctx->tbuf, ret); 235e1051a39Sopenharmony_ci } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { 236e1051a39Sopenharmony_ci size_t sltmp; 237e1051a39Sopenharmony_ci ret = ossl_rsa_verify(EVP_MD_get_type(rctx->md), 238e1051a39Sopenharmony_ci NULL, 0, rout, &sltmp, 239e1051a39Sopenharmony_ci sig, siglen, rsa); 240e1051a39Sopenharmony_ci if (ret <= 0) 241e1051a39Sopenharmony_ci return 0; 242e1051a39Sopenharmony_ci ret = sltmp; 243e1051a39Sopenharmony_ci } else { 244e1051a39Sopenharmony_ci return -1; 245e1051a39Sopenharmony_ci } 246e1051a39Sopenharmony_ci } else { 247e1051a39Sopenharmony_ci ret = RSA_public_decrypt(siglen, sig, rout, rsa, rctx->pad_mode); 248e1051a39Sopenharmony_ci } 249e1051a39Sopenharmony_ci if (ret < 0) 250e1051a39Sopenharmony_ci return ret; 251e1051a39Sopenharmony_ci *routlen = ret; 252e1051a39Sopenharmony_ci return 1; 253e1051a39Sopenharmony_ci} 254e1051a39Sopenharmony_ci 255e1051a39Sopenharmony_cistatic int pkey_rsa_verify(EVP_PKEY_CTX *ctx, 256e1051a39Sopenharmony_ci const unsigned char *sig, size_t siglen, 257e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen) 258e1051a39Sopenharmony_ci{ 259e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 260e1051a39Sopenharmony_ci /* 261e1051a39Sopenharmony_ci * Discard const. Its marked as const because this may be a cached copy of 262e1051a39Sopenharmony_ci * the "real" key. These calls don't make any modifications that need to 263e1051a39Sopenharmony_ci * be reflected back in the "original" key. 264e1051a39Sopenharmony_ci */ 265e1051a39Sopenharmony_ci RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); 266e1051a39Sopenharmony_ci size_t rslen; 267e1051a39Sopenharmony_ci 268e1051a39Sopenharmony_ci if (rctx->md) { 269e1051a39Sopenharmony_ci if (rctx->pad_mode == RSA_PKCS1_PADDING) 270e1051a39Sopenharmony_ci return RSA_verify(EVP_MD_get_type(rctx->md), tbs, tbslen, 271e1051a39Sopenharmony_ci sig, siglen, rsa); 272e1051a39Sopenharmony_ci if (tbslen != (size_t)EVP_MD_get_size(rctx->md)) { 273e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH); 274e1051a39Sopenharmony_ci return -1; 275e1051a39Sopenharmony_ci } 276e1051a39Sopenharmony_ci if (rctx->pad_mode == RSA_X931_PADDING) { 277e1051a39Sopenharmony_ci if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0) 278e1051a39Sopenharmony_ci return 0; 279e1051a39Sopenharmony_ci } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { 280e1051a39Sopenharmony_ci int ret; 281e1051a39Sopenharmony_ci if (!setup_tbuf(rctx, ctx)) 282e1051a39Sopenharmony_ci return -1; 283e1051a39Sopenharmony_ci ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, 284e1051a39Sopenharmony_ci rsa, RSA_NO_PADDING); 285e1051a39Sopenharmony_ci if (ret <= 0) 286e1051a39Sopenharmony_ci return 0; 287e1051a39Sopenharmony_ci ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, 288e1051a39Sopenharmony_ci rctx->md, rctx->mgf1md, 289e1051a39Sopenharmony_ci rctx->tbuf, rctx->saltlen); 290e1051a39Sopenharmony_ci if (ret <= 0) 291e1051a39Sopenharmony_ci return 0; 292e1051a39Sopenharmony_ci return 1; 293e1051a39Sopenharmony_ci } else { 294e1051a39Sopenharmony_ci return -1; 295e1051a39Sopenharmony_ci } 296e1051a39Sopenharmony_ci } else { 297e1051a39Sopenharmony_ci if (!setup_tbuf(rctx, ctx)) 298e1051a39Sopenharmony_ci return -1; 299e1051a39Sopenharmony_ci rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, 300e1051a39Sopenharmony_ci rsa, rctx->pad_mode); 301e1051a39Sopenharmony_ci if (rslen == 0) 302e1051a39Sopenharmony_ci return 0; 303e1051a39Sopenharmony_ci } 304e1051a39Sopenharmony_ci 305e1051a39Sopenharmony_ci if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) 306e1051a39Sopenharmony_ci return 0; 307e1051a39Sopenharmony_ci 308e1051a39Sopenharmony_ci return 1; 309e1051a39Sopenharmony_ci 310e1051a39Sopenharmony_ci} 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_cistatic int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, 313e1051a39Sopenharmony_ci unsigned char *out, size_t *outlen, 314e1051a39Sopenharmony_ci const unsigned char *in, size_t inlen) 315e1051a39Sopenharmony_ci{ 316e1051a39Sopenharmony_ci int ret; 317e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 318e1051a39Sopenharmony_ci /* 319e1051a39Sopenharmony_ci * Discard const. Its marked as const because this may be a cached copy of 320e1051a39Sopenharmony_ci * the "real" key. These calls don't make any modifications that need to 321e1051a39Sopenharmony_ci * be reflected back in the "original" key. 322e1051a39Sopenharmony_ci */ 323e1051a39Sopenharmony_ci RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); 324e1051a39Sopenharmony_ci 325e1051a39Sopenharmony_ci if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { 326e1051a39Sopenharmony_ci int klen = RSA_size(rsa); 327e1051a39Sopenharmony_ci if (!setup_tbuf(rctx, ctx)) 328e1051a39Sopenharmony_ci return -1; 329e1051a39Sopenharmony_ci if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen, 330e1051a39Sopenharmony_ci in, inlen, 331e1051a39Sopenharmony_ci rctx->oaep_label, 332e1051a39Sopenharmony_ci rctx->oaep_labellen, 333e1051a39Sopenharmony_ci rctx->md, rctx->mgf1md)) 334e1051a39Sopenharmony_ci return -1; 335e1051a39Sopenharmony_ci ret = RSA_public_encrypt(klen, rctx->tbuf, out, rsa, RSA_NO_PADDING); 336e1051a39Sopenharmony_ci } else { 337e1051a39Sopenharmony_ci ret = RSA_public_encrypt(inlen, in, out, rsa, rctx->pad_mode); 338e1051a39Sopenharmony_ci } 339e1051a39Sopenharmony_ci if (ret < 0) 340e1051a39Sopenharmony_ci return ret; 341e1051a39Sopenharmony_ci *outlen = ret; 342e1051a39Sopenharmony_ci return 1; 343e1051a39Sopenharmony_ci} 344e1051a39Sopenharmony_ci 345e1051a39Sopenharmony_cistatic int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, 346e1051a39Sopenharmony_ci unsigned char *out, size_t *outlen, 347e1051a39Sopenharmony_ci const unsigned char *in, size_t inlen) 348e1051a39Sopenharmony_ci{ 349e1051a39Sopenharmony_ci int ret; 350e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 351e1051a39Sopenharmony_ci /* 352e1051a39Sopenharmony_ci * Discard const. Its marked as const because this may be a cached copy of 353e1051a39Sopenharmony_ci * the "real" key. These calls don't make any modifications that need to 354e1051a39Sopenharmony_ci * be reflected back in the "original" key. 355e1051a39Sopenharmony_ci */ 356e1051a39Sopenharmony_ci RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); 357e1051a39Sopenharmony_ci 358e1051a39Sopenharmony_ci if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { 359e1051a39Sopenharmony_ci if (!setup_tbuf(rctx, ctx)) 360e1051a39Sopenharmony_ci return -1; 361e1051a39Sopenharmony_ci ret = RSA_private_decrypt(inlen, in, rctx->tbuf, rsa, RSA_NO_PADDING); 362e1051a39Sopenharmony_ci if (ret <= 0) 363e1051a39Sopenharmony_ci return ret; 364e1051a39Sopenharmony_ci ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf, 365e1051a39Sopenharmony_ci ret, ret, 366e1051a39Sopenharmony_ci rctx->oaep_label, 367e1051a39Sopenharmony_ci rctx->oaep_labellen, 368e1051a39Sopenharmony_ci rctx->md, rctx->mgf1md); 369e1051a39Sopenharmony_ci } else { 370e1051a39Sopenharmony_ci ret = RSA_private_decrypt(inlen, in, out, rsa, rctx->pad_mode); 371e1051a39Sopenharmony_ci } 372e1051a39Sopenharmony_ci *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret); 373e1051a39Sopenharmony_ci ret = constant_time_select_int(constant_time_msb(ret), ret, 1); 374e1051a39Sopenharmony_ci return ret; 375e1051a39Sopenharmony_ci} 376e1051a39Sopenharmony_ci 377e1051a39Sopenharmony_cistatic int check_padding_md(const EVP_MD *md, int padding) 378e1051a39Sopenharmony_ci{ 379e1051a39Sopenharmony_ci int mdnid; 380e1051a39Sopenharmony_ci 381e1051a39Sopenharmony_ci if (!md) 382e1051a39Sopenharmony_ci return 1; 383e1051a39Sopenharmony_ci 384e1051a39Sopenharmony_ci mdnid = EVP_MD_get_type(md); 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_ci if (padding == RSA_NO_PADDING) { 387e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); 388e1051a39Sopenharmony_ci return 0; 389e1051a39Sopenharmony_ci } 390e1051a39Sopenharmony_ci 391e1051a39Sopenharmony_ci if (padding == RSA_X931_PADDING) { 392e1051a39Sopenharmony_ci if (RSA_X931_hash_id(mdnid) == -1) { 393e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_X931_DIGEST); 394e1051a39Sopenharmony_ci return 0; 395e1051a39Sopenharmony_ci } 396e1051a39Sopenharmony_ci } else { 397e1051a39Sopenharmony_ci switch(mdnid) { 398e1051a39Sopenharmony_ci /* List of all supported RSA digests */ 399e1051a39Sopenharmony_ci case NID_sha1: 400e1051a39Sopenharmony_ci case NID_sha224: 401e1051a39Sopenharmony_ci case NID_sha256: 402e1051a39Sopenharmony_ci case NID_sha384: 403e1051a39Sopenharmony_ci case NID_sha512: 404e1051a39Sopenharmony_ci case NID_sha512_224: 405e1051a39Sopenharmony_ci case NID_sha512_256: 406e1051a39Sopenharmony_ci case NID_md5: 407e1051a39Sopenharmony_ci case NID_md5_sha1: 408e1051a39Sopenharmony_ci case NID_md2: 409e1051a39Sopenharmony_ci case NID_md4: 410e1051a39Sopenharmony_ci case NID_mdc2: 411e1051a39Sopenharmony_ci case NID_ripemd160: 412e1051a39Sopenharmony_ci case NID_sha3_224: 413e1051a39Sopenharmony_ci case NID_sha3_256: 414e1051a39Sopenharmony_ci case NID_sha3_384: 415e1051a39Sopenharmony_ci case NID_sha3_512: 416e1051a39Sopenharmony_ci return 1; 417e1051a39Sopenharmony_ci 418e1051a39Sopenharmony_ci default: 419e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST); 420e1051a39Sopenharmony_ci return 0; 421e1051a39Sopenharmony_ci 422e1051a39Sopenharmony_ci } 423e1051a39Sopenharmony_ci } 424e1051a39Sopenharmony_ci 425e1051a39Sopenharmony_ci return 1; 426e1051a39Sopenharmony_ci} 427e1051a39Sopenharmony_ci 428e1051a39Sopenharmony_cistatic int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 429e1051a39Sopenharmony_ci{ 430e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 431e1051a39Sopenharmony_ci 432e1051a39Sopenharmony_ci switch (type) { 433e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_RSA_PADDING: 434e1051a39Sopenharmony_ci if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { 435e1051a39Sopenharmony_ci if (!check_padding_md(rctx->md, p1)) 436e1051a39Sopenharmony_ci return 0; 437e1051a39Sopenharmony_ci if (p1 == RSA_PKCS1_PSS_PADDING) { 438e1051a39Sopenharmony_ci if (!(ctx->operation & 439e1051a39Sopenharmony_ci (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) 440e1051a39Sopenharmony_ci goto bad_pad; 441e1051a39Sopenharmony_ci if (!rctx->md) 442e1051a39Sopenharmony_ci rctx->md = EVP_sha1(); 443e1051a39Sopenharmony_ci } else if (pkey_ctx_is_pss(ctx)) { 444e1051a39Sopenharmony_ci goto bad_pad; 445e1051a39Sopenharmony_ci } 446e1051a39Sopenharmony_ci if (p1 == RSA_PKCS1_OAEP_PADDING) { 447e1051a39Sopenharmony_ci if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) 448e1051a39Sopenharmony_ci goto bad_pad; 449e1051a39Sopenharmony_ci if (!rctx->md) 450e1051a39Sopenharmony_ci rctx->md = EVP_sha1(); 451e1051a39Sopenharmony_ci } 452e1051a39Sopenharmony_ci rctx->pad_mode = p1; 453e1051a39Sopenharmony_ci return 1; 454e1051a39Sopenharmony_ci } 455e1051a39Sopenharmony_ci bad_pad: 456e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); 457e1051a39Sopenharmony_ci return -2; 458e1051a39Sopenharmony_ci 459e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_GET_RSA_PADDING: 460e1051a39Sopenharmony_ci *(int *)p2 = rctx->pad_mode; 461e1051a39Sopenharmony_ci return 1; 462e1051a39Sopenharmony_ci 463e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: 464e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: 465e1051a39Sopenharmony_ci if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { 466e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_SALTLEN); 467e1051a39Sopenharmony_ci return -2; 468e1051a39Sopenharmony_ci } 469e1051a39Sopenharmony_ci if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { 470e1051a39Sopenharmony_ci *(int *)p2 = rctx->saltlen; 471e1051a39Sopenharmony_ci } else { 472e1051a39Sopenharmony_ci if (p1 < RSA_PSS_SALTLEN_MAX) 473e1051a39Sopenharmony_ci return -2; 474e1051a39Sopenharmony_ci if (rsa_pss_restricted(rctx)) { 475e1051a39Sopenharmony_ci if (p1 == RSA_PSS_SALTLEN_AUTO 476e1051a39Sopenharmony_ci && ctx->operation == EVP_PKEY_OP_VERIFY) { 477e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_SALTLEN); 478e1051a39Sopenharmony_ci return -2; 479e1051a39Sopenharmony_ci } 480e1051a39Sopenharmony_ci if ((p1 == RSA_PSS_SALTLEN_DIGEST 481e1051a39Sopenharmony_ci && rctx->min_saltlen > EVP_MD_get_size(rctx->md)) 482e1051a39Sopenharmony_ci || (p1 >= 0 && p1 < rctx->min_saltlen)) { 483e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_PSS_SALTLEN_TOO_SMALL); 484e1051a39Sopenharmony_ci return 0; 485e1051a39Sopenharmony_ci } 486e1051a39Sopenharmony_ci } 487e1051a39Sopenharmony_ci rctx->saltlen = p1; 488e1051a39Sopenharmony_ci } 489e1051a39Sopenharmony_ci return 1; 490e1051a39Sopenharmony_ci 491e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: 492e1051a39Sopenharmony_ci if (p1 < RSA_MIN_MODULUS_BITS) { 493e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); 494e1051a39Sopenharmony_ci return -2; 495e1051a39Sopenharmony_ci } 496e1051a39Sopenharmony_ci rctx->nbits = p1; 497e1051a39Sopenharmony_ci return 1; 498e1051a39Sopenharmony_ci 499e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: 500e1051a39Sopenharmony_ci if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) { 501e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); 502e1051a39Sopenharmony_ci return -2; 503e1051a39Sopenharmony_ci } 504e1051a39Sopenharmony_ci BN_free(rctx->pub_exp); 505e1051a39Sopenharmony_ci rctx->pub_exp = p2; 506e1051a39Sopenharmony_ci return 1; 507e1051a39Sopenharmony_ci 508e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES: 509e1051a39Sopenharmony_ci if (p1 < RSA_DEFAULT_PRIME_NUM || p1 > RSA_MAX_PRIME_NUM) { 510e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_KEY_PRIME_NUM_INVALID); 511e1051a39Sopenharmony_ci return -2; 512e1051a39Sopenharmony_ci } 513e1051a39Sopenharmony_ci rctx->primes = p1; 514e1051a39Sopenharmony_ci return 1; 515e1051a39Sopenharmony_ci 516e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_RSA_OAEP_MD: 517e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: 518e1051a39Sopenharmony_ci if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 519e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); 520e1051a39Sopenharmony_ci return -2; 521e1051a39Sopenharmony_ci } 522e1051a39Sopenharmony_ci if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) 523e1051a39Sopenharmony_ci *(const EVP_MD **)p2 = rctx->md; 524e1051a39Sopenharmony_ci else 525e1051a39Sopenharmony_ci rctx->md = p2; 526e1051a39Sopenharmony_ci return 1; 527e1051a39Sopenharmony_ci 528e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_MD: 529e1051a39Sopenharmony_ci if (!check_padding_md(p2, rctx->pad_mode)) 530e1051a39Sopenharmony_ci return 0; 531e1051a39Sopenharmony_ci if (rsa_pss_restricted(rctx)) { 532e1051a39Sopenharmony_ci if (EVP_MD_get_type(rctx->md) == EVP_MD_get_type(p2)) 533e1051a39Sopenharmony_ci return 1; 534e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED); 535e1051a39Sopenharmony_ci return 0; 536e1051a39Sopenharmony_ci } 537e1051a39Sopenharmony_ci rctx->md = p2; 538e1051a39Sopenharmony_ci return 1; 539e1051a39Sopenharmony_ci 540e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_GET_MD: 541e1051a39Sopenharmony_ci *(const EVP_MD **)p2 = rctx->md; 542e1051a39Sopenharmony_ci return 1; 543e1051a39Sopenharmony_ci 544e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_RSA_MGF1_MD: 545e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: 546e1051a39Sopenharmony_ci if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING 547e1051a39Sopenharmony_ci && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 548e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MGF1_MD); 549e1051a39Sopenharmony_ci return -2; 550e1051a39Sopenharmony_ci } 551e1051a39Sopenharmony_ci if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { 552e1051a39Sopenharmony_ci if (rctx->mgf1md) 553e1051a39Sopenharmony_ci *(const EVP_MD **)p2 = rctx->mgf1md; 554e1051a39Sopenharmony_ci else 555e1051a39Sopenharmony_ci *(const EVP_MD **)p2 = rctx->md; 556e1051a39Sopenharmony_ci } else { 557e1051a39Sopenharmony_ci if (rsa_pss_restricted(rctx)) { 558e1051a39Sopenharmony_ci if (EVP_MD_get_type(rctx->mgf1md) == EVP_MD_get_type(p2)) 559e1051a39Sopenharmony_ci return 1; 560e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_MGF1_DIGEST_NOT_ALLOWED); 561e1051a39Sopenharmony_ci return 0; 562e1051a39Sopenharmony_ci } 563e1051a39Sopenharmony_ci rctx->mgf1md = p2; 564e1051a39Sopenharmony_ci } 565e1051a39Sopenharmony_ci return 1; 566e1051a39Sopenharmony_ci 567e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_RSA_OAEP_LABEL: 568e1051a39Sopenharmony_ci if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 569e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); 570e1051a39Sopenharmony_ci return -2; 571e1051a39Sopenharmony_ci } 572e1051a39Sopenharmony_ci OPENSSL_free(rctx->oaep_label); 573e1051a39Sopenharmony_ci if (p2 && p1 > 0) { 574e1051a39Sopenharmony_ci rctx->oaep_label = p2; 575e1051a39Sopenharmony_ci rctx->oaep_labellen = p1; 576e1051a39Sopenharmony_ci } else { 577e1051a39Sopenharmony_ci rctx->oaep_label = NULL; 578e1051a39Sopenharmony_ci rctx->oaep_labellen = 0; 579e1051a39Sopenharmony_ci } 580e1051a39Sopenharmony_ci return 1; 581e1051a39Sopenharmony_ci 582e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: 583e1051a39Sopenharmony_ci if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 584e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); 585e1051a39Sopenharmony_ci return -2; 586e1051a39Sopenharmony_ci } 587e1051a39Sopenharmony_ci *(unsigned char **)p2 = rctx->oaep_label; 588e1051a39Sopenharmony_ci return rctx->oaep_labellen; 589e1051a39Sopenharmony_ci 590e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_DIGESTINIT: 591e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_PKCS7_SIGN: 592e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_CMS 593e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_CMS_SIGN: 594e1051a39Sopenharmony_ci#endif 595e1051a39Sopenharmony_ci return 1; 596e1051a39Sopenharmony_ci 597e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_PKCS7_ENCRYPT: 598e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_PKCS7_DECRYPT: 599e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_CMS 600e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_CMS_DECRYPT: 601e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_CMS_ENCRYPT: 602e1051a39Sopenharmony_ci#endif 603e1051a39Sopenharmony_ci if (!pkey_ctx_is_pss(ctx)) 604e1051a39Sopenharmony_ci return 1; 605e1051a39Sopenharmony_ci /* fall through */ 606e1051a39Sopenharmony_ci case EVP_PKEY_CTRL_PEER_KEY: 607e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 608e1051a39Sopenharmony_ci return -2; 609e1051a39Sopenharmony_ci 610e1051a39Sopenharmony_ci default: 611e1051a39Sopenharmony_ci return -2; 612e1051a39Sopenharmony_ci 613e1051a39Sopenharmony_ci } 614e1051a39Sopenharmony_ci} 615e1051a39Sopenharmony_ci 616e1051a39Sopenharmony_cistatic int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, 617e1051a39Sopenharmony_ci const char *type, const char *value) 618e1051a39Sopenharmony_ci{ 619e1051a39Sopenharmony_ci if (value == NULL) { 620e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_VALUE_MISSING); 621e1051a39Sopenharmony_ci return 0; 622e1051a39Sopenharmony_ci } 623e1051a39Sopenharmony_ci if (strcmp(type, "rsa_padding_mode") == 0) { 624e1051a39Sopenharmony_ci int pm; 625e1051a39Sopenharmony_ci 626e1051a39Sopenharmony_ci if (strcmp(value, "pkcs1") == 0) { 627e1051a39Sopenharmony_ci pm = RSA_PKCS1_PADDING; 628e1051a39Sopenharmony_ci } else if (strcmp(value, "none") == 0) { 629e1051a39Sopenharmony_ci pm = RSA_NO_PADDING; 630e1051a39Sopenharmony_ci } else if (strcmp(value, "oeap") == 0) { 631e1051a39Sopenharmony_ci pm = RSA_PKCS1_OAEP_PADDING; 632e1051a39Sopenharmony_ci } else if (strcmp(value, "oaep") == 0) { 633e1051a39Sopenharmony_ci pm = RSA_PKCS1_OAEP_PADDING; 634e1051a39Sopenharmony_ci } else if (strcmp(value, "x931") == 0) { 635e1051a39Sopenharmony_ci pm = RSA_X931_PADDING; 636e1051a39Sopenharmony_ci } else if (strcmp(value, "pss") == 0) { 637e1051a39Sopenharmony_ci pm = RSA_PKCS1_PSS_PADDING; 638e1051a39Sopenharmony_ci } else { 639e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE); 640e1051a39Sopenharmony_ci return -2; 641e1051a39Sopenharmony_ci } 642e1051a39Sopenharmony_ci return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); 643e1051a39Sopenharmony_ci } 644e1051a39Sopenharmony_ci 645e1051a39Sopenharmony_ci if (strcmp(type, "rsa_pss_saltlen") == 0) { 646e1051a39Sopenharmony_ci int saltlen; 647e1051a39Sopenharmony_ci 648e1051a39Sopenharmony_ci if (!strcmp(value, "digest")) 649e1051a39Sopenharmony_ci saltlen = RSA_PSS_SALTLEN_DIGEST; 650e1051a39Sopenharmony_ci else if (!strcmp(value, "max")) 651e1051a39Sopenharmony_ci saltlen = RSA_PSS_SALTLEN_MAX; 652e1051a39Sopenharmony_ci else if (!strcmp(value, "auto")) 653e1051a39Sopenharmony_ci saltlen = RSA_PSS_SALTLEN_AUTO; 654e1051a39Sopenharmony_ci else 655e1051a39Sopenharmony_ci saltlen = atoi(value); 656e1051a39Sopenharmony_ci return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); 657e1051a39Sopenharmony_ci } 658e1051a39Sopenharmony_ci 659e1051a39Sopenharmony_ci if (strcmp(type, "rsa_keygen_bits") == 0) { 660e1051a39Sopenharmony_ci int nbits = atoi(value); 661e1051a39Sopenharmony_ci 662e1051a39Sopenharmony_ci return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); 663e1051a39Sopenharmony_ci } 664e1051a39Sopenharmony_ci 665e1051a39Sopenharmony_ci if (strcmp(type, "rsa_keygen_pubexp") == 0) { 666e1051a39Sopenharmony_ci int ret; 667e1051a39Sopenharmony_ci 668e1051a39Sopenharmony_ci BIGNUM *pubexp = NULL; 669e1051a39Sopenharmony_ci if (!BN_asc2bn(&pubexp, value)) 670e1051a39Sopenharmony_ci return 0; 671e1051a39Sopenharmony_ci ret = EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, pubexp); 672e1051a39Sopenharmony_ci BN_free(pubexp); 673e1051a39Sopenharmony_ci return ret; 674e1051a39Sopenharmony_ci } 675e1051a39Sopenharmony_ci 676e1051a39Sopenharmony_ci if (strcmp(type, "rsa_keygen_primes") == 0) { 677e1051a39Sopenharmony_ci int nprimes = atoi(value); 678e1051a39Sopenharmony_ci 679e1051a39Sopenharmony_ci return EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, nprimes); 680e1051a39Sopenharmony_ci } 681e1051a39Sopenharmony_ci 682e1051a39Sopenharmony_ci if (strcmp(type, "rsa_mgf1_md") == 0) 683e1051a39Sopenharmony_ci return EVP_PKEY_CTX_md(ctx, 684e1051a39Sopenharmony_ci EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, 685e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_MGF1_MD, value); 686e1051a39Sopenharmony_ci 687e1051a39Sopenharmony_ci if (pkey_ctx_is_pss(ctx)) { 688e1051a39Sopenharmony_ci 689e1051a39Sopenharmony_ci if (strcmp(type, "rsa_pss_keygen_mgf1_md") == 0) 690e1051a39Sopenharmony_ci return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, 691e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_MGF1_MD, value); 692e1051a39Sopenharmony_ci 693e1051a39Sopenharmony_ci if (strcmp(type, "rsa_pss_keygen_md") == 0) 694e1051a39Sopenharmony_ci return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, 695e1051a39Sopenharmony_ci EVP_PKEY_CTRL_MD, value); 696e1051a39Sopenharmony_ci 697e1051a39Sopenharmony_ci if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) { 698e1051a39Sopenharmony_ci int saltlen = atoi(value); 699e1051a39Sopenharmony_ci 700e1051a39Sopenharmony_ci return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen); 701e1051a39Sopenharmony_ci } 702e1051a39Sopenharmony_ci } 703e1051a39Sopenharmony_ci 704e1051a39Sopenharmony_ci if (strcmp(type, "rsa_oaep_md") == 0) 705e1051a39Sopenharmony_ci return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_CRYPT, 706e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_OAEP_MD, value); 707e1051a39Sopenharmony_ci 708e1051a39Sopenharmony_ci if (strcmp(type, "rsa_oaep_label") == 0) { 709e1051a39Sopenharmony_ci unsigned char *lab; 710e1051a39Sopenharmony_ci long lablen; 711e1051a39Sopenharmony_ci int ret; 712e1051a39Sopenharmony_ci 713e1051a39Sopenharmony_ci lab = OPENSSL_hexstr2buf(value, &lablen); 714e1051a39Sopenharmony_ci if (!lab) 715e1051a39Sopenharmony_ci return 0; 716e1051a39Sopenharmony_ci ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); 717e1051a39Sopenharmony_ci if (ret <= 0) 718e1051a39Sopenharmony_ci OPENSSL_free(lab); 719e1051a39Sopenharmony_ci return ret; 720e1051a39Sopenharmony_ci } 721e1051a39Sopenharmony_ci 722e1051a39Sopenharmony_ci return -2; 723e1051a39Sopenharmony_ci} 724e1051a39Sopenharmony_ci 725e1051a39Sopenharmony_ci/* Set PSS parameters when generating a key, if necessary */ 726e1051a39Sopenharmony_cistatic int rsa_set_pss_param(RSA *rsa, EVP_PKEY_CTX *ctx) 727e1051a39Sopenharmony_ci{ 728e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 729e1051a39Sopenharmony_ci 730e1051a39Sopenharmony_ci if (!pkey_ctx_is_pss(ctx)) 731e1051a39Sopenharmony_ci return 1; 732e1051a39Sopenharmony_ci /* If all parameters are default values don't set pss */ 733e1051a39Sopenharmony_ci if (rctx->md == NULL && rctx->mgf1md == NULL && rctx->saltlen == -2) 734e1051a39Sopenharmony_ci return 1; 735e1051a39Sopenharmony_ci rsa->pss = ossl_rsa_pss_params_create(rctx->md, rctx->mgf1md, 736e1051a39Sopenharmony_ci rctx->saltlen == -2 737e1051a39Sopenharmony_ci ? 0 : rctx->saltlen); 738e1051a39Sopenharmony_ci if (rsa->pss == NULL) 739e1051a39Sopenharmony_ci return 0; 740e1051a39Sopenharmony_ci return 1; 741e1051a39Sopenharmony_ci} 742e1051a39Sopenharmony_ci 743e1051a39Sopenharmony_cistatic int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 744e1051a39Sopenharmony_ci{ 745e1051a39Sopenharmony_ci RSA *rsa = NULL; 746e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 747e1051a39Sopenharmony_ci BN_GENCB *pcb; 748e1051a39Sopenharmony_ci int ret; 749e1051a39Sopenharmony_ci 750e1051a39Sopenharmony_ci if (rctx->pub_exp == NULL) { 751e1051a39Sopenharmony_ci rctx->pub_exp = BN_new(); 752e1051a39Sopenharmony_ci if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4)) 753e1051a39Sopenharmony_ci return 0; 754e1051a39Sopenharmony_ci } 755e1051a39Sopenharmony_ci rsa = RSA_new(); 756e1051a39Sopenharmony_ci if (rsa == NULL) 757e1051a39Sopenharmony_ci return 0; 758e1051a39Sopenharmony_ci if (ctx->pkey_gencb) { 759e1051a39Sopenharmony_ci pcb = BN_GENCB_new(); 760e1051a39Sopenharmony_ci if (pcb == NULL) { 761e1051a39Sopenharmony_ci RSA_free(rsa); 762e1051a39Sopenharmony_ci return 0; 763e1051a39Sopenharmony_ci } 764e1051a39Sopenharmony_ci evp_pkey_set_cb_translate(pcb, ctx); 765e1051a39Sopenharmony_ci } else { 766e1051a39Sopenharmony_ci pcb = NULL; 767e1051a39Sopenharmony_ci } 768e1051a39Sopenharmony_ci ret = RSA_generate_multi_prime_key(rsa, rctx->nbits, rctx->primes, 769e1051a39Sopenharmony_ci rctx->pub_exp, pcb); 770e1051a39Sopenharmony_ci BN_GENCB_free(pcb); 771e1051a39Sopenharmony_ci if (ret > 0 && !rsa_set_pss_param(rsa, ctx)) { 772e1051a39Sopenharmony_ci RSA_free(rsa); 773e1051a39Sopenharmony_ci return 0; 774e1051a39Sopenharmony_ci } 775e1051a39Sopenharmony_ci if (ret > 0) 776e1051a39Sopenharmony_ci EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, rsa); 777e1051a39Sopenharmony_ci else 778e1051a39Sopenharmony_ci RSA_free(rsa); 779e1051a39Sopenharmony_ci return ret; 780e1051a39Sopenharmony_ci} 781e1051a39Sopenharmony_ci 782e1051a39Sopenharmony_cistatic const EVP_PKEY_METHOD rsa_pkey_meth = { 783e1051a39Sopenharmony_ci EVP_PKEY_RSA, 784e1051a39Sopenharmony_ci EVP_PKEY_FLAG_AUTOARGLEN, 785e1051a39Sopenharmony_ci pkey_rsa_init, 786e1051a39Sopenharmony_ci pkey_rsa_copy, 787e1051a39Sopenharmony_ci pkey_rsa_cleanup, 788e1051a39Sopenharmony_ci 789e1051a39Sopenharmony_ci 0, 0, 790e1051a39Sopenharmony_ci 791e1051a39Sopenharmony_ci 0, 792e1051a39Sopenharmony_ci pkey_rsa_keygen, 793e1051a39Sopenharmony_ci 794e1051a39Sopenharmony_ci 0, 795e1051a39Sopenharmony_ci pkey_rsa_sign, 796e1051a39Sopenharmony_ci 797e1051a39Sopenharmony_ci 0, 798e1051a39Sopenharmony_ci pkey_rsa_verify, 799e1051a39Sopenharmony_ci 800e1051a39Sopenharmony_ci 0, 801e1051a39Sopenharmony_ci pkey_rsa_verifyrecover, 802e1051a39Sopenharmony_ci 803e1051a39Sopenharmony_ci 0, 0, 0, 0, 804e1051a39Sopenharmony_ci 805e1051a39Sopenharmony_ci 0, 806e1051a39Sopenharmony_ci pkey_rsa_encrypt, 807e1051a39Sopenharmony_ci 808e1051a39Sopenharmony_ci 0, 809e1051a39Sopenharmony_ci pkey_rsa_decrypt, 810e1051a39Sopenharmony_ci 811e1051a39Sopenharmony_ci 0, 0, 812e1051a39Sopenharmony_ci 813e1051a39Sopenharmony_ci pkey_rsa_ctrl, 814e1051a39Sopenharmony_ci pkey_rsa_ctrl_str 815e1051a39Sopenharmony_ci}; 816e1051a39Sopenharmony_ci 817e1051a39Sopenharmony_ciconst EVP_PKEY_METHOD *ossl_rsa_pkey_method(void) 818e1051a39Sopenharmony_ci{ 819e1051a39Sopenharmony_ci return &rsa_pkey_meth; 820e1051a39Sopenharmony_ci} 821e1051a39Sopenharmony_ci 822e1051a39Sopenharmony_ci/* 823e1051a39Sopenharmony_ci * Called for PSS sign or verify initialisation: checks PSS parameter 824e1051a39Sopenharmony_ci * sanity and sets any restrictions on key usage. 825e1051a39Sopenharmony_ci */ 826e1051a39Sopenharmony_ci 827e1051a39Sopenharmony_cistatic int pkey_pss_init(EVP_PKEY_CTX *ctx) 828e1051a39Sopenharmony_ci{ 829e1051a39Sopenharmony_ci const RSA *rsa; 830e1051a39Sopenharmony_ci RSA_PKEY_CTX *rctx = ctx->data; 831e1051a39Sopenharmony_ci const EVP_MD *md; 832e1051a39Sopenharmony_ci const EVP_MD *mgf1md; 833e1051a39Sopenharmony_ci int min_saltlen, max_saltlen; 834e1051a39Sopenharmony_ci 835e1051a39Sopenharmony_ci /* Should never happen */ 836e1051a39Sopenharmony_ci if (!pkey_ctx_is_pss(ctx)) 837e1051a39Sopenharmony_ci return 0; 838e1051a39Sopenharmony_ci rsa = EVP_PKEY_get0_RSA(ctx->pkey); 839e1051a39Sopenharmony_ci /* If no restrictions just return */ 840e1051a39Sopenharmony_ci if (rsa->pss == NULL) 841e1051a39Sopenharmony_ci return 1; 842e1051a39Sopenharmony_ci /* Get and check parameters */ 843e1051a39Sopenharmony_ci if (!ossl_rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen)) 844e1051a39Sopenharmony_ci return 0; 845e1051a39Sopenharmony_ci 846e1051a39Sopenharmony_ci /* See if minimum salt length exceeds maximum possible */ 847e1051a39Sopenharmony_ci max_saltlen = RSA_size(rsa) - EVP_MD_get_size(md); 848e1051a39Sopenharmony_ci if ((RSA_bits(rsa) & 0x7) == 1) 849e1051a39Sopenharmony_ci max_saltlen--; 850e1051a39Sopenharmony_ci if (min_saltlen > max_saltlen) { 851e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH); 852e1051a39Sopenharmony_ci return 0; 853e1051a39Sopenharmony_ci } 854e1051a39Sopenharmony_ci 855e1051a39Sopenharmony_ci rctx->min_saltlen = min_saltlen; 856e1051a39Sopenharmony_ci 857e1051a39Sopenharmony_ci /* 858e1051a39Sopenharmony_ci * Set PSS restrictions as defaults: we can then block any attempt to 859e1051a39Sopenharmony_ci * use invalid values in pkey_rsa_ctrl 860e1051a39Sopenharmony_ci */ 861e1051a39Sopenharmony_ci 862e1051a39Sopenharmony_ci rctx->md = md; 863e1051a39Sopenharmony_ci rctx->mgf1md = mgf1md; 864e1051a39Sopenharmony_ci rctx->saltlen = min_saltlen; 865e1051a39Sopenharmony_ci 866e1051a39Sopenharmony_ci return 1; 867e1051a39Sopenharmony_ci} 868e1051a39Sopenharmony_ci 869e1051a39Sopenharmony_cistatic const EVP_PKEY_METHOD rsa_pss_pkey_meth = { 870e1051a39Sopenharmony_ci EVP_PKEY_RSA_PSS, 871e1051a39Sopenharmony_ci EVP_PKEY_FLAG_AUTOARGLEN, 872e1051a39Sopenharmony_ci pkey_rsa_init, 873e1051a39Sopenharmony_ci pkey_rsa_copy, 874e1051a39Sopenharmony_ci pkey_rsa_cleanup, 875e1051a39Sopenharmony_ci 876e1051a39Sopenharmony_ci 0, 0, 877e1051a39Sopenharmony_ci 878e1051a39Sopenharmony_ci 0, 879e1051a39Sopenharmony_ci pkey_rsa_keygen, 880e1051a39Sopenharmony_ci 881e1051a39Sopenharmony_ci pkey_pss_init, 882e1051a39Sopenharmony_ci pkey_rsa_sign, 883e1051a39Sopenharmony_ci 884e1051a39Sopenharmony_ci pkey_pss_init, 885e1051a39Sopenharmony_ci pkey_rsa_verify, 886e1051a39Sopenharmony_ci 887e1051a39Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 888e1051a39Sopenharmony_ci 889e1051a39Sopenharmony_ci pkey_rsa_ctrl, 890e1051a39Sopenharmony_ci pkey_rsa_ctrl_str 891e1051a39Sopenharmony_ci}; 892e1051a39Sopenharmony_ci 893e1051a39Sopenharmony_ciconst EVP_PKEY_METHOD *ossl_rsa_pss_pkey_method(void) 894e1051a39Sopenharmony_ci{ 895e1051a39Sopenharmony_ci return &rsa_pss_pkey_meth; 896e1051a39Sopenharmony_ci} 897