• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2  * project 2006.
3  */
4 /* ====================================================================
5  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com). */
55 
56 #include <openssl/evp.h>
57 
58 #include <limits.h>
59 #include <string.h>
60 
61 #include <openssl/bn.h>
62 #include <openssl/buf.h>
63 #include <openssl/bytestring.h>
64 #include <openssl/digest.h>
65 #include <openssl/err.h>
66 #include <openssl/mem.h>
67 #include <openssl/obj.h>
68 #include <openssl/rsa.h>
69 
70 #include "../rsa/internal.h"
71 #include "internal.h"
72 
73 
74 typedef struct {
75   /* Key gen parameters */
76   int nbits;
77   BIGNUM *pub_exp;
78   /* RSA padding mode */
79   int pad_mode;
80   /* message digest */
81   const EVP_MD *md;
82   /* message digest for MGF1 */
83   const EVP_MD *mgf1md;
84   /* PSS salt length */
85   int saltlen;
86   /* tbuf is a buffer which is either NULL, or is the size of the RSA modulus.
87    * It's used to store the output of RSA operations. */
88   uint8_t *tbuf;
89   /* OAEP label */
90   uint8_t *oaep_label;
91   size_t oaep_labellen;
92 } RSA_PKEY_CTX;
93 
pkey_rsa_init(EVP_PKEY_CTX * ctx)94 static int pkey_rsa_init(EVP_PKEY_CTX *ctx) {
95   RSA_PKEY_CTX *rctx;
96   rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
97   if (!rctx) {
98     return 0;
99   }
100   memset(rctx, 0, sizeof(RSA_PKEY_CTX));
101 
102   rctx->nbits = 2048;
103   rctx->pad_mode = RSA_PKCS1_PADDING;
104   rctx->saltlen = -2;
105 
106   ctx->data = rctx;
107 
108   return 1;
109 }
110 
pkey_rsa_copy(EVP_PKEY_CTX * dst,EVP_PKEY_CTX * src)111 static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
112   RSA_PKEY_CTX *dctx, *sctx;
113   if (!pkey_rsa_init(dst)) {
114     return 0;
115   }
116   sctx = src->data;
117   dctx = dst->data;
118   dctx->nbits = sctx->nbits;
119   if (sctx->pub_exp) {
120     dctx->pub_exp = BN_dup(sctx->pub_exp);
121     if (!dctx->pub_exp) {
122       return 0;
123     }
124   }
125 
126   dctx->pad_mode = sctx->pad_mode;
127   dctx->md = sctx->md;
128   dctx->mgf1md = sctx->mgf1md;
129   if (sctx->oaep_label) {
130     OPENSSL_free(dctx->oaep_label);
131     dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen);
132     if (!dctx->oaep_label) {
133       return 0;
134     }
135     dctx->oaep_labellen = sctx->oaep_labellen;
136   }
137 
138   return 1;
139 }
140 
pkey_rsa_cleanup(EVP_PKEY_CTX * ctx)141 static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) {
142   RSA_PKEY_CTX *rctx = ctx->data;
143 
144   if (rctx == NULL) {
145     return;
146   }
147 
148   BN_free(rctx->pub_exp);
149   OPENSSL_free(rctx->tbuf);
150   OPENSSL_free(rctx->oaep_label);
151   OPENSSL_free(rctx);
152 }
153 
setup_tbuf(RSA_PKEY_CTX * ctx,EVP_PKEY_CTX * pk)154 static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) {
155   if (ctx->tbuf) {
156     return 1;
157   }
158   ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
159   if (!ctx->tbuf) {
160     return 0;
161   }
162   return 1;
163 }
164 
pkey_rsa_sign(EVP_PKEY_CTX * ctx,uint8_t * sig,size_t * siglen,const uint8_t * tbs,size_t tbslen)165 static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
166                          const uint8_t *tbs, size_t tbslen) {
167   RSA_PKEY_CTX *rctx = ctx->data;
168   RSA *rsa = ctx->pkey->pkey.rsa;
169   const size_t key_len = EVP_PKEY_size(ctx->pkey);
170 
171   if (!sig) {
172     *siglen = key_len;
173     return 1;
174   }
175 
176   if (*siglen < key_len) {
177     OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_BUFFER_TOO_SMALL);
178     return 0;
179   }
180 
181   if (rctx->md) {
182     unsigned int out_len;
183 
184     if (tbslen != EVP_MD_size(rctx->md)) {
185       OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_INVALID_DIGEST_LENGTH);
186       return 0;
187     }
188 
189     if (EVP_MD_type(rctx->md) == NID_mdc2) {
190       OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_NO_MDC2_SUPPORT);
191       return 0;
192     }
193 
194     switch (rctx->pad_mode) {
195       case RSA_PKCS1_PADDING:
196         if (!RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &out_len, rsa)) {
197           return 0;
198         }
199         *siglen = out_len;
200         return 1;
201 
202       case RSA_PKCS1_PSS_PADDING:
203         if (!setup_tbuf(rctx, ctx) ||
204             !RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, rctx->md,
205                                             rctx->mgf1md, rctx->saltlen) ||
206             !RSA_sign_raw(rsa, siglen, sig, *siglen, rctx->tbuf, key_len,
207                           RSA_NO_PADDING)) {
208           return 0;
209         }
210         return 1;
211 
212       default:
213         return 0;
214     }
215   }
216 
217   return RSA_sign_raw(rsa, siglen, sig, *siglen, tbs, tbslen, rctx->pad_mode);
218 }
219 
pkey_rsa_verify(EVP_PKEY_CTX * ctx,const uint8_t * sig,size_t siglen,const uint8_t * tbs,size_t tbslen)220 static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig,
221                            size_t siglen, const uint8_t *tbs,
222                            size_t tbslen) {
223   RSA_PKEY_CTX *rctx = ctx->data;
224   RSA *rsa = ctx->pkey->pkey.rsa;
225   size_t rslen;
226   const size_t key_len = EVP_PKEY_size(ctx->pkey);
227 
228   if (rctx->md) {
229     switch (rctx->pad_mode) {
230       case RSA_PKCS1_PADDING:
231         return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa);
232 
233       case RSA_PKCS1_PSS_PADDING:
234         if (!setup_tbuf(rctx, ctx) ||
235             !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen,
236                             RSA_NO_PADDING) ||
237             !RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, rctx->md, rctx->mgf1md,
238                                        rctx->tbuf, rctx->saltlen)) {
239           return 0;
240         }
241         return 1;
242 
243       default:
244         return 0;
245     }
246   }
247 
248   if (!setup_tbuf(rctx, ctx) ||
249       !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen,
250                       rctx->pad_mode) ||
251       rslen != tbslen ||
252       CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) {
253     return 0;
254   }
255 
256   return 1;
257 }
258 
pkey_rsa_encrypt(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * outlen,const uint8_t * in,size_t inlen)259 static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
260                             const uint8_t *in, size_t inlen) {
261   RSA_PKEY_CTX *rctx = ctx->data;
262   RSA *rsa = ctx->pkey->pkey.rsa;
263   const size_t key_len = EVP_PKEY_size(ctx->pkey);
264 
265   if (!out) {
266     *outlen = key_len;
267     return 1;
268   }
269 
270   if (*outlen < key_len) {
271     OPENSSL_PUT_ERROR(EVP, pkey_rsa_encrypt, EVP_R_BUFFER_TOO_SMALL);
272     return 0;
273   }
274 
275   if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
276     if (!setup_tbuf(rctx, ctx) ||
277         !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen,
278                                          rctx->oaep_label, rctx->oaep_labellen,
279                                          rctx->md, rctx->mgf1md) ||
280         !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len,
281                      RSA_NO_PADDING)) {
282       return 0;
283     }
284     return 1;
285   }
286 
287   return RSA_encrypt(rsa, outlen, out, *outlen, in, inlen, rctx->pad_mode);
288 }
289 
pkey_rsa_decrypt(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * outlen,const uint8_t * in,size_t inlen)290 static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out,
291                             size_t *outlen, const uint8_t *in,
292                             size_t inlen) {
293   RSA_PKEY_CTX *rctx = ctx->data;
294   RSA *rsa = ctx->pkey->pkey.rsa;
295   const size_t key_len = EVP_PKEY_size(ctx->pkey);
296 
297   if (!out) {
298     *outlen = key_len;
299     return 1;
300   }
301 
302   if (*outlen < key_len) {
303     OPENSSL_PUT_ERROR(EVP, pkey_rsa_decrypt, EVP_R_BUFFER_TOO_SMALL);
304     return 0;
305   }
306 
307   if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
308     size_t plaintext_len;
309     int message_len;
310 
311     if (!setup_tbuf(rctx, ctx) ||
312         !RSA_decrypt(rsa, &plaintext_len, rctx->tbuf, key_len, in, inlen,
313                      RSA_NO_PADDING)) {
314       return 0;
315     }
316 
317     message_len = RSA_padding_check_PKCS1_OAEP_mgf1(
318         out, key_len, rctx->tbuf, plaintext_len, rctx->oaep_label,
319         rctx->oaep_labellen, rctx->md, rctx->mgf1md);
320     if (message_len < 0) {
321       return 0;
322     }
323     *outlen = message_len;
324     return 1;
325   }
326 
327   return RSA_decrypt(rsa, outlen, out, key_len, in, inlen, rctx->pad_mode);
328 }
329 
check_padding_md(const EVP_MD * md,int padding)330 static int check_padding_md(const EVP_MD *md, int padding) {
331   if (!md) {
332     return 1;
333   }
334 
335   if (padding == RSA_NO_PADDING) {
336     OPENSSL_PUT_ERROR(EVP, check_padding_md, EVP_R_INVALID_PADDING_MODE);
337     return 0;
338   }
339 
340   return 1;
341 }
342 
is_known_padding(int padding_mode)343 static int is_known_padding(int padding_mode) {
344   switch (padding_mode) {
345     case RSA_PKCS1_PADDING:
346     case RSA_NO_PADDING:
347     case RSA_PKCS1_OAEP_PADDING:
348     case RSA_PKCS1_PSS_PADDING:
349       return 1;
350     default:
351       return 0;
352   }
353 }
354 
pkey_rsa_ctrl(EVP_PKEY_CTX * ctx,int type,int p1,void * p2)355 static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
356   RSA_PKEY_CTX *rctx = ctx->data;
357   switch (type) {
358     case EVP_PKEY_CTRL_RSA_PADDING:
359       if (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) ||
360           (p1 == RSA_PKCS1_PSS_PADDING &&
361            0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) ||
362           (p1 == RSA_PKCS1_OAEP_PADDING &&
363            0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) {
364         OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl,
365                           EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
366         return 0;
367       }
368       if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) &&
369           rctx->md == NULL) {
370         rctx->md = EVP_sha1();
371       }
372       rctx->pad_mode = p1;
373       return 1;
374 
375     case EVP_PKEY_CTRL_GET_RSA_PADDING:
376       *(int *)p2 = rctx->pad_mode;
377       return 1;
378 
379     case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
380     case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
381       if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
382         OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PSS_SALTLEN);
383         return 0;
384       }
385       if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
386         *(int *)p2 = rctx->saltlen;
387       } else {
388         if (p1 < -2) {
389           return 0;
390         }
391         rctx->saltlen = p1;
392       }
393       return 1;
394 
395     case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
396       if (p1 < 256) {
397         OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_KEYBITS);
398         return 0;
399       }
400       rctx->nbits = p1;
401       return 1;
402 
403     case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
404       if (!p2) {
405         return 0;
406       }
407       BN_free(rctx->pub_exp);
408       rctx->pub_exp = p2;
409       return 1;
410 
411     case EVP_PKEY_CTRL_RSA_OAEP_MD:
412     case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
413       if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
414         OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
415         return 0;
416       }
417       if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) {
418         *(const EVP_MD **)p2 = rctx->md;
419       } else {
420         rctx->md = p2;
421       }
422       return 1;
423 
424     case EVP_PKEY_CTRL_MD:
425       if (!check_padding_md(p2, rctx->pad_mode)) {
426         return 0;
427       }
428       rctx->md = p2;
429       return 1;
430 
431     case EVP_PKEY_CTRL_GET_MD:
432       *(const EVP_MD **)p2 = rctx->md;
433       return 1;
434 
435     case EVP_PKEY_CTRL_RSA_MGF1_MD:
436     case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
437       if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING &&
438           rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
439         OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_MGF1_MD);
440         return 0;
441       }
442       if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
443         if (rctx->mgf1md) {
444           *(const EVP_MD **)p2 = rctx->mgf1md;
445         } else {
446           *(const EVP_MD **)p2 = rctx->md;
447         }
448       } else {
449         rctx->mgf1md = p2;
450       }
451       return 1;
452 
453     case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
454       if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
455         OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
456         return 0;
457       }
458       OPENSSL_free(rctx->oaep_label);
459       if (p2 && p1 > 0) {
460         /* TODO(fork): this seems wrong. Shouldn't it take a copy of the
461          * buffer? */
462         rctx->oaep_label = p2;
463         rctx->oaep_labellen = p1;
464       } else {
465         rctx->oaep_label = NULL;
466         rctx->oaep_labellen = 0;
467       }
468       return 1;
469 
470     case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
471       if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
472         OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
473         return 0;
474       }
475       CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen);
476       return 1;
477 
478     case EVP_PKEY_CTRL_DIGESTINIT:
479       return 1;
480 
481     default:
482       OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
483       return 0;
484   }
485 }
486 
pkey_rsa_keygen(EVP_PKEY_CTX * ctx,EVP_PKEY * pkey)487 static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
488   RSA *rsa = NULL;
489   RSA_PKEY_CTX *rctx = ctx->data;
490 
491   if (!rctx->pub_exp) {
492     rctx->pub_exp = BN_new();
493     if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) {
494       return 0;
495     }
496   }
497   rsa = RSA_new();
498   if (!rsa) {
499     return 0;
500   }
501 
502   if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) {
503     RSA_free(rsa);
504     return 0;
505   }
506 
507   EVP_PKEY_assign_RSA(pkey, rsa);
508   return 1;
509 }
510 
511 const EVP_PKEY_METHOD rsa_pkey_meth = {
512     EVP_PKEY_RSA,           0 /* flags */,        pkey_rsa_init,
513     pkey_rsa_copy,          pkey_rsa_cleanup,     0 /* paramgen_init */,
514     0 /* paramgen */,       0 /* keygen_init */,  pkey_rsa_keygen,
515     0 /* sign_init */,      pkey_rsa_sign,        0 /* verify_init */,
516     pkey_rsa_verify,        0 /* signctx_init */, 0 /* signctx */,
517     0 /* verifyctx_init */, 0 /* verifyctx */,    0 /* encrypt_init */,
518     pkey_rsa_encrypt,       0 /* decrypt_init */, pkey_rsa_decrypt,
519     0 /* derive_init */,    0 /* derive */,       pkey_rsa_ctrl,
520 };
521 
EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX * ctx,int padding)522 int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) {
523   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING,
524                            padding, NULL);
525 }
526 
EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX * ctx,int * out_padding)527 int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) {
528   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING,
529                            0, out_padding);
530 }
531 
EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX * ctx,int salt_len)532 int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) {
533   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
534                            (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY),
535                            EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL);
536 }
537 
EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX * ctx,int * out_salt_len)538 int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) {
539   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
540                            (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY),
541                            EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len);
542 }
543 
EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX * ctx,int bits)544 int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) {
545   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
546                            EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL);
547 }
548 
EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX * ctx,BIGNUM * e)549 int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) {
550   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
551                            EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e);
552 }
553 
EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX * ctx,const EVP_MD * md)554 int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
555   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
556                            EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md);
557 }
558 
EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX * ctx,const EVP_MD ** out_md)559 int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
560   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
561                            EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void*) out_md);
562 }
563 
EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX * ctx,const EVP_MD * md)564 int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
565   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
566                            EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
567                            EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void*) md);
568 }
569 
EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX * ctx,const EVP_MD ** out_md)570 int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
571   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
572                            EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
573                            EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void*) out_md);
574 }
575 
EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX * ctx,const uint8_t * label,size_t label_len)576 int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label,
577                                      size_t label_len) {
578   int label_len_int = label_len;
579   if (((size_t) label_len_int) != label_len) {
580     return 0;
581   }
582 
583   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
584                            EVP_PKEY_CTRL_RSA_OAEP_LABEL, label_len,
585                            (void *)label);
586 }
587 
EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX * ctx,const uint8_t ** out_label)588 int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
589                                      const uint8_t **out_label) {
590   CBS label;
591   if (!EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
592                          EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, &label)) {
593     return -1;
594   }
595   if (CBS_len(&label) > INT_MAX) {
596     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_get0_rsa_oaep_label, ERR_R_OVERFLOW);
597     return -1;
598   }
599   *out_label = CBS_data(&label);
600   return (int)CBS_len(&label);
601 }
602