1*457dff42Stb /* $OpenBSD: rsa_pmeth.c,v 1.43 2025/01/17 15:39:19 tb Exp $ */ 2f1535dc8Sdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3f1535dc8Sdjm * project 2006. 4f1535dc8Sdjm */ 5f1535dc8Sdjm /* ==================================================================== 6f1535dc8Sdjm * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7f1535dc8Sdjm * 8f1535dc8Sdjm * Redistribution and use in source and binary forms, with or without 9f1535dc8Sdjm * modification, are permitted provided that the following conditions 10f1535dc8Sdjm * are met: 11f1535dc8Sdjm * 12f1535dc8Sdjm * 1. Redistributions of source code must retain the above copyright 13f1535dc8Sdjm * notice, this list of conditions and the following disclaimer. 14f1535dc8Sdjm * 15f1535dc8Sdjm * 2. Redistributions in binary form must reproduce the above copyright 16f1535dc8Sdjm * notice, this list of conditions and the following disclaimer in 17f1535dc8Sdjm * the documentation and/or other materials provided with the 18f1535dc8Sdjm * distribution. 19f1535dc8Sdjm * 20f1535dc8Sdjm * 3. All advertising materials mentioning features or use of this 21f1535dc8Sdjm * software must display the following acknowledgment: 22f1535dc8Sdjm * "This product includes software developed by the OpenSSL Project 23f1535dc8Sdjm * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24f1535dc8Sdjm * 25f1535dc8Sdjm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26f1535dc8Sdjm * endorse or promote products derived from this software without 27f1535dc8Sdjm * prior written permission. For written permission, please contact 28f1535dc8Sdjm * licensing@OpenSSL.org. 29f1535dc8Sdjm * 30f1535dc8Sdjm * 5. Products derived from this software may not be called "OpenSSL" 31f1535dc8Sdjm * nor may "OpenSSL" appear in their names without prior written 32f1535dc8Sdjm * permission of the OpenSSL Project. 33f1535dc8Sdjm * 34f1535dc8Sdjm * 6. Redistributions of any form whatsoever must retain the following 35f1535dc8Sdjm * acknowledgment: 36f1535dc8Sdjm * "This product includes software developed by the OpenSSL Project 37f1535dc8Sdjm * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38f1535dc8Sdjm * 39f1535dc8Sdjm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40f1535dc8Sdjm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41f1535dc8Sdjm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42f1535dc8Sdjm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43f1535dc8Sdjm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44f1535dc8Sdjm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45f1535dc8Sdjm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46f1535dc8Sdjm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47f1535dc8Sdjm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48f1535dc8Sdjm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49f1535dc8Sdjm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50f1535dc8Sdjm * OF THE POSSIBILITY OF SUCH DAMAGE. 51f1535dc8Sdjm * ==================================================================== 52f1535dc8Sdjm * 53f1535dc8Sdjm * This product includes cryptographic software written by Eric Young 54f1535dc8Sdjm * (eay@cryptsoft.com). This product includes software written by Tim 55f1535dc8Sdjm * Hudson (tjh@cryptsoft.com). 56f1535dc8Sdjm * 57f1535dc8Sdjm */ 58f1535dc8Sdjm 59b1d57841Sderaadt #include <limits.h> 60a8913c44Sjsing #include <stdio.h> 6140e63673Sop #include <stdlib.h> 62a8913c44Sjsing #include <string.h> 63a8913c44Sjsing 648cf4d6a6Sjsing #include <openssl/opensslconf.h> 658cf4d6a6Sjsing 66f1535dc8Sdjm #include <openssl/asn1t.h> 67f1535dc8Sdjm #include <openssl/bn.h> 68b6ab114eSjsing #include <openssl/err.h> 69f1535dc8Sdjm #include <openssl/evp.h> 70b6ab114eSjsing #include <openssl/rsa.h> 71b6ab114eSjsing #include <openssl/x509.h> 7295285806Sjsing #include <openssl/x509v3.h> 73b6ab114eSjsing 74c9675a23Stb #include "bn_local.h" 75c9675a23Stb #include "evp_local.h" 76c9675a23Stb #include "rsa_local.h" 77f1535dc8Sdjm 78f1535dc8Sdjm /* RSA pkey context structure */ 79f1535dc8Sdjm 8087203b09Smiod typedef struct { 81f1535dc8Sdjm /* Key gen parameters */ 82f1535dc8Sdjm int nbits; 83f1535dc8Sdjm BIGNUM *pub_exp; 84f1535dc8Sdjm /* Keygen callback info */ 85f1535dc8Sdjm int gentmp[2]; 86f1535dc8Sdjm /* RSA padding mode */ 87f1535dc8Sdjm int pad_mode; 88f1535dc8Sdjm /* message digest */ 89f1535dc8Sdjm const EVP_MD *md; 90ec07fdf1Sdjm /* message digest for MGF1 */ 91ec07fdf1Sdjm const EVP_MD *mgf1md; 9295285806Sjsing /* PSS salt length */ 93f1535dc8Sdjm int saltlen; 94ba05ae2dSjsing /* Minimum salt length or -1 if no PSS parameter restriction */ 95ba05ae2dSjsing int min_saltlen; 96f1535dc8Sdjm /* Temp buffer */ 97f1535dc8Sdjm unsigned char *tbuf; 9895285806Sjsing /* OAEP label */ 9995285806Sjsing unsigned char *oaep_label; 10095285806Sjsing size_t oaep_labellen; 101f1535dc8Sdjm } RSA_PKEY_CTX; 102f1535dc8Sdjm 103ba05ae2dSjsing /* True if PSS parameters are restricted */ 104ba05ae2dSjsing #define rsa_pss_restricted(rctx) (rctx->min_saltlen != -1) 105ba05ae2dSjsing 10687203b09Smiod static int 10787203b09Smiod pkey_rsa_init(EVP_PKEY_CTX *ctx) 108f1535dc8Sdjm { 109f1535dc8Sdjm RSA_PKEY_CTX *rctx; 11087203b09Smiod 11195285806Sjsing if ((rctx = calloc(1, sizeof(RSA_PKEY_CTX))) == NULL) 112f1535dc8Sdjm return 0; 11395285806Sjsing 1144794023eSsthen rctx->nbits = 2048; 115ba05ae2dSjsing 116ba05ae2dSjsing if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) 117ba05ae2dSjsing rctx->pad_mode = RSA_PKCS1_PSS_PADDING; 118ba05ae2dSjsing else 119f1535dc8Sdjm rctx->pad_mode = RSA_PKCS1_PADDING; 120f1535dc8Sdjm 121ba05ae2dSjsing /* Maximum for sign, auto for verify */ 122ba05ae2dSjsing rctx->saltlen = RSA_PSS_SALTLEN_AUTO; 123ba05ae2dSjsing rctx->min_saltlen = -1; 124f1535dc8Sdjm 125f1535dc8Sdjm ctx->data = rctx; 126f1535dc8Sdjm ctx->keygen_info = rctx->gentmp; 127f1535dc8Sdjm ctx->keygen_info_count = 2; 128f1535dc8Sdjm 129f1535dc8Sdjm return 1; 130f1535dc8Sdjm } 131f1535dc8Sdjm 13287203b09Smiod static int 13387203b09Smiod pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) 134f1535dc8Sdjm { 135f1535dc8Sdjm RSA_PKEY_CTX *dctx, *sctx; 13687203b09Smiod 137f1535dc8Sdjm if (!pkey_rsa_init(dst)) 138f1535dc8Sdjm return 0; 13995285806Sjsing 140f1535dc8Sdjm sctx = src->data; 141f1535dc8Sdjm dctx = dst->data; 142f1535dc8Sdjm dctx->nbits = sctx->nbits; 143b8d43259Sjsing if (sctx->pub_exp != NULL) { 144b8d43259Sjsing BN_free(dctx->pub_exp); 145b8d43259Sjsing if ((dctx->pub_exp = BN_dup(sctx->pub_exp)) == NULL) 146f1535dc8Sdjm return 0; 147f1535dc8Sdjm } 148f1535dc8Sdjm dctx->pad_mode = sctx->pad_mode; 149f1535dc8Sdjm dctx->md = sctx->md; 15095285806Sjsing dctx->mgf1md = sctx->mgf1md; 15195285806Sjsing if (sctx->oaep_label != NULL) { 15295285806Sjsing free(dctx->oaep_label); 15395285806Sjsing if ((dctx->oaep_label = calloc(1, sctx->oaep_labellen)) == NULL) 15495285806Sjsing return 0; 15595285806Sjsing memcpy(dctx->oaep_label, sctx->oaep_label, sctx->oaep_labellen); 15695285806Sjsing dctx->oaep_labellen = sctx->oaep_labellen; 15795285806Sjsing } 15895285806Sjsing 159f1535dc8Sdjm return 1; 160f1535dc8Sdjm } 161f1535dc8Sdjm 16287203b09Smiod static int 16387203b09Smiod setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) 164f1535dc8Sdjm { 1655bc73cc3Sjsing if (ctx->tbuf != NULL) 166f1535dc8Sdjm return 1; 1675bc73cc3Sjsing if ((ctx->tbuf = calloc(1, EVP_PKEY_size(pk->pkey))) == NULL) { 1685bc73cc3Sjsing RSAerror(ERR_R_MALLOC_FAILURE); 169f1535dc8Sdjm return 0; 1705bc73cc3Sjsing } 171f1535dc8Sdjm return 1; 172f1535dc8Sdjm } 173f1535dc8Sdjm 17487203b09Smiod static void 17587203b09Smiod pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) 176f1535dc8Sdjm { 177f1535dc8Sdjm RSA_PKEY_CTX *rctx = ctx->data; 17887203b09Smiod 17987203b09Smiod if (rctx) { 180f1535dc8Sdjm BN_free(rctx->pub_exp); 1816f3a6cb1Sbeck free(rctx->tbuf); 18295285806Sjsing free(rctx->oaep_label); 1836f3a6cb1Sbeck free(rctx); 184f1535dc8Sdjm } 185f1535dc8Sdjm } 18687203b09Smiod 18787203b09Smiod static int 18887203b09Smiod pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, 189f1535dc8Sdjm const unsigned char *tbs, size_t tbslen) 190f1535dc8Sdjm { 1914349b8b3Stb int ret; 192f1535dc8Sdjm RSA_PKEY_CTX *rctx = ctx->data; 193f1535dc8Sdjm RSA *rsa = ctx->pkey->pkey.rsa; 194f1535dc8Sdjm 19587203b09Smiod if (rctx->md) { 19687203b09Smiod if (tbslen != (size_t)EVP_MD_size(rctx->md)) { 1975067ae9fSbeck RSAerror(RSA_R_INVALID_DIGEST_LENGTH); 198f1535dc8Sdjm return -1; 199f1535dc8Sdjm } 200ec07fdf1Sdjm 2014349b8b3Stb if (rctx->pad_mode == RSA_X931_PADDING) { 2024349b8b3Stb if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { 2034349b8b3Stb RSAerror(RSA_R_KEY_SIZE_TOO_SMALL); 204f1535dc8Sdjm return -1; 2054349b8b3Stb } 2064349b8b3Stb if (!setup_tbuf(rctx, ctx)) { 2074349b8b3Stb RSAerror(ERR_R_MALLOC_FAILURE); 2084349b8b3Stb return -1; 2094349b8b3Stb } 2104349b8b3Stb memcpy(rctx->tbuf, tbs, tbslen); 2114349b8b3Stb rctx->tbuf[tbslen] = 2124349b8b3Stb RSA_X931_hash_id(EVP_MD_type(rctx->md)); 2134349b8b3Stb ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, 2144349b8b3Stb rsa, RSA_X931_PADDING); 2154349b8b3Stb } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { 216f1535dc8Sdjm unsigned int sltmp; 21787203b09Smiod 21887203b09Smiod ret = RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, 21987203b09Smiod &sltmp, rsa); 220f1535dc8Sdjm if (ret <= 0) 221f1535dc8Sdjm return ret; 222f1535dc8Sdjm ret = sltmp; 22387203b09Smiod } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { 224f1535dc8Sdjm if (!setup_tbuf(rctx, ctx)) 225f1535dc8Sdjm return -1; 22687203b09Smiod if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, 22787203b09Smiod tbs, rctx->md, rctx->mgf1md, rctx->saltlen)) 228f1535dc8Sdjm return -1; 229f1535dc8Sdjm ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, 230f1535dc8Sdjm sig, rsa, RSA_NO_PADDING); 2314349b8b3Stb } else { 2324349b8b3Stb return -1; 2330a0c1944Sjsing } 2340a0c1944Sjsing } else { 235f1535dc8Sdjm ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, 236f1535dc8Sdjm rctx->pad_mode); 2370a0c1944Sjsing } 238f1535dc8Sdjm if (ret < 0) 239f1535dc8Sdjm return ret; 240f1535dc8Sdjm *siglen = ret; 241f1535dc8Sdjm return 1; 242f1535dc8Sdjm } 243f1535dc8Sdjm 24487203b09Smiod static int 24587203b09Smiod pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen, 246f1535dc8Sdjm const unsigned char *sig, size_t siglen) 247f1535dc8Sdjm { 248f1535dc8Sdjm int ret; 249f1535dc8Sdjm RSA_PKEY_CTX *rctx = ctx->data; 250f1535dc8Sdjm 25187203b09Smiod if (rctx->md) { 2524349b8b3Stb if (rctx->pad_mode == RSA_X931_PADDING) { 2534349b8b3Stb if (!setup_tbuf(rctx, ctx)) 254e0681702Stb return -1; 2554349b8b3Stb ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, 2564349b8b3Stb ctx->pkey->pkey.rsa, RSA_X931_PADDING); 2574349b8b3Stb if (ret < 1) 2584349b8b3Stb return 0; 2594349b8b3Stb ret--; 2604349b8b3Stb if (rctx->tbuf[ret] != 2614349b8b3Stb RSA_X931_hash_id(EVP_MD_type(rctx->md))) { 2624349b8b3Stb RSAerror(RSA_R_ALGORITHM_MISMATCH); 2634349b8b3Stb return 0; 2644349b8b3Stb } 2654349b8b3Stb if (ret != EVP_MD_size(rctx->md)) { 2664349b8b3Stb RSAerror(RSA_R_INVALID_DIGEST_LENGTH); 2674349b8b3Stb return 0; 2684349b8b3Stb } 2694349b8b3Stb if (rout) 2704349b8b3Stb memcpy(rout, rctx->tbuf, ret); 2714349b8b3Stb } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { 2724349b8b3Stb size_t sltmp; 273e0681702Stb 27487203b09Smiod ret = int_rsa_verify(EVP_MD_type(rctx->md), NULL, 0, 27587203b09Smiod rout, &sltmp, sig, siglen, ctx->pkey->pkey.rsa); 276f1535dc8Sdjm if (ret <= 0) 277f1535dc8Sdjm return 0; 278f1535dc8Sdjm ret = sltmp; 2790a0c1944Sjsing } else { 2804349b8b3Stb return -1; 2814349b8b3Stb } 2824349b8b3Stb } else { 283f1535dc8Sdjm ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, 284f1535dc8Sdjm rctx->pad_mode); 2850a0c1944Sjsing } 286f1535dc8Sdjm if (ret < 0) 287f1535dc8Sdjm return ret; 288f1535dc8Sdjm *routlen = ret; 289f1535dc8Sdjm return 1; 290f1535dc8Sdjm } 291f1535dc8Sdjm 29287203b09Smiod static int 29387203b09Smiod pkey_rsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, 294f1535dc8Sdjm const unsigned char *tbs, size_t tbslen) 295f1535dc8Sdjm { 296f1535dc8Sdjm RSA_PKEY_CTX *rctx = ctx->data; 297f1535dc8Sdjm RSA *rsa = ctx->pkey->pkey.rsa; 298f1535dc8Sdjm size_t rslen; 29987203b09Smiod 30087203b09Smiod if (rctx->md) { 301f1535dc8Sdjm if (rctx->pad_mode == RSA_PKCS1_PADDING) 302f1535dc8Sdjm return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, 303f1535dc8Sdjm sig, siglen, rsa); 3046fbfd349Sjsing if (tbslen != (size_t)EVP_MD_size(rctx->md)) { 3056fbfd349Sjsing RSAerror(RSA_R_INVALID_DIGEST_LENGTH); 3066fbfd349Sjsing return -1; 3076fbfd349Sjsing } 3084349b8b3Stb if (rctx->pad_mode == RSA_X931_PADDING) { 3094349b8b3Stb if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, 3104349b8b3Stb siglen) <= 0) 3114349b8b3Stb return 0; 3124349b8b3Stb } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { 3134349b8b3Stb int ret; 31487203b09Smiod 315f1535dc8Sdjm if (!setup_tbuf(rctx, ctx)) 316f1535dc8Sdjm return -1; 317f1535dc8Sdjm ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, 318f1535dc8Sdjm rsa, RSA_NO_PADDING); 319f1535dc8Sdjm if (ret <= 0) 320f1535dc8Sdjm return 0; 32187203b09Smiod ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, rctx->md, 32287203b09Smiod rctx->mgf1md, rctx->tbuf, rctx->saltlen); 323f1535dc8Sdjm if (ret <= 0) 324f1535dc8Sdjm return 0; 325f1535dc8Sdjm return 1; 3260a0c1944Sjsing } else { 3274349b8b3Stb return -1; 3284349b8b3Stb } 3294349b8b3Stb } else { 3304349b8b3Stb int ret; 3314349b8b3Stb 332f1535dc8Sdjm if (!setup_tbuf(rctx, ctx)) 333f1535dc8Sdjm return -1; 334e8c28445Stb 335e8c28445Stb if ((ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, rsa, 336e8c28445Stb rctx->pad_mode)) <= 0) 337f1535dc8Sdjm return 0; 338e8c28445Stb 339e8c28445Stb rslen = ret; 340f1535dc8Sdjm } 341f1535dc8Sdjm 3422f115aa8Sdjm if (rslen != tbslen || timingsafe_bcmp(tbs, rctx->tbuf, rslen)) 343f1535dc8Sdjm return 0; 344f1535dc8Sdjm 345f1535dc8Sdjm return 1; 346f1535dc8Sdjm } 347f1535dc8Sdjm 34887203b09Smiod static int 34987203b09Smiod pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, 350f1535dc8Sdjm const unsigned char *in, size_t inlen) 351f1535dc8Sdjm { 352f1535dc8Sdjm RSA_PKEY_CTX *rctx = ctx->data; 35395285806Sjsing int ret; 35487203b09Smiod 35595285806Sjsing if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { 35695285806Sjsing int klen = RSA_size(ctx->pkey->pkey.rsa); 35795285806Sjsing if (!setup_tbuf(rctx, ctx)) 35895285806Sjsing return -1; 35995285806Sjsing if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen, 36095285806Sjsing in, inlen, rctx->oaep_label, rctx->oaep_labellen, 36195285806Sjsing rctx->md, rctx->mgf1md)) 36295285806Sjsing return -1; 36395285806Sjsing ret = RSA_public_encrypt(klen, rctx->tbuf, out, 36495285806Sjsing ctx->pkey->pkey.rsa, RSA_NO_PADDING); 36595285806Sjsing } else { 366f1535dc8Sdjm ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, 367f1535dc8Sdjm rctx->pad_mode); 36895285806Sjsing } 369f1535dc8Sdjm if (ret < 0) 370f1535dc8Sdjm return ret; 371f1535dc8Sdjm *outlen = ret; 372f1535dc8Sdjm return 1; 373f1535dc8Sdjm } 374f1535dc8Sdjm 37587203b09Smiod static int 37687203b09Smiod pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, 377f1535dc8Sdjm const unsigned char *in, size_t inlen) 378f1535dc8Sdjm { 379f1535dc8Sdjm int ret; 380f1535dc8Sdjm RSA_PKEY_CTX *rctx = ctx->data; 38187203b09Smiod 38295285806Sjsing if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { 38395285806Sjsing if (!setup_tbuf(rctx, ctx)) 38495285806Sjsing return -1; 38595285806Sjsing ret = RSA_private_decrypt(inlen, in, rctx->tbuf, 38695285806Sjsing ctx->pkey->pkey.rsa, RSA_NO_PADDING); 38795285806Sjsing if (ret <= 0) 38895285806Sjsing return ret; 38995285806Sjsing ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf, 39095285806Sjsing ret, ret, rctx->oaep_label, rctx->oaep_labellen, rctx->md, 39195285806Sjsing rctx->mgf1md); 39295285806Sjsing } else { 393f1535dc8Sdjm ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, 394f1535dc8Sdjm rctx->pad_mode); 39595285806Sjsing } 396f1535dc8Sdjm if (ret < 0) 397f1535dc8Sdjm return ret; 398f1535dc8Sdjm *outlen = ret; 399f1535dc8Sdjm return 1; 400f1535dc8Sdjm } 401f1535dc8Sdjm 40287203b09Smiod static int 40387203b09Smiod check_padding_md(const EVP_MD *md, int padding) 404f1535dc8Sdjm { 405ba05ae2dSjsing if (md == NULL) 406f1535dc8Sdjm return 1; 407f1535dc8Sdjm 4084349b8b3Stb if (padding == RSA_NO_PADDING) { 4094349b8b3Stb RSAerror(RSA_R_INVALID_PADDING_MODE); 410f1535dc8Sdjm return 0; 411f1535dc8Sdjm } 412f1535dc8Sdjm 4134349b8b3Stb if (padding == RSA_X931_PADDING) { 4144349b8b3Stb if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) { 4154349b8b3Stb RSAerror(RSA_R_INVALID_X931_DIGEST); 4164349b8b3Stb return 0; 4174349b8b3Stb } 4184349b8b3Stb } else { 419ba05ae2dSjsing /* List of all supported RSA digests. */ 4209a5a6ad9Stb /* RFC 8017 and NIST CSOR. */ 421ba05ae2dSjsing switch(EVP_MD_type(md)) { 422ba05ae2dSjsing case NID_sha1: 423ba05ae2dSjsing case NID_sha224: 424ba05ae2dSjsing case NID_sha256: 425ba05ae2dSjsing case NID_sha384: 426ba05ae2dSjsing case NID_sha512: 4279a5a6ad9Stb case NID_sha512_224: 4289a5a6ad9Stb case NID_sha512_256: 4299a5a6ad9Stb case NID_sha3_224: 4309a5a6ad9Stb case NID_sha3_256: 4319a5a6ad9Stb case NID_sha3_384: 4329a5a6ad9Stb case NID_sha3_512: 433ba05ae2dSjsing case NID_md5: 434ba05ae2dSjsing case NID_md5_sha1: 435ba05ae2dSjsing case NID_md4: 436ba05ae2dSjsing case NID_ripemd160: 437f1535dc8Sdjm return 1; 438ba05ae2dSjsing 439ba05ae2dSjsing default: 440ba05ae2dSjsing RSAerror(RSA_R_INVALID_DIGEST); 441ba05ae2dSjsing return 0; 442ba05ae2dSjsing } 4434349b8b3Stb } 444f1535dc8Sdjm 445f1535dc8Sdjm return 1; 446f1535dc8Sdjm } 447f1535dc8Sdjm 44887203b09Smiod static int 44987203b09Smiod pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 450f1535dc8Sdjm { 451f1535dc8Sdjm RSA_PKEY_CTX *rctx = ctx->data; 45214a995a9Sjsing 45387203b09Smiod switch (type) { 454f1535dc8Sdjm case EVP_PKEY_CTRL_RSA_PADDING: 45587203b09Smiod if (p1 >= RSA_PKCS1_PADDING && p1 <= RSA_PKCS1_PSS_PADDING) { 456f1535dc8Sdjm if (!check_padding_md(rctx->md, p1)) 457f1535dc8Sdjm return 0; 45887203b09Smiod if (p1 == RSA_PKCS1_PSS_PADDING) { 459f1535dc8Sdjm if (!(ctx->operation & 460f1535dc8Sdjm (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) 461f1535dc8Sdjm goto bad_pad; 462f1535dc8Sdjm if (!rctx->md) 463f1535dc8Sdjm rctx->md = EVP_sha1(); 464ba05ae2dSjsing } else if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) { 465ba05ae2dSjsing goto bad_pad; 466f1535dc8Sdjm } 46787203b09Smiod if (p1 == RSA_PKCS1_OAEP_PADDING) { 468f1535dc8Sdjm if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) 469f1535dc8Sdjm goto bad_pad; 470f1535dc8Sdjm if (!rctx->md) 471f1535dc8Sdjm rctx->md = EVP_sha1(); 472f1535dc8Sdjm } 473f1535dc8Sdjm rctx->pad_mode = p1; 474f1535dc8Sdjm return 1; 475f1535dc8Sdjm } 476f1535dc8Sdjm bad_pad: 4775067ae9fSbeck RSAerror(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); 478f1535dc8Sdjm return -2; 479f1535dc8Sdjm 480ec07fdf1Sdjm case EVP_PKEY_CTRL_GET_RSA_PADDING: 481ec07fdf1Sdjm *(int *)p2 = rctx->pad_mode; 482ec07fdf1Sdjm return 1; 483ec07fdf1Sdjm 484f1535dc8Sdjm case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: 485ec07fdf1Sdjm case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: 48687203b09Smiod if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { 4875067ae9fSbeck RSAerror(RSA_R_INVALID_PSS_SALTLEN); 488f1535dc8Sdjm return -2; 489f1535dc8Sdjm } 4900a0c1944Sjsing if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { 491ec07fdf1Sdjm *(int *)p2 = rctx->saltlen; 4920a0c1944Sjsing } else { 493ba05ae2dSjsing if (p1 < RSA_PSS_SALTLEN_MAX) 494ec07fdf1Sdjm return -2; 495ba05ae2dSjsing if (rsa_pss_restricted(rctx)) { 496ba05ae2dSjsing if (p1 == RSA_PSS_SALTLEN_AUTO && 497ba05ae2dSjsing ctx->operation == EVP_PKEY_OP_VERIFY) { 498ba05ae2dSjsing RSAerror(RSA_R_INVALID_PSS_SALTLEN); 499ba05ae2dSjsing return -2; 500ba05ae2dSjsing } 501ba05ae2dSjsing if ((p1 == RSA_PSS_SALTLEN_DIGEST && 502ba05ae2dSjsing rctx->min_saltlen > EVP_MD_size(rctx->md)) || 503ba05ae2dSjsing (p1 >= 0 && p1 < rctx->min_saltlen)) { 504ba05ae2dSjsing RSAerror(RSA_R_PSS_SALTLEN_TOO_SMALL); 505ba05ae2dSjsing return 0; 506ba05ae2dSjsing } 507ba05ae2dSjsing } 508f1535dc8Sdjm rctx->saltlen = p1; 509ec07fdf1Sdjm } 510f1535dc8Sdjm return 1; 511f1535dc8Sdjm 512f1535dc8Sdjm case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: 513a307e4caSjsing if (p1 < RSA_MIN_MODULUS_BITS) { 514a307e4caSjsing RSAerror(RSA_R_KEY_SIZE_TOO_SMALL); 515f1535dc8Sdjm return -2; 516f1535dc8Sdjm } 517f1535dc8Sdjm rctx->nbits = p1; 518f1535dc8Sdjm return 1; 519f1535dc8Sdjm 520f1535dc8Sdjm case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: 5216fbfd349Sjsing if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || 5226fbfd349Sjsing BN_is_one((BIGNUM *)p2)) { 5236fbfd349Sjsing RSAerror(RSA_R_BAD_E_VALUE); 524f1535dc8Sdjm return -2; 5256fbfd349Sjsing } 5266fbfd349Sjsing BN_free(rctx->pub_exp); 527f1535dc8Sdjm rctx->pub_exp = p2; 528f1535dc8Sdjm return 1; 529f1535dc8Sdjm 53085ca4670Sjsing case EVP_PKEY_CTRL_RSA_OAEP_MD: 53185ca4670Sjsing case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: 53285ca4670Sjsing if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 53385ca4670Sjsing RSAerror(RSA_R_INVALID_PADDING_MODE); 53485ca4670Sjsing return -2; 53585ca4670Sjsing } 53685ca4670Sjsing if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) 53785ca4670Sjsing *(const EVP_MD **)p2 = rctx->md; 53885ca4670Sjsing else 53985ca4670Sjsing rctx->md = p2; 54085ca4670Sjsing return 1; 54185ca4670Sjsing 542f1535dc8Sdjm case EVP_PKEY_CTRL_MD: 543f1535dc8Sdjm if (!check_padding_md(p2, rctx->pad_mode)) 544f1535dc8Sdjm return 0; 545ba05ae2dSjsing if (rsa_pss_restricted(rctx)) { 546ba05ae2dSjsing if (EVP_MD_type(rctx->md) == EVP_MD_type(p2)) 547ba05ae2dSjsing return 1; 548ba05ae2dSjsing RSAerror(RSA_R_DIGEST_NOT_ALLOWED); 549ba05ae2dSjsing return 0; 550ba05ae2dSjsing } 551f1535dc8Sdjm rctx->md = p2; 552f1535dc8Sdjm return 1; 553f1535dc8Sdjm 5546627381bSjsing case EVP_PKEY_CTRL_GET_MD: 5556627381bSjsing *(const EVP_MD **)p2 = rctx->md; 5566627381bSjsing return 1; 5576627381bSjsing 558ec07fdf1Sdjm case EVP_PKEY_CTRL_RSA_MGF1_MD: 559ec07fdf1Sdjm case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: 56095285806Sjsing if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && 56195285806Sjsing rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 5625067ae9fSbeck RSAerror(RSA_R_INVALID_MGF1_MD); 563ec07fdf1Sdjm return -2; 564ec07fdf1Sdjm } 56587203b09Smiod if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { 566ec07fdf1Sdjm if (rctx->mgf1md) 567ec07fdf1Sdjm *(const EVP_MD **)p2 = rctx->mgf1md; 568ec07fdf1Sdjm else 569ec07fdf1Sdjm *(const EVP_MD **)p2 = rctx->md; 570ba05ae2dSjsing } else { 571ba05ae2dSjsing if (rsa_pss_restricted(rctx)) { 572ba05ae2dSjsing if (EVP_MD_type(rctx->mgf1md) == EVP_MD_type(p2)) 573ba05ae2dSjsing return 1; 574ba05ae2dSjsing RSAerror(RSA_R_MGF1_DIGEST_NOT_ALLOWED); 575ba05ae2dSjsing return 0; 576ba05ae2dSjsing } 577ec07fdf1Sdjm rctx->mgf1md = p2; 578ba05ae2dSjsing } 579ec07fdf1Sdjm return 1; 580ec07fdf1Sdjm 58195285806Sjsing case EVP_PKEY_CTRL_RSA_OAEP_LABEL: 58295285806Sjsing if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 58395285806Sjsing RSAerror(RSA_R_INVALID_PADDING_MODE); 58495285806Sjsing return -2; 58595285806Sjsing } 58695285806Sjsing free(rctx->oaep_label); 58795285806Sjsing if (p2 != NULL && p1 > 0) { 58895285806Sjsing rctx->oaep_label = p2; 58995285806Sjsing rctx->oaep_labellen = p1; 59095285806Sjsing } else { 59195285806Sjsing rctx->oaep_label = NULL; 59295285806Sjsing rctx->oaep_labellen = 0; 59395285806Sjsing } 59495285806Sjsing return 1; 59595285806Sjsing 59695285806Sjsing case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: 59795285806Sjsing if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 59895285806Sjsing RSAerror(RSA_R_INVALID_PADDING_MODE); 59995285806Sjsing return -2; 60095285806Sjsing } 60195285806Sjsing *(unsigned char **)p2 = rctx->oaep_label; 60295285806Sjsing return rctx->oaep_labellen; 60395285806Sjsing 604f1535dc8Sdjm case EVP_PKEY_CTRL_DIGESTINIT: 605f1535dc8Sdjm case EVP_PKEY_CTRL_PKCS7_SIGN: 606a48d29b1Sjsing #ifndef OPENSSL_NO_CMS 607a48d29b1Sjsing case EVP_PKEY_CTRL_CMS_SIGN: 608a48d29b1Sjsing #endif 609f1535dc8Sdjm return 1; 610ba05ae2dSjsing 611ba05ae2dSjsing case EVP_PKEY_CTRL_PKCS7_ENCRYPT: 612ba05ae2dSjsing case EVP_PKEY_CTRL_PKCS7_DECRYPT: 613a48d29b1Sjsing #ifndef OPENSSL_NO_CMS 614a48d29b1Sjsing case EVP_PKEY_CTRL_CMS_DECRYPT: 615a48d29b1Sjsing case EVP_PKEY_CTRL_CMS_ENCRYPT: 616a48d29b1Sjsing #endif 617ba05ae2dSjsing if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) 618ba05ae2dSjsing return 1; 619ba05ae2dSjsing 620ba05ae2dSjsing /* fall through */ 621f1535dc8Sdjm case EVP_PKEY_CTRL_PEER_KEY: 6225067ae9fSbeck RSAerror(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 623f1535dc8Sdjm return -2; 624f1535dc8Sdjm 625f1535dc8Sdjm default: 626f1535dc8Sdjm return -2; 627ba05ae2dSjsing 628f1535dc8Sdjm } 629f1535dc8Sdjm } 630f1535dc8Sdjm 63187203b09Smiod static int 63287203b09Smiod pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) 633f1535dc8Sdjm { 63440e63673Sop const char *errstr; 63540e63673Sop 63687203b09Smiod if (!value) { 6375067ae9fSbeck RSAerror(RSA_R_VALUE_MISSING); 638f1535dc8Sdjm return 0; 639f1535dc8Sdjm } 640*457dff42Stb if (strcmp(type, "rsa_padding_mode") == 0) { 641f1535dc8Sdjm int pm; 642*457dff42Stb if (strcmp(value, "pkcs1") == 0) 643f1535dc8Sdjm pm = RSA_PKCS1_PADDING; 644*457dff42Stb else if (strcmp(value, "none") == 0) 645f1535dc8Sdjm pm = RSA_NO_PADDING; 646*457dff42Stb else if (strcmp(value, "oaep") == 0 || strcmp(value, "oeap") == 0) 647f1535dc8Sdjm pm = RSA_PKCS1_OAEP_PADDING; 648*457dff42Stb else if (strcmp(value, "x931") == 0) 6494349b8b3Stb pm = RSA_X931_PADDING; 650*457dff42Stb else if (strcmp(value, "pss") == 0) 651f1535dc8Sdjm pm = RSA_PKCS1_PSS_PADDING; 65287203b09Smiod else { 6535067ae9fSbeck RSAerror(RSA_R_UNKNOWN_PADDING_TYPE); 654f1535dc8Sdjm return -2; 655f1535dc8Sdjm } 656f1535dc8Sdjm return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); 657f1535dc8Sdjm } 658f1535dc8Sdjm 659ba05ae2dSjsing if (strcmp(type, "rsa_pss_saltlen") == 0) { 660f1535dc8Sdjm int saltlen; 661b1d57841Sderaadt 662*457dff42Stb if (strcmp(value, "digest") == 0) 663ba05ae2dSjsing saltlen = RSA_PSS_SALTLEN_DIGEST; 664*457dff42Stb else if (strcmp(value, "max") == 0) 665ba05ae2dSjsing saltlen = RSA_PSS_SALTLEN_MAX; 666*457dff42Stb else if (strcmp(value, "auto") == 0) 667ba05ae2dSjsing saltlen = RSA_PSS_SALTLEN_AUTO; 66840e63673Sop else { 669ac07061aStb /* 670ac07061aStb * Accept the special values -1, -2, -3 since that's 671ac07061aStb * what atoi() historically did. Lower values are later 672ac07061aStb * rejected in EVP_PKEY_CTRL_RSA_PSS_SALTLEN anyway. 673ac07061aStb */ 674ac07061aStb saltlen = strtonum(value, -3, INT_MAX, &errstr); 67540e63673Sop if (errstr != NULL) { 67640e63673Sop RSAerror(RSA_R_INVALID_PSS_SALTLEN); 67740e63673Sop return -2; 67840e63673Sop } 67940e63673Sop } 680f1535dc8Sdjm return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); 681f1535dc8Sdjm } 682f1535dc8Sdjm 683ba05ae2dSjsing if (strcmp(type, "rsa_keygen_bits") == 0) { 68440e63673Sop int nbits; 68540e63673Sop 68640e63673Sop nbits = strtonum(value, 0, INT_MAX, &errstr); 68740e63673Sop if (errstr != NULL) { 68840e63673Sop RSAerror(RSA_R_INVALID_KEYBITS); 68940e63673Sop return -2; 69040e63673Sop } 691b1d57841Sderaadt 692f1535dc8Sdjm return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); 693f1535dc8Sdjm } 694f1535dc8Sdjm 695ba05ae2dSjsing if (strcmp(type, "rsa_keygen_pubexp") == 0) { 696f1535dc8Sdjm BIGNUM *pubexp = NULL; 697ba05ae2dSjsing int ret; 69887203b09Smiod 699f1535dc8Sdjm if (!BN_asc2bn(&pubexp, value)) 700f1535dc8Sdjm return 0; 701f1535dc8Sdjm ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); 702f1535dc8Sdjm if (ret <= 0) 703f1535dc8Sdjm BN_free(pubexp); 704f1535dc8Sdjm return ret; 705f1535dc8Sdjm } 706f1535dc8Sdjm 70795285806Sjsing if (strcmp(type, "rsa_mgf1_md") == 0) 70895285806Sjsing return EVP_PKEY_CTX_md(ctx, 70995285806Sjsing EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, 71095285806Sjsing EVP_PKEY_CTRL_RSA_MGF1_MD, value); 71195285806Sjsing 712ba05ae2dSjsing if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) { 713ba05ae2dSjsing if (strcmp(type, "rsa_pss_keygen_mgf1_md") == 0) 714ba05ae2dSjsing return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, 715ba05ae2dSjsing EVP_PKEY_CTRL_RSA_MGF1_MD, value); 716ba05ae2dSjsing 717ba05ae2dSjsing if (strcmp(type, "rsa_pss_keygen_md") == 0) 718ba05ae2dSjsing return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, 719ba05ae2dSjsing EVP_PKEY_CTRL_MD, value); 720ba05ae2dSjsing 721ba05ae2dSjsing if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) { 72240e63673Sop int saltlen; 72340e63673Sop 724ac07061aStb /* 725ac07061aStb * Accept the special values -1, -2, -3 since that's 726ac07061aStb * what atoi() historically did. Lower values are later 727ac07061aStb * rejected in EVP_PKEY_CTRL_RSA_PSS_SALTLEN anyway. 728ac07061aStb */ 729ac07061aStb saltlen = strtonum(value, -3, INT_MAX, &errstr); 73040e63673Sop if (errstr != NULL) { 73140e63673Sop RSAerror(RSA_R_INVALID_PSS_SALTLEN); 73240e63673Sop return -2; 73340e63673Sop } 734ba05ae2dSjsing 735ba05ae2dSjsing return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen); 736ba05ae2dSjsing } 737ba05ae2dSjsing } 738ba05ae2dSjsing 73995285806Sjsing if (strcmp(type, "rsa_oaep_md") == 0) 74095285806Sjsing return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_CRYPT, 74195285806Sjsing EVP_PKEY_CTRL_RSA_OAEP_MD, value); 74295285806Sjsing 74395285806Sjsing if (strcmp(type, "rsa_oaep_label") == 0) { 74495285806Sjsing unsigned char *lab; 74595285806Sjsing long lablen; 74695285806Sjsing int ret; 74795285806Sjsing 74895285806Sjsing if ((lab = string_to_hex(value, &lablen)) == NULL) 74995285806Sjsing return 0; 75095285806Sjsing ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); 75195285806Sjsing if (ret <= 0) 75295285806Sjsing free(lab); 75395285806Sjsing 75495285806Sjsing return ret; 75595285806Sjsing } 75695285806Sjsing 757f1535dc8Sdjm return -2; 758f1535dc8Sdjm } 759f1535dc8Sdjm 760ba05ae2dSjsing /* Set PSS parameters when generating a key, if necessary. */ 761ba05ae2dSjsing static int 762ba05ae2dSjsing rsa_set_pss_param(RSA *rsa, EVP_PKEY_CTX *ctx) 763ba05ae2dSjsing { 764ba05ae2dSjsing RSA_PKEY_CTX *rctx = ctx->data; 765ba05ae2dSjsing 766ba05ae2dSjsing if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) 767ba05ae2dSjsing return 1; 768ba05ae2dSjsing 769ba05ae2dSjsing /* If all parameters are default values then do not set PSS. */ 770ba05ae2dSjsing if (rctx->md == NULL && rctx->mgf1md == NULL && 771ba05ae2dSjsing rctx->saltlen == RSA_PSS_SALTLEN_AUTO) 772ba05ae2dSjsing return 1; 773ba05ae2dSjsing 774ba05ae2dSjsing rsa->pss = rsa_pss_params_create(rctx->md, rctx->mgf1md, 775ba05ae2dSjsing rctx->saltlen == RSA_PSS_SALTLEN_AUTO ? 0 : rctx->saltlen); 776ba05ae2dSjsing if (rsa->pss == NULL) 777ba05ae2dSjsing return 0; 778ba05ae2dSjsing 779ba05ae2dSjsing return 1; 780ba05ae2dSjsing } 781ba05ae2dSjsing 78287203b09Smiod static int 78387203b09Smiod pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 784f1535dc8Sdjm { 785f1535dc8Sdjm RSA *rsa = NULL; 786f1535dc8Sdjm RSA_PKEY_CTX *rctx = ctx->data; 7870f0ee19aStb BN_GENCB *pcb = NULL; 7880f0ee19aStb BN_GENCB cb = {0}; 7890f0ee19aStb int ret = 0; 79087203b09Smiod 7915bc73cc3Sjsing if (rctx->pub_exp == NULL) { 7925bc73cc3Sjsing if ((rctx->pub_exp = BN_new()) == NULL) 7930f0ee19aStb goto err; 7945bc73cc3Sjsing if (!BN_set_word(rctx->pub_exp, RSA_F4)) 7950f0ee19aStb goto err; 796f1535dc8Sdjm } 7970f0ee19aStb 7985bc73cc3Sjsing if ((rsa = RSA_new()) == NULL) 7990f0ee19aStb goto err; 8005bc73cc3Sjsing if (ctx->pkey_gencb != NULL) { 801f1535dc8Sdjm pcb = &cb; 802f1535dc8Sdjm evp_pkey_set_cb_translate(pcb, ctx); 8035bc73cc3Sjsing } 8040f0ee19aStb if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb)) 8050f0ee19aStb goto err; 8060f0ee19aStb if (!rsa_set_pss_param(rsa, ctx)) 8070f0ee19aStb goto err; 8080f0ee19aStb if (!EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, rsa)) 8090f0ee19aStb goto err; 8100f0ee19aStb rsa = NULL; 8110f0ee19aStb 8120f0ee19aStb ret = 1; 8130f0ee19aStb 8140f0ee19aStb err: 815ba05ae2dSjsing RSA_free(rsa); 8160f0ee19aStb 817f1535dc8Sdjm return ret; 818f1535dc8Sdjm } 819f1535dc8Sdjm 820e402ce74Smiod const EVP_PKEY_METHOD rsa_pkey_meth = { 821e402ce74Smiod .pkey_id = EVP_PKEY_RSA, 822e402ce74Smiod .flags = EVP_PKEY_FLAG_AUTOARGLEN, 823f1535dc8Sdjm 824e402ce74Smiod .init = pkey_rsa_init, 825e402ce74Smiod .copy = pkey_rsa_copy, 826e402ce74Smiod .cleanup = pkey_rsa_cleanup, 827f1535dc8Sdjm 828e402ce74Smiod .keygen = pkey_rsa_keygen, 829f1535dc8Sdjm 830e402ce74Smiod .sign = pkey_rsa_sign, 831f1535dc8Sdjm 832e402ce74Smiod .verify = pkey_rsa_verify, 833f1535dc8Sdjm 834e402ce74Smiod .verify_recover = pkey_rsa_verifyrecover, 835f1535dc8Sdjm 836e402ce74Smiod .encrypt = pkey_rsa_encrypt, 837f1535dc8Sdjm 838e402ce74Smiod .decrypt = pkey_rsa_decrypt, 839f1535dc8Sdjm 840e402ce74Smiod .ctrl = pkey_rsa_ctrl, 841e402ce74Smiod .ctrl_str = pkey_rsa_ctrl_str 842f1535dc8Sdjm }; 843ba05ae2dSjsing 844ba05ae2dSjsing /* 845ba05ae2dSjsing * Called for PSS sign or verify initialisation: checks PSS parameter 846ba05ae2dSjsing * sanity and sets any restrictions on key usage. 847ba05ae2dSjsing */ 848ba05ae2dSjsing 849ba05ae2dSjsing static int 850ba05ae2dSjsing pkey_pss_init(EVP_PKEY_CTX *ctx) 851ba05ae2dSjsing { 852ba05ae2dSjsing RSA *rsa; 853ba05ae2dSjsing RSA_PKEY_CTX *rctx = ctx->data; 854ba05ae2dSjsing const EVP_MD *md; 855ba05ae2dSjsing const EVP_MD *mgf1md; 856ba05ae2dSjsing int min_saltlen, max_saltlen; 857ba05ae2dSjsing 858ba05ae2dSjsing /* Should never happen */ 859ba05ae2dSjsing if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) 860ba05ae2dSjsing return 0; 861ba05ae2dSjsing rsa = ctx->pkey->pkey.rsa; 862ba05ae2dSjsing 863ba05ae2dSjsing /* If no restrictions just return */ 864ba05ae2dSjsing if (rsa->pss == NULL) 865ba05ae2dSjsing return 1; 866ba05ae2dSjsing 867ba05ae2dSjsing /* Get and check parameters */ 868ba05ae2dSjsing if (!rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen)) 869ba05ae2dSjsing return 0; 870ba05ae2dSjsing 871ba05ae2dSjsing /* See if minimum salt length exceeds maximum possible */ 872ba05ae2dSjsing max_saltlen = RSA_size(rsa) - EVP_MD_size(md); 873ba05ae2dSjsing if ((RSA_bits(rsa) & 0x7) == 1) 874ba05ae2dSjsing max_saltlen--; 875ba05ae2dSjsing if (min_saltlen > max_saltlen) { 876ba05ae2dSjsing RSAerror(RSA_R_INVALID_SALT_LENGTH); 877ba05ae2dSjsing return 0; 878ba05ae2dSjsing } 879ba05ae2dSjsing rctx->min_saltlen = min_saltlen; 880ba05ae2dSjsing 881ba05ae2dSjsing /* 882ba05ae2dSjsing * Set PSS restrictions as defaults: we can then block any attempt to 883ba05ae2dSjsing * use invalid values in pkey_rsa_ctrl 884ba05ae2dSjsing */ 885ba05ae2dSjsing 886ba05ae2dSjsing rctx->md = md; 887ba05ae2dSjsing rctx->mgf1md = mgf1md; 888ba05ae2dSjsing rctx->saltlen = min_saltlen; 889ba05ae2dSjsing 890ba05ae2dSjsing return 1; 891ba05ae2dSjsing } 892ba05ae2dSjsing 893ba05ae2dSjsing const EVP_PKEY_METHOD rsa_pss_pkey_meth = { 894ba05ae2dSjsing .pkey_id = EVP_PKEY_RSA_PSS, 895ba05ae2dSjsing .flags = EVP_PKEY_FLAG_AUTOARGLEN, 896ba05ae2dSjsing 897ba05ae2dSjsing .init = pkey_rsa_init, 898ba05ae2dSjsing .copy = pkey_rsa_copy, 899ba05ae2dSjsing .cleanup = pkey_rsa_cleanup, 900ba05ae2dSjsing 901ba05ae2dSjsing .keygen = pkey_rsa_keygen, 902ba05ae2dSjsing 903ba05ae2dSjsing .sign_init = pkey_pss_init, 904ba05ae2dSjsing .sign = pkey_rsa_sign, 905ba05ae2dSjsing 906ba05ae2dSjsing .verify_init = pkey_pss_init, 907ba05ae2dSjsing .verify = pkey_rsa_verify, 908ba05ae2dSjsing 909ba05ae2dSjsing .ctrl = pkey_rsa_ctrl, 910ba05ae2dSjsing .ctrl_str = pkey_rsa_ctrl_str 911ba05ae2dSjsing }; 912