]>
Commit | Line | Data |
---|---|---|
0f113f3e MC |
1 | /* |
2 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project | |
3 | * 2006. | |
0b6f3c66 DSH |
4 | */ |
5 | /* ==================================================================== | |
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * | |
12 | * 1. Redistributions of source code must retain the above copyright | |
0f113f3e | 13 | * notice, this list of conditions and the following disclaimer. |
0b6f3c66 DSH |
14 | * |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in | |
17 | * the documentation and/or other materials provided with the | |
18 | * distribution. | |
19 | * | |
20 | * 3. All advertising materials mentioning features or use of this | |
21 | * software must display the following acknowledgment: | |
22 | * "This product includes software developed by the OpenSSL Project | |
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
24 | * | |
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
26 | * endorse or promote products derived from this software without | |
27 | * prior written permission. For written permission, please contact | |
28 | * licensing@OpenSSL.org. | |
29 | * | |
30 | * 5. Products derived from this software may not be called "OpenSSL" | |
31 | * nor may "OpenSSL" appear in their names without prior written | |
32 | * permission of the OpenSSL Project. | |
33 | * | |
34 | * 6. Redistributions of any form whatsoever must retain the following | |
35 | * acknowledgment: | |
36 | * "This product includes software developed by the OpenSSL Project | |
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
38 | * | |
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
51 | * ==================================================================== | |
52 | * | |
53 | * This product includes cryptographic software written by Eric Young | |
54 | * (eay@cryptsoft.com). This product includes software written by Tim | |
55 | * Hudson (tjh@cryptsoft.com). | |
56 | * | |
57 | */ | |
58 | ||
59 | #include <stdio.h> | |
b39fc560 | 60 | #include "internal/cryptlib.h" |
0b6f3c66 DSH |
61 | #include <openssl/asn1t.h> |
62 | #include <openssl/x509.h> | |
63 | #include <openssl/rsa.h> | |
1e26a8ba | 64 | #include <openssl/bn.h> |
b2a97be7 | 65 | #include <openssl/evp.h> |
271fef0e | 66 | #include <openssl/x509v3.h> |
3c27208f | 67 | #include <openssl/cms.h> |
27af42f9 | 68 | #include "internal/evp_int.h" |
777c47ac | 69 | #include "rsa_locl.h" |
b2a97be7 | 70 | |
07e970c7 DSH |
71 | /* RSA pkey context structure */ |
72 | ||
0f113f3e MC |
73 | typedef struct { |
74 | /* Key gen parameters */ | |
75 | int nbits; | |
76 | BIGNUM *pub_exp; | |
77 | /* Keygen callback info */ | |
78 | int gentmp[2]; | |
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 | /* Temp buffer */ | |
88 | unsigned char *tbuf; | |
89 | /* OAEP label */ | |
90 | unsigned char *oaep_label; | |
91 | size_t oaep_labellen; | |
92 | } RSA_PKEY_CTX; | |
07e970c7 DSH |
93 | |
94 | static int pkey_rsa_init(EVP_PKEY_CTX *ctx) | |
0f113f3e MC |
95 | { |
96 | RSA_PKEY_CTX *rctx; | |
64b25758 | 97 | rctx = OPENSSL_zalloc(sizeof(*rctx)); |
90945fa3 | 98 | if (rctx == NULL) |
0f113f3e MC |
99 | return 0; |
100 | rctx->nbits = 1024; | |
0f113f3e | 101 | rctx->pad_mode = RSA_PKCS1_PADDING; |
0f113f3e | 102 | rctx->saltlen = -2; |
0f113f3e MC |
103 | ctx->data = rctx; |
104 | ctx->keygen_info = rctx->gentmp; | |
105 | ctx->keygen_info_count = 2; | |
106 | ||
107 | return 1; | |
108 | } | |
b2a97be7 | 109 | |
8bdcef40 | 110 | static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) |
0f113f3e MC |
111 | { |
112 | RSA_PKEY_CTX *dctx, *sctx; | |
113 | if (!pkey_rsa_init(dst)) | |
114 | return 0; | |
115 | sctx = src->data; | |
116 | dctx = dst->data; | |
117 | dctx->nbits = sctx->nbits; | |
118 | if (sctx->pub_exp) { | |
119 | dctx->pub_exp = BN_dup(sctx->pub_exp); | |
120 | if (!dctx->pub_exp) | |
121 | return 0; | |
122 | } | |
123 | dctx->pad_mode = sctx->pad_mode; | |
124 | dctx->md = sctx->md; | |
125 | dctx->mgf1md = sctx->mgf1md; | |
126 | if (sctx->oaep_label) { | |
b548a1f1 | 127 | OPENSSL_free(dctx->oaep_label); |
7644a9ae | 128 | dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen); |
0f113f3e MC |
129 | if (!dctx->oaep_label) |
130 | return 0; | |
131 | dctx->oaep_labellen = sctx->oaep_labellen; | |
132 | } | |
133 | return 1; | |
134 | } | |
8bdcef40 | 135 | |
b2a97be7 | 136 | static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) |
0f113f3e MC |
137 | { |
138 | if (ctx->tbuf) | |
139 | return 1; | |
140 | ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); | |
90945fa3 | 141 | if (ctx->tbuf == NULL) |
0f113f3e MC |
142 | return 0; |
143 | return 1; | |
144 | } | |
07e970c7 DSH |
145 | |
146 | static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) | |
0f113f3e MC |
147 | { |
148 | RSA_PKEY_CTX *rctx = ctx->data; | |
149 | if (rctx) { | |
23a1d5e9 | 150 | BN_free(rctx->pub_exp); |
b548a1f1 RS |
151 | OPENSSL_free(rctx->tbuf); |
152 | OPENSSL_free(rctx->oaep_label); | |
0f113f3e MC |
153 | OPENSSL_free(rctx); |
154 | } | |
155 | } | |
156 | ||
157 | static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, | |
158 | size_t *siglen, const unsigned char *tbs, | |
159 | size_t tbslen) | |
160 | { | |
161 | int ret; | |
162 | RSA_PKEY_CTX *rctx = ctx->data; | |
163 | RSA *rsa = ctx->pkey->pkey.rsa; | |
164 | ||
165 | if (rctx->md) { | |
166 | if (tbslen != (size_t)EVP_MD_size(rctx->md)) { | |
167 | RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); | |
168 | return -1; | |
169 | } | |
170 | ||
171 | if (EVP_MD_type(rctx->md) == NID_mdc2) { | |
172 | unsigned int sltmp; | |
173 | if (rctx->pad_mode != RSA_PKCS1_PADDING) | |
174 | return -1; | |
a773b52a | 175 | ret = RSA_sign_ASN1_OCTET_STRING(0, |
0f113f3e MC |
176 | tbs, tbslen, sig, &sltmp, rsa); |
177 | ||
178 | if (ret <= 0) | |
179 | return ret; | |
180 | ret = sltmp; | |
181 | } else if (rctx->pad_mode == RSA_X931_PADDING) { | |
34166d41 MC |
182 | if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { |
183 | RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL); | |
0f113f3e | 184 | return -1; |
34166d41 MC |
185 | } |
186 | if (!setup_tbuf(rctx, ctx)) { | |
187 | RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE); | |
188 | return -1; | |
189 | } | |
0f113f3e MC |
190 | memcpy(rctx->tbuf, tbs, tbslen); |
191 | rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); | |
192 | ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, | |
193 | sig, rsa, RSA_X931_PADDING); | |
194 | } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { | |
195 | unsigned int sltmp; | |
196 | ret = RSA_sign(EVP_MD_type(rctx->md), | |
197 | tbs, tbslen, sig, &sltmp, rsa); | |
198 | if (ret <= 0) | |
199 | return ret; | |
200 | ret = sltmp; | |
201 | } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { | |
202 | if (!setup_tbuf(rctx, ctx)) | |
203 | return -1; | |
204 | if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, | |
205 | rctx->tbuf, tbs, | |
206 | rctx->md, rctx->mgf1md, | |
207 | rctx->saltlen)) | |
208 | return -1; | |
209 | ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, | |
210 | sig, rsa, RSA_NO_PADDING); | |
211 | } else | |
212 | return -1; | |
213 | } else | |
214 | ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, | |
215 | rctx->pad_mode); | |
216 | if (ret < 0) | |
217 | return ret; | |
218 | *siglen = ret; | |
219 | return 1; | |
220 | } | |
07e970c7 DSH |
221 | |
222 | static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, | |
0f113f3e MC |
223 | unsigned char *rout, size_t *routlen, |
224 | const unsigned char *sig, size_t siglen) | |
225 | { | |
226 | int ret; | |
227 | RSA_PKEY_CTX *rctx = ctx->data; | |
228 | ||
229 | if (rctx->md) { | |
230 | if (rctx->pad_mode == RSA_X931_PADDING) { | |
231 | if (!setup_tbuf(rctx, ctx)) | |
232 | return -1; | |
233 | ret = RSA_public_decrypt(siglen, sig, | |
234 | rctx->tbuf, ctx->pkey->pkey.rsa, | |
235 | RSA_X931_PADDING); | |
236 | if (ret < 1) | |
237 | return 0; | |
238 | ret--; | |
239 | if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_type(rctx->md))) { | |
240 | RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, | |
241 | RSA_R_ALGORITHM_MISMATCH); | |
242 | return 0; | |
243 | } | |
244 | if (ret != EVP_MD_size(rctx->md)) { | |
245 | RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, | |
246 | RSA_R_INVALID_DIGEST_LENGTH); | |
247 | return 0; | |
248 | } | |
249 | if (rout) | |
250 | memcpy(rout, rctx->tbuf, ret); | |
251 | } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { | |
252 | size_t sltmp; | |
253 | ret = int_rsa_verify(EVP_MD_type(rctx->md), | |
254 | NULL, 0, rout, &sltmp, | |
255 | sig, siglen, ctx->pkey->pkey.rsa); | |
256 | if (ret <= 0) | |
257 | return 0; | |
258 | ret = sltmp; | |
259 | } else | |
260 | return -1; | |
261 | } else | |
262 | ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, | |
263 | rctx->pad_mode); | |
264 | if (ret < 0) | |
265 | return ret; | |
266 | *routlen = ret; | |
267 | return 1; | |
268 | } | |
07e970c7 | 269 | |
4f59b658 | 270 | static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, |
0f113f3e MC |
271 | const unsigned char *sig, size_t siglen, |
272 | const unsigned char *tbs, size_t tbslen) | |
273 | { | |
274 | RSA_PKEY_CTX *rctx = ctx->data; | |
275 | RSA *rsa = ctx->pkey->pkey.rsa; | |
276 | size_t rslen; | |
277 | if (rctx->md) { | |
278 | if (rctx->pad_mode == RSA_PKCS1_PADDING) | |
279 | return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, | |
280 | sig, siglen, rsa); | |
281 | if (rctx->pad_mode == RSA_X931_PADDING) { | |
282 | if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0) | |
283 | return 0; | |
284 | } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { | |
285 | int ret; | |
286 | if (!setup_tbuf(rctx, ctx)) | |
287 | return -1; | |
288 | ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, | |
289 | rsa, RSA_NO_PADDING); | |
290 | if (ret <= 0) | |
291 | return 0; | |
292 | ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, | |
293 | rctx->md, rctx->mgf1md, | |
294 | rctx->tbuf, rctx->saltlen); | |
295 | if (ret <= 0) | |
296 | return 0; | |
297 | return 1; | |
298 | } else | |
299 | return -1; | |
300 | } else { | |
301 | if (!setup_tbuf(rctx, ctx)) | |
302 | return -1; | |
303 | rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, | |
304 | rsa, rctx->pad_mode); | |
305 | if (rslen == 0) | |
306 | return 0; | |
307 | } | |
308 | ||
309 | if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) | |
310 | return 0; | |
311 | ||
312 | return 1; | |
313 | ||
314 | } | |
4f59b658 | 315 | |
eaff5a14 | 316 | static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, |
0f113f3e MC |
317 | unsigned char *out, size_t *outlen, |
318 | const unsigned char *in, size_t inlen) | |
319 | { | |
320 | int ret; | |
321 | RSA_PKEY_CTX *rctx = ctx->data; | |
322 | if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { | |
323 | int klen = RSA_size(ctx->pkey->pkey.rsa); | |
324 | if (!setup_tbuf(rctx, ctx)) | |
325 | return -1; | |
326 | if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen, | |
327 | in, inlen, | |
328 | rctx->oaep_label, | |
329 | rctx->oaep_labellen, | |
330 | rctx->md, rctx->mgf1md)) | |
331 | return -1; | |
332 | ret = RSA_public_encrypt(klen, rctx->tbuf, out, | |
333 | ctx->pkey->pkey.rsa, RSA_NO_PADDING); | |
334 | } else | |
335 | ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, | |
336 | rctx->pad_mode); | |
337 | if (ret < 0) | |
338 | return ret; | |
339 | *outlen = ret; | |
340 | return 1; | |
341 | } | |
8cd44e36 | 342 | |
eaff5a14 | 343 | static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, |
0f113f3e MC |
344 | unsigned char *out, size_t *outlen, |
345 | const unsigned char *in, size_t inlen) | |
346 | { | |
347 | int ret; | |
348 | RSA_PKEY_CTX *rctx = ctx->data; | |
349 | if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { | |
350 | int i; | |
351 | if (!setup_tbuf(rctx, ctx)) | |
352 | return -1; | |
353 | ret = RSA_private_decrypt(inlen, in, rctx->tbuf, | |
354 | ctx->pkey->pkey.rsa, RSA_NO_PADDING); | |
355 | if (ret <= 0) | |
356 | return ret; | |
357 | for (i = 0; i < ret; i++) { | |
358 | if (rctx->tbuf[i]) | |
359 | break; | |
360 | } | |
361 | ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf + i, | |
362 | ret - i, ret, | |
363 | rctx->oaep_label, | |
364 | rctx->oaep_labellen, | |
365 | rctx->md, rctx->mgf1md); | |
366 | } else | |
367 | ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, | |
368 | rctx->pad_mode); | |
369 | if (ret < 0) | |
370 | return ret; | |
371 | *outlen = ret; | |
372 | return 1; | |
373 | } | |
07e970c7 | 374 | |
75d44c04 | 375 | static int check_padding_md(const EVP_MD *md, int padding) |
0f113f3e | 376 | { |
7f572e95 | 377 | int mdnid; |
0f113f3e MC |
378 | if (!md) |
379 | return 1; | |
380 | ||
7f572e95 DSH |
381 | mdnid = EVP_MD_type(md); |
382 | ||
0f113f3e MC |
383 | if (padding == RSA_NO_PADDING) { |
384 | RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); | |
385 | return 0; | |
386 | } | |
387 | ||
388 | if (padding == RSA_X931_PADDING) { | |
7f572e95 | 389 | if (RSA_X931_hash_id(mdnid) == -1) { |
0f113f3e MC |
390 | RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); |
391 | return 0; | |
392 | } | |
7f572e95 DSH |
393 | } else { |
394 | switch(mdnid) { | |
395 | /* List of all supported RSA digests */ | |
396 | case NID_sha1: | |
397 | case NID_sha224: | |
398 | case NID_sha256: | |
399 | case NID_sha384: | |
400 | case NID_sha512: | |
401 | case NID_md5: | |
402 | case NID_md5_sha1: | |
403 | case NID_md2: | |
404 | case NID_md4: | |
405 | case NID_mdc2: | |
406 | case NID_ripemd160: | |
407 | return 1; | |
408 | ||
409 | default: | |
410 | RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_DIGEST); | |
411 | return 0; | |
412 | ||
413 | } | |
0f113f3e MC |
414 | } |
415 | ||
416 | return 1; | |
417 | } | |
b2a97be7 | 418 | |
4a3dc3c0 | 419 | static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) |
0f113f3e MC |
420 | { |
421 | RSA_PKEY_CTX *rctx = ctx->data; | |
422 | switch (type) { | |
423 | case EVP_PKEY_CTRL_RSA_PADDING: | |
424 | if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { | |
425 | if (!check_padding_md(rctx->md, p1)) | |
426 | return 0; | |
427 | if (p1 == RSA_PKCS1_PSS_PADDING) { | |
428 | if (!(ctx->operation & | |
429 | (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) | |
430 | goto bad_pad; | |
431 | if (!rctx->md) | |
432 | rctx->md = EVP_sha1(); | |
433 | } | |
434 | if (p1 == RSA_PKCS1_OAEP_PADDING) { | |
435 | if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) | |
436 | goto bad_pad; | |
437 | if (!rctx->md) | |
438 | rctx->md = EVP_sha1(); | |
439 | } | |
440 | rctx->pad_mode = p1; | |
441 | return 1; | |
442 | } | |
443 | bad_pad: | |
444 | RSAerr(RSA_F_PKEY_RSA_CTRL, | |
445 | RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); | |
446 | return -2; | |
447 | ||
448 | case EVP_PKEY_CTRL_GET_RSA_PADDING: | |
449 | *(int *)p2 = rctx->pad_mode; | |
450 | return 1; | |
451 | ||
452 | case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: | |
453 | case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: | |
454 | if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { | |
455 | RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); | |
456 | return -2; | |
457 | } | |
458 | if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) | |
459 | *(int *)p2 = rctx->saltlen; | |
460 | else { | |
461 | if (p1 < -2) | |
462 | return -2; | |
463 | rctx->saltlen = p1; | |
464 | } | |
465 | return 1; | |
466 | ||
467 | case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: | |
468 | if (p1 < 512) { | |
469 | RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL); | |
470 | return -2; | |
471 | } | |
472 | rctx->nbits = p1; | |
473 | return 1; | |
474 | ||
475 | case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: | |
476 | if (!p2) | |
477 | return -2; | |
478 | BN_free(rctx->pub_exp); | |
479 | rctx->pub_exp = p2; | |
480 | return 1; | |
481 | ||
482 | case EVP_PKEY_CTRL_RSA_OAEP_MD: | |
483 | case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: | |
484 | if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { | |
485 | RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); | |
486 | return -2; | |
487 | } | |
488 | if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) | |
489 | *(const EVP_MD **)p2 = rctx->md; | |
490 | else | |
491 | rctx->md = p2; | |
492 | return 1; | |
493 | ||
494 | case EVP_PKEY_CTRL_MD: | |
495 | if (!check_padding_md(p2, rctx->pad_mode)) | |
496 | return 0; | |
497 | rctx->md = p2; | |
498 | return 1; | |
499 | ||
500 | case EVP_PKEY_CTRL_GET_MD: | |
501 | *(const EVP_MD **)p2 = rctx->md; | |
502 | return 1; | |
503 | ||
504 | case EVP_PKEY_CTRL_RSA_MGF1_MD: | |
505 | case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: | |
506 | if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING | |
507 | && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { | |
508 | RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); | |
509 | return -2; | |
510 | } | |
511 | if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { | |
512 | if (rctx->mgf1md) | |
513 | *(const EVP_MD **)p2 = rctx->mgf1md; | |
514 | else | |
515 | *(const EVP_MD **)p2 = rctx->md; | |
516 | } else | |
517 | rctx->mgf1md = p2; | |
518 | return 1; | |
519 | ||
520 | case EVP_PKEY_CTRL_RSA_OAEP_LABEL: | |
521 | if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { | |
522 | RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); | |
523 | return -2; | |
524 | } | |
b548a1f1 | 525 | OPENSSL_free(rctx->oaep_label); |
0f113f3e MC |
526 | if (p2 && p1 > 0) { |
527 | rctx->oaep_label = p2; | |
528 | rctx->oaep_labellen = p1; | |
529 | } else { | |
530 | rctx->oaep_label = NULL; | |
531 | rctx->oaep_labellen = 0; | |
532 | } | |
533 | return 1; | |
534 | ||
535 | case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: | |
536 | if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { | |
537 | RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); | |
538 | return -2; | |
539 | } | |
540 | *(unsigned char **)p2 = rctx->oaep_label; | |
541 | return rctx->oaep_labellen; | |
542 | ||
543 | case EVP_PKEY_CTRL_DIGESTINIT: | |
544 | case EVP_PKEY_CTRL_PKCS7_ENCRYPT: | |
545 | case EVP_PKEY_CTRL_PKCS7_DECRYPT: | |
546 | case EVP_PKEY_CTRL_PKCS7_SIGN: | |
547 | return 1; | |
8931b30d | 548 | #ifndef OPENSSL_NO_CMS |
0f113f3e MC |
549 | case EVP_PKEY_CTRL_CMS_DECRYPT: |
550 | case EVP_PKEY_CTRL_CMS_ENCRYPT: | |
551 | case EVP_PKEY_CTRL_CMS_SIGN: | |
552 | return 1; | |
b3339050 | 553 | #endif |
0f113f3e MC |
554 | case EVP_PKEY_CTRL_PEER_KEY: |
555 | RSAerr(RSA_F_PKEY_RSA_CTRL, | |
556 | RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | |
557 | return -2; | |
558 | ||
559 | default: | |
560 | return -2; | |
399a6f0b | 561 | |
0f113f3e MC |
562 | } |
563 | } | |
4a3dc3c0 | 564 | |
4a3dc3c0 | 565 | static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, |
0f113f3e MC |
566 | const char *type, const char *value) |
567 | { | |
568 | if (!value) { | |
569 | RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); | |
570 | return 0; | |
571 | } | |
86885c28 | 572 | if (strcmp(type, "rsa_padding_mode") == 0) { |
0f113f3e | 573 | int pm; |
86885c28 | 574 | if (strcmp(value, "pkcs1") == 0) |
0f113f3e | 575 | pm = RSA_PKCS1_PADDING; |
86885c28 | 576 | else if (strcmp(value, "sslv23") == 0) |
0f113f3e | 577 | pm = RSA_SSLV23_PADDING; |
86885c28 | 578 | else if (strcmp(value, "none") == 0) |
0f113f3e | 579 | pm = RSA_NO_PADDING; |
86885c28 | 580 | else if (strcmp(value, "oeap") == 0) |
0f113f3e | 581 | pm = RSA_PKCS1_OAEP_PADDING; |
86885c28 | 582 | else if (strcmp(value, "oaep") == 0) |
0f113f3e | 583 | pm = RSA_PKCS1_OAEP_PADDING; |
86885c28 | 584 | else if (strcmp(value, "x931") == 0) |
0f113f3e | 585 | pm = RSA_X931_PADDING; |
86885c28 | 586 | else if (strcmp(value, "pss") == 0) |
0f113f3e MC |
587 | pm = RSA_PKCS1_PSS_PADDING; |
588 | else { | |
589 | RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); | |
590 | return -2; | |
591 | } | |
592 | return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); | |
593 | } | |
594 | ||
86885c28 | 595 | if (strcmp(type, "rsa_pss_saltlen") == 0) { |
0f113f3e MC |
596 | int saltlen; |
597 | saltlen = atoi(value); | |
598 | return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); | |
599 | } | |
600 | ||
86885c28 | 601 | if (strcmp(type, "rsa_keygen_bits") == 0) { |
0f113f3e MC |
602 | int nbits; |
603 | nbits = atoi(value); | |
604 | return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); | |
605 | } | |
606 | ||
86885c28 | 607 | if (strcmp(type, "rsa_keygen_pubexp") == 0) { |
0f113f3e MC |
608 | int ret; |
609 | BIGNUM *pubexp = NULL; | |
610 | if (!BN_asc2bn(&pubexp, value)) | |
611 | return 0; | |
612 | ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); | |
613 | if (ret <= 0) | |
614 | BN_free(pubexp); | |
615 | return ret; | |
616 | } | |
617 | ||
86885c28 | 618 | if (strcmp(type, "rsa_mgf1_md") == 0) { |
0f113f3e | 619 | const EVP_MD *md; |
75ebbd9a | 620 | if ((md = EVP_get_digestbyname(value)) == NULL) { |
0f113f3e MC |
621 | RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); |
622 | return 0; | |
623 | } | |
624 | return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md); | |
625 | } | |
626 | ||
86885c28 | 627 | if (strcmp(type, "rsa_oaep_md") == 0) { |
0f113f3e | 628 | const EVP_MD *md; |
75ebbd9a | 629 | if ((md = EVP_get_digestbyname(value)) == NULL) { |
0f113f3e MC |
630 | RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); |
631 | return 0; | |
632 | } | |
633 | return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md); | |
634 | } | |
86885c28 | 635 | if (strcmp(type, "rsa_oaep_label") == 0) { |
0f113f3e MC |
636 | unsigned char *lab; |
637 | long lablen; | |
638 | int ret; | |
14f051a0 | 639 | lab = OPENSSL_hexstr2buf(value, &lablen); |
0f113f3e MC |
640 | if (!lab) |
641 | return 0; | |
642 | ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); | |
643 | if (ret <= 0) | |
644 | OPENSSL_free(lab); | |
645 | return ret; | |
646 | } | |
647 | ||
648 | return -2; | |
649 | } | |
4a3dc3c0 | 650 | |
f5cda4cb | 651 | static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
0f113f3e MC |
652 | { |
653 | RSA *rsa = NULL; | |
654 | RSA_PKEY_CTX *rctx = ctx->data; | |
655 | BN_GENCB *pcb; | |
656 | int ret; | |
90945fa3 | 657 | if (rctx->pub_exp == NULL) { |
0f113f3e | 658 | rctx->pub_exp = BN_new(); |
90945fa3 | 659 | if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4)) |
0f113f3e MC |
660 | return 0; |
661 | } | |
662 | rsa = RSA_new(); | |
90945fa3 | 663 | if (rsa == NULL) |
0f113f3e MC |
664 | return 0; |
665 | if (ctx->pkey_gencb) { | |
666 | pcb = BN_GENCB_new(); | |
90945fa3 | 667 | if (pcb == NULL) { |
0f113f3e MC |
668 | RSA_free(rsa); |
669 | return 0; | |
670 | } | |
671 | evp_pkey_set_cb_translate(pcb, ctx); | |
672 | } else | |
673 | pcb = NULL; | |
674 | ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); | |
675 | BN_GENCB_free(pcb); | |
676 | if (ret > 0) | |
677 | EVP_PKEY_assign_RSA(pkey, rsa); | |
678 | else | |
679 | RSA_free(rsa); | |
680 | return ret; | |
681 | } | |
682 | ||
683 | const EVP_PKEY_METHOD rsa_pkey_meth = { | |
684 | EVP_PKEY_RSA, | |
685 | EVP_PKEY_FLAG_AUTOARGLEN, | |
686 | pkey_rsa_init, | |
687 | pkey_rsa_copy, | |
688 | pkey_rsa_cleanup, | |
689 | ||
690 | 0, 0, | |
691 | ||
692 | 0, | |
693 | pkey_rsa_keygen, | |
694 | ||
695 | 0, | |
696 | pkey_rsa_sign, | |
697 | ||
698 | 0, | |
699 | pkey_rsa_verify, | |
700 | ||
701 | 0, | |
702 | pkey_rsa_verifyrecover, | |
703 | ||
704 | 0, 0, 0, 0, | |
705 | ||
706 | 0, | |
707 | pkey_rsa_encrypt, | |
708 | ||
709 | 0, | |
710 | pkey_rsa_decrypt, | |
711 | ||
712 | 0, 0, | |
713 | ||
714 | pkey_rsa_ctrl, | |
715 | pkey_rsa_ctrl_str | |
716 | }; |