1238384Sjkim/* crypto/rsa/rsa_pmeth.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4296341Sdelphij * 2006. 5238384Sjkim */ 6238384Sjkim/* ==================================================================== 7238384Sjkim * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 8238384Sjkim * 9238384Sjkim * Redistribution and use in source and binary forms, with or without 10238384Sjkim * modification, are permitted provided that the following conditions 11238384Sjkim * are met: 12238384Sjkim * 13238384Sjkim * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 15238384Sjkim * 16238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 17238384Sjkim * notice, this list of conditions and the following disclaimer in 18238384Sjkim * the documentation and/or other materials provided with the 19238384Sjkim * distribution. 20238384Sjkim * 21238384Sjkim * 3. All advertising materials mentioning features or use of this 22238384Sjkim * software must display the following acknowledgment: 23238384Sjkim * "This product includes software developed by the OpenSSL Project 24238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25238384Sjkim * 26238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27238384Sjkim * endorse or promote products derived from this software without 28238384Sjkim * prior written permission. For written permission, please contact 29238384Sjkim * licensing@OpenSSL.org. 30238384Sjkim * 31238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 32238384Sjkim * nor may "OpenSSL" appear in their names without prior written 33238384Sjkim * permission of the OpenSSL Project. 34238384Sjkim * 35238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 36238384Sjkim * acknowledgment: 37238384Sjkim * "This product includes software developed by the OpenSSL Project 38238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39238384Sjkim * 40238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 52238384Sjkim * ==================================================================== 53238384Sjkim * 54238384Sjkim * This product includes cryptographic software written by Eric Young 55238384Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 56238384Sjkim * Hudson (tjh@cryptsoft.com). 57238384Sjkim * 58238384Sjkim */ 59238384Sjkim 60238384Sjkim#include <stdio.h> 61238384Sjkim#include "cryptlib.h" 62238384Sjkim#include <openssl/asn1t.h> 63238384Sjkim#include <openssl/x509.h> 64238384Sjkim#include <openssl/rsa.h> 65238384Sjkim#include <openssl/bn.h> 66238384Sjkim#include <openssl/evp.h> 67238384Sjkim#ifndef OPENSSL_NO_CMS 68296341Sdelphij# include <openssl/cms.h> 69238384Sjkim#endif 70238384Sjkim#ifdef OPENSSL_FIPS 71296341Sdelphij# include <openssl/fips.h> 72238384Sjkim#endif 73238384Sjkim#include "evp_locl.h" 74238384Sjkim#include "rsa_locl.h" 75238384Sjkim 76238384Sjkim/* RSA pkey context structure */ 77238384Sjkim 78296341Sdelphijtypedef struct { 79296341Sdelphij /* Key gen parameters */ 80296341Sdelphij int nbits; 81296341Sdelphij BIGNUM *pub_exp; 82296341Sdelphij /* Keygen callback info */ 83296341Sdelphij int gentmp[2]; 84296341Sdelphij /* RSA padding mode */ 85296341Sdelphij int pad_mode; 86296341Sdelphij /* message digest */ 87296341Sdelphij const EVP_MD *md; 88296341Sdelphij /* message digest for MGF1 */ 89296341Sdelphij const EVP_MD *mgf1md; 90296341Sdelphij /* PSS/OAEP salt length */ 91296341Sdelphij int saltlen; 92296341Sdelphij /* Temp buffer */ 93296341Sdelphij unsigned char *tbuf; 94296341Sdelphij} RSA_PKEY_CTX; 95238384Sjkim 96238384Sjkimstatic int pkey_rsa_init(EVP_PKEY_CTX *ctx) 97296341Sdelphij{ 98296341Sdelphij RSA_PKEY_CTX *rctx; 99296341Sdelphij rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); 100296341Sdelphij if (!rctx) 101296341Sdelphij return 0; 102296341Sdelphij rctx->nbits = 1024; 103296341Sdelphij rctx->pub_exp = NULL; 104296341Sdelphij rctx->pad_mode = RSA_PKCS1_PADDING; 105296341Sdelphij rctx->md = NULL; 106296341Sdelphij rctx->mgf1md = NULL; 107296341Sdelphij rctx->tbuf = NULL; 108238384Sjkim 109296341Sdelphij rctx->saltlen = -2; 110238384Sjkim 111296341Sdelphij ctx->data = rctx; 112296341Sdelphij ctx->keygen_info = rctx->gentmp; 113296341Sdelphij ctx->keygen_info_count = 2; 114238384Sjkim 115296341Sdelphij return 1; 116296341Sdelphij} 117296341Sdelphij 118238384Sjkimstatic int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) 119296341Sdelphij{ 120296341Sdelphij RSA_PKEY_CTX *dctx, *sctx; 121296341Sdelphij if (!pkey_rsa_init(dst)) 122296341Sdelphij return 0; 123296341Sdelphij sctx = src->data; 124296341Sdelphij dctx = dst->data; 125296341Sdelphij dctx->nbits = sctx->nbits; 126296341Sdelphij if (sctx->pub_exp) { 127296341Sdelphij dctx->pub_exp = BN_dup(sctx->pub_exp); 128296341Sdelphij if (!dctx->pub_exp) 129296341Sdelphij return 0; 130296341Sdelphij } 131296341Sdelphij dctx->pad_mode = sctx->pad_mode; 132296341Sdelphij dctx->md = sctx->md; 133296341Sdelphij return 1; 134296341Sdelphij} 135238384Sjkim 136238384Sjkimstatic int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) 137296341Sdelphij{ 138296341Sdelphij if (ctx->tbuf) 139296341Sdelphij return 1; 140296341Sdelphij ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); 141296341Sdelphij if (!ctx->tbuf) 142296341Sdelphij return 0; 143296341Sdelphij return 1; 144296341Sdelphij} 145238384Sjkim 146238384Sjkimstatic void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) 147296341Sdelphij{ 148296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 149296341Sdelphij if (rctx) { 150296341Sdelphij if (rctx->pub_exp) 151296341Sdelphij BN_free(rctx->pub_exp); 152296341Sdelphij if (rctx->tbuf) 153296341Sdelphij OPENSSL_free(rctx->tbuf); 154296341Sdelphij OPENSSL_free(rctx); 155296341Sdelphij } 156296341Sdelphij} 157296341Sdelphij 158238384Sjkim#ifdef OPENSSL_FIPS 159296341Sdelphij/* 160296341Sdelphij * FIP checker. Return value indicates status of context parameters: 1 : 161296341Sdelphij * redirect to FIPS. 0 : don't redirect to FIPS. -1 : illegal operation in 162296341Sdelphij * FIPS mode. 163238384Sjkim */ 164238384Sjkim 165238384Sjkimstatic int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx) 166296341Sdelphij{ 167296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 168296341Sdelphij RSA *rsa = ctx->pkey->pkey.rsa; 169296341Sdelphij int rv = -1; 170296341Sdelphij if (!FIPS_mode()) 171296341Sdelphij return 0; 172296341Sdelphij if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) 173296341Sdelphij rv = 0; 174296341Sdelphij if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) 175296341Sdelphij return -1; 176296341Sdelphij if (rctx->md && !(rctx->md->flags & EVP_MD_FLAG_FIPS)) 177296341Sdelphij return rv; 178296341Sdelphij if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) 179296341Sdelphij return rv; 180296341Sdelphij return 1; 181296341Sdelphij} 182238384Sjkim#endif 183238384Sjkim 184296341Sdelphijstatic int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, 185296341Sdelphij size_t *siglen, const unsigned char *tbs, 186296341Sdelphij size_t tbslen) 187296341Sdelphij{ 188296341Sdelphij int ret; 189296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 190296341Sdelphij RSA *rsa = ctx->pkey->pkey.rsa; 191238384Sjkim 192238384Sjkim#ifdef OPENSSL_FIPS 193296341Sdelphij ret = pkey_fips_check_ctx(ctx); 194296341Sdelphij if (ret < 0) { 195296341Sdelphij RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); 196296341Sdelphij return -1; 197296341Sdelphij } 198238384Sjkim#endif 199238384Sjkim 200296341Sdelphij if (rctx->md) { 201296341Sdelphij if (tbslen != (size_t)EVP_MD_size(rctx->md)) { 202296341Sdelphij RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); 203296341Sdelphij return -1; 204296341Sdelphij } 205238384Sjkim#ifdef OPENSSL_FIPS 206296341Sdelphij if (ret > 0) { 207296341Sdelphij unsigned int slen; 208296341Sdelphij ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, 209296341Sdelphij rctx->pad_mode, 210296341Sdelphij rctx->saltlen, 211296341Sdelphij rctx->mgf1md, sig, &slen); 212296341Sdelphij if (ret > 0) 213296341Sdelphij *siglen = slen; 214296341Sdelphij else 215296341Sdelphij *siglen = 0; 216296341Sdelphij return ret; 217296341Sdelphij } 218238384Sjkim#endif 219238384Sjkim 220296341Sdelphij if (EVP_MD_type(rctx->md) == NID_mdc2) { 221296341Sdelphij unsigned int sltmp; 222296341Sdelphij if (rctx->pad_mode != RSA_PKCS1_PADDING) 223296341Sdelphij return -1; 224296341Sdelphij ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, 225296341Sdelphij tbs, tbslen, sig, &sltmp, rsa); 226238384Sjkim 227296341Sdelphij if (ret <= 0) 228296341Sdelphij return ret; 229296341Sdelphij ret = sltmp; 230296341Sdelphij } else if (rctx->pad_mode == RSA_X931_PADDING) { 231296341Sdelphij if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { 232296341Sdelphij RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL); 233296341Sdelphij return -1; 234296341Sdelphij } 235296341Sdelphij if (!setup_tbuf(rctx, ctx)) { 236296341Sdelphij RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE); 237296341Sdelphij return -1; 238296341Sdelphij } 239296341Sdelphij memcpy(rctx->tbuf, tbs, tbslen); 240296341Sdelphij rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); 241296341Sdelphij ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, 242296341Sdelphij sig, rsa, RSA_X931_PADDING); 243296341Sdelphij } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { 244296341Sdelphij unsigned int sltmp; 245296341Sdelphij ret = RSA_sign(EVP_MD_type(rctx->md), 246296341Sdelphij tbs, tbslen, sig, &sltmp, rsa); 247296341Sdelphij if (ret <= 0) 248296341Sdelphij return ret; 249296341Sdelphij ret = sltmp; 250296341Sdelphij } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { 251296341Sdelphij if (!setup_tbuf(rctx, ctx)) 252296341Sdelphij return -1; 253296341Sdelphij if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, 254296341Sdelphij rctx->tbuf, tbs, 255296341Sdelphij rctx->md, rctx->mgf1md, 256296341Sdelphij rctx->saltlen)) 257296341Sdelphij return -1; 258296341Sdelphij ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, 259296341Sdelphij sig, rsa, RSA_NO_PADDING); 260296341Sdelphij } else 261296341Sdelphij return -1; 262296341Sdelphij } else 263296341Sdelphij ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, 264296341Sdelphij rctx->pad_mode); 265296341Sdelphij if (ret < 0) 266296341Sdelphij return ret; 267296341Sdelphij *siglen = ret; 268296341Sdelphij return 1; 269296341Sdelphij} 270238384Sjkim 271238384Sjkimstatic int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, 272296341Sdelphij unsigned char *rout, size_t *routlen, 273296341Sdelphij const unsigned char *sig, size_t siglen) 274296341Sdelphij{ 275296341Sdelphij int ret; 276296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 277238384Sjkim 278296341Sdelphij if (rctx->md) { 279296341Sdelphij if (rctx->pad_mode == RSA_X931_PADDING) { 280296341Sdelphij if (!setup_tbuf(rctx, ctx)) 281296341Sdelphij return -1; 282296341Sdelphij ret = RSA_public_decrypt(siglen, sig, 283296341Sdelphij rctx->tbuf, ctx->pkey->pkey.rsa, 284296341Sdelphij RSA_X931_PADDING); 285296341Sdelphij if (ret < 1) 286296341Sdelphij return 0; 287296341Sdelphij ret--; 288296341Sdelphij if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_type(rctx->md))) { 289296341Sdelphij RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, 290296341Sdelphij RSA_R_ALGORITHM_MISMATCH); 291296341Sdelphij return 0; 292296341Sdelphij } 293296341Sdelphij if (ret != EVP_MD_size(rctx->md)) { 294296341Sdelphij RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, 295296341Sdelphij RSA_R_INVALID_DIGEST_LENGTH); 296296341Sdelphij return 0; 297296341Sdelphij } 298296341Sdelphij if (rout) 299296341Sdelphij memcpy(rout, rctx->tbuf, ret); 300296341Sdelphij } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { 301296341Sdelphij size_t sltmp; 302296341Sdelphij ret = int_rsa_verify(EVP_MD_type(rctx->md), 303296341Sdelphij NULL, 0, rout, &sltmp, 304296341Sdelphij sig, siglen, ctx->pkey->pkey.rsa); 305296341Sdelphij if (ret <= 0) 306296341Sdelphij return 0; 307296341Sdelphij ret = sltmp; 308296341Sdelphij } else 309296341Sdelphij return -1; 310296341Sdelphij } else 311296341Sdelphij ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, 312296341Sdelphij rctx->pad_mode); 313296341Sdelphij if (ret < 0) 314296341Sdelphij return ret; 315296341Sdelphij *routlen = ret; 316296341Sdelphij return 1; 317296341Sdelphij} 318238384Sjkim 319238384Sjkimstatic int pkey_rsa_verify(EVP_PKEY_CTX *ctx, 320296341Sdelphij const unsigned char *sig, size_t siglen, 321296341Sdelphij const unsigned char *tbs, size_t tbslen) 322296341Sdelphij{ 323296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 324296341Sdelphij RSA *rsa = ctx->pkey->pkey.rsa; 325296341Sdelphij size_t rslen; 326238384Sjkim#ifdef OPENSSL_FIPS 327296341Sdelphij int rv; 328296341Sdelphij rv = pkey_fips_check_ctx(ctx); 329296341Sdelphij if (rv < 0) { 330296341Sdelphij RSAerr(RSA_F_PKEY_RSA_VERIFY, 331296341Sdelphij RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); 332296341Sdelphij return -1; 333296341Sdelphij } 334238384Sjkim#endif 335296341Sdelphij if (rctx->md) { 336238384Sjkim#ifdef OPENSSL_FIPS 337296341Sdelphij if (rv > 0) { 338296341Sdelphij return FIPS_rsa_verify_digest(rsa, 339296341Sdelphij tbs, tbslen, 340296341Sdelphij rctx->md, 341296341Sdelphij rctx->pad_mode, 342296341Sdelphij rctx->saltlen, 343296341Sdelphij rctx->mgf1md, sig, siglen); 344296341Sdelphij 345296341Sdelphij } 346238384Sjkim#endif 347296341Sdelphij if (rctx->pad_mode == RSA_PKCS1_PADDING) 348296341Sdelphij return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, 349296341Sdelphij sig, siglen, rsa); 350296341Sdelphij if (rctx->pad_mode == RSA_X931_PADDING) { 351296341Sdelphij if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0) 352296341Sdelphij return 0; 353296341Sdelphij } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { 354296341Sdelphij int ret; 355296341Sdelphij if (!setup_tbuf(rctx, ctx)) 356296341Sdelphij return -1; 357296341Sdelphij ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, 358296341Sdelphij rsa, RSA_NO_PADDING); 359296341Sdelphij if (ret <= 0) 360296341Sdelphij return 0; 361296341Sdelphij ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, 362296341Sdelphij rctx->md, rctx->mgf1md, 363296341Sdelphij rctx->tbuf, rctx->saltlen); 364296341Sdelphij if (ret <= 0) 365296341Sdelphij return 0; 366296341Sdelphij return 1; 367296341Sdelphij } else 368296341Sdelphij return -1; 369296341Sdelphij } else { 370296341Sdelphij if (!setup_tbuf(rctx, ctx)) 371296341Sdelphij return -1; 372296341Sdelphij rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, 373296341Sdelphij rsa, rctx->pad_mode); 374296341Sdelphij if (rslen == 0) 375296341Sdelphij return 0; 376296341Sdelphij } 377238384Sjkim 378296341Sdelphij if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) 379296341Sdelphij return 0; 380238384Sjkim 381296341Sdelphij return 1; 382238384Sjkim 383296341Sdelphij} 384296341Sdelphij 385238384Sjkimstatic int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, 386296341Sdelphij unsigned char *out, size_t *outlen, 387296341Sdelphij const unsigned char *in, size_t inlen) 388296341Sdelphij{ 389296341Sdelphij int ret; 390296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 391296341Sdelphij ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, 392296341Sdelphij rctx->pad_mode); 393296341Sdelphij if (ret < 0) 394296341Sdelphij return ret; 395296341Sdelphij *outlen = ret; 396296341Sdelphij return 1; 397296341Sdelphij} 398238384Sjkim 399238384Sjkimstatic int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, 400296341Sdelphij unsigned char *out, size_t *outlen, 401296341Sdelphij const unsigned char *in, size_t inlen) 402296341Sdelphij{ 403296341Sdelphij int ret; 404296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 405296341Sdelphij ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, 406296341Sdelphij rctx->pad_mode); 407296341Sdelphij if (ret < 0) 408296341Sdelphij return ret; 409296341Sdelphij *outlen = ret; 410296341Sdelphij return 1; 411296341Sdelphij} 412238384Sjkim 413238384Sjkimstatic int check_padding_md(const EVP_MD *md, int padding) 414296341Sdelphij{ 415296341Sdelphij if (!md) 416296341Sdelphij return 1; 417238384Sjkim 418296341Sdelphij if (padding == RSA_NO_PADDING) { 419296341Sdelphij RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); 420296341Sdelphij return 0; 421296341Sdelphij } 422238384Sjkim 423296341Sdelphij if (padding == RSA_X931_PADDING) { 424296341Sdelphij if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) { 425296341Sdelphij RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); 426296341Sdelphij return 0; 427296341Sdelphij } 428296341Sdelphij return 1; 429296341Sdelphij } 430238384Sjkim 431296341Sdelphij return 1; 432296341Sdelphij} 433238384Sjkim 434238384Sjkimstatic int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 435296341Sdelphij{ 436296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 437296341Sdelphij switch (type) { 438296341Sdelphij case EVP_PKEY_CTRL_RSA_PADDING: 439296341Sdelphij if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { 440296341Sdelphij if (!check_padding_md(rctx->md, p1)) 441296341Sdelphij return 0; 442296341Sdelphij if (p1 == RSA_PKCS1_PSS_PADDING) { 443296341Sdelphij if (!(ctx->operation & 444296341Sdelphij (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) 445296341Sdelphij goto bad_pad; 446296341Sdelphij if (!rctx->md) 447296341Sdelphij rctx->md = EVP_sha1(); 448296341Sdelphij } 449296341Sdelphij if (p1 == RSA_PKCS1_OAEP_PADDING) { 450296341Sdelphij if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) 451296341Sdelphij goto bad_pad; 452296341Sdelphij if (!rctx->md) 453296341Sdelphij rctx->md = EVP_sha1(); 454296341Sdelphij } 455296341Sdelphij rctx->pad_mode = p1; 456296341Sdelphij return 1; 457296341Sdelphij } 458296341Sdelphij bad_pad: 459296341Sdelphij RSAerr(RSA_F_PKEY_RSA_CTRL, 460296341Sdelphij RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); 461296341Sdelphij return -2; 462238384Sjkim 463296341Sdelphij case EVP_PKEY_CTRL_GET_RSA_PADDING: 464296341Sdelphij *(int *)p2 = rctx->pad_mode; 465296341Sdelphij return 1; 466238384Sjkim 467296341Sdelphij case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: 468296341Sdelphij case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: 469296341Sdelphij if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { 470296341Sdelphij RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); 471296341Sdelphij return -2; 472296341Sdelphij } 473296341Sdelphij if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) 474296341Sdelphij *(int *)p2 = rctx->saltlen; 475296341Sdelphij else { 476296341Sdelphij if (p1 < -2) 477296341Sdelphij return -2; 478296341Sdelphij rctx->saltlen = p1; 479296341Sdelphij } 480296341Sdelphij return 1; 481238384Sjkim 482296341Sdelphij case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: 483296341Sdelphij if (p1 < 256) { 484296341Sdelphij RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); 485296341Sdelphij return -2; 486296341Sdelphij } 487296341Sdelphij rctx->nbits = p1; 488296341Sdelphij return 1; 489238384Sjkim 490296341Sdelphij case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: 491296341Sdelphij if (!p2) 492296341Sdelphij return -2; 493296341Sdelphij rctx->pub_exp = p2; 494296341Sdelphij return 1; 495238384Sjkim 496296341Sdelphij case EVP_PKEY_CTRL_MD: 497296341Sdelphij if (!check_padding_md(p2, rctx->pad_mode)) 498296341Sdelphij return 0; 499296341Sdelphij rctx->md = p2; 500296341Sdelphij return 1; 501238384Sjkim 502296341Sdelphij case EVP_PKEY_CTRL_RSA_MGF1_MD: 503296341Sdelphij case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: 504296341Sdelphij if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { 505296341Sdelphij RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); 506296341Sdelphij return -2; 507296341Sdelphij } 508296341Sdelphij if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { 509296341Sdelphij if (rctx->mgf1md) 510296341Sdelphij *(const EVP_MD **)p2 = rctx->mgf1md; 511296341Sdelphij else 512296341Sdelphij *(const EVP_MD **)p2 = rctx->md; 513296341Sdelphij } else 514296341Sdelphij rctx->mgf1md = p2; 515296341Sdelphij return 1; 516238384Sjkim 517296341Sdelphij case EVP_PKEY_CTRL_DIGESTINIT: 518296341Sdelphij case EVP_PKEY_CTRL_PKCS7_ENCRYPT: 519296341Sdelphij case EVP_PKEY_CTRL_PKCS7_DECRYPT: 520296341Sdelphij case EVP_PKEY_CTRL_PKCS7_SIGN: 521296341Sdelphij return 1; 522238384Sjkim#ifndef OPENSSL_NO_CMS 523296341Sdelphij case EVP_PKEY_CTRL_CMS_DECRYPT: 524296341Sdelphij { 525296341Sdelphij X509_ALGOR *alg = NULL; 526296341Sdelphij ASN1_OBJECT *encalg = NULL; 527296341Sdelphij if (p2) 528296341Sdelphij CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg); 529296341Sdelphij if (alg) 530296341Sdelphij X509_ALGOR_get0(&encalg, NULL, NULL, alg); 531296341Sdelphij if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep) 532296341Sdelphij rctx->pad_mode = RSA_PKCS1_OAEP_PADDING; 533296341Sdelphij } 534296341Sdelphij case EVP_PKEY_CTRL_CMS_ENCRYPT: 535296341Sdelphij case EVP_PKEY_CTRL_CMS_SIGN: 536296341Sdelphij return 1; 537238384Sjkim#endif 538296341Sdelphij case EVP_PKEY_CTRL_PEER_KEY: 539296341Sdelphij RSAerr(RSA_F_PKEY_RSA_CTRL, 540296341Sdelphij RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 541296341Sdelphij return -2; 542238384Sjkim 543296341Sdelphij default: 544296341Sdelphij return -2; 545238384Sjkim 546296341Sdelphij } 547296341Sdelphij} 548296341Sdelphij 549238384Sjkimstatic int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, 550296341Sdelphij const char *type, const char *value) 551296341Sdelphij{ 552296341Sdelphij if (!value) { 553296341Sdelphij RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); 554296341Sdelphij return 0; 555296341Sdelphij } 556296341Sdelphij if (!strcmp(type, "rsa_padding_mode")) { 557296341Sdelphij int pm; 558296341Sdelphij if (!strcmp(value, "pkcs1")) 559296341Sdelphij pm = RSA_PKCS1_PADDING; 560296341Sdelphij else if (!strcmp(value, "sslv23")) 561296341Sdelphij pm = RSA_SSLV23_PADDING; 562296341Sdelphij else if (!strcmp(value, "none")) 563296341Sdelphij pm = RSA_NO_PADDING; 564296341Sdelphij else if (!strcmp(value, "oeap")) 565296341Sdelphij pm = RSA_PKCS1_OAEP_PADDING; 566296341Sdelphij else if (!strcmp(value, "oaep")) 567296341Sdelphij pm = RSA_PKCS1_OAEP_PADDING; 568296341Sdelphij else if (!strcmp(value, "x931")) 569296341Sdelphij pm = RSA_X931_PADDING; 570296341Sdelphij else if (!strcmp(value, "pss")) 571296341Sdelphij pm = RSA_PKCS1_PSS_PADDING; 572296341Sdelphij else { 573296341Sdelphij RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); 574296341Sdelphij return -2; 575296341Sdelphij } 576296341Sdelphij return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); 577296341Sdelphij } 578238384Sjkim 579296341Sdelphij if (!strcmp(type, "rsa_pss_saltlen")) { 580296341Sdelphij int saltlen; 581296341Sdelphij saltlen = atoi(value); 582296341Sdelphij return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); 583296341Sdelphij } 584238384Sjkim 585296341Sdelphij if (!strcmp(type, "rsa_keygen_bits")) { 586296341Sdelphij int nbits; 587296341Sdelphij nbits = atoi(value); 588296341Sdelphij return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); 589296341Sdelphij } 590238384Sjkim 591296341Sdelphij if (!strcmp(type, "rsa_keygen_pubexp")) { 592296341Sdelphij int ret; 593296341Sdelphij BIGNUM *pubexp = NULL; 594296341Sdelphij if (!BN_asc2bn(&pubexp, value)) 595296341Sdelphij return 0; 596296341Sdelphij ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); 597296341Sdelphij if (ret <= 0) 598296341Sdelphij BN_free(pubexp); 599296341Sdelphij return ret; 600296341Sdelphij } 601238384Sjkim 602296341Sdelphij return -2; 603296341Sdelphij} 604238384Sjkim 605238384Sjkimstatic int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 606296341Sdelphij{ 607296341Sdelphij RSA *rsa = NULL; 608296341Sdelphij RSA_PKEY_CTX *rctx = ctx->data; 609296341Sdelphij BN_GENCB *pcb, cb; 610296341Sdelphij int ret; 611296341Sdelphij if (!rctx->pub_exp) { 612296341Sdelphij rctx->pub_exp = BN_new(); 613296341Sdelphij if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) 614296341Sdelphij return 0; 615296341Sdelphij } 616296341Sdelphij rsa = RSA_new(); 617296341Sdelphij if (!rsa) 618296341Sdelphij return 0; 619296341Sdelphij if (ctx->pkey_gencb) { 620296341Sdelphij pcb = &cb; 621296341Sdelphij evp_pkey_set_cb_translate(pcb, ctx); 622296341Sdelphij } else 623296341Sdelphij pcb = NULL; 624296341Sdelphij ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); 625296341Sdelphij if (ret > 0) 626296341Sdelphij EVP_PKEY_assign_RSA(pkey, rsa); 627296341Sdelphij else 628296341Sdelphij RSA_free(rsa); 629296341Sdelphij return ret; 630296341Sdelphij} 631238384Sjkim 632296341Sdelphijconst EVP_PKEY_METHOD rsa_pkey_meth = { 633296341Sdelphij EVP_PKEY_RSA, 634296341Sdelphij EVP_PKEY_FLAG_AUTOARGLEN, 635296341Sdelphij pkey_rsa_init, 636296341Sdelphij pkey_rsa_copy, 637296341Sdelphij pkey_rsa_cleanup, 638238384Sjkim 639296341Sdelphij 0, 0, 640238384Sjkim 641296341Sdelphij 0, 642296341Sdelphij pkey_rsa_keygen, 643238384Sjkim 644296341Sdelphij 0, 645296341Sdelphij pkey_rsa_sign, 646238384Sjkim 647296341Sdelphij 0, 648296341Sdelphij pkey_rsa_verify, 649238384Sjkim 650296341Sdelphij 0, 651296341Sdelphij pkey_rsa_verifyrecover, 652238384Sjkim 653296341Sdelphij 0, 0, 0, 0, 654238384Sjkim 655296341Sdelphij 0, 656296341Sdelphij pkey_rsa_encrypt, 657238384Sjkim 658296341Sdelphij 0, 659296341Sdelphij pkey_rsa_decrypt, 660238384Sjkim 661296341Sdelphij 0, 0, 662238384Sjkim 663296341Sdelphij pkey_rsa_ctrl, 664296341Sdelphij pkey_rsa_ctrl_str 665296341Sdelphij}; 666