• 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/nid.h>
68 #include <openssl/rsa.h>
69 
70 #include "../internal.h"
71 #include "../fipsmodule/rsa/internal.h"
72 #include "internal.h"
73 
74 
75 typedef struct {
76   // Key gen parameters
77   int nbits;
78   BIGNUM *pub_exp;
79   // RSA padding mode
80   int pad_mode;
81   // message digest
82   const EVP_MD *md;
83   // message digest for MGF1
84   const EVP_MD *mgf1md;
85   // PSS salt length
86   int saltlen;
87   // tbuf is a buffer which is either NULL, or is the size of the RSA modulus.
88   // It's used to store the output of RSA operations.
89   uint8_t *tbuf;
90   // OAEP label
91   uint8_t *oaep_label;
92   size_t oaep_labellen;
93 } RSA_PKEY_CTX;
94 
95 typedef struct {
96   uint8_t *data;
97   size_t len;
98 } RSA_OAEP_LABEL_PARAMS;
99 
pkey_rsa_init(EVP_PKEY_CTX * ctx)100 static int pkey_rsa_init(EVP_PKEY_CTX *ctx) {
101   RSA_PKEY_CTX *rctx;
102   rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
103   if (!rctx) {
104     return 0;
105   }
106   OPENSSL_memset(rctx, 0, sizeof(RSA_PKEY_CTX));
107 
108   rctx->nbits = 2048;
109   rctx->pad_mode = RSA_PKCS1_PADDING;
110   rctx->saltlen = -2;
111 
112   ctx->data = rctx;
113 
114   return 1;
115 }
116 
pkey_rsa_copy(EVP_PKEY_CTX * dst,EVP_PKEY_CTX * src)117 static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
118   RSA_PKEY_CTX *dctx, *sctx;
119   if (!pkey_rsa_init(dst)) {
120     return 0;
121   }
122   sctx = src->data;
123   dctx = dst->data;
124   dctx->nbits = sctx->nbits;
125   if (sctx->pub_exp) {
126     dctx->pub_exp = BN_dup(sctx->pub_exp);
127     if (!dctx->pub_exp) {
128       return 0;
129     }
130   }
131 
132   dctx->pad_mode = sctx->pad_mode;
133   dctx->md = sctx->md;
134   dctx->mgf1md = sctx->mgf1md;
135   if (sctx->oaep_label) {
136     OPENSSL_free(dctx->oaep_label);
137     dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen);
138     if (!dctx->oaep_label) {
139       return 0;
140     }
141     dctx->oaep_labellen = sctx->oaep_labellen;
142   }
143 
144   return 1;
145 }
146 
pkey_rsa_cleanup(EVP_PKEY_CTX * ctx)147 static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) {
148   RSA_PKEY_CTX *rctx = ctx->data;
149 
150   if (rctx == NULL) {
151     return;
152   }
153 
154   BN_free(rctx->pub_exp);
155   OPENSSL_free(rctx->tbuf);
156   OPENSSL_free(rctx->oaep_label);
157   OPENSSL_free(rctx);
158 }
159 
setup_tbuf(RSA_PKEY_CTX * ctx,EVP_PKEY_CTX * pk)160 static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) {
161   if (ctx->tbuf) {
162     return 1;
163   }
164   ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
165   if (!ctx->tbuf) {
166     return 0;
167   }
168   return 1;
169 }
170 
pkey_rsa_sign(EVP_PKEY_CTX * ctx,uint8_t * sig,size_t * siglen,const uint8_t * tbs,size_t tbslen)171 static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
172                          const uint8_t *tbs, size_t tbslen) {
173   RSA_PKEY_CTX *rctx = ctx->data;
174   RSA *rsa = ctx->pkey->pkey.rsa;
175   const size_t key_len = EVP_PKEY_size(ctx->pkey);
176 
177   if (!sig) {
178     *siglen = key_len;
179     return 1;
180   }
181 
182   if (*siglen < key_len) {
183     OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
184     return 0;
185   }
186 
187   if (rctx->md) {
188     unsigned out_len;
189     switch (rctx->pad_mode) {
190       case RSA_PKCS1_PADDING:
191         if (!RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &out_len, rsa)) {
192           return 0;
193         }
194         *siglen = out_len;
195         return 1;
196 
197       case RSA_PKCS1_PSS_PADDING:
198         return RSA_sign_pss_mgf1(rsa, siglen, sig, *siglen, tbs, tbslen,
199                                  rctx->md, rctx->mgf1md, rctx->saltlen);
200 
201       default:
202         return 0;
203     }
204   }
205 
206   return RSA_sign_raw(rsa, siglen, sig, *siglen, tbs, tbslen, rctx->pad_mode);
207 }
208 
pkey_rsa_verify(EVP_PKEY_CTX * ctx,const uint8_t * sig,size_t siglen,const uint8_t * tbs,size_t tbslen)209 static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig,
210                            size_t siglen, const uint8_t *tbs,
211                            size_t tbslen) {
212   RSA_PKEY_CTX *rctx = ctx->data;
213   RSA *rsa = ctx->pkey->pkey.rsa;
214 
215   if (rctx->md) {
216     switch (rctx->pad_mode) {
217       case RSA_PKCS1_PADDING:
218         return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa);
219 
220       case RSA_PKCS1_PSS_PADDING:
221         return RSA_verify_pss_mgf1(rsa, tbs, tbslen, rctx->md, rctx->mgf1md,
222                                    rctx->saltlen, sig, siglen);
223 
224       default:
225         return 0;
226     }
227   }
228 
229   size_t rslen;
230   const size_t key_len = EVP_PKEY_size(ctx->pkey);
231   if (!setup_tbuf(rctx, ctx) ||
232       !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen,
233                       rctx->pad_mode) ||
234       rslen != tbslen ||
235       CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) {
236     return 0;
237   }
238 
239   return 1;
240 }
241 
pkey_rsa_verify_recover(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * out_len,const uint8_t * sig,size_t sig_len)242 static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out,
243                                    size_t *out_len, const uint8_t *sig,
244                                    size_t sig_len) {
245   RSA_PKEY_CTX *rctx = ctx->data;
246   RSA *rsa = ctx->pkey->pkey.rsa;
247   const size_t key_len = EVP_PKEY_size(ctx->pkey);
248 
249   if (out == NULL) {
250     *out_len = key_len;
251     return 1;
252   }
253 
254   if (*out_len < key_len) {
255     OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
256     return 0;
257   }
258 
259   if (rctx->md == NULL) {
260     return RSA_verify_raw(rsa, out_len, out, *out_len, sig, sig_len,
261                           rctx->pad_mode);
262   }
263 
264   if (rctx->pad_mode != RSA_PKCS1_PADDING) {
265     return 0;
266   }
267 
268   // Assemble the encoded hash, using a placeholder hash value.
269   static const uint8_t kDummyHash[EVP_MAX_MD_SIZE] = {0};
270   const size_t hash_len = EVP_MD_size(rctx->md);
271   uint8_t *asn1_prefix;
272   size_t asn1_prefix_len;
273   int asn1_prefix_allocated;
274   if (!setup_tbuf(rctx, ctx) ||
275       !RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len,
276                             &asn1_prefix_allocated, EVP_MD_type(rctx->md),
277                             kDummyHash, hash_len)) {
278     return 0;
279   }
280 
281   size_t rslen;
282   int ok = 1;
283   if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len,
284                       RSA_PKCS1_PADDING) ||
285       rslen != asn1_prefix_len ||
286       // Compare all but the hash suffix.
287       CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len - hash_len) != 0) {
288     ok = 0;
289   }
290 
291   if (asn1_prefix_allocated) {
292     OPENSSL_free(asn1_prefix);
293   }
294 
295   if (!ok) {
296     return 0;
297   }
298 
299   if (out != NULL) {
300     OPENSSL_memcpy(out, rctx->tbuf + rslen - hash_len, hash_len);
301   }
302   *out_len = hash_len;
303 
304   return 1;
305 }
306 
pkey_rsa_encrypt(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * outlen,const uint8_t * in,size_t inlen)307 static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
308                             const uint8_t *in, size_t inlen) {
309   RSA_PKEY_CTX *rctx = ctx->data;
310   RSA *rsa = ctx->pkey->pkey.rsa;
311   const size_t key_len = EVP_PKEY_size(ctx->pkey);
312 
313   if (!out) {
314     *outlen = key_len;
315     return 1;
316   }
317 
318   if (*outlen < key_len) {
319     OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
320     return 0;
321   }
322 
323   if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
324     if (!setup_tbuf(rctx, ctx) ||
325         !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen,
326                                          rctx->oaep_label, rctx->oaep_labellen,
327                                          rctx->md, rctx->mgf1md) ||
328         !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len,
329                      RSA_NO_PADDING)) {
330       return 0;
331     }
332     return 1;
333   }
334 
335   return RSA_encrypt(rsa, outlen, out, *outlen, in, inlen, rctx->pad_mode);
336 }
337 
pkey_rsa_decrypt(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * outlen,const uint8_t * in,size_t inlen)338 static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out,
339                             size_t *outlen, const uint8_t *in,
340                             size_t inlen) {
341   RSA_PKEY_CTX *rctx = ctx->data;
342   RSA *rsa = ctx->pkey->pkey.rsa;
343   const size_t key_len = EVP_PKEY_size(ctx->pkey);
344 
345   if (!out) {
346     *outlen = key_len;
347     return 1;
348   }
349 
350   if (*outlen < key_len) {
351     OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
352     return 0;
353   }
354 
355   if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
356     size_t padded_len;
357     if (!setup_tbuf(rctx, ctx) ||
358         !RSA_decrypt(rsa, &padded_len, rctx->tbuf, key_len, in, inlen,
359                      RSA_NO_PADDING) ||
360         !RSA_padding_check_PKCS1_OAEP_mgf1(
361             out, outlen, key_len, rctx->tbuf, padded_len, rctx->oaep_label,
362             rctx->oaep_labellen, rctx->md, rctx->mgf1md)) {
363       return 0;
364     }
365     return 1;
366   }
367 
368   return RSA_decrypt(rsa, outlen, out, key_len, in, inlen, rctx->pad_mode);
369 }
370 
check_padding_md(const EVP_MD * md,int padding)371 static int check_padding_md(const EVP_MD *md, int padding) {
372   if (!md) {
373     return 1;
374   }
375 
376   if (padding == RSA_NO_PADDING) {
377     OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
378     return 0;
379   }
380 
381   return 1;
382 }
383 
is_known_padding(int padding_mode)384 static int is_known_padding(int padding_mode) {
385   switch (padding_mode) {
386     case RSA_PKCS1_PADDING:
387     case RSA_NO_PADDING:
388     case RSA_PKCS1_OAEP_PADDING:
389     case RSA_PKCS1_PSS_PADDING:
390       return 1;
391     default:
392       return 0;
393   }
394 }
395 
pkey_rsa_ctrl(EVP_PKEY_CTX * ctx,int type,int p1,void * p2)396 static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
397   RSA_PKEY_CTX *rctx = ctx->data;
398   switch (type) {
399     case EVP_PKEY_CTRL_RSA_PADDING:
400       if (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) ||
401           (p1 == RSA_PKCS1_PSS_PADDING &&
402            0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) ||
403           (p1 == RSA_PKCS1_OAEP_PADDING &&
404            0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) {
405         OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
406         return 0;
407       }
408       if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) &&
409           rctx->md == NULL) {
410         rctx->md = EVP_sha1();
411       }
412       rctx->pad_mode = p1;
413       return 1;
414 
415     case EVP_PKEY_CTRL_GET_RSA_PADDING:
416       *(int *)p2 = rctx->pad_mode;
417       return 1;
418 
419     case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
420     case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
421       if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
422         OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN);
423         return 0;
424       }
425       if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
426         *(int *)p2 = rctx->saltlen;
427       } else {
428         if (p1 < -2) {
429           return 0;
430         }
431         rctx->saltlen = p1;
432       }
433       return 1;
434 
435     case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
436       if (p1 < 256) {
437         OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_KEYBITS);
438         return 0;
439       }
440       rctx->nbits = p1;
441       return 1;
442 
443     case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
444       if (!p2) {
445         return 0;
446       }
447       BN_free(rctx->pub_exp);
448       rctx->pub_exp = p2;
449       return 1;
450 
451     case EVP_PKEY_CTRL_RSA_OAEP_MD:
452     case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
453       if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
454         OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
455         return 0;
456       }
457       if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) {
458         *(const EVP_MD **)p2 = rctx->md;
459       } else {
460         rctx->md = p2;
461       }
462       return 1;
463 
464     case EVP_PKEY_CTRL_MD:
465       if (!check_padding_md(p2, rctx->pad_mode)) {
466         return 0;
467       }
468       rctx->md = p2;
469       return 1;
470 
471     case EVP_PKEY_CTRL_GET_MD:
472       *(const EVP_MD **)p2 = rctx->md;
473       return 1;
474 
475     case EVP_PKEY_CTRL_RSA_MGF1_MD:
476     case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
477       if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING &&
478           rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
479         OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD);
480         return 0;
481       }
482       if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
483         if (rctx->mgf1md) {
484           *(const EVP_MD **)p2 = rctx->mgf1md;
485         } else {
486           *(const EVP_MD **)p2 = rctx->md;
487         }
488       } else {
489         rctx->mgf1md = p2;
490       }
491       return 1;
492 
493     case EVP_PKEY_CTRL_RSA_OAEP_LABEL: {
494       if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
495         OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
496         return 0;
497       }
498       OPENSSL_free(rctx->oaep_label);
499       RSA_OAEP_LABEL_PARAMS *params = p2;
500       rctx->oaep_label = params->data;
501       rctx->oaep_labellen = params->len;
502       return 1;
503     }
504 
505     case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
506       if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
507         OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
508         return 0;
509       }
510       CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen);
511       return 1;
512 
513     default:
514       OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
515       return 0;
516   }
517 }
518 
pkey_rsa_keygen(EVP_PKEY_CTX * ctx,EVP_PKEY * pkey)519 static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
520   RSA *rsa = NULL;
521   RSA_PKEY_CTX *rctx = ctx->data;
522 
523   if (!rctx->pub_exp) {
524     rctx->pub_exp = BN_new();
525     if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) {
526       return 0;
527     }
528   }
529   rsa = RSA_new();
530   if (!rsa) {
531     return 0;
532   }
533 
534   if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) {
535     RSA_free(rsa);
536     return 0;
537   }
538 
539   EVP_PKEY_assign_RSA(pkey, rsa);
540   return 1;
541 }
542 
543 const EVP_PKEY_METHOD rsa_pkey_meth = {
544     EVP_PKEY_RSA,
545     pkey_rsa_init,
546     pkey_rsa_copy,
547     pkey_rsa_cleanup,
548     pkey_rsa_keygen,
549     pkey_rsa_sign,
550     NULL /* sign_message */,
551     pkey_rsa_verify,
552     NULL /* verify_message */,
553     pkey_rsa_verify_recover,
554     pkey_rsa_encrypt,
555     pkey_rsa_decrypt,
556     0 /* derive */,
557     pkey_rsa_ctrl,
558 };
559 
EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX * ctx,int padding)560 int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) {
561   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING,
562                            padding, NULL);
563 }
564 
EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX * ctx,int * out_padding)565 int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) {
566   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING,
567                            0, out_padding);
568 }
569 
EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX * ctx,int salt_len)570 int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) {
571   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
572                            (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY),
573                            EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL);
574 }
575 
EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX * ctx,int * out_salt_len)576 int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) {
577   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
578                            (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY),
579                            EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len);
580 }
581 
EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX * ctx,int bits)582 int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) {
583   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
584                            EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL);
585 }
586 
EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX * ctx,BIGNUM * e)587 int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) {
588   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
589                            EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e);
590 }
591 
EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX * ctx,const EVP_MD * md)592 int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
593   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
594                            EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md);
595 }
596 
EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX * ctx,const EVP_MD ** out_md)597 int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
598   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
599                            EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void*) out_md);
600 }
601 
EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX * ctx,const EVP_MD * md)602 int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
603   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
604                            EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
605                            EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void*) md);
606 }
607 
EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX * ctx,const EVP_MD ** out_md)608 int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
609   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
610                            EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
611                            EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void*) out_md);
612 }
613 
EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX * ctx,uint8_t * label,size_t label_len)614 int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label,
615                                      size_t label_len) {
616   RSA_OAEP_LABEL_PARAMS params = {label, label_len};
617   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
618                            EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, &params);
619 }
620 
EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX * ctx,const uint8_t ** out_label)621 int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
622                                      const uint8_t **out_label) {
623   CBS label;
624   if (!EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
625                          EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, &label)) {
626     return -1;
627   }
628   if (CBS_len(&label) > INT_MAX) {
629     OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
630     return -1;
631   }
632   *out_label = CBS_data(&label);
633   return (int)CBS_len(&label);
634 }
635