| 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 |  | 
|---|