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