195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * project 2006. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* ==================================================================== 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the above copyright 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the documentation and/or other materials provided with the 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * distribution. 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * software must display the following acknowledgment: 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software developed by the OpenSSL Project 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * endorse or promote products derived from this software without 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * prior written permission. For written permission, please contact 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * licensing@OpenSSL.org. 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5. Products derived from this software may not be called "OpenSSL" 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * nor may "OpenSSL" appear in their names without prior written 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * permission of the OpenSSL Project. 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6. Redistributions of any form whatsoever must retain the following 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * acknowledgment: 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software developed by the OpenSSL Project 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ==================================================================== 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This product includes cryptographic software written by Eric Young 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (eay@cryptsoft.com). This product includes software written by Tim 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Hudson (tjh@cryptsoft.com). */ 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/evp.h> 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/bn.h> 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/buf.h> 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/digest.h> 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h> 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/obj.h> 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/rsa.h> 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "../rsa/internal.h" 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "internal.h" 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleytypedef struct { 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Key gen parameters */ 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int nbits; 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIGNUM *pub_exp; 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* RSA padding mode */ 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int pad_mode; 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* message digest */ 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const EVP_MD *md; 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* message digest for MGF1 */ 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const EVP_MD *mgf1md; 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* PSS salt length */ 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int saltlen; 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* tbuf is a buffer which is either NULL, or is the size of the RSA modulus. 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * It's used to store the output of RSA operations. */ 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley uint8_t *tbuf; 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* OAEP label */ 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley uint8_t *oaep_label; 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t oaep_labellen; 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} RSA_PKEY_CTX; 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int pkey_rsa_init(EVP_PKEY_CTX *ctx) { 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *rctx; 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!rctx) { 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(rctx, 0, sizeof(RSA_PKEY_CTX)); 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->nbits = 2048; 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->pad_mode = RSA_PKCS1_PADDING; 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->saltlen = -2; 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->data = rctx; 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *dctx, *sctx; 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!pkey_rsa_init(dst)) { 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sctx = src->data; 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dctx = dst->data; 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dctx->nbits = sctx->nbits; 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sctx->pub_exp) { 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dctx->pub_exp = BN_dup(sctx->pub_exp); 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!dctx->pub_exp) { 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dctx->pad_mode = sctx->pad_mode; 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dctx->md = sctx->md; 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dctx->mgf1md = sctx->mgf1md; 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sctx->oaep_label) { 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (dctx->oaep_label) { 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(dctx->oaep_label); 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen); 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!dctx->oaep_label) { 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dctx->oaep_labellen = sctx->oaep_labellen; 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) { 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *rctx = ctx->data; 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx == NULL) { 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->pub_exp) { 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_free(rctx->pub_exp); 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->tbuf) { 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(rctx->tbuf); 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->oaep_label) { 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(rctx->oaep_label); 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(rctx); 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) { 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->tbuf) { 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ctx->tbuf) { 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t *tbs, size_t tbslen) { 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *rctx = ctx->data; 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA *rsa = ctx->pkey->pkey.rsa; 1735129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley const size_t key_len = EVP_PKEY_size(ctx->pkey); 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1759b561e69b63266a34675ad610f3da76c899c5750David Benjamin if (!sig) { 1765129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley *siglen = key_len; 1779b561e69b63266a34675ad610f3da76c899c5750David Benjamin return 1; 1785129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley } 1795129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 1805129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (*siglen < key_len) { 1819b561e69b63266a34675ad610f3da76c899c5750David Benjamin OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_BUFFER_TOO_SMALL); 1829b561e69b63266a34675ad610f3da76c899c5750David Benjamin return 0; 1839b561e69b63266a34675ad610f3da76c899c5750David Benjamin } 1849b561e69b63266a34675ad610f3da76c899c5750David Benjamin 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->md) { 1865129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley unsigned int out_len; 1875129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tbslen != EVP_MD_size(rctx->md)) { 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_INVALID_DIGEST_LENGTH); 1905129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EVP_MD_type(rctx->md) == NID_mdc2) { 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_NO_MDC2_SUPPORT); 1955129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1985129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley switch (rctx->pad_mode) { 1995129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley case RSA_PKCS1_PADDING: 2005129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (!RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &out_len, rsa)) { 2015129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 2025129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley } 2035129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley *siglen = out_len; 2045129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 1; 2055129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 2065129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley case RSA_PKCS1_PSS_PADDING: 2075129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (!setup_tbuf(rctx, ctx) || 2085129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley !RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, rctx->md, 2095129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley rctx->mgf1md, rctx->saltlen) || 2105129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley !RSA_encrypt(rsa, siglen, sig, *siglen, rctx->tbuf, key_len, 2115129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley RSA_NO_PADDING)) { 2125129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 2135129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley } 2145129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 1; 2155129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 2165129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley default: 2175129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 2185129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley } 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2215129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return RSA_sign_raw(rsa, siglen, sig, *siglen, tbs, tbslen, rctx->pad_mode); 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t siglen, const uint8_t *tbs, 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t tbslen) { 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *rctx = ctx->data; 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA *rsa = ctx->pkey->pkey.rsa; 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t rslen; 2305129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley const size_t key_len = EVP_PKEY_size(ctx->pkey); 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->md) { 2335129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley switch (rctx->pad_mode) { 2345129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley case RSA_PKCS1_PADDING: 2355129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa); 2365129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 2375129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley case RSA_PKCS1_PSS_PADDING: 2385129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (!setup_tbuf(rctx, ctx) || 2395129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, 2405129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley RSA_NO_PADDING) || 2415129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley !RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, rctx->md, rctx->mgf1md, 2425129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley rctx->tbuf, rctx->saltlen)) { 2435129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 2445129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley } 2455129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 1; 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2475129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley default: 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2525129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (!setup_tbuf(rctx, ctx) || 2535129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, 2545129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley rctx->pad_mode) || 2555129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley rslen != tbslen || 2565129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) { 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t *in, size_t inlen) { 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *rctx = ctx->data; 2669b561e69b63266a34675ad610f3da76c899c5750David Benjamin RSA *rsa = ctx->pkey->pkey.rsa; 2675129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley const size_t key_len = EVP_PKEY_size(ctx->pkey); 2689b561e69b63266a34675ad610f3da76c899c5750David Benjamin 2699b561e69b63266a34675ad610f3da76c899c5750David Benjamin if (!out) { 2705129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley *outlen = key_len; 2719b561e69b63266a34675ad610f3da76c899c5750David Benjamin return 1; 2725129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley } 2735129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 2745129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (*outlen < key_len) { 2759b561e69b63266a34675ad610f3da76c899c5750David Benjamin OPENSSL_PUT_ERROR(EVP, pkey_rsa_encrypt, EVP_R_BUFFER_TOO_SMALL); 2769b561e69b63266a34675ad610f3da76c899c5750David Benjamin return 0; 2779b561e69b63266a34675ad610f3da76c899c5750David Benjamin } 27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { 2805129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (!setup_tbuf(rctx, ctx) || 2815129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen, 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->oaep_label, rctx->oaep_labellen, 2835129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley rctx->md, rctx->mgf1md) || 2845129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len, 2855129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley RSA_NO_PADDING)) { 2865129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 2885129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 1; 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2915129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return RSA_encrypt(rsa, outlen, out, *outlen, in, inlen, rctx->pad_mode); 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t *outlen, const uint8_t *in, 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t inlen) { 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *rctx = ctx->data; 2989b561e69b63266a34675ad610f3da76c899c5750David Benjamin RSA *rsa = ctx->pkey->pkey.rsa; 2995129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley const size_t key_len = EVP_PKEY_size(ctx->pkey); 3009b561e69b63266a34675ad610f3da76c899c5750David Benjamin 3019b561e69b63266a34675ad610f3da76c899c5750David Benjamin if (!out) { 3025129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley *outlen = key_len; 3039b561e69b63266a34675ad610f3da76c899c5750David Benjamin return 1; 3045129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley } 3055129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 3065129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (*outlen < key_len) { 3079b561e69b63266a34675ad610f3da76c899c5750David Benjamin OPENSSL_PUT_ERROR(EVP, pkey_rsa_decrypt, EVP_R_BUFFER_TOO_SMALL); 3089b561e69b63266a34675ad610f3da76c899c5750David Benjamin return 0; 3099b561e69b63266a34675ad610f3da76c899c5750David Benjamin } 31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { 3125129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley size_t plaintext_len; 3135129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley int message_len; 3145129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 3155129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (!setup_tbuf(rctx, ctx) || 3165129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley !RSA_decrypt(rsa, &plaintext_len, rctx->tbuf, key_len, in, inlen, 3175129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley RSA_NO_PADDING)) { 3185129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3215129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley message_len = RSA_padding_check_PKCS1_OAEP_mgf1( 3225129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley out, key_len, rctx->tbuf, plaintext_len, rctx->oaep_label, 3235129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley rctx->oaep_labellen, rctx->md, rctx->mgf1md); 3245129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (message_len < 0) { 3255129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 3265129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley } 3275129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley *outlen = message_len; 3285129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 1; 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3315129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return RSA_decrypt(rsa, outlen, out, key_len, in, inlen, rctx->pad_mode); 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int check_padding_md(const EVP_MD *md, int padding) { 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!md) { 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (padding == RSA_NO_PADDING) { 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, check_padding_md, EVP_R_INVALID_PADDING_MODE); 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int is_known_padding(int padding_mode) { 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch (padding_mode) { 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case RSA_PKCS1_PADDING: 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case RSA_NO_PADDING: 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case RSA_PKCS1_OAEP_PADDING: 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case RSA_PKCS1_PSS_PADDING: 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley default: 35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *rctx = ctx->data; 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch (type) { 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_RSA_PADDING: 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) || 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (p1 == RSA_PKCS1_PSS_PADDING && 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) || 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (p1 == RSA_PKCS1_OAEP_PADDING && 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) { 36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); 37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->md == NULL) { 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->md = EVP_sha1(); 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->pad_mode = p1; 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_GET_RSA_PADDING: 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(int *)p2 = rctx->pad_mode; 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PSS_SALTLEN); 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(int *)p2 = rctx->saltlen; 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (p1 < -2) { 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->saltlen = p1; 39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: 40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (p1 < 256) { 40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_KEYBITS); 40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->nbits = p1; 40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: 40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!p2) { 40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_free(rctx->pub_exp); 41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->pub_exp = p2; 41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_RSA_OAEP_MD: 41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: 41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); 41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) { 42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(const EVP_MD **)p2 = rctx->md; 42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->md = p2; 42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_MD: 42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!check_padding_md(p2, rctx->pad_mode)) { 43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->md = p2; 43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_GET_MD: 43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(const EVP_MD **)p2 = rctx->md; 43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_RSA_MGF1_MD: 44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: 44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && 44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_MGF1_MD); 44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { 44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->mgf1md) { 44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(const EVP_MD **)p2 = rctx->mgf1md; 44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(const EVP_MD **)p2 = rctx->md; 45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->mgf1md = p2; 45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_RSA_OAEP_LABEL: 45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); 46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->oaep_label) { 46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(rctx->oaep_label); 46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (p2 && p1 > 0) { 46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* TODO(fork): this seems wrong. Shouldn't it take a copy of the 46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * buffer? */ 46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->oaep_label = p2; 46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->oaep_labellen = p1; 47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->oaep_label = NULL; 47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->oaep_labellen = 0; 47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: 47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { 47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); 47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(uint8_t **)p2 = rctx->oaep_label; 48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rctx->oaep_labellen; 48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_PKEY_CTRL_DIGESTINIT: 48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley default: 48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 49195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { 49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA *rsa = NULL; 49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_PKEY_CTX *rctx = ctx->data; 49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!rctx->pub_exp) { 49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rctx->pub_exp = BN_new(); 49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) 49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 50095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rsa = RSA_new(); 50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!rsa) { 50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5065129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) { 50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_free(rsa); 5085129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 0; 50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 5105129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley 5115129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley EVP_PKEY_assign_RSA(pkey, rsa); 5125129e2d69582c0c54a335eb7e0bc794a02418403Adam Langley return 1; 51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst EVP_PKEY_METHOD rsa_pkey_meth = { 5169b561e69b63266a34675ad610f3da76c899c5750David Benjamin EVP_PKEY_RSA, 0 /* flags */, pkey_rsa_init, 5179b561e69b63266a34675ad610f3da76c899c5750David Benjamin pkey_rsa_copy, pkey_rsa_cleanup, 0 /* paramgen_init */, 5189b561e69b63266a34675ad610f3da76c899c5750David Benjamin 0 /* paramgen */, 0 /* keygen_init */, pkey_rsa_keygen, 5199b561e69b63266a34675ad610f3da76c899c5750David Benjamin 0 /* sign_init */, pkey_rsa_sign, 0 /* verify_init */, 5209b561e69b63266a34675ad610f3da76c899c5750David Benjamin pkey_rsa_verify, 0 /* signctx_init */, 0 /* signctx */, 5219b561e69b63266a34675ad610f3da76c899c5750David Benjamin 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */, 5229b561e69b63266a34675ad610f3da76c899c5750David Benjamin pkey_rsa_encrypt, 0 /* decrypt_init */, pkey_rsa_decrypt, 5239b561e69b63266a34675ad610f3da76c899c5750David Benjamin 0 /* derive_init */, 0 /* derive */, pkey_rsa_ctrl, 52495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 52595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 52695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) { 52795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, 52895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley padding, NULL); 52995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) { 53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0, out_padding); 53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 53595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { 53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, 53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), 53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL); 54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) { 54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, 54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), 54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len); 54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 54895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) { 54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, 55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL); 55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 55395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) { 55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, 55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e); 55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { 55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, 56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md); 56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { 56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, 56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void*) out_md); 56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { 56995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, 57095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, 57195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void*) md); 57295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 57395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 57495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { 57595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, 57695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, 57795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void*) out_md); 57895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 57995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label, 58195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t label_len) { 58295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int label_len_int = label_len; 58395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (((size_t) label_len_int) != label_len) { 58495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 58595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 58695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, 58895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_RSA_OAEP_LABEL, label_len, 58995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (void *)label); 59095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 59195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 59295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, 59395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t **out_label) { 59495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, 59595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *) out_label); 59695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 597