blob: 3ea4bff989df1cd2a2bf6aba294270f5726f9da9 [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
David Benjamin79c59a32015-09-19 13:35:39 -040059#include <limits.h>
Adam Langley2b2d66d2015-01-30 17:08:37 -080060#include <string.h>
61
Adam Langley95c29f32014-06-20 12:00:00 -070062#include <openssl/bn.h>
63#include <openssl/engine.h>
64#include <openssl/err.h>
65#include <openssl/ex_data.h>
66#include <openssl/mem.h>
67#include <openssl/obj.h>
Brian Smith054e6822015-03-27 21:12:01 -100068#include <openssl/thread.h>
Adam Langley95c29f32014-06-20 12:00:00 -070069
70#include "internal.h"
Adam Langley683d7bd2015-04-13 11:04:14 -070071#include "../internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -070072
73
74extern const RSA_METHOD RSA_default_method;
75
David Benjamin9f33fc62015-04-15 17:29:53 -040076static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
77
Adam Langley95c29f32014-06-20 12:00:00 -070078RSA *RSA_new(void) { return RSA_new_method(NULL); }
79
80RSA *RSA_new_method(const ENGINE *engine) {
81 RSA *rsa = (RSA *)OPENSSL_malloc(sizeof(RSA));
82 if (rsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -040083 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -070084 return NULL;
85 }
86
87 memset(rsa, 0, sizeof(RSA));
88
89 if (engine) {
90 rsa->meth = ENGINE_get_RSA_method(engine);
91 }
92
93 if (rsa->meth == NULL) {
94 rsa->meth = (RSA_METHOD*) &RSA_default_method;
95 }
96 METHOD_ref(rsa->meth);
97
98 rsa->references = 1;
99 rsa->flags = rsa->meth->flags;
Adam Langley683d7bd2015-04-13 11:04:14 -0700100 CRYPTO_MUTEX_init(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700101
David Benjamin9f33fc62015-04-15 17:29:53 -0400102 if (!CRYPTO_new_ex_data(&g_ex_data_class, rsa, &rsa->ex_data)) {
David Benjamin79680ff2015-10-23 18:46:16 -0400103 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700104 METHOD_unref(rsa->meth);
105 OPENSSL_free(rsa);
106 return NULL;
107 }
108
109 if (rsa->meth->init && !rsa->meth->init(rsa)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400110 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
David Benjamin79680ff2015-10-23 18:46:16 -0400111 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700112 METHOD_unref(rsa->meth);
113 OPENSSL_free(rsa);
114 return NULL;
115 }
116
117 return rsa;
118}
119
Adam Langley839b8812015-05-26 11:36:46 -0700120void RSA_additional_prime_free(RSA_additional_prime *ap) {
121 if (ap == NULL) {
122 return;
123 }
124
125 BN_clear_free(ap->prime);
126 BN_clear_free(ap->exp);
127 BN_clear_free(ap->coeff);
128 BN_clear_free(ap->r);
129 OPENSSL_free(ap);
130}
131
Adam Langley95c29f32014-06-20 12:00:00 -0700132void RSA_free(RSA *rsa) {
133 unsigned u;
134
135 if (rsa == NULL) {
136 return;
137 }
138
Adam Langley0da323a2015-05-15 12:49:30 -0700139 if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700140 return;
141 }
142
143 if (rsa->meth->finish) {
144 rsa->meth->finish(rsa);
145 }
146 METHOD_unref(rsa->meth);
147
David Benjamin9f33fc62015-04-15 17:29:53 -0400148 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700149
David Benjamind8b65c82015-04-22 16:09:09 -0400150 BN_clear_free(rsa->n);
151 BN_clear_free(rsa->e);
152 BN_clear_free(rsa->d);
153 BN_clear_free(rsa->p);
154 BN_clear_free(rsa->q);
155 BN_clear_free(rsa->dmp1);
156 BN_clear_free(rsa->dmq1);
157 BN_clear_free(rsa->iqmp);
Adam Langley95c29f32014-06-20 12:00:00 -0700158 for (u = 0; u < rsa->num_blindings; u++) {
159 BN_BLINDING_free(rsa->blindings[u]);
160 }
David Benjamind8b65c82015-04-22 16:09:09 -0400161 OPENSSL_free(rsa->blindings);
162 OPENSSL_free(rsa->blindings_inuse);
Adam Langley839b8812015-05-26 11:36:46 -0700163 if (rsa->additional_primes != NULL) {
164 sk_RSA_additional_prime_pop_free(rsa->additional_primes,
165 RSA_additional_prime_free);
166 }
Adam Langley683d7bd2015-04-13 11:04:14 -0700167 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700168 OPENSSL_free(rsa);
169}
170
171int RSA_up_ref(RSA *rsa) {
Adam Langley0da323a2015-05-15 12:49:30 -0700172 CRYPTO_refcount_inc(&rsa->references);
Adam Langley95c29f32014-06-20 12:00:00 -0700173 return 1;
174}
175
176int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
177 if (rsa->meth->keygen) {
178 return rsa->meth->keygen(rsa, bits, e_value, cb);
179 }
180
181 return RSA_default_method.keygen(rsa, bits, e_value, cb);
182}
183
Adam Langley839b8812015-05-26 11:36:46 -0700184int RSA_generate_multi_prime_key(RSA *rsa, int bits, int num_primes,
185 BIGNUM *e_value, BN_GENCB *cb) {
186 if (rsa->meth->multi_prime_keygen) {
187 return rsa->meth->multi_prime_keygen(rsa, bits, num_primes, e_value, cb);
188 }
189
190 return RSA_default_method.multi_prime_keygen(rsa, bits, num_primes, e_value,
191 cb);
192}
193
Adam Langley95c29f32014-06-20 12:00:00 -0700194int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
195 const uint8_t *in, size_t in_len, int padding) {
196 if (rsa->meth->encrypt) {
197 return rsa->meth->encrypt(rsa, out_len, out, max_out, in, in_len, padding);
198 }
199
200 return RSA_default_method.encrypt(rsa, out_len, out, max_out, in, in_len,
201 padding);
202}
203
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700204int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700205 int padding) {
206 size_t out_len;
207
208 if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
209 return -1;
210 }
211
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700212 if (out_len > INT_MAX) {
213 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
214 return -1;
215 }
Adam Langley95c29f32014-06-20 12:00:00 -0700216 return out_len;
217}
218
219int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
220 const uint8_t *in, size_t in_len, int padding) {
221 if (rsa->meth->sign_raw) {
222 return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
223 }
224
225 return RSA_default_method.sign_raw(rsa, out_len, out, max_out, in, in_len,
226 padding);
227}
228
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700229int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700230 int padding) {
231 size_t out_len;
232
233 if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
234 return -1;
235 }
236
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700237 if (out_len > INT_MAX) {
238 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
239 return -1;
240 }
Adam Langley95c29f32014-06-20 12:00:00 -0700241 return out_len;
242}
243
244int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
245 const uint8_t *in, size_t in_len, int padding) {
246 if (rsa->meth->decrypt) {
247 return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
248 }
249
250 return RSA_default_method.decrypt(rsa, out_len, out, max_out, in, in_len,
251 padding);
252}
253
David Benjamin79c59a32015-09-19 13:35:39 -0400254int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700255 int padding) {
256 size_t out_len;
257
258 if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
259 return -1;
260 }
261
David Benjamin79c59a32015-09-19 13:35:39 -0400262 if (out_len > INT_MAX) {
263 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
264 return -1;
265 }
Adam Langley95c29f32014-06-20 12:00:00 -0700266 return out_len;
267}
268
269int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
270 const uint8_t *in, size_t in_len, int padding) {
271 if (rsa->meth->verify_raw) {
272 return rsa->meth->verify_raw(rsa, out_len, out, max_out, in, in_len, padding);
273 }
274
275 return RSA_default_method.verify_raw(rsa, out_len, out, max_out, in, in_len,
276 padding);
277}
278
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700279int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700280 int padding) {
281 size_t out_len;
282
283 if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
284 return -1;
285 }
286
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700287 if (out_len > INT_MAX) {
288 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
289 return -1;
290 }
Adam Langley95c29f32014-06-20 12:00:00 -0700291 return out_len;
292}
293
294unsigned RSA_size(const RSA *rsa) {
David Benjamin925fee32014-07-11 14:14:08 -0400295 if (rsa->meth->size) {
296 return rsa->meth->size(rsa);
297 }
298
299 return RSA_default_method.size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700300}
301
David Benjaminecc0ce72014-07-18 18:39:42 -0400302int RSA_is_opaque(const RSA *rsa) {
303 return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
304}
305
David Benjaminc20febe2014-11-11 23:47:50 -0500306int RSA_supports_digest(const RSA *rsa, const EVP_MD *md) {
307 if (rsa->meth && rsa->meth->supports_digest) {
308 return rsa->meth->supports_digest(rsa, md);
309 }
310 return 1;
311}
312
Adam Langley95c29f32014-06-20 12:00:00 -0700313int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
314 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400315 int index;
316 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
317 dup_func, free_func)) {
318 return -1;
319 }
320 return index;
Adam Langley95c29f32014-06-20 12:00:00 -0700321}
322
323int RSA_set_ex_data(RSA *d, int idx, void *arg) {
324 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
325}
326
327void *RSA_get_ex_data(const RSA *d, int idx) {
328 return CRYPTO_get_ex_data(&d->ex_data, idx);
329}
330
331/* SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
332 * the length of an MD5 and SHA1 hash. */
333static const unsigned SSL_SIG_LENGTH = 36;
334
335/* pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is
336 * to be signed with PKCS#1. */
337struct pkcs1_sig_prefix {
338 /* nid identifies the hash function. */
339 int nid;
340 /* len is the number of bytes of |bytes| which are valid. */
341 uint8_t len;
342 /* bytes contains the DER bytes. */
343 uint8_t bytes[19];
344};
345
346/* kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with
347 * different hash functions. */
348static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
349 {
350 NID_md5,
351 18,
352 {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
353 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
354 },
355 {
356 NID_sha1,
357 15,
358 {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
359 0x00, 0x04, 0x14},
360 },
361 {
362 NID_sha224,
363 19,
364 {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
365 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
366 },
367 {
368 NID_sha256,
369 19,
370 {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
371 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
372 },
373 {
374 NID_sha384,
375 19,
376 {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
377 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
378 },
379 {
380 NID_sha512,
381 19,
382 {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
383 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
384 },
385 {
Adam Langley95c29f32014-06-20 12:00:00 -0700386 NID_undef, 0, {0},
387 },
388};
389
David Benjaminb0acb772015-05-28 16:53:31 -0400390int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
391 int *is_alloced, int hash_nid, const uint8_t *msg,
392 size_t msg_len) {
Adam Langley95c29f32014-06-20 12:00:00 -0700393 unsigned i;
Adam Langley95c29f32014-06-20 12:00:00 -0700394
395 if (hash_nid == NID_md5_sha1) {
396 /* Special case: SSL signature, just check the length. */
397 if (msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400398 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700399 return 0;
400 }
401
402 *out_msg = (uint8_t*) msg;
403 *out_msg_len = SSL_SIG_LENGTH;
404 *is_alloced = 0;
405 return 1;
406 }
407
408 for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
409 const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
Brian Smitha039d702015-01-29 15:03:18 -0800410 if (sig_prefix->nid != hash_nid) {
411 continue;
Adam Langley95c29f32014-06-20 12:00:00 -0700412 }
Brian Smitha039d702015-01-29 15:03:18 -0800413
414 const uint8_t* prefix = sig_prefix->bytes;
415 unsigned prefix_len = sig_prefix->len;
416 unsigned signed_msg_len;
417 uint8_t *signed_msg;
418
419 signed_msg_len = prefix_len + msg_len;
420 if (signed_msg_len < prefix_len) {
David Benjamin3570d732015-06-29 00:28:17 -0400421 OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
Brian Smitha039d702015-01-29 15:03:18 -0800422 return 0;
423 }
424
425 signed_msg = OPENSSL_malloc(signed_msg_len);
426 if (!signed_msg) {
David Benjamin3570d732015-06-29 00:28:17 -0400427 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Brian Smitha039d702015-01-29 15:03:18 -0800428 return 0;
429 }
430
431 memcpy(signed_msg, prefix, prefix_len);
432 memcpy(signed_msg + prefix_len, msg, msg_len);
433
434 *out_msg = signed_msg;
435 *out_msg_len = signed_msg_len;
436 *is_alloced = 1;
437
438 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700439 }
440
David Benjamin3570d732015-06-29 00:28:17 -0400441 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
Brian Smitha039d702015-01-29 15:03:18 -0800442 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700443}
444
445int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out,
446 unsigned *out_len, RSA *rsa) {
447 const unsigned rsa_size = RSA_size(rsa);
448 int ret = 0;
449 uint8_t *signed_msg;
450 size_t signed_msg_len;
451 int signed_msg_is_alloced = 0;
452 size_t size_t_out_len;
453
454 if (rsa->meth->sign) {
455 return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa);
456 }
457
David Benjaminb0acb772015-05-28 16:53:31 -0400458 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
459 &signed_msg_is_alloced, hash_nid, in, in_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700460 return 0;
461 }
462
463 if (rsa_size < RSA_PKCS1_PADDING_SIZE ||
464 signed_msg_len > rsa_size - RSA_PKCS1_PADDING_SIZE) {
David Benjamin3570d732015-06-29 00:28:17 -0400465 OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
Adam Langley95c29f32014-06-20 12:00:00 -0700466 goto finish;
467 }
468
469 if (RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg,
470 signed_msg_len, RSA_PKCS1_PADDING)) {
471 *out_len = size_t_out_len;
472 ret = 1;
473 }
474
475finish:
476 if (signed_msg_is_alloced) {
477 OPENSSL_free(signed_msg);
478 }
479 return ret;
480}
481
482int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
483 const uint8_t *sig, size_t sig_len, RSA *rsa) {
484 const size_t rsa_size = RSA_size(rsa);
485 uint8_t *buf = NULL;
486 int ret = 0;
487 uint8_t *signed_msg = NULL;
488 size_t signed_msg_len, len;
489 int signed_msg_is_alloced = 0;
490
491 if (rsa->meth->verify) {
492 return rsa->meth->verify(hash_nid, msg, msg_len, sig, sig_len, rsa);
493 }
494
495 if (sig_len != rsa_size) {
David Benjamin3570d732015-06-29 00:28:17 -0400496 OPENSSL_PUT_ERROR(RSA, RSA_R_WRONG_SIGNATURE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700497 return 0;
498 }
499
500 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400501 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700502 return 0;
503 }
504
505 buf = OPENSSL_malloc(rsa_size);
506 if (!buf) {
David Benjamin3570d732015-06-29 00:28:17 -0400507 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700508 return 0;
509 }
510
511 if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len,
512 RSA_PKCS1_PADDING)) {
513 goto out;
514 }
515
David Benjaminb0acb772015-05-28 16:53:31 -0400516 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
517 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700518 goto out;
519 }
520
521 if (len != signed_msg_len || CRYPTO_memcmp(buf, signed_msg, len) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400522 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700523 goto out;
524 }
525
526 ret = 1;
527
528out:
David Benjamind8b65c82015-04-22 16:09:09 -0400529 OPENSSL_free(buf);
Adam Langley95c29f32014-06-20 12:00:00 -0700530 if (signed_msg_is_alloced) {
531 OPENSSL_free(signed_msg);
532 }
533 return ret;
534}
Adam Langley409766d2014-06-20 12:00:00 -0700535
536static void bn_free_and_null(BIGNUM **bn) {
Adam Langley409766d2014-06-20 12:00:00 -0700537 BN_free(*bn);
538 *bn = NULL;
539}
540
Adam Langley05b73772014-07-25 12:03:51 -0700541int RSA_check_key(const RSA *key) {
542 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp;
543 BN_CTX *ctx;
544 int ok = 0, has_crt_values;
545
546 if (RSA_is_opaque(key)) {
547 /* Opaque keys can't be checked. */
548 return 1;
549 }
550
551 if ((key->p != NULL) != (key->q != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400552 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langley05b73772014-07-25 12:03:51 -0700553 return 0;
554 }
555
556 if (!key->n || !key->e) {
David Benjamin3570d732015-06-29 00:28:17 -0400557 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langley05b73772014-07-25 12:03:51 -0700558 return 0;
559 }
560
561 if (!key->d || !key->p) {
562 /* For a public key, or without p and q, there's nothing that can be
563 * checked. */
564 return 1;
565 }
566
567 ctx = BN_CTX_new();
568 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400569 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley05b73772014-07-25 12:03:51 -0700570 return 0;
571 }
572
573 BN_init(&n);
574 BN_init(&pm1);
575 BN_init(&qm1);
576 BN_init(&lcm);
577 BN_init(&gcd);
578 BN_init(&de);
579 BN_init(&dmp1);
580 BN_init(&dmq1);
581 BN_init(&iqmp);
582
Adam Langley839b8812015-05-26 11:36:46 -0700583 if (!BN_mul(&n, key->p, key->q, ctx) ||
584 /* lcm = lcm(prime-1, for all primes) */
Adam Langley05b73772014-07-25 12:03:51 -0700585 !BN_sub(&pm1, key->p, BN_value_one()) ||
586 !BN_sub(&qm1, key->q, BN_value_one()) ||
587 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700588 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400589 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley839b8812015-05-26 11:36:46 -0700590 goto out;
591 }
592
593 size_t num_additional_primes = 0;
594 if (key->additional_primes != NULL) {
595 num_additional_primes = sk_RSA_additional_prime_num(key->additional_primes);
596 }
597
598 size_t i;
599 for (i = 0; i < num_additional_primes; i++) {
600 const RSA_additional_prime *ap =
601 sk_RSA_additional_prime_value(key->additional_primes, i);
602 if (!BN_mul(&n, &n, ap->prime, ctx) ||
603 !BN_sub(&pm1, ap->prime, BN_value_one()) ||
604 !BN_mul(&lcm, &lcm, &pm1, ctx) ||
605 !BN_gcd(&gcd, &gcd, &pm1, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400606 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley839b8812015-05-26 11:36:46 -0700607 goto out;
608 }
609 }
610
611 if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
Adam Langley05b73772014-07-25 12:03:51 -0700612 !BN_gcd(&gcd, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700613 /* de = d*e mod lcm(prime-1, for all primes). */
Adam Langley05b73772014-07-25 12:03:51 -0700614 !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400615 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700616 goto out;
617 }
618
619 if (BN_cmp(&n, key->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400620 OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
Adam Langley05b73772014-07-25 12:03:51 -0700621 goto out;
622 }
623
624 if (!BN_is_one(&de)) {
David Benjamin3570d732015-06-29 00:28:17 -0400625 OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
Adam Langley05b73772014-07-25 12:03:51 -0700626 goto out;
627 }
628
629 has_crt_values = key->dmp1 != NULL;
630 if (has_crt_values != (key->dmq1 != NULL) ||
631 has_crt_values != (key->iqmp != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400632 OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
Adam Langley05b73772014-07-25 12:03:51 -0700633 goto out;
634 }
635
Adam Langley839b8812015-05-26 11:36:46 -0700636 if (has_crt_values && num_additional_primes == 0) {
Adam Langley05b73772014-07-25 12:03:51 -0700637 if (/* dmp1 = d mod (p-1) */
638 !BN_mod(&dmp1, key->d, &pm1, ctx) ||
639 /* dmq1 = d mod (q-1) */
640 !BN_mod(&dmq1, key->d, &qm1, ctx) ||
641 /* iqmp = q^-1 mod p */
642 !BN_mod_inverse(&iqmp, key->q, key->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400643 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700644 goto out;
645 }
646
647 if (BN_cmp(&dmp1, key->dmp1) != 0 ||
648 BN_cmp(&dmq1, key->dmq1) != 0 ||
649 BN_cmp(&iqmp, key->iqmp) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400650 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langley05b73772014-07-25 12:03:51 -0700651 goto out;
652 }
653 }
654
655 ok = 1;
656
657out:
658 BN_free(&n);
659 BN_free(&pm1);
660 BN_free(&qm1);
661 BN_free(&lcm);
662 BN_free(&gcd);
663 BN_free(&de);
664 BN_free(&dmp1);
665 BN_free(&dmq1);
666 BN_free(&iqmp);
667 BN_CTX_free(ctx);
668
669 return ok;
670}
671
Adam Langley409766d2014-06-20 12:00:00 -0700672int RSA_recover_crt_params(RSA *rsa) {
673 BN_CTX *ctx;
674 BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q;
675 int ok = 0;
676
677 if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400678 OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
Adam Langley409766d2014-06-20 12:00:00 -0700679 return 0;
680 }
681
682 if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
David Benjamin3570d732015-06-29 00:28:17 -0400683 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
Adam Langley409766d2014-06-20 12:00:00 -0700684 return 0;
685 }
686
Adam Langley839b8812015-05-26 11:36:46 -0700687 if (rsa->additional_primes != NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400688 OPENSSL_PUT_ERROR(RSA, RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY);
Adam Langley839b8812015-05-26 11:36:46 -0700689 return 0;
690 }
691
Adam Langley409766d2014-06-20 12:00:00 -0700692 /* This uses the algorithm from section 9B of the RSA paper:
693 * http://people.csail.mit.edu/rivest/Rsapaper.pdf */
694
695 ctx = BN_CTX_new();
696 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400697 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700698 return 0;
699 }
700
701 BN_CTX_start(ctx);
702 totient = BN_CTX_get(ctx);
703 rem = BN_CTX_get(ctx);
704 multiple = BN_CTX_get(ctx);
705 p_plus_q = BN_CTX_get(ctx);
706 p_minus_q = BN_CTX_get(ctx);
707
708 if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
709 p_minus_q == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400710 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700711 goto err;
712 }
713
714 /* ed-1 is a small multiple of φ(n). */
715 if (!BN_mul(totient, rsa->e, rsa->d, ctx) ||
716 !BN_sub_word(totient, 1) ||
717 /* φ(n) =
718 * pq - p - q + 1 =
719 * n - (p + q) + 1
720 *
721 * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very
722 * close. But, when we calculate the quotient, we'll be truncating it
723 * because we discard the remainder. Thus (ed-1)/multiple will be >= n,
724 * which the totient cannot be. So we add one to the estimate.
725 *
726 * Consider ed-1 as:
727 *
728 * multiple * (n - (p+q) + 1) =
729 * multiple*n - multiple*(p+q) + multiple
730 *
731 * When we divide by n, the first term becomes multiple and, since
732 * multiple and p+q is tiny compared to n, the second and third terms can
733 * be ignored. Thus I claim that subtracting one from the estimate is
734 * sufficient. */
735 !BN_div(multiple, NULL, totient, rsa->n, ctx) ||
736 !BN_add_word(multiple, 1) ||
737 !BN_div(totient, rem, totient, multiple, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400738 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700739 goto err;
740 }
741
742 if (!BN_is_zero(rem)) {
David Benjamin3570d732015-06-29 00:28:17 -0400743 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
Adam Langley409766d2014-06-20 12:00:00 -0700744 goto err;
745 }
746
747 rsa->p = BN_new();
748 rsa->q = BN_new();
749 rsa->dmp1 = BN_new();
750 rsa->dmq1 = BN_new();
751 rsa->iqmp = BN_new();
752 if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
753 NULL || rsa->iqmp == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400754 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700755 goto err;
756 }
757
758 /* φ(n) = n - (p + q) + 1 =>
759 * n - totient + 1 = p + q */
760 if (!BN_sub(p_plus_q, rsa->n, totient) ||
761 !BN_add_word(p_plus_q, 1) ||
762 /* p - q = sqrt((p+q)^2 - 4n) */
763 !BN_sqr(rem, p_plus_q, ctx) ||
764 !BN_lshift(multiple, rsa->n, 2) ||
765 !BN_sub(rem, rem, multiple) ||
766 !BN_sqrt(p_minus_q, rem, ctx) ||
767 /* q is 1/2 (p+q)-(p-q) */
768 !BN_sub(rsa->q, p_plus_q, p_minus_q) ||
769 !BN_rshift1(rsa->q, rsa->q) ||
770 !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
771 !BN_mul(multiple, rsa->p, rsa->q, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400772 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700773 goto err;
774 }
775
776 if (BN_cmp(multiple, rsa->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400777 OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
Adam Langley409766d2014-06-20 12:00:00 -0700778 goto err;
779 }
780
781 if (!BN_sub(rem, rsa->p, BN_value_one()) ||
782 !BN_mod(rsa->dmp1, rsa->d, rem, ctx) ||
783 !BN_sub(rem, rsa->q, BN_value_one()) ||
784 !BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
785 !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400786 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700787 goto err;
788 }
789
790 ok = 1;
791
792err:
793 BN_CTX_end(ctx);
794 BN_CTX_free(ctx);
795 if (!ok) {
796 bn_free_and_null(&rsa->p);
797 bn_free_and_null(&rsa->q);
798 bn_free_and_null(&rsa->dmp1);
799 bn_free_and_null(&rsa->dmq1);
800 bn_free_and_null(&rsa->iqmp);
801 }
802 return ok;
803}
Adam Langley6bc658d2014-08-18 13:29:45 -0700804
805int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
806 size_t len) {
807 if (rsa->meth->private_transform) {
808 return rsa->meth->private_transform(rsa, out, in, len);
809 }
810
811 return RSA_default_method.private_transform(rsa, out, in, len);
812}
Adam Langleyc3ef76f2015-04-13 14:34:17 -0700813
814int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
815 return 1;
816}