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 70typedef 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 90static 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 107static 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 139static 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 158static 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 169static 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 224static 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 263static 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 294static 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 334static 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 347static 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 359static 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 492static 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 515const 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 526int 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 531int 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 536int 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 542int 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 548int 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 553int 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 558int 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 563int 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 568int 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 574int 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 580int 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 592int 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