blob: f8c5a5f773ef8e02be45b0820394361a8162b679 [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>
David Benjamin98193672016-03-25 18:07:11 -040067#include <openssl/nid.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"
Steven Valdezd0b98822017-04-11 12:46:03 -040072#include "../bn/internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -070073
74
David Benjamin9f33fc62015-04-15 17:29:53 -040075static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
76
Adam Langley95c29f32014-06-20 12:00:00 -070077RSA *RSA_new(void) { return RSA_new_method(NULL); }
78
79RSA *RSA_new_method(const ENGINE *engine) {
Brian Smith5ba06892016-02-07 09:36:04 -100080 RSA *rsa = OPENSSL_malloc(sizeof(RSA));
Adam Langley95c29f32014-06-20 12:00:00 -070081 if (rsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -040082 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -070083 return NULL;
84 }
85
David Benjamin17cf2cb2016-12-13 01:07:13 -050086 OPENSSL_memset(rsa, 0, sizeof(RSA));
Adam Langley95c29f32014-06-20 12:00:00 -070087
88 if (engine) {
89 rsa->meth = ENGINE_get_RSA_method(engine);
90 }
91
92 if (rsa->meth == NULL) {
93 rsa->meth = (RSA_METHOD*) &RSA_default_method;
94 }
95 METHOD_ref(rsa->meth);
96
97 rsa->references = 1;
98 rsa->flags = rsa->meth->flags;
Adam Langley683d7bd2015-04-13 11:04:14 -070099 CRYPTO_MUTEX_init(&rsa->lock);
David Benjamin8a589332015-12-04 23:14:35 -0500100 CRYPTO_new_ex_data(&rsa->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700101
102 if (rsa->meth->init && !rsa->meth->init(rsa)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400103 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
David Benjamin79680ff2015-10-23 18:46:16 -0400104 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700105 METHOD_unref(rsa->meth);
106 OPENSSL_free(rsa);
107 return NULL;
108 }
109
110 return rsa;
111}
112
Adam Langley839b8812015-05-26 11:36:46 -0700113void RSA_additional_prime_free(RSA_additional_prime *ap) {
114 if (ap == NULL) {
115 return;
116 }
117
118 BN_clear_free(ap->prime);
119 BN_clear_free(ap->exp);
120 BN_clear_free(ap->coeff);
121 BN_clear_free(ap->r);
David Benjamin8fb0f522015-11-03 18:24:07 -0500122 BN_MONT_CTX_free(ap->mont);
Adam Langley839b8812015-05-26 11:36:46 -0700123 OPENSSL_free(ap);
124}
125
Adam Langley95c29f32014-06-20 12:00:00 -0700126void RSA_free(RSA *rsa) {
127 unsigned u;
128
129 if (rsa == NULL) {
130 return;
131 }
132
Adam Langley0da323a2015-05-15 12:49:30 -0700133 if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700134 return;
135 }
136
David Benjamin8fb0f522015-11-03 18:24:07 -0500137 if (rsa->meth->finish) {
Adam Langley95c29f32014-06-20 12:00:00 -0700138 rsa->meth->finish(rsa);
139 }
140 METHOD_unref(rsa->meth);
141
David Benjamin9f33fc62015-04-15 17:29:53 -0400142 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700143
David Benjamind8b65c82015-04-22 16:09:09 -0400144 BN_clear_free(rsa->n);
145 BN_clear_free(rsa->e);
146 BN_clear_free(rsa->d);
147 BN_clear_free(rsa->p);
148 BN_clear_free(rsa->q);
149 BN_clear_free(rsa->dmp1);
150 BN_clear_free(rsa->dmq1);
151 BN_clear_free(rsa->iqmp);
David Benjamin8fb0f522015-11-03 18:24:07 -0500152 BN_MONT_CTX_free(rsa->mont_n);
153 BN_MONT_CTX_free(rsa->mont_p);
154 BN_MONT_CTX_free(rsa->mont_q);
Adam Langley95c29f32014-06-20 12:00:00 -0700155 for (u = 0; u < rsa->num_blindings; u++) {
156 BN_BLINDING_free(rsa->blindings[u]);
157 }
David Benjamind8b65c82015-04-22 16:09:09 -0400158 OPENSSL_free(rsa->blindings);
159 OPENSSL_free(rsa->blindings_inuse);
Adam Langley839b8812015-05-26 11:36:46 -0700160 if (rsa->additional_primes != NULL) {
161 sk_RSA_additional_prime_pop_free(rsa->additional_primes,
162 RSA_additional_prime_free);
163 }
Adam Langley683d7bd2015-04-13 11:04:14 -0700164 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700165 OPENSSL_free(rsa);
166}
167
168int RSA_up_ref(RSA *rsa) {
Adam Langley0da323a2015-05-15 12:49:30 -0700169 CRYPTO_refcount_inc(&rsa->references);
Adam Langley95c29f32014-06-20 12:00:00 -0700170 return 1;
171}
172
David Benjamin5a915032016-08-09 11:04:24 -0400173void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e,
174 const BIGNUM **out_d) {
175 if (out_n != NULL) {
176 *out_n = rsa->n;
177 }
178 if (out_e != NULL) {
179 *out_e = rsa->e;
180 }
181 if (out_d != NULL) {
182 *out_d = rsa->d;
183 }
184}
185
186void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p,
187 const BIGNUM **out_q) {
188 if (out_p != NULL) {
189 *out_p = rsa->p;
190 }
191 if (out_q != NULL) {
192 *out_q = rsa->q;
193 }
194}
195
196void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1,
197 const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) {
198 if (out_dmp1 != NULL) {
199 *out_dmp1 = rsa->dmp1;
200 }
201 if (out_dmq1 != NULL) {
202 *out_dmq1 = rsa->dmq1;
203 }
204 if (out_iqmp != NULL) {
205 *out_iqmp = rsa->iqmp;
206 }
207}
208
Adam Langley95c29f32014-06-20 12:00:00 -0700209int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
210 if (rsa->meth->keygen) {
211 return rsa->meth->keygen(rsa, bits, e_value, cb);
212 }
213
David Benjamind93831d2015-10-29 13:19:12 -0400214 return rsa_default_keygen(rsa, bits, e_value, cb);
Adam Langley95c29f32014-06-20 12:00:00 -0700215}
216
217int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
218 const uint8_t *in, size_t in_len, int padding) {
219 if (rsa->meth->encrypt) {
220 return rsa->meth->encrypt(rsa, out_len, out, max_out, in, in_len, padding);
221 }
222
David Benjamind93831d2015-10-29 13:19:12 -0400223 return rsa_default_encrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700224}
225
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700226int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700227 int padding) {
228 size_t out_len;
229
230 if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
231 return -1;
232 }
233
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700234 if (out_len > INT_MAX) {
235 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
236 return -1;
237 }
Adam Langley95c29f32014-06-20 12:00:00 -0700238 return out_len;
239}
240
241int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
242 const uint8_t *in, size_t in_len, int padding) {
243 if (rsa->meth->sign_raw) {
244 return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
245 }
246
David Benjamind93831d2015-10-29 13:19:12 -0400247 return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700248}
249
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700250int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700251 int padding) {
252 size_t out_len;
253
254 if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
255 return -1;
256 }
257
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700258 if (out_len > INT_MAX) {
259 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
260 return -1;
261 }
Adam Langley95c29f32014-06-20 12:00:00 -0700262 return out_len;
263}
264
265int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
266 const uint8_t *in, size_t in_len, int padding) {
267 if (rsa->meth->decrypt) {
268 return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
269 }
270
David Benjamind93831d2015-10-29 13:19:12 -0400271 return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700272}
273
David Benjamin79c59a32015-09-19 13:35:39 -0400274int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700275 int padding) {
276 size_t out_len;
277
278 if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
279 return -1;
280 }
281
David Benjamin79c59a32015-09-19 13:35:39 -0400282 if (out_len > INT_MAX) {
283 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
284 return -1;
285 }
Adam Langley95c29f32014-06-20 12:00:00 -0700286 return out_len;
287}
288
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700289int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700290 int padding) {
291 size_t out_len;
292
293 if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
294 return -1;
295 }
296
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700297 if (out_len > INT_MAX) {
298 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
299 return -1;
300 }
Adam Langley95c29f32014-06-20 12:00:00 -0700301 return out_len;
302}
303
304unsigned RSA_size(const RSA *rsa) {
David Benjamin925fee32014-07-11 14:14:08 -0400305 if (rsa->meth->size) {
306 return rsa->meth->size(rsa);
307 }
308
David Benjamind93831d2015-10-29 13:19:12 -0400309 return rsa_default_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700310}
311
David Benjaminecc0ce72014-07-18 18:39:42 -0400312int RSA_is_opaque(const RSA *rsa) {
313 return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
314}
315
David Benjamin8a589332015-12-04 23:14:35 -0500316int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langley95c29f32014-06-20 12:00:00 -0700317 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400318 int index;
David Benjamin8a589332015-12-04 23:14:35 -0500319 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
320 free_func)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400321 return -1;
322 }
323 return index;
Adam Langley95c29f32014-06-20 12:00:00 -0700324}
325
326int RSA_set_ex_data(RSA *d, int idx, void *arg) {
327 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
328}
329
330void *RSA_get_ex_data(const RSA *d, int idx) {
331 return CRYPTO_get_ex_data(&d->ex_data, idx);
332}
333
334/* SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
335 * the length of an MD5 and SHA1 hash. */
336static const unsigned SSL_SIG_LENGTH = 36;
337
338/* pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is
339 * to be signed with PKCS#1. */
340struct pkcs1_sig_prefix {
341 /* nid identifies the hash function. */
342 int nid;
343 /* len is the number of bytes of |bytes| which are valid. */
344 uint8_t len;
345 /* bytes contains the DER bytes. */
346 uint8_t bytes[19];
347};
348
349/* kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with
350 * different hash functions. */
351static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
352 {
353 NID_md5,
354 18,
355 {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
356 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
357 },
358 {
359 NID_sha1,
360 15,
361 {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
362 0x00, 0x04, 0x14},
363 },
364 {
365 NID_sha224,
366 19,
367 {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
368 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
369 },
370 {
371 NID_sha256,
372 19,
373 {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
374 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
375 },
376 {
377 NID_sha384,
378 19,
379 {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
380 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
381 },
382 {
383 NID_sha512,
384 19,
385 {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
386 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
387 },
388 {
Adam Langley95c29f32014-06-20 12:00:00 -0700389 NID_undef, 0, {0},
390 },
391};
392
David Benjaminb0acb772015-05-28 16:53:31 -0400393int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
394 int *is_alloced, int hash_nid, const uint8_t *msg,
395 size_t msg_len) {
Adam Langley95c29f32014-06-20 12:00:00 -0700396 unsigned i;
Adam Langley95c29f32014-06-20 12:00:00 -0700397
398 if (hash_nid == NID_md5_sha1) {
399 /* Special case: SSL signature, just check the length. */
400 if (msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400401 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700402 return 0;
403 }
404
405 *out_msg = (uint8_t*) msg;
406 *out_msg_len = SSL_SIG_LENGTH;
407 *is_alloced = 0;
408 return 1;
409 }
410
411 for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
412 const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
Brian Smitha039d702015-01-29 15:03:18 -0800413 if (sig_prefix->nid != hash_nid) {
414 continue;
Adam Langley95c29f32014-06-20 12:00:00 -0700415 }
Brian Smitha039d702015-01-29 15:03:18 -0800416
417 const uint8_t* prefix = sig_prefix->bytes;
418 unsigned prefix_len = sig_prefix->len;
419 unsigned signed_msg_len;
420 uint8_t *signed_msg;
421
422 signed_msg_len = prefix_len + msg_len;
423 if (signed_msg_len < prefix_len) {
David Benjamin3570d732015-06-29 00:28:17 -0400424 OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
Brian Smitha039d702015-01-29 15:03:18 -0800425 return 0;
426 }
427
428 signed_msg = OPENSSL_malloc(signed_msg_len);
429 if (!signed_msg) {
David Benjamin3570d732015-06-29 00:28:17 -0400430 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Brian Smitha039d702015-01-29 15:03:18 -0800431 return 0;
432 }
433
David Benjamin17cf2cb2016-12-13 01:07:13 -0500434 OPENSSL_memcpy(signed_msg, prefix, prefix_len);
435 OPENSSL_memcpy(signed_msg + prefix_len, msg, msg_len);
Brian Smitha039d702015-01-29 15:03:18 -0800436
437 *out_msg = signed_msg;
438 *out_msg_len = signed_msg_len;
439 *is_alloced = 1;
440
441 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700442 }
443
David Benjamin3570d732015-06-29 00:28:17 -0400444 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
Brian Smitha039d702015-01-29 15:03:18 -0800445 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700446}
447
448int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out,
449 unsigned *out_len, RSA *rsa) {
450 const unsigned rsa_size = RSA_size(rsa);
451 int ret = 0;
452 uint8_t *signed_msg;
453 size_t signed_msg_len;
454 int signed_msg_is_alloced = 0;
455 size_t size_t_out_len;
456
457 if (rsa->meth->sign) {
458 return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa);
459 }
460
David Benjaminb0acb772015-05-28 16:53:31 -0400461 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
462 &signed_msg_is_alloced, hash_nid, in, in_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700463 return 0;
464 }
465
466 if (rsa_size < RSA_PKCS1_PADDING_SIZE ||
467 signed_msg_len > rsa_size - RSA_PKCS1_PADDING_SIZE) {
David Benjamin3570d732015-06-29 00:28:17 -0400468 OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
Adam Langley95c29f32014-06-20 12:00:00 -0700469 goto finish;
470 }
471
472 if (RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg,
473 signed_msg_len, RSA_PKCS1_PADDING)) {
474 *out_len = size_t_out_len;
475 ret = 1;
476 }
477
478finish:
479 if (signed_msg_is_alloced) {
480 OPENSSL_free(signed_msg);
481 }
482 return ret;
483}
484
485int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
486 const uint8_t *sig, size_t sig_len, RSA *rsa) {
Brian Smithc0b196d2016-03-04 08:54:07 -1000487 if (rsa->n == NULL || rsa->e == NULL) {
488 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
489 return 0;
490 }
491
Adam Langley95c29f32014-06-20 12:00:00 -0700492 const size_t rsa_size = RSA_size(rsa);
493 uint8_t *buf = NULL;
494 int ret = 0;
495 uint8_t *signed_msg = NULL;
496 size_t signed_msg_len, len;
497 int signed_msg_is_alloced = 0;
498
Adam Langley95c29f32014-06-20 12:00:00 -0700499 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400500 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700501 return 0;
502 }
503
504 buf = OPENSSL_malloc(rsa_size);
505 if (!buf) {
David Benjamin3570d732015-06-29 00:28:17 -0400506 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700507 return 0;
508 }
509
510 if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len,
511 RSA_PKCS1_PADDING)) {
512 goto out;
513 }
514
David Benjaminb0acb772015-05-28 16:53:31 -0400515 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
516 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700517 goto out;
518 }
519
Steven Valdezc1966802017-04-10 15:52:19 -0400520 /* Check that no other information follows the hash value (FIPS 186-4 Section
521 * 5.5) and it matches the expected hash. */
David Benjamin17cf2cb2016-12-13 01:07:13 -0500522 if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400523 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700524 goto out;
525 }
526
527 ret = 1;
528
529out:
David Benjamind8b65c82015-04-22 16:09:09 -0400530 OPENSSL_free(buf);
Adam Langley95c29f32014-06-20 12:00:00 -0700531 if (signed_msg_is_alloced) {
532 OPENSSL_free(signed_msg);
533 }
534 return ret;
535}
Adam Langley409766d2014-06-20 12:00:00 -0700536
537static void bn_free_and_null(BIGNUM **bn) {
Adam Langley409766d2014-06-20 12:00:00 -0700538 BN_free(*bn);
539 *bn = NULL;
540}
541
Adam Langley05b73772014-07-25 12:03:51 -0700542int RSA_check_key(const RSA *key) {
Brian Smith7241ca52016-07-25 16:01:10 -1000543 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q;
Adam Langley05b73772014-07-25 12:03:51 -0700544 BN_CTX *ctx;
545 int ok = 0, has_crt_values;
546
547 if (RSA_is_opaque(key)) {
548 /* Opaque keys can't be checked. */
549 return 1;
550 }
551
552 if ((key->p != NULL) != (key->q != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400553 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langley05b73772014-07-25 12:03:51 -0700554 return 0;
555 }
556
557 if (!key->n || !key->e) {
David Benjamin3570d732015-06-29 00:28:17 -0400558 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langley05b73772014-07-25 12:03:51 -0700559 return 0;
560 }
561
562 if (!key->d || !key->p) {
563 /* For a public key, or without p and q, there's nothing that can be
564 * checked. */
565 return 1;
566 }
567
568 ctx = BN_CTX_new();
569 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400570 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley05b73772014-07-25 12:03:51 -0700571 return 0;
572 }
573
574 BN_init(&n);
575 BN_init(&pm1);
576 BN_init(&qm1);
577 BN_init(&lcm);
578 BN_init(&gcd);
579 BN_init(&de);
580 BN_init(&dmp1);
581 BN_init(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000582 BN_init(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700583
Adam Langley839b8812015-05-26 11:36:46 -0700584 if (!BN_mul(&n, key->p, key->q, ctx) ||
585 /* lcm = lcm(prime-1, for all primes) */
Adam Langley05b73772014-07-25 12:03:51 -0700586 !BN_sub(&pm1, key->p, BN_value_one()) ||
587 !BN_sub(&qm1, key->q, BN_value_one()) ||
588 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700589 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400590 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley839b8812015-05-26 11:36:46 -0700591 goto out;
592 }
593
594 size_t num_additional_primes = 0;
595 if (key->additional_primes != NULL) {
596 num_additional_primes = sk_RSA_additional_prime_num(key->additional_primes);
597 }
598
David Benjamin54091232016-09-05 12:47:25 -0400599 for (size_t i = 0; i < num_additional_primes; i++) {
Adam Langley839b8812015-05-26 11:36:46 -0700600 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 */
Brian Smith7241ca52016-07-25 16:01:10 -1000642 !BN_mod_mul(&iqmp_times_q, key->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 ||
Brian Smith7241ca52016-07-25 16:01:10 -1000649 BN_cmp(key->iqmp, key->p) >= 0 ||
650 !BN_is_one(&iqmp_times_q)) {
David Benjamin3570d732015-06-29 00:28:17 -0400651 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langley05b73772014-07-25 12:03:51 -0700652 goto out;
653 }
654 }
655
656 ok = 1;
657
658out:
659 BN_free(&n);
660 BN_free(&pm1);
661 BN_free(&qm1);
662 BN_free(&lcm);
663 BN_free(&gcd);
664 BN_free(&de);
665 BN_free(&dmp1);
666 BN_free(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000667 BN_free(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700668 BN_CTX_free(ctx);
669
670 return ok;
671}
672
Steven Valdezd0b98822017-04-11 12:46:03 -0400673
674/* This is the product of the 132 smallest odd primes, from 3 to 751. */
675static const BN_ULONG kSmallFactorsLimbs[] = {
676 TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f),
677 TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b),
678 TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871),
679 TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3),
680 TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893),
681 TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e),
682 TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea),
683 TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727),
684 0x000017b1
685};
686static const BIGNUM kSmallFactors = STATIC_BIGNUM(kSmallFactorsLimbs);
687
688int RSA_check_fips(const RSA *key) {
689 if (RSA_is_opaque(key)) {
690 /* Opaque keys can't be checked. */
691 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
692 return 0;
693 }
694
695 if (!RSA_check_key(key)) {
696 return 0;
697 }
698
699 BN_CTX *ctx = BN_CTX_new();
700 if (ctx == NULL) {
701 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
702 return 0;
703 }
704
705 BIGNUM small_gcd;
706 BN_init(&small_gcd);
707
708 int ret = 1;
709
710 /* Perform partial public key validation of RSA keys (SP 800-89 5.3.3). */
711 /* TODO(svaldez): Check that n is composite and not a power of a prime using
712 * extended Miller-Rabin. */
713 if (BN_num_bits(key->e) < 16 ||
714 BN_num_bits(key->e) > 256 ||
715 !BN_is_odd(key->n) ||
716 !BN_is_odd(key->e) ||
717 !BN_gcd(&small_gcd, key->n, &kSmallFactors, ctx) ||
718 !BN_is_one(&small_gcd)) {
719 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
720 ret = 0;
721 }
722
723 BN_free(&small_gcd);
724 BN_CTX_free(ctx);
725
726 return ret;
727}
728
Adam Langley409766d2014-06-20 12:00:00 -0700729int RSA_recover_crt_params(RSA *rsa) {
730 BN_CTX *ctx;
731 BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q;
732 int ok = 0;
733
734 if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400735 OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
Adam Langley409766d2014-06-20 12:00:00 -0700736 return 0;
737 }
738
739 if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
David Benjamin3570d732015-06-29 00:28:17 -0400740 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
Adam Langley409766d2014-06-20 12:00:00 -0700741 return 0;
742 }
743
Adam Langley839b8812015-05-26 11:36:46 -0700744 if (rsa->additional_primes != NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400745 OPENSSL_PUT_ERROR(RSA, RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY);
Adam Langley839b8812015-05-26 11:36:46 -0700746 return 0;
747 }
748
Adam Langley409766d2014-06-20 12:00:00 -0700749 /* This uses the algorithm from section 9B of the RSA paper:
750 * http://people.csail.mit.edu/rivest/Rsapaper.pdf */
751
752 ctx = BN_CTX_new();
753 if (ctx == 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 return 0;
756 }
757
758 BN_CTX_start(ctx);
759 totient = BN_CTX_get(ctx);
760 rem = BN_CTX_get(ctx);
761 multiple = BN_CTX_get(ctx);
762 p_plus_q = BN_CTX_get(ctx);
763 p_minus_q = BN_CTX_get(ctx);
764
765 if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
766 p_minus_q == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400767 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700768 goto err;
769 }
770
771 /* ed-1 is a small multiple of φ(n). */
772 if (!BN_mul(totient, rsa->e, rsa->d, ctx) ||
773 !BN_sub_word(totient, 1) ||
774 /* φ(n) =
775 * pq - p - q + 1 =
776 * n - (p + q) + 1
777 *
778 * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very
779 * close. But, when we calculate the quotient, we'll be truncating it
780 * because we discard the remainder. Thus (ed-1)/multiple will be >= n,
781 * which the totient cannot be. So we add one to the estimate.
782 *
783 * Consider ed-1 as:
784 *
785 * multiple * (n - (p+q) + 1) =
786 * multiple*n - multiple*(p+q) + multiple
787 *
788 * When we divide by n, the first term becomes multiple and, since
789 * multiple and p+q is tiny compared to n, the second and third terms can
790 * be ignored. Thus I claim that subtracting one from the estimate is
791 * sufficient. */
792 !BN_div(multiple, NULL, totient, rsa->n, ctx) ||
793 !BN_add_word(multiple, 1) ||
794 !BN_div(totient, rem, totient, multiple, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400795 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700796 goto err;
797 }
798
799 if (!BN_is_zero(rem)) {
David Benjamin3570d732015-06-29 00:28:17 -0400800 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
Adam Langley409766d2014-06-20 12:00:00 -0700801 goto err;
802 }
803
804 rsa->p = BN_new();
805 rsa->q = BN_new();
806 rsa->dmp1 = BN_new();
807 rsa->dmq1 = BN_new();
808 rsa->iqmp = BN_new();
809 if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
810 NULL || rsa->iqmp == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400811 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700812 goto err;
813 }
814
815 /* φ(n) = n - (p + q) + 1 =>
816 * n - totient + 1 = p + q */
817 if (!BN_sub(p_plus_q, rsa->n, totient) ||
818 !BN_add_word(p_plus_q, 1) ||
819 /* p - q = sqrt((p+q)^2 - 4n) */
820 !BN_sqr(rem, p_plus_q, ctx) ||
821 !BN_lshift(multiple, rsa->n, 2) ||
822 !BN_sub(rem, rem, multiple) ||
823 !BN_sqrt(p_minus_q, rem, ctx) ||
824 /* q is 1/2 (p+q)-(p-q) */
825 !BN_sub(rsa->q, p_plus_q, p_minus_q) ||
826 !BN_rshift1(rsa->q, rsa->q) ||
827 !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
828 !BN_mul(multiple, rsa->p, rsa->q, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400829 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700830 goto err;
831 }
832
833 if (BN_cmp(multiple, rsa->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400834 OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
Adam Langley409766d2014-06-20 12:00:00 -0700835 goto err;
836 }
837
838 if (!BN_sub(rem, rsa->p, BN_value_one()) ||
839 !BN_mod(rsa->dmp1, rsa->d, rem, ctx) ||
840 !BN_sub(rem, rsa->q, BN_value_one()) ||
841 !BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
842 !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400843 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700844 goto err;
845 }
846
847 ok = 1;
848
849err:
850 BN_CTX_end(ctx);
851 BN_CTX_free(ctx);
852 if (!ok) {
853 bn_free_and_null(&rsa->p);
854 bn_free_and_null(&rsa->q);
855 bn_free_and_null(&rsa->dmp1);
856 bn_free_and_null(&rsa->dmq1);
857 bn_free_and_null(&rsa->iqmp);
858 }
859 return ok;
860}
Adam Langley6bc658d2014-08-18 13:29:45 -0700861
862int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
863 size_t len) {
864 if (rsa->meth->private_transform) {
865 return rsa->meth->private_transform(rsa, out, in, len);
866 }
867
David Benjamind93831d2015-10-29 13:19:12 -0400868 return rsa_default_private_transform(rsa, out, in, len);
Adam Langley6bc658d2014-08-18 13:29:45 -0700869}
Adam Langleyc3ef76f2015-04-13 14:34:17 -0700870
871int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
872 return 1;
873}