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