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