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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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, ¶ms); |
621 | } |
622 | |
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 | |