blob: 6bb22146755ab0c8986b49ab6d8fb25590fc9b22 [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>
Brian Smith054e6822015-03-27 21:12:01 -100064#include <openssl/thread.h>
Adam Langley95c29f32014-06-20 12:00:00 -070065
66#include "internal.h"
Adam Langley683d7bd2015-04-13 11:04:14 -070067#include "../internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -070068
69
70#define OPENSSL_RSA_MAX_MODULUS_BITS 16384
71#define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
72#define OPENSSL_RSA_MAX_PUBEXP_BITS \
73 64 /* exponent limit enforced for "large" modulus only */
74
75
David Benjamind93831d2015-10-29 13:19:12 -040076int rsa_default_finish(RSA *rsa) {
David Benjamind8b65c82015-04-22 16:09:09 -040077 BN_MONT_CTX_free(rsa->_method_mod_n);
78 BN_MONT_CTX_free(rsa->_method_mod_p);
79 BN_MONT_CTX_free(rsa->_method_mod_q);
Adam Langley95c29f32014-06-20 12:00:00 -070080
Adam Langley839b8812015-05-26 11:36:46 -070081 if (rsa->additional_primes != NULL) {
82 size_t i;
83 for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); i++) {
84 RSA_additional_prime *ap =
85 sk_RSA_additional_prime_value(rsa->additional_primes, i);
86 BN_MONT_CTX_free(ap->method_mod);
87 }
88 }
89
Adam Langley95c29f32014-06-20 12:00:00 -070090 return 1;
91}
92
David Benjamind93831d2015-10-29 13:19:12 -040093size_t rsa_default_size(const RSA *rsa) {
David Benjamin925fee32014-07-11 14:14:08 -040094 return BN_num_bytes(rsa->n);
95}
96
David Benjamind93831d2015-10-29 13:19:12 -040097int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
98 const uint8_t *in, size_t in_len, int padding) {
Adam Langley95c29f32014-06-20 12:00:00 -070099 const unsigned rsa_size = RSA_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700100 BIGNUM *f, *result;
101 uint8_t *buf = NULL;
102 BN_CTX *ctx = NULL;
Adam Langley6887edb2014-06-20 12:00:00 -0700103 int i, ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700104
105 if (rsa_size > OPENSSL_RSA_MAX_MODULUS_BITS) {
David Benjamin3570d732015-06-29 00:28:17 -0400106 OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
Adam Langley95c29f32014-06-20 12:00:00 -0700107 return 0;
108 }
109
110 if (max_out < rsa_size) {
David Benjamin3570d732015-06-29 00:28:17 -0400111 OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
Adam Langley95c29f32014-06-20 12:00:00 -0700112 return 0;
113 }
114
115 if (BN_ucmp(rsa->n, rsa->e) <= 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400116 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
Adam Langley95c29f32014-06-20 12:00:00 -0700117 return 0;
118 }
119
120 /* for large moduli, enforce exponent limit */
121 if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
122 BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
David Benjamin3570d732015-06-29 00:28:17 -0400123 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
Adam Langley95c29f32014-06-20 12:00:00 -0700124 return 0;
125 }
126
127 ctx = BN_CTX_new();
128 if (ctx == NULL) {
129 goto err;
130 }
131
132 BN_CTX_start(ctx);
133 f = BN_CTX_get(ctx);
134 result = BN_CTX_get(ctx);
135 buf = OPENSSL_malloc(rsa_size);
136 if (!f || !result || !buf) {
David Benjamin3570d732015-06-29 00:28:17 -0400137 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700138 goto err;
139 }
140
141 switch (padding) {
142 case RSA_PKCS1_PADDING:
143 i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len);
144 break;
145 case RSA_PKCS1_OAEP_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700146 /* Use the default parameters: SHA-1 for both hashes and no label. */
147 i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len,
148 NULL, 0, NULL, NULL);
Adam Langley95c29f32014-06-20 12:00:00 -0700149 break;
Adam Langley95c29f32014-06-20 12:00:00 -0700150 case RSA_NO_PADDING:
151 i = RSA_padding_add_none(buf, rsa_size, in, in_len);
152 break;
153 default:
David Benjamin3570d732015-06-29 00:28:17 -0400154 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
Adam Langley95c29f32014-06-20 12:00:00 -0700155 goto err;
156 }
157
158 if (i <= 0) {
159 goto err;
160 }
161
162 if (BN_bin2bn(buf, rsa_size, f) == NULL) {
163 goto err;
164 }
165
166 if (BN_ucmp(f, rsa->n) >= 0) {
167 /* usually the padding functions would catch this */
David Benjamin3570d732015-06-29 00:28:17 -0400168 OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
Adam Langley95c29f32014-06-20 12:00:00 -0700169 goto err;
170 }
171
172 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
Adam Langley683d7bd2015-04-13 11:04:14 -0700173 if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n, ctx) ==
174 NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700175 goto err;
176 }
177 }
178
Adam Langley683d7bd2015-04-13 11:04:14 -0700179 if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx,
180 rsa->_method_mod_n)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700181 goto err;
182 }
183
184 /* put in leading 0 bytes if the number is less than the length of the
185 * modulus */
Adam Langley6887edb2014-06-20 12:00:00 -0700186 if (!BN_bn2bin_padded(out, rsa_size, result)) {
David Benjamin3570d732015-06-29 00:28:17 -0400187 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
Adam Langley6887edb2014-06-20 12:00:00 -0700188 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700189 }
190
191 *out_len = rsa_size;
192 ret = 1;
193
194err:
195 if (ctx != NULL) {
196 BN_CTX_end(ctx);
197 BN_CTX_free(ctx);
198 }
199 if (buf != NULL) {
200 OPENSSL_cleanse(buf, rsa_size);
201 OPENSSL_free(buf);
202 }
203
204 return ret;
205}
206
207/* MAX_BLINDINGS_PER_RSA defines the maximum number of cached BN_BLINDINGs per
208 * RSA*. Then this limit is exceeded, BN_BLINDING objects will be created and
209 * destroyed as needed. */
210#define MAX_BLINDINGS_PER_RSA 1024
211
212/* rsa_blinding_get returns a BN_BLINDING to use with |rsa|. It does this by
213 * allocating one of the cached BN_BLINDING objects in |rsa->blindings|. If
214 * none are free, the cache will be extended by a extra element and the new
215 * BN_BLINDING is returned.
216 *
217 * On success, the index of the assigned BN_BLINDING is written to
218 * |*index_used| and must be passed to |rsa_blinding_release| when finished. */
219static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used,
220 BN_CTX *ctx) {
221 BN_BLINDING *ret = NULL;
222 BN_BLINDING **new_blindings;
223 uint8_t *new_blindings_inuse;
224 char overflow = 0;
225
Adam Langley683d7bd2015-04-13 11:04:14 -0700226 CRYPTO_MUTEX_lock_write(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700227
Adam Langley33672732015-03-31 18:55:53 -0700228 unsigned i;
229 for (i = 0; i < rsa->num_blindings; i++) {
230 if (rsa->blindings_inuse[i] == 0) {
231 rsa->blindings_inuse[i] = 1;
232 ret = rsa->blindings[i];
233 *index_used = i;
234 break;
Adam Langley95c29f32014-06-20 12:00:00 -0700235 }
236 }
237
238 if (ret != NULL) {
Adam Langley683d7bd2015-04-13 11:04:14 -0700239 CRYPTO_MUTEX_unlock(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700240 return ret;
241 }
242
243 overflow = rsa->num_blindings >= MAX_BLINDINGS_PER_RSA;
244
245 /* We didn't find a free BN_BLINDING to use so increase the length of
246 * the arrays by one and use the newly created element. */
247
Adam Langley683d7bd2015-04-13 11:04:14 -0700248 CRYPTO_MUTEX_unlock(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700249 ret = rsa_setup_blinding(rsa, ctx);
250 if (ret == NULL) {
251 return NULL;
252 }
253
254 if (overflow) {
255 /* We cannot add any more cached BN_BLINDINGs so we use |ret|
256 * and mark it for destruction in |rsa_blinding_release|. */
257 *index_used = MAX_BLINDINGS_PER_RSA;
258 return ret;
259 }
260
Adam Langley683d7bd2015-04-13 11:04:14 -0700261 CRYPTO_MUTEX_lock_write(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700262
263 new_blindings =
264 OPENSSL_malloc(sizeof(BN_BLINDING *) * (rsa->num_blindings + 1));
265 if (new_blindings == NULL) {
266 goto err1;
267 }
268 memcpy(new_blindings, rsa->blindings,
269 sizeof(BN_BLINDING *) * rsa->num_blindings);
270 new_blindings[rsa->num_blindings] = ret;
271
272 new_blindings_inuse = OPENSSL_malloc(rsa->num_blindings + 1);
273 if (new_blindings_inuse == NULL) {
274 goto err2;
275 }
276 memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings);
277 new_blindings_inuse[rsa->num_blindings] = 1;
278 *index_used = rsa->num_blindings;
279
David Benjamind8b65c82015-04-22 16:09:09 -0400280 OPENSSL_free(rsa->blindings);
Adam Langley95c29f32014-06-20 12:00:00 -0700281 rsa->blindings = new_blindings;
David Benjamind8b65c82015-04-22 16:09:09 -0400282 OPENSSL_free(rsa->blindings_inuse);
Adam Langley95c29f32014-06-20 12:00:00 -0700283 rsa->blindings_inuse = new_blindings_inuse;
284 rsa->num_blindings++;
285
Adam Langley683d7bd2015-04-13 11:04:14 -0700286 CRYPTO_MUTEX_unlock(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700287 return ret;
288
289err2:
290 OPENSSL_free(new_blindings);
291
292err1:
Adam Langley683d7bd2015-04-13 11:04:14 -0700293 CRYPTO_MUTEX_unlock(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700294 BN_BLINDING_free(ret);
295 return NULL;
296}
297
298/* rsa_blinding_release marks the cached BN_BLINDING at the given index as free
299 * for other threads to use. */
300static void rsa_blinding_release(RSA *rsa, BN_BLINDING *blinding,
301 unsigned blinding_index) {
302 if (blinding_index == MAX_BLINDINGS_PER_RSA) {
303 /* This blinding wasn't cached. */
304 BN_BLINDING_free(blinding);
305 return;
306 }
307
Adam Langley683d7bd2015-04-13 11:04:14 -0700308 CRYPTO_MUTEX_lock_write(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700309 rsa->blindings_inuse[blinding_index] = 0;
Adam Langley683d7bd2015-04-13 11:04:14 -0700310 CRYPTO_MUTEX_unlock(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700311}
312
313/* signing */
David Benjamind93831d2015-10-29 13:19:12 -0400314int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out,
315 size_t max_out, const uint8_t *in, size_t in_len,
316 int padding) {
Adam Langley95c29f32014-06-20 12:00:00 -0700317 const unsigned rsa_size = RSA_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700318 uint8_t *buf = NULL;
Adam Langley6887edb2014-06-20 12:00:00 -0700319 int i, ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700320
321 if (max_out < rsa_size) {
David Benjamin3570d732015-06-29 00:28:17 -0400322 OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
Adam Langley95c29f32014-06-20 12:00:00 -0700323 return 0;
324 }
325
Adam Langley95c29f32014-06-20 12:00:00 -0700326 buf = OPENSSL_malloc(rsa_size);
Adam Langley6bc658d2014-08-18 13:29:45 -0700327 if (buf == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400328 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700329 goto err;
330 }
331
332 switch (padding) {
333 case RSA_PKCS1_PADDING:
334 i = RSA_padding_add_PKCS1_type_1(buf, rsa_size, in, in_len);
335 break;
336 case RSA_NO_PADDING:
337 i = RSA_padding_add_none(buf, rsa_size, in, in_len);
338 break;
339 default:
David Benjamin3570d732015-06-29 00:28:17 -0400340 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
Adam Langley95c29f32014-06-20 12:00:00 -0700341 goto err;
342 }
Adam Langley6bc658d2014-08-18 13:29:45 -0700343
Adam Langley95c29f32014-06-20 12:00:00 -0700344 if (i <= 0) {
345 goto err;
346 }
347
Adam Langley6bc658d2014-08-18 13:29:45 -0700348 if (!RSA_private_transform(rsa, out, buf, rsa_size)) {
Adam Langley5f5bf6f2015-02-24 13:49:41 -0800349 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700350 }
351
352 *out_len = rsa_size;
353 ret = 1;
354
355err:
Adam Langley95c29f32014-06-20 12:00:00 -0700356 if (buf != NULL) {
357 OPENSSL_cleanse(buf, rsa_size);
358 OPENSSL_free(buf);
359 }
Adam Langley95c29f32014-06-20 12:00:00 -0700360
361 return ret;
362}
363
David Benjamind93831d2015-10-29 13:19:12 -0400364int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
365 const uint8_t *in, size_t in_len, int padding) {
Adam Langley95c29f32014-06-20 12:00:00 -0700366 const unsigned rsa_size = RSA_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700367 int r = -1;
368 uint8_t *buf = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700369 int ret = 0;
370
371 if (max_out < rsa_size) {
David Benjamin3570d732015-06-29 00:28:17 -0400372 OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
Adam Langley95c29f32014-06-20 12:00:00 -0700373 return 0;
374 }
375
David Benjamin74279b62014-07-24 13:09:19 -0400376 if (padding == RSA_NO_PADDING) {
377 buf = out;
378 } else {
379 /* Allocate a temporary buffer to hold the padded plaintext. */
380 buf = OPENSSL_malloc(rsa_size);
381 if (buf == NULL) {
382 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
383 goto err;
384 }
Adam Langley95c29f32014-06-20 12:00:00 -0700385 }
386
Adam Langley6bc658d2014-08-18 13:29:45 -0700387 if (in_len != rsa_size) {
David Benjamin3570d732015-06-29 00:28:17 -0400388 OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
Adam Langley95c29f32014-06-20 12:00:00 -0700389 goto err;
390 }
391
Adam Langley6bc658d2014-08-18 13:29:45 -0700392 if (!RSA_private_transform(rsa, buf, in, rsa_size)) {
Adam Langley6887edb2014-06-20 12:00:00 -0700393 goto err;
394 }
Adam Langley95c29f32014-06-20 12:00:00 -0700395
396 switch (padding) {
397 case RSA_PKCS1_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700398 r = RSA_padding_check_PKCS1_type_2(out, rsa_size, buf, rsa_size);
Adam Langley95c29f32014-06-20 12:00:00 -0700399 break;
400 case RSA_PKCS1_OAEP_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700401 /* Use the default parameters: SHA-1 for both hashes and no label. */
402 r = RSA_padding_check_PKCS1_OAEP_mgf1(out, rsa_size, buf, rsa_size,
403 NULL, 0, NULL, NULL);
Adam Langley95c29f32014-06-20 12:00:00 -0700404 break;
Adam Langley95c29f32014-06-20 12:00:00 -0700405 case RSA_NO_PADDING:
David Benjamin74279b62014-07-24 13:09:19 -0400406 r = rsa_size;
Adam Langley95c29f32014-06-20 12:00:00 -0700407 break;
408 default:
David Benjamin3570d732015-06-29 00:28:17 -0400409 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
Adam Langley95c29f32014-06-20 12:00:00 -0700410 goto err;
411 }
412
413 if (r < 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400414 OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
Adam Langley95c29f32014-06-20 12:00:00 -0700415 } else {
416 *out_len = r;
417 ret = 1;
418 }
419
420err:
David Benjamin74279b62014-07-24 13:09:19 -0400421 if (padding != RSA_NO_PADDING && buf != NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700422 OPENSSL_cleanse(buf, rsa_size);
423 OPENSSL_free(buf);
424 }
Adam Langley95c29f32014-06-20 12:00:00 -0700425
426 return ret;
427}
428
David Benjamind93831d2015-10-29 13:19:12 -0400429int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
430 size_t max_out, const uint8_t *in, size_t in_len,
431 int padding) {
Adam Langley95c29f32014-06-20 12:00:00 -0700432 const unsigned rsa_size = RSA_size(rsa);
433 BIGNUM *f, *result;
434 int ret = 0;
Adam Langley6887edb2014-06-20 12:00:00 -0700435 int r = -1;
Adam Langley95c29f32014-06-20 12:00:00 -0700436 uint8_t *buf = NULL;
437 BN_CTX *ctx = NULL;
438
439 if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
David Benjamin3570d732015-06-29 00:28:17 -0400440 OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
Adam Langley95c29f32014-06-20 12:00:00 -0700441 return 0;
442 }
443
444 if (BN_ucmp(rsa->n, rsa->e) <= 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400445 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
Adam Langley95c29f32014-06-20 12:00:00 -0700446 return 0;
447 }
448
449 if (max_out < rsa_size) {
David Benjamin3570d732015-06-29 00:28:17 -0400450 OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
Adam Langley95c29f32014-06-20 12:00:00 -0700451 return 0;
452 }
453
454 /* for large moduli, enforce exponent limit */
455 if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
456 BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
David Benjamin3570d732015-06-29 00:28:17 -0400457 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
Adam Langley95c29f32014-06-20 12:00:00 -0700458 return 0;
459 }
460
461 ctx = BN_CTX_new();
462 if (ctx == NULL) {
463 goto err;
464 }
465
466 BN_CTX_start(ctx);
467 f = BN_CTX_get(ctx);
468 result = BN_CTX_get(ctx);
David Benjamin74279b62014-07-24 13:09:19 -0400469 if (padding == RSA_NO_PADDING) {
470 buf = out;
471 } else {
472 /* Allocate a temporary buffer to hold the padded plaintext. */
473 buf = OPENSSL_malloc(rsa_size);
474 if (buf == NULL) {
475 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
476 goto err;
477 }
478 }
479 if (!f || !result) {
David Benjamin3570d732015-06-29 00:28:17 -0400480 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700481 goto err;
482 }
483
Adam Langley6bc658d2014-08-18 13:29:45 -0700484 if (in_len != rsa_size) {
David Benjamin3570d732015-06-29 00:28:17 -0400485 OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
Adam Langley95c29f32014-06-20 12:00:00 -0700486 goto err;
487 }
488
489 if (BN_bin2bn(in, in_len, f) == NULL) {
490 goto err;
491 }
492
493 if (BN_ucmp(f, rsa->n) >= 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400494 OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
Adam Langley95c29f32014-06-20 12:00:00 -0700495 goto err;
496 }
497
498 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
Adam Langley683d7bd2015-04-13 11:04:14 -0700499 if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n, ctx) ==
500 NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700501 goto err;
502 }
503 }
504
505 if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx,
506 rsa->_method_mod_n)) {
507 goto err;
508 }
509
Adam Langley6887edb2014-06-20 12:00:00 -0700510 if (!BN_bn2bin_padded(buf, rsa_size, result)) {
David Benjamin3570d732015-06-29 00:28:17 -0400511 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
Adam Langley6887edb2014-06-20 12:00:00 -0700512 goto err;
513 }
Adam Langley95c29f32014-06-20 12:00:00 -0700514
515 switch (padding) {
516 case RSA_PKCS1_PADDING:
Adam Langley6887edb2014-06-20 12:00:00 -0700517 r = RSA_padding_check_PKCS1_type_1(out, rsa_size, buf, rsa_size);
Adam Langley95c29f32014-06-20 12:00:00 -0700518 break;
519 case RSA_NO_PADDING:
David Benjamin74279b62014-07-24 13:09:19 -0400520 r = rsa_size;
Adam Langley95c29f32014-06-20 12:00:00 -0700521 break;
522 default:
David Benjamin3570d732015-06-29 00:28:17 -0400523 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
Adam Langley95c29f32014-06-20 12:00:00 -0700524 goto err;
525 }
526
527 if (r < 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400528 OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
Adam Langley95c29f32014-06-20 12:00:00 -0700529 } else {
530 *out_len = r;
531 ret = 1;
532 }
533
534err:
535 if (ctx != NULL) {
536 BN_CTX_end(ctx);
537 BN_CTX_free(ctx);
538 }
David Benjamin74279b62014-07-24 13:09:19 -0400539 if (padding != RSA_NO_PADDING && buf != NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700540 OPENSSL_cleanse(buf, rsa_size);
541 OPENSSL_free(buf);
542 }
543 return ret;
544}
545
David Benjamind93831d2015-10-29 13:19:12 -0400546int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
547 size_t len) {
Adam Langley6bc658d2014-08-18 13:29:45 -0700548 BIGNUM *f, *result;
549 BN_CTX *ctx = NULL;
550 unsigned blinding_index = 0;
551 BN_BLINDING *blinding = NULL;
552 int ret = 0;
553
554 ctx = BN_CTX_new();
555 if (ctx == NULL) {
556 goto err;
557 }
558 BN_CTX_start(ctx);
559 f = BN_CTX_get(ctx);
560 result = BN_CTX_get(ctx);
561
562 if (f == NULL || result == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400563 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley6bc658d2014-08-18 13:29:45 -0700564 goto err;
565 }
566
567 if (BN_bin2bn(in, len, f) == NULL) {
568 goto err;
569 }
570
571 if (BN_ucmp(f, rsa->n) >= 0) {
572 /* Usually the padding functions would catch this. */
David Benjamin3570d732015-06-29 00:28:17 -0400573 OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
Adam Langley6bc658d2014-08-18 13:29:45 -0700574 goto err;
575 }
576
577 if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
578 blinding = rsa_blinding_get(rsa, &blinding_index, ctx);
579 if (blinding == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400580 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
Adam Langley6bc658d2014-08-18 13:29:45 -0700581 goto err;
582 }
583 if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) {
584 goto err;
585 }
586 }
587
588 if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
589 ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) &&
590 (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
591 if (!rsa->meth->mod_exp(result, f, rsa, ctx)) {
592 goto err;
593 }
594 } else {
595 BIGNUM local_d;
596 BIGNUM *d = NULL;
597
598 BN_init(&local_d);
599 d = &local_d;
600 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
601
602 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
Adam Langley683d7bd2015-04-13 11:04:14 -0700603 if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n,
604 ctx) == NULL) {
Adam Langley6bc658d2014-08-18 13:29:45 -0700605 goto err;
606 }
607 }
608
609 if (!rsa->meth->bn_mod_exp(result, f, d, rsa->n, ctx, rsa->_method_mod_n)) {
610 goto err;
611 }
612 }
613
614 if (blinding) {
615 if (!BN_BLINDING_invert_ex(result, NULL, blinding, ctx)) {
616 goto err;
617 }
618 }
619
620 if (!BN_bn2bin_padded(out, len, result)) {
David Benjamin3570d732015-06-29 00:28:17 -0400621 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
Adam Langley6bc658d2014-08-18 13:29:45 -0700622 goto err;
623 }
624
625 ret = 1;
626
627err:
628 if (ctx != NULL) {
629 BN_CTX_end(ctx);
630 BN_CTX_free(ctx);
631 }
632 if (blinding != NULL) {
633 rsa_blinding_release(rsa, blinding, blinding_index);
634 }
635
636 return ret;
637}
638
Adam Langley95c29f32014-06-20 12:00:00 -0700639static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
640 BIGNUM *r1, *m1, *vrfy;
641 BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
642 BIGNUM *dmp1, *dmq1, *c, *pr1;
643 int ret = 0;
Adam Langley839b8812015-05-26 11:36:46 -0700644 size_t i, num_additional_primes = 0;
645
646 if (rsa->additional_primes != NULL) {
647 num_additional_primes = sk_RSA_additional_prime_num(rsa->additional_primes);
648 }
Adam Langley95c29f32014-06-20 12:00:00 -0700649
650 BN_CTX_start(ctx);
651 r1 = BN_CTX_get(ctx);
652 m1 = BN_CTX_get(ctx);
653 vrfy = BN_CTX_get(ctx);
654
655 {
656 BIGNUM local_p, local_q;
657 BIGNUM *p = NULL, *q = NULL;
658
659 /* Make sure BN_mod_inverse in Montgomery intialization uses the
660 * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) */
661 BN_init(&local_p);
662 p = &local_p;
663 BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
664
665 BN_init(&local_q);
666 q = &local_q;
667 BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
668
669 if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
Adam Langley683d7bd2015-04-13 11:04:14 -0700670 if (BN_MONT_CTX_set_locked(&rsa->_method_mod_p, &rsa->lock, p, ctx) ==
671 NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700672 goto err;
673 }
Adam Langley683d7bd2015-04-13 11:04:14 -0700674 if (BN_MONT_CTX_set_locked(&rsa->_method_mod_q, &rsa->lock, q, ctx) ==
675 NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700676 goto err;
677 }
678 }
679 }
680
681 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
Adam Langley683d7bd2015-04-13 11:04:14 -0700682 if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n, ctx) ==
683 NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700684 goto err;
685 }
686 }
687
688 /* compute I mod q */
689 c = &local_c;
690 BN_with_flags(c, I, BN_FLG_CONSTTIME);
691 if (!BN_mod(r1, c, rsa->q, ctx)) {
692 goto err;
693 }
694
695 /* compute r1^dmq1 mod q */
696 dmq1 = &local_dmq1;
697 BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
698 if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) {
699 goto err;
700 }
701
702 /* compute I mod p */
703 c = &local_c;
704 BN_with_flags(c, I, BN_FLG_CONSTTIME);
705 if (!BN_mod(r1, c, rsa->p, ctx)) {
706 goto err;
707 }
708
709 /* compute r1^dmp1 mod p */
710 dmp1 = &local_dmp1;
711 BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
712 if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) {
713 goto err;
714 }
715
716 if (!BN_sub(r0, r0, m1)) {
717 goto err;
718 }
719 /* This will help stop the size of r0 increasing, which does
720 * affect the multiply if it optimised for a power of 2 size */
721 if (BN_is_negative(r0)) {
722 if (!BN_add(r0, r0, rsa->p)) {
723 goto err;
724 }
725 }
726
727 if (!BN_mul(r1, r0, rsa->iqmp, ctx)) {
728 goto err;
729 }
730
731 /* Turn BN_FLG_CONSTTIME flag on before division operation */
732 pr1 = &local_r1;
733 BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
734
735 if (!BN_mod(r0, pr1, rsa->p, ctx)) {
736 goto err;
737 }
738
739 /* If p < q it is occasionally possible for the correction of
740 * adding 'p' if r0 is negative above to leave the result still
741 * negative. This can break the private key operations: the following
742 * second correction should *always* correct this rare occurrence.
743 * This will *never* happen with OpenSSL generated keys because
744 * they ensure p > q [steve] */
745 if (BN_is_negative(r0)) {
746 if (!BN_add(r0, r0, rsa->p)) {
747 goto err;
748 }
749 }
750 if (!BN_mul(r1, r0, rsa->q, ctx)) {
751 goto err;
752 }
753 if (!BN_add(r0, r1, m1)) {
754 goto err;
755 }
756
Adam Langley839b8812015-05-26 11:36:46 -0700757 for (i = 0; i < num_additional_primes; i++) {
758 /* multi-prime RSA. */
759 BIGNUM local_exp, local_prime;
760 BIGNUM *exp = &local_exp, *prime = &local_prime;
761 RSA_additional_prime *ap =
762 sk_RSA_additional_prime_value(rsa->additional_primes, i);
763
764 BN_with_flags(exp, ap->exp, BN_FLG_CONSTTIME);
765 BN_with_flags(prime, ap->prime, BN_FLG_CONSTTIME);
766
767 /* c will already point to a BIGNUM with the correct flags. */
768 if (!BN_mod(r1, c, prime, ctx)) {
769 goto err;
770 }
771
772 if ((rsa->flags & RSA_FLAG_CACHE_PRIVATE) &&
773 !BN_MONT_CTX_set_locked(&ap->method_mod, &rsa->lock, prime, ctx)) {
774 goto err;
775 }
776
777 if (!rsa->meth->bn_mod_exp(m1, r1, exp, prime, ctx, ap->method_mod)) {
778 goto err;
779 }
780
781 BN_set_flags(m1, BN_FLG_CONSTTIME);
782
783 if (!BN_sub(m1, m1, r0) ||
784 !BN_mul(m1, m1, ap->coeff, ctx) ||
785 !BN_mod(m1, m1, prime, ctx) ||
786 (BN_is_negative(m1) && !BN_add(m1, m1, prime)) ||
787 !BN_mul(m1, m1, ap->r, ctx) ||
788 !BN_add(r0, r0, m1)) {
789 goto err;
790 }
791 }
792
Adam Langley95c29f32014-06-20 12:00:00 -0700793 if (rsa->e && rsa->n) {
794 if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
795 rsa->_method_mod_n)) {
796 goto err;
797 }
798 /* If 'I' was greater than (or equal to) rsa->n, the operation
799 * will be equivalent to using 'I mod n'. However, the result of
800 * the verify will *always* be less than 'n' so we don't check
801 * for absolute equality, just congruency. */
802 if (!BN_sub(vrfy, vrfy, I)) {
803 goto err;
804 }
805 if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) {
806 goto err;
807 }
808 if (BN_is_negative(vrfy)) {
809 if (!BN_add(vrfy, vrfy, rsa->n)) {
810 goto err;
811 }
812 }
813 if (!BN_is_zero(vrfy)) {
814 /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
815 * miscalculated CRT output, just do a raw (slower)
816 * mod_exp and return that instead. */
817
818 BIGNUM local_d;
819 BIGNUM *d = NULL;
820
821 d = &local_d;
822 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
823 if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->_method_mod_n)) {
824 goto err;
825 }
826 }
827 }
828 ret = 1;
829
830err:
831 BN_CTX_end(ctx);
832 return ret;
833}
834
David Benjamind93831d2015-10-29 13:19:12 -0400835int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes,
836 BIGNUM *e_value, BN_GENCB *cb) {
Adam Langley95c29f32014-06-20 12:00:00 -0700837 BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
838 BIGNUM local_r0, local_d, local_p;
839 BIGNUM *pr0, *d, *p;
Adam Langley839b8812015-05-26 11:36:46 -0700840 int prime_bits, ok = -1, n = 0, i, j;
Adam Langley95c29f32014-06-20 12:00:00 -0700841 BN_CTX *ctx = NULL;
Adam Langley839b8812015-05-26 11:36:46 -0700842 STACK_OF(RSA_additional_prime) *additional_primes = NULL;
843
844 if (num_primes < 2) {
845 ok = 0; /* we set our own err */
David Benjamin3570d732015-06-29 00:28:17 -0400846 OPENSSL_PUT_ERROR(RSA, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES);
Adam Langley839b8812015-05-26 11:36:46 -0700847 goto err;
848 }
Adam Langley95c29f32014-06-20 12:00:00 -0700849
850 ctx = BN_CTX_new();
851 if (ctx == NULL) {
852 goto err;
853 }
854 BN_CTX_start(ctx);
855 r0 = BN_CTX_get(ctx);
856 r1 = BN_CTX_get(ctx);
857 r2 = BN_CTX_get(ctx);
858 r3 = BN_CTX_get(ctx);
Brian Smithf4bbc2a2015-08-06 10:42:27 -0400859 if (r0 == NULL || r1 == NULL || r2 == NULL || r3 == NULL) {
Adam Langley95c29f32014-06-20 12:00:00 -0700860 goto err;
861 }
862
Adam Langley839b8812015-05-26 11:36:46 -0700863 if (num_primes > 2) {
864 additional_primes = sk_RSA_additional_prime_new_null();
865 if (additional_primes == NULL) {
866 goto err;
867 }
868 }
869
870 for (i = 2; i < num_primes; i++) {
871 RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime));
872 if (ap == NULL) {
873 goto err;
874 }
875 memset(ap, 0, sizeof(RSA_additional_prime));
876 ap->prime = BN_new();
877 ap->exp = BN_new();
878 ap->coeff = BN_new();
879 ap->r = BN_new();
880 if (ap->prime == NULL ||
881 ap->exp == NULL ||
882 ap->coeff == NULL ||
883 ap->r == NULL ||
884 !sk_RSA_additional_prime_push(additional_primes, ap)) {
885 RSA_additional_prime_free(ap);
886 goto err;
887 }
888 }
Adam Langley95c29f32014-06-20 12:00:00 -0700889
890 /* We need the RSA components non-NULL */
David Benjamin6eb000d2015-02-11 01:17:41 -0500891 if (!rsa->n && ((rsa->n = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700892 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500893 }
894 if (!rsa->d && ((rsa->d = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700895 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500896 }
897 if (!rsa->e && ((rsa->e = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700898 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500899 }
900 if (!rsa->p && ((rsa->p = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700901 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500902 }
903 if (!rsa->q && ((rsa->q = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700904 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500905 }
906 if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700907 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500908 }
909 if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700910 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500911 }
912 if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700913 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500914 }
Adam Langley95c29f32014-06-20 12:00:00 -0700915
David Benjamin1c703cb2015-06-11 21:42:14 -0400916 if (!BN_copy(rsa->e, e_value)) {
917 goto err;
918 }
Adam Langley95c29f32014-06-20 12:00:00 -0700919
920 /* generate p and q */
Adam Langley839b8812015-05-26 11:36:46 -0700921 prime_bits = (bits + (num_primes - 1)) / num_primes;
Adam Langley95c29f32014-06-20 12:00:00 -0700922 for (;;) {
Adam Langley839b8812015-05-26 11:36:46 -0700923 if (!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb) ||
David Benjamin6eb000d2015-02-11 01:17:41 -0500924 !BN_sub(r2, rsa->p, BN_value_one()) ||
925 !BN_gcd(r1, r2, rsa->e, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700926 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500927 }
928 if (BN_is_one(r1)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700929 break;
David Benjamin6eb000d2015-02-11 01:17:41 -0500930 }
931 if (!BN_GENCB_call(cb, 2, n++)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700932 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500933 }
Adam Langley95c29f32014-06-20 12:00:00 -0700934 }
David Benjamin6eb000d2015-02-11 01:17:41 -0500935 if (!BN_GENCB_call(cb, 3, 0)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700936 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500937 }
Adam Langley839b8812015-05-26 11:36:46 -0700938 prime_bits = ((bits - prime_bits) + (num_primes - 2)) / (num_primes - 1);
Adam Langley95c29f32014-06-20 12:00:00 -0700939 for (;;) {
940 /* When generating ridiculously small keys, we can get stuck
941 * continually regenerating the same prime values. Check for
942 * this and bail if it happens 3 times. */
943 unsigned int degenerate = 0;
944 do {
Adam Langley839b8812015-05-26 11:36:46 -0700945 if (!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700946 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500947 }
Adam Langley95c29f32014-06-20 12:00:00 -0700948 } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
949 if (degenerate == 3) {
950 ok = 0; /* we set our own err */
David Benjamin3570d732015-06-29 00:28:17 -0400951 OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
Adam Langley95c29f32014-06-20 12:00:00 -0700952 goto err;
953 }
David Benjamin6eb000d2015-02-11 01:17:41 -0500954 if (!BN_sub(r2, rsa->q, BN_value_one()) ||
955 !BN_gcd(r1, r2, rsa->e, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700956 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500957 }
958 if (BN_is_one(r1)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700959 break;
David Benjamin6eb000d2015-02-11 01:17:41 -0500960 }
961 if (!BN_GENCB_call(cb, 2, n++)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700962 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500963 }
Adam Langley95c29f32014-06-20 12:00:00 -0700964 }
Adam Langley839b8812015-05-26 11:36:46 -0700965
966 if (!BN_GENCB_call(cb, 3, 1) ||
967 !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700968 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -0500969 }
Adam Langley839b8812015-05-26 11:36:46 -0700970
971 for (i = 2; i < num_primes; i++) {
972 RSA_additional_prime *ap =
973 sk_RSA_additional_prime_value(additional_primes, i - 2);
974 prime_bits = ((bits - BN_num_bits(rsa->n)) + (num_primes - (i + 1))) /
975 (num_primes - i);
976
977 for (;;) {
978 if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) {
979 goto err;
980 }
981 if (BN_cmp(rsa->p, ap->prime) == 0 ||
982 BN_cmp(rsa->q, ap->prime) == 0) {
983 continue;
984 }
985
986 for (j = 0; j < i - 2; j++) {
987 if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime,
988 ap->prime) == 0) {
989 break;
990 }
991 }
992 if (j != i - 2) {
993 continue;
994 }
995
996 if (!BN_sub(r2, ap->prime, BN_value_one()) ||
997 !BN_gcd(r1, r2, rsa->e, ctx)) {
998 goto err;
999 }
1000
1001 if (!BN_is_one(r1)) {
1002 continue;
1003 }
1004 if (i != num_primes - 1) {
1005 break;
1006 }
1007
1008 /* For the last prime we'll check that it makes n large enough. In the
1009 * two prime case this isn't a problem because we generate primes with
1010 * the top two bits set and so the product is always of the expected
1011 * size. In the multi prime case, this doesn't follow. */
1012 if (!BN_mul(r1, rsa->n, ap->prime, ctx)) {
1013 goto err;
1014 }
Adam Langley96c2a282015-06-02 14:16:44 -07001015 if (BN_num_bits(r1) == (unsigned) bits) {
Adam Langley839b8812015-05-26 11:36:46 -07001016 break;
1017 }
1018
1019 if (!BN_GENCB_call(cb, 2, n++)) {
1020 goto err;
1021 }
1022 }
1023
1024 /* ap->r is is the product of all the primes prior to the current one
1025 * (including p and q). */
1026 if (!BN_copy(ap->r, rsa->n)) {
1027 goto err;
1028 }
1029 if (i == num_primes - 1) {
1030 /* In the case of the last prime, we calculated n as |r1| in the loop
1031 * above. */
1032 if (!BN_copy(rsa->n, r1)) {
1033 goto err;
1034 }
1035 } else if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) {
1036 goto err;
1037 }
1038
1039 if (!BN_GENCB_call(cb, 3, 1)) {
1040 goto err;
1041 }
1042 }
1043
Adam Langley95c29f32014-06-20 12:00:00 -07001044 if (BN_cmp(rsa->p, rsa->q) < 0) {
1045 tmp = rsa->p;
1046 rsa->p = rsa->q;
1047 rsa->q = tmp;
1048 }
1049
Adam Langley95c29f32014-06-20 12:00:00 -07001050 /* calculate d */
David Benjamin6eb000d2015-02-11 01:17:41 -05001051 if (!BN_sub(r1, rsa->p, BN_value_one())) {
Adam Langley95c29f32014-06-20 12:00:00 -07001052 goto err; /* p-1 */
David Benjamin6eb000d2015-02-11 01:17:41 -05001053 }
1054 if (!BN_sub(r2, rsa->q, BN_value_one())) {
Adam Langley95c29f32014-06-20 12:00:00 -07001055 goto err; /* q-1 */
David Benjamin6eb000d2015-02-11 01:17:41 -05001056 }
1057 if (!BN_mul(r0, r1, r2, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -07001058 goto err; /* (p-1)(q-1) */
David Benjamin6eb000d2015-02-11 01:17:41 -05001059 }
Adam Langley839b8812015-05-26 11:36:46 -07001060 for (i = 2; i < num_primes; i++) {
1061 RSA_additional_prime *ap =
1062 sk_RSA_additional_prime_value(additional_primes, i - 2);
1063 if (!BN_sub(r3, ap->prime, BN_value_one()) ||
1064 !BN_mul(r0, r0, r3, ctx)) {
1065 goto err;
1066 }
1067 }
Adam Langley95c29f32014-06-20 12:00:00 -07001068 pr0 = &local_r0;
1069 BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
David Benjamin6eb000d2015-02-11 01:17:41 -05001070 if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -07001071 goto err; /* d */
David Benjamin6eb000d2015-02-11 01:17:41 -05001072 }
Adam Langley95c29f32014-06-20 12:00:00 -07001073
1074 /* set up d for correct BN_FLG_CONSTTIME flag */
1075 d = &local_d;
1076 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
1077
1078 /* calculate d mod (p-1) */
David Benjamin6eb000d2015-02-11 01:17:41 -05001079 if (!BN_mod(rsa->dmp1, d, r1, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -07001080 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -05001081 }
Adam Langley95c29f32014-06-20 12:00:00 -07001082
1083 /* calculate d mod (q-1) */
David Benjamin6eb000d2015-02-11 01:17:41 -05001084 if (!BN_mod(rsa->dmq1, d, r2, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -07001085 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -05001086 }
Adam Langley95c29f32014-06-20 12:00:00 -07001087
1088 /* calculate inverse of q mod p */
1089 p = &local_p;
1090 BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
1091
David Benjamin6eb000d2015-02-11 01:17:41 -05001092 if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) {
Adam Langley95c29f32014-06-20 12:00:00 -07001093 goto err;
David Benjamin6eb000d2015-02-11 01:17:41 -05001094 }
Adam Langley95c29f32014-06-20 12:00:00 -07001095
Adam Langley839b8812015-05-26 11:36:46 -07001096 for (i = 2; i < num_primes; i++) {
1097 RSA_additional_prime *ap =
1098 sk_RSA_additional_prime_value(additional_primes, i - 2);
1099 if (!BN_sub(ap->exp, ap->prime, BN_value_one()) ||
1100 !BN_mod(ap->exp, rsa->d, ap->exp, ctx) ||
1101 !BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) {
1102 goto err;
1103 }
1104 }
1105
Adam Langley95c29f32014-06-20 12:00:00 -07001106 ok = 1;
Adam Langley839b8812015-05-26 11:36:46 -07001107 rsa->additional_primes = additional_primes;
1108 additional_primes = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001109
1110err:
1111 if (ok == -1) {
David Benjamin3570d732015-06-29 00:28:17 -04001112 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley95c29f32014-06-20 12:00:00 -07001113 ok = 0;
1114 }
1115 if (ctx != NULL) {
1116 BN_CTX_end(ctx);
1117 BN_CTX_free(ctx);
1118 }
Adam Langley839b8812015-05-26 11:36:46 -07001119 sk_RSA_additional_prime_pop_free(additional_primes,
1120 RSA_additional_prime_free);
Adam Langley95c29f32014-06-20 12:00:00 -07001121 return ok;
1122}
1123
David Benjamind93831d2015-10-29 13:19:12 -04001124int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
1125 return rsa_default_multi_prime_keygen(rsa, bits, 2 /* num primes */, e_value,
1126 cb);
Adam Langley839b8812015-05-26 11:36:46 -07001127}
1128
David Benjamind93831d2015-10-29 13:19:12 -04001129/* Many of these methods are NULL to more easily drop unused functions. The
1130 * wrapper functions will select the appropriate |rsa_default_*| for all
1131 * methods. */
1132const RSA_METHOD RSA_default_method = {
Adam Langley95c29f32014-06-20 12:00:00 -07001133 {
1134 0 /* references */,
1135 1 /* is_static */,
1136 },
1137 NULL /* app_data */,
1138
1139 NULL /* init */,
David Benjamind93831d2015-10-29 13:19:12 -04001140 NULL /* finish (defaults to rsa_default_finish) */,
Adam Langley95c29f32014-06-20 12:00:00 -07001141
David Benjamind93831d2015-10-29 13:19:12 -04001142 NULL /* size (defaults to rsa_default_size) */,
David Benjamin925fee32014-07-11 14:14:08 -04001143
Adam Langley95c29f32014-06-20 12:00:00 -07001144 NULL /* sign */,
1145 NULL /* verify */,
1146
David Benjamind93831d2015-10-29 13:19:12 -04001147 NULL /* encrypt (defaults to rsa_default_encrypt) */,
1148 NULL /* sign_raw (defaults to rsa_default_sign_raw) */,
1149 NULL /* decrypt (defaults to rsa_default_decrypt) */,
1150 NULL /* verify_raw (defaults to rsa_default_verify_raw) */,
Adam Langley95c29f32014-06-20 12:00:00 -07001151
David Benjamind93831d2015-10-29 13:19:12 -04001152 NULL /* private_transform (defaults to rsa_default_private_transform) */,
Adam Langley6bc658d2014-08-18 13:29:45 -07001153
David Benjamind93831d2015-10-29 13:19:12 -04001154 mod_exp,
Adam Langley95c29f32014-06-20 12:00:00 -07001155 BN_mod_exp_mont /* bn_mod_exp */,
1156
1157 RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
1158
David Benjamind93831d2015-10-29 13:19:12 -04001159 NULL /* keygen (defaults to rsa_default_keygen) */,
1160 NULL /* multi_prime_keygen (defaults to rsa_default_multi_prime_keygen) */,
Adam Langley626c6862015-09-11 16:17:44 -07001161
1162 NULL /* supports_digest */,
Adam Langley95c29f32014-06-20 12:00:00 -07001163};