blob: 59271263de8520ae575d4c7a9619140fbdf89a71 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57#include <openssl/rsa.h>
58
Adam Langley2b2d66d2015-01-30 17:08:37 -080059#include <string.h>
60
Adam Langley95c29f32014-06-20 12:00:00 -070061#include <openssl/bn.h>
62#include <openssl/err.h>
63#include <openssl/mem.h>
64
65#include "internal.h"
66
67
68#define OPENSSL_RSA_MAX_MODULUS_BITS 16384
69#define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
70#define OPENSSL_RSA_MAX_PUBEXP_BITS \
71 64 /* exponent limit enforced for "large" modulus only */
72
73
74static int finish(RSA *rsa) {
75 if (rsa->_method_mod_n != NULL) {
76 BN_MONT_CTX_free(rsa->_method_mod_n);
77 }
78 if (rsa->_method_mod_p != NULL) {
79 BN_MONT_CTX_free(rsa->_method_mod_p);
80 }
81 if (rsa->_method_mod_q != NULL) {
82 BN_MONT_CTX_free(rsa->_method_mod_q);
83 }
84
85 return 1;
86}
87
David Benjamin925fee32014-07-11 14:14:08 -040088static size_t size(const RSA *rsa) {
89 return BN_num_bytes(rsa->n);
90}
91
Adam Langley95c29f32014-06-20 12:00:00 -070092static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
93 const uint8_t *in, size_t in_len, int padding) {
94 const unsigned rsa_size = RSA_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -070095 BIGNUM *f, *result;
96 uint8_t *buf = NULL;
97 BN_CTX *ctx = NULL;
Adam Langley6887edb2014-06-20 12:00:00 -070098 int i, ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -070099
100 if (rsa_size > OPENSSL_RSA_MAX_MODULUS_BITS) {
101 OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_MODULUS_TOO_LARGE);
102 return 0;
103 }
104
105 if (max_out < rsa_size) {
106 OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
107 return 0;
108 }
109
110 if (BN_ucmp(rsa->n, rsa->e) <= 0) {
111 OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_BAD_E_VALUE);
112 return 0;
113 }
114
115 /* for large moduli, enforce exponent limit */
116 if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
117 BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
118 OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_BAD_E_VALUE);
119 return 0;
120 }
121
122 ctx = BN_CTX_new();
123 if (ctx == NULL) {
124 goto err;
125 }
126
127 BN_CTX_start(ctx);
128 f = BN_CTX_get(ctx);
129 result = BN_CTX_get(ctx);
130 buf = OPENSSL_malloc(rsa_size);
131 if (!f || !result || !buf) {
132 OPENSSL_PUT_ERROR(RSA, encrypt, ERR_R_MALLOC_FAILURE);
133 goto err;
134 }
135
136 switch (padding) {
137 case RSA_PKCS1_PADDING:
138 i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len);
139 break;
140 case RSA_PKCS1_OAEP_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700141 /* Use the default parameters: SHA-1 for both hashes and no label. */
142 i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len,
143 NULL, 0, NULL, NULL);
Adam Langley95c29f32014-06-20 12:00:00 -0700144 break;
Adam Langley95c29f32014-06-20 12:00:00 -0700145 case RSA_NO_PADDING:
146 i = RSA_padding_add_none(buf, rsa_size, in, in_len);
147 break;
148 default:
149 OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_UNKNOWN_PADDING_TYPE);
150 goto err;
151 }
152
153 if (i <= 0) {
154 goto err;
155 }
156
157 if (BN_bin2bn(buf, rsa_size, f) == NULL) {
158 goto err;
159 }
160
161 if (BN_ucmp(f, rsa->n) >= 0) {
162 /* usually the padding functions would catch this */
163 OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
164 goto err;
165 }
166
167 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
168 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n,
169 ctx)) {
170 goto err;
171 }
172 }
173
174 if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) {
175 goto err;
176 }
177
178 /* put in leading 0 bytes if the number is less than the length of the
179 * modulus */
Adam Langley6887edb2014-06-20 12:00:00 -0700180 if (!BN_bn2bin_padded(out, rsa_size, result)) {
181 OPENSSL_PUT_ERROR(RSA, encrypt, ERR_R_INTERNAL_ERROR);
182 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700183 }
184
185 *out_len = rsa_size;
186 ret = 1;
187
188err:
189 if (ctx != NULL) {
190 BN_CTX_end(ctx);
191 BN_CTX_free(ctx);
192 }
193 if (buf != NULL) {
194 OPENSSL_cleanse(buf, rsa_size);
195 OPENSSL_free(buf);
196 }
197
198 return ret;
199}
200
201/* MAX_BLINDINGS_PER_RSA defines the maximum number of cached BN_BLINDINGs per
202 * RSA*. Then this limit is exceeded, BN_BLINDING objects will be created and
203 * destroyed as needed. */
204#define MAX_BLINDINGS_PER_RSA 1024
205
206/* rsa_blinding_get returns a BN_BLINDING to use with |rsa|. It does this by
207 * allocating one of the cached BN_BLINDING objects in |rsa->blindings|. If
208 * none are free, the cache will be extended by a extra element and the new
209 * BN_BLINDING is returned.
210 *
211 * On success, the index of the assigned BN_BLINDING is written to
212 * |*index_used| and must be passed to |rsa_blinding_release| when finished. */
213static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used,
214 BN_CTX *ctx) {
215 BN_BLINDING *ret = NULL;
216 BN_BLINDING **new_blindings;
217 uint8_t *new_blindings_inuse;
218 char overflow = 0;
219
220 CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
221 if (rsa->num_blindings > 0) {
222 unsigned i, starting_index;
223 CRYPTO_THREADID threadid;
224
225 /* We start searching the array at a value based on the
226 * threadid in order to try avoid bouncing the BN_BLINDING
227 * values around different threads. It's harmless if
228 * threadid.val is always set to zero. */
229 CRYPTO_THREADID_current(&threadid);
230 starting_index = threadid.val % rsa->num_blindings;
231
232 for (i = starting_index;;) {
233 if (rsa->blindings_inuse[i] == 0) {
234 rsa->blindings_inuse[i] = 1;
235 ret = rsa->blindings[i];
236 *index_used = i;
237 break;
238 }
239 i++;
240 if (i == rsa->num_blindings) {
241 i = 0;
242 }
243 if (i == starting_index) {
244 break;
245 }
246 }
247 }
248
249 if (ret != NULL) {
250 CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
251 return ret;
252 }
253
254 overflow = rsa->num_blindings >= MAX_BLINDINGS_PER_RSA;
255
256 /* We didn't find a free BN_BLINDING to use so increase the length of
257 * the arrays by one and use the newly created element. */
258
259 CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
260 ret = rsa_setup_blinding(rsa, ctx);
261 if (ret == NULL) {
262 return NULL;
263 }
264
265 if (overflow) {
266 /* We cannot add any more cached BN_BLINDINGs so we use |ret|
267 * and mark it for destruction in |rsa_blinding_release|. */
268 *index_used = MAX_BLINDINGS_PER_RSA;
269 return ret;
270 }
271
272 CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
273
274 new_blindings =
275 OPENSSL_malloc(sizeof(BN_BLINDING *) * (rsa->num_blindings + 1));
276 if (new_blindings == NULL) {
277 goto err1;
278 }
279 memcpy(new_blindings, rsa->blindings,
280 sizeof(BN_BLINDING *) * rsa->num_blindings);
281 new_blindings[rsa->num_blindings] = ret;
282
283 new_blindings_inuse = OPENSSL_malloc(rsa->num_blindings + 1);
284 if (new_blindings_inuse == NULL) {
285 goto err2;
286 }
287 memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings);
288 new_blindings_inuse[rsa->num_blindings] = 1;
289 *index_used = rsa->num_blindings;
290
291 if (rsa->blindings != NULL) {
292 OPENSSL_free(rsa->blindings);
293 }
294 rsa->blindings = new_blindings;
295 if (rsa->blindings_inuse != NULL) {
296 OPENSSL_free(rsa->blindings_inuse);
297 }
298 rsa->blindings_inuse = new_blindings_inuse;
299 rsa->num_blindings++;
300
301 CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
302 return ret;
303
304err2:
305 OPENSSL_free(new_blindings);
306
307err1:
308 CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
309 BN_BLINDING_free(ret);
310 return NULL;
311}
312
313/* rsa_blinding_release marks the cached BN_BLINDING at the given index as free
314 * for other threads to use. */
315static void rsa_blinding_release(RSA *rsa, BN_BLINDING *blinding,
316 unsigned blinding_index) {
317 if (blinding_index == MAX_BLINDINGS_PER_RSA) {
318 /* This blinding wasn't cached. */
319 BN_BLINDING_free(blinding);
320 return;
321 }
322
323 CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
324 rsa->blindings_inuse[blinding_index] = 0;
325 CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
326}
327
328/* signing */
329static int sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
330 const uint8_t *in, size_t in_len, int padding) {
331 const unsigned rsa_size = RSA_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700332 uint8_t *buf = NULL;
Adam Langley6887edb2014-06-20 12:00:00 -0700333 int i, ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700334
335 if (max_out < rsa_size) {
336 OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
337 return 0;
338 }
339
Adam Langley95c29f32014-06-20 12:00:00 -0700340 buf = OPENSSL_malloc(rsa_size);
Adam Langley6bc658d2014-08-18 13:29:45 -0700341 if (buf == NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700342 OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_MALLOC_FAILURE);
343 goto err;
344 }
345
346 switch (padding) {
347 case RSA_PKCS1_PADDING:
348 i = RSA_padding_add_PKCS1_type_1(buf, rsa_size, in, in_len);
349 break;
350 case RSA_NO_PADDING:
351 i = RSA_padding_add_none(buf, rsa_size, in, in_len);
352 break;
353 default:
354 OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_UNKNOWN_PADDING_TYPE);
355 goto err;
356 }
Adam Langley6bc658d2014-08-18 13:29:45 -0700357
Adam Langley95c29f32014-06-20 12:00:00 -0700358 if (i <= 0) {
359 goto err;
360 }
361
Adam Langley6bc658d2014-08-18 13:29:45 -0700362 if (!RSA_private_transform(rsa, out, buf, rsa_size)) {
Adam Langley5f5bf6f2015-02-24 13:49:41 -0800363 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700364 }
365
366 *out_len = rsa_size;
367 ret = 1;
368
369err:
Adam Langley95c29f32014-06-20 12:00:00 -0700370 if (buf != NULL) {
371 OPENSSL_cleanse(buf, rsa_size);
372 OPENSSL_free(buf);
373 }
Adam Langley95c29f32014-06-20 12:00:00 -0700374
375 return ret;
376}
377
378static int decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
379 const uint8_t *in, size_t in_len, int padding) {
380 const unsigned rsa_size = RSA_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700381 int r = -1;
382 uint8_t *buf = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700383 int ret = 0;
384
385 if (max_out < rsa_size) {
386 OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
387 return 0;
388 }
389
Adam Langley95c29f32014-06-20 12:00:00 -0700390 buf = OPENSSL_malloc(rsa_size);
Adam Langley6bc658d2014-08-18 13:29:45 -0700391 if (buf == NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700392 OPENSSL_PUT_ERROR(RSA, decrypt, ERR_R_MALLOC_FAILURE);
393 goto err;
394 }
395
Adam Langley6bc658d2014-08-18 13:29:45 -0700396 if (in_len != rsa_size) {
397 OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
Adam Langley95c29f32014-06-20 12:00:00 -0700398 goto err;
399 }
400
Adam Langley6bc658d2014-08-18 13:29:45 -0700401 if (!RSA_private_transform(rsa, buf, in, rsa_size)) {
Adam Langley6887edb2014-06-20 12:00:00 -0700402 goto err;
403 }
Adam Langley95c29f32014-06-20 12:00:00 -0700404
405 switch (padding) {
406 case RSA_PKCS1_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700407 r = RSA_padding_check_PKCS1_type_2(out, rsa_size, buf, rsa_size);
Adam Langley95c29f32014-06-20 12:00:00 -0700408 break;
409 case RSA_PKCS1_OAEP_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700410 /* Use the default parameters: SHA-1 for both hashes and no label. */
411 r = RSA_padding_check_PKCS1_OAEP_mgf1(out, rsa_size, buf, rsa_size,
412 NULL, 0, NULL, NULL);
Adam Langley95c29f32014-06-20 12:00:00 -0700413 break;
Adam Langley95c29f32014-06-20 12:00:00 -0700414 case RSA_NO_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700415 r = RSA_padding_check_none(out, rsa_size, buf, rsa_size);
Adam Langley95c29f32014-06-20 12:00:00 -0700416 break;
417 default:
418 OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_UNKNOWN_PADDING_TYPE);
419 goto err;
420 }
421
422 if (r < 0) {
423 OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_PADDING_CHECK_FAILED);
424 } else {
425 *out_len = r;
426 ret = 1;
427 }
428
429err:
Adam Langley95c29f32014-06-20 12:00:00 -0700430 if (buf != NULL) {
431 OPENSSL_cleanse(buf, rsa_size);
432 OPENSSL_free(buf);
433 }
Adam Langley95c29f32014-06-20 12:00:00 -0700434
435 return ret;
436}
437
438static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
439 const uint8_t *in, size_t in_len, int padding) {
440 const unsigned rsa_size = RSA_size(rsa);
441 BIGNUM *f, *result;
442 int ret = 0;
Adam Langley6887edb2014-06-20 12:00:00 -0700443 int r = -1;
Adam Langley95c29f32014-06-20 12:00:00 -0700444 uint8_t *buf = NULL;
445 BN_CTX *ctx = NULL;
446
447 if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
448 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_MODULUS_TOO_LARGE);
449 return 0;
450 }
451
452 if (BN_ucmp(rsa->n, rsa->e) <= 0) {
453 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_BAD_E_VALUE);
454 return 0;
455 }
456
457 if (max_out < rsa_size) {
458 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
459 return 0;
460 }
461
462 /* for large moduli, enforce exponent limit */
463 if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
464 BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
465 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_BAD_E_VALUE);
466 return 0;
467 }
468
469 ctx = BN_CTX_new();
470 if (ctx == NULL) {
471 goto err;
472 }
473
474 BN_CTX_start(ctx);
475 f = BN_CTX_get(ctx);
476 result = BN_CTX_get(ctx);
477 buf = OPENSSL_malloc(rsa_size);
478 if (!f || !result || !buf) {
479 OPENSSL_PUT_ERROR(RSA, verify_raw, ERR_R_MALLOC_FAILURE);
480 goto err;
481 }
482
Adam Langley6bc658d2014-08-18 13:29:45 -0700483 if (in_len != rsa_size) {
484 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
Adam Langley95c29f32014-06-20 12:00:00 -0700485 goto err;
486 }
487
488 if (BN_bin2bn(in, in_len, f) == NULL) {
489 goto err;
490 }
491
492 if (BN_ucmp(f, rsa->n) >= 0) {
493 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
494 goto err;
495 }
496
497 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
498 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n,
499 ctx)) {
500 goto err;
501 }
502 }
503
504 if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx,
505 rsa->_method_mod_n)) {
506 goto err;
507 }
508
Adam Langley6887edb2014-06-20 12:00:00 -0700509 if (!BN_bn2bin_padded(buf, rsa_size, result)) {
510 OPENSSL_PUT_ERROR(RSA, verify_raw, ERR_R_INTERNAL_ERROR);
511 goto err;
512 }
Adam Langley95c29f32014-06-20 12:00:00 -0700513
514 switch (padding) {
515 case RSA_PKCS1_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700516 r = RSA_padding_check_PKCS1_type_1(out, rsa_size, buf, rsa_size);
Adam Langley95c29f32014-06-20 12:00:00 -0700517 break;
518 case RSA_NO_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700519 r = RSA_padding_check_none(out, rsa_size, buf, rsa_size);
Adam Langley95c29f32014-06-20 12:00:00 -0700520 break;
521 default:
522 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_UNKNOWN_PADDING_TYPE);
523 goto err;
524 }
525
526 if (r < 0) {
527 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_PADDING_CHECK_FAILED);
528 } else {
529 *out_len = r;
530 ret = 1;
531 }
532
533err:
534 if (ctx != NULL) {
535 BN_CTX_end(ctx);
536 BN_CTX_free(ctx);
537 }
538 if (buf != NULL) {
539 OPENSSL_cleanse(buf, rsa_size);
540 OPENSSL_free(buf);
541 }
542 return ret;
543}
544
Adam Langley6bc658d2014-08-18 13:29:45 -0700545static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
546 size_t len) {
547 BIGNUM *f, *result;
548 BN_CTX *ctx = NULL;
549 unsigned blinding_index = 0;
550 BN_BLINDING *blinding = NULL;
551 int ret = 0;
552
553 ctx = BN_CTX_new();
554 if (ctx == NULL) {
555 goto err;
556 }
557 BN_CTX_start(ctx);
558 f = BN_CTX_get(ctx);
559 result = BN_CTX_get(ctx);
560
561 if (f == NULL || result == NULL) {
562 OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_MALLOC_FAILURE);
563 goto err;
564 }
565
566 if (BN_bin2bn(in, len, f) == NULL) {
567 goto err;
568 }
569
570 if (BN_ucmp(f, rsa->n) >= 0) {
571 /* Usually the padding functions would catch this. */
572 OPENSSL_PUT_ERROR(RSA, private_transform, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
573 goto err;
574 }
575
576 if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
577 blinding = rsa_blinding_get(rsa, &blinding_index, ctx);
578 if (blinding == NULL) {
579 OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_INTERNAL_ERROR);
580 goto err;
581 }
582 if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) {
583 goto err;
584 }
585 }
586
587 if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
588 ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) &&
589 (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
590 if (!rsa->meth->mod_exp(result, f, rsa, ctx)) {
591 goto err;
592 }
593 } else {
594 BIGNUM local_d;
595 BIGNUM *d = NULL;
596
597 BN_init(&local_d);
598 d = &local_d;
599 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
600
601 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
602 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n,
603 ctx)) {
604 goto err;
605 }
606 }
607
608 if (!rsa->meth->bn_mod_exp(result, f, d, rsa->n, ctx, rsa->_method_mod_n)) {
609 goto err;
610 }
611 }
612
613 if (blinding) {
614 if (!BN_BLINDING_invert_ex(result, NULL, blinding, ctx)) {
615 goto err;
616 }
617 }
618
619 if (!BN_bn2bin_padded(out, len, result)) {
620 OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_INTERNAL_ERROR);
621 goto err;
622 }
623
624 ret = 1;
625
626err:
627 if (ctx != NULL) {
628 BN_CTX_end(ctx);
629 BN_CTX_free(ctx);
630 }
631 if (blinding != NULL) {
632 rsa_blinding_release(rsa, blinding, blinding_index);
633 }
634
635 return ret;
636}
637
Adam Langley95c29f32014-06-20 12:00:00 -0700638static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
639 BIGNUM *r1, *m1, *vrfy;
640 BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
641 BIGNUM *dmp1, *dmq1, *c, *pr1;
642 int ret = 0;
643
644 BN_CTX_start(ctx);
645 r1 = BN_CTX_get(ctx);
646 m1 = BN_CTX_get(ctx);
647 vrfy = BN_CTX_get(ctx);
648
649 {
650 BIGNUM local_p, local_q;
651 BIGNUM *p = NULL, *q = NULL;
652
653 /* Make sure BN_mod_inverse in Montgomery intialization uses the
654 * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) */
655 BN_init(&local_p);
656 p = &local_p;
657 BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
658
659 BN_init(&local_q);
660 q = &local_q;
661 BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
662
663 if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
664 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx)) {
665 goto err;
666 }
667 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx)) {
668 goto err;
669 }
670 }
671 }
672
673 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
674 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n,
675 ctx)) {
676 goto err;
677 }
678 }
679
680 /* compute I mod q */
681 c = &local_c;
682 BN_with_flags(c, I, BN_FLG_CONSTTIME);
683 if (!BN_mod(r1, c, rsa->q, ctx)) {
684 goto err;
685 }
686
687 /* compute r1^dmq1 mod q */
688 dmq1 = &local_dmq1;
689 BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
690 if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) {
691 goto err;
692 }
693
694 /* compute I mod p */
695 c = &local_c;
696 BN_with_flags(c, I, BN_FLG_CONSTTIME);
697 if (!BN_mod(r1, c, rsa->p, ctx)) {
698 goto err;
699 }
700
701 /* compute r1^dmp1 mod p */
702 dmp1 = &local_dmp1;
703 BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
704 if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) {
705 goto err;
706 }
707
708 if (!BN_sub(r0, r0, m1)) {
709 goto err;
710 }
711 /* This will help stop the size of r0 increasing, which does
712 * affect the multiply if it optimised for a power of 2 size */
713 if (BN_is_negative(r0)) {
714 if (!BN_add(r0, r0, rsa->p)) {
715 goto err;
716 }
717 }
718
719 if (!BN_mul(r1, r0, rsa->iqmp, ctx)) {
720 goto err;
721 }
722
723 /* Turn BN_FLG_CONSTTIME flag on before division operation */
724 pr1 = &local_r1;
725 BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
726
727 if (!BN_mod(r0, pr1, rsa->p, ctx)) {
728 goto err;
729 }
730
731 /* If p < q it is occasionally possible for the correction of
732 * adding 'p' if r0 is negative above to leave the result still
733 * negative. This can break the private key operations: the following
734 * second correction should *always* correct this rare occurrence.
735 * This will *never* happen with OpenSSL generated keys because
736 * they ensure p > q [steve] */
737 if (BN_is_negative(r0)) {
738 if (!BN_add(r0, r0, rsa->p)) {
739 goto err;
740 }
741 }
742 if (!BN_mul(r1, r0, rsa->q, ctx)) {
743 goto err;
744 }
745 if (!BN_add(r0, r1, m1)) {
746 goto err;
747 }
748
749 if (rsa->e && rsa->n) {
750 if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
751 rsa->_method_mod_n)) {
752 goto err;
753 }
754 /* If 'I' was greater than (or equal to) rsa->n, the operation
755 * will be equivalent to using 'I mod n'. However, the result of
756 * the verify will *always* be less than 'n' so we don't check
757 * for absolute equality, just congruency. */
758 if (!BN_sub(vrfy, vrfy, I)) {
759 goto err;
760 }
761 if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) {
762 goto err;
763 }
764 if (BN_is_negative(vrfy)) {
765 if (!BN_add(vrfy, vrfy, rsa->n)) {
766 goto err;
767 }
768 }
769 if (!BN_is_zero(vrfy)) {
770 /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
771 * miscalculated CRT output, just do a raw (slower)
772 * mod_exp and return that instead. */
773
774 BIGNUM local_d;
775 BIGNUM *d = NULL;
776
777 d = &local_d;
778 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
779 if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->_method_mod_n)) {
780 goto err;
781 }
782 }
783 }
784 ret = 1;
785
786err:
787 BN_CTX_end(ctx);
788 return ret;
789}
790
791static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
792 BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
793 BIGNUM local_r0, local_d, local_p;
794 BIGNUM *pr0, *d, *p;
795 int bitsp, bitsq, ok = -1, n = 0;
796 BN_CTX *ctx = NULL;
797
798 ctx = BN_CTX_new();
799 if (ctx == NULL) {
800 goto err;
801 }
802 BN_CTX_start(ctx);
803 r0 = BN_CTX_get(ctx);
804 r1 = BN_CTX_get(ctx);
805 r2 = BN_CTX_get(ctx);
806 r3 = BN_CTX_get(ctx);
807 if (r3 == NULL) {
808 goto err;
809 }
810
811 bitsp = (bits + 1) / 2;
812 bitsq = bits - bitsp;
813
814 /* We need the RSA components non-NULL */
David Benjamin6eb000d2015-02-11 01:17:41 -0500815 if (!rsa->n && ((rsa->n = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700816 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500817 }
818 if (!rsa->d && ((rsa->d = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700819 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500820 }
821 if (!rsa->e && ((rsa->e = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700822 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500823 }
824 if (!rsa->p && ((rsa->p = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700825 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500826 }
827 if (!rsa->q && ((rsa->q = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700828 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500829 }
830 if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700831 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500832 }
833 if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700834 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500835 }
836 if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700837 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500838 }
Adam Langley95c29f32014-06-20 12:00:00 -0700839
840 BN_copy(rsa->e, e_value);
841
842 /* generate p and q */
843 for (;;) {
David Benjamin6eb000d2015-02-11 01:17:41 -0500844 if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb) ||
845 !BN_sub(r2, rsa->p, BN_value_one()) ||
846 !BN_gcd(r1, r2, rsa->e, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700847 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500848 }
849 if (BN_is_one(r1)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700850 break;
David Benjamin6eb000d2015-02-11 01:17:41 -0500851 }
852 if (!BN_GENCB_call(cb, 2, n++)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700853 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500854 }
Adam Langley95c29f32014-06-20 12:00:00 -0700855 }
David Benjamin6eb000d2015-02-11 01:17:41 -0500856 if (!BN_GENCB_call(cb, 3, 0)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700857 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500858 }
Adam Langley95c29f32014-06-20 12:00:00 -0700859 for (;;) {
860 /* When generating ridiculously small keys, we can get stuck
861 * continually regenerating the same prime values. Check for
862 * this and bail if it happens 3 times. */
863 unsigned int degenerate = 0;
864 do {
David Benjamin6eb000d2015-02-11 01:17:41 -0500865 if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700866 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500867 }
Adam Langley95c29f32014-06-20 12:00:00 -0700868 } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
869 if (degenerate == 3) {
870 ok = 0; /* we set our own err */
871 OPENSSL_PUT_ERROR(RSA, keygen, RSA_R_KEY_SIZE_TOO_SMALL);
872 goto err;
873 }
David Benjamin6eb000d2015-02-11 01:17:41 -0500874 if (!BN_sub(r2, rsa->q, BN_value_one()) ||
875 !BN_gcd(r1, r2, rsa->e, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700876 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500877 }
878 if (BN_is_one(r1)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700879 break;
David Benjamin6eb000d2015-02-11 01:17:41 -0500880 }
881 if (!BN_GENCB_call(cb, 2, n++)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700882 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500883 }
Adam Langley95c29f32014-06-20 12:00:00 -0700884 }
David Benjamin6eb000d2015-02-11 01:17:41 -0500885 if (!BN_GENCB_call(cb, 3, 1)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700886 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500887 }
Adam Langley95c29f32014-06-20 12:00:00 -0700888 if (BN_cmp(rsa->p, rsa->q) < 0) {
889 tmp = rsa->p;
890 rsa->p = rsa->q;
891 rsa->q = tmp;
892 }
893
894 /* calculate n */
David Benjamin6eb000d2015-02-11 01:17:41 -0500895 if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700896 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500897 }
Adam Langley95c29f32014-06-20 12:00:00 -0700898
899 /* calculate d */
David Benjamin6eb000d2015-02-11 01:17:41 -0500900 if (!BN_sub(r1, rsa->p, BN_value_one())) {
Adam Langley95c29f32014-06-20 12:00:00 -0700901 goto err; /* p-1 */
David Benjamin6eb000d2015-02-11 01:17:41 -0500902 }
903 if (!BN_sub(r2, rsa->q, BN_value_one())) {
Adam Langley95c29f32014-06-20 12:00:00 -0700904 goto err; /* q-1 */
David Benjamin6eb000d2015-02-11 01:17:41 -0500905 }
906 if (!BN_mul(r0, r1, r2, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700907 goto err; /* (p-1)(q-1) */
David Benjamin6eb000d2015-02-11 01:17:41 -0500908 }
Adam Langley95c29f32014-06-20 12:00:00 -0700909 pr0 = &local_r0;
910 BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
David Benjamin6eb000d2015-02-11 01:17:41 -0500911 if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700912 goto err; /* d */
David Benjamin6eb000d2015-02-11 01:17:41 -0500913 }
Adam Langley95c29f32014-06-20 12:00:00 -0700914
915 /* set up d for correct BN_FLG_CONSTTIME flag */
916 d = &local_d;
917 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
918
919 /* calculate d mod (p-1) */
David Benjamin6eb000d2015-02-11 01:17:41 -0500920 if (!BN_mod(rsa->dmp1, d, r1, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700921 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500922 }
Adam Langley95c29f32014-06-20 12:00:00 -0700923
924 /* calculate d mod (q-1) */
David Benjamin6eb000d2015-02-11 01:17:41 -0500925 if (!BN_mod(rsa->dmq1, d, r2, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700926 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500927 }
Adam Langley95c29f32014-06-20 12:00:00 -0700928
929 /* calculate inverse of q mod p */
930 p = &local_p;
931 BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
932
David Benjamin6eb000d2015-02-11 01:17:41 -0500933 if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700934 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500935 }
Adam Langley95c29f32014-06-20 12:00:00 -0700936
937 ok = 1;
938
939err:
940 if (ok == -1) {
941 OPENSSL_PUT_ERROR(RSA, keygen, ERR_LIB_BN);
942 ok = 0;
943 }
944 if (ctx != NULL) {
945 BN_CTX_end(ctx);
946 BN_CTX_free(ctx);
947 }
948
949 return ok;
950}
951
952const struct rsa_meth_st RSA_default_method = {
953 {
954 0 /* references */,
955 1 /* is_static */,
956 },
957 NULL /* app_data */,
958
959 NULL /* init */,
960 finish,
961
David Benjamin925fee32014-07-11 14:14:08 -0400962 size,
963
Adam Langley95c29f32014-06-20 12:00:00 -0700964 NULL /* sign */,
965 NULL /* verify */,
966
967 encrypt,
968 sign_raw,
969 decrypt,
970 verify_raw,
971
Adam Langley6bc658d2014-08-18 13:29:45 -0700972 private_transform,
973
Adam Langley95c29f32014-06-20 12:00:00 -0700974 mod_exp /* mod_exp */,
975 BN_mod_exp_mont /* bn_mod_exp */,
976
977 RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
978
979 keygen,
980};