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
75typedef 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
95typedef struct {
96 uint8_t *data;
97 size_t len;
98} RSA_OAEP_LABEL_PARAMS;
99
100static 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
117static 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
148static 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
161static 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
172static 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
210static 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
243static 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
308static 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
339static 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
372static 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
385static 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
397static 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
520static 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
544const 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
562int 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
567int 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
572int 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
578int 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
584int 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
589int 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
594int 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
599int 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
604int 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
610int 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
616int 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
623int 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