blob: f84c42a6ccf98bc4c2abb5bb5358f0b8bbc3d4db [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,
David Benjaminddd5ba72017-04-11 12:54:06 -0400462 &signed_msg_is_alloced, hash_nid, in, in_len) ||
463 !RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg,
464 signed_msg_len, RSA_PKCS1_PADDING)) {
465 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700466 }
467
David Benjaminddd5ba72017-04-11 12:54:06 -0400468 *out_len = size_t_out_len;
469 ret = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700470
David Benjaminddd5ba72017-04-11 12:54:06 -0400471err:
Adam Langley95c29f32014-06-20 12:00:00 -0700472 if (signed_msg_is_alloced) {
473 OPENSSL_free(signed_msg);
474 }
475 return ret;
476}
477
478int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
479 const uint8_t *sig, size_t sig_len, RSA *rsa) {
Brian Smithc0b196d2016-03-04 08:54:07 -1000480 if (rsa->n == NULL || rsa->e == NULL) {
481 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
482 return 0;
483 }
484
Adam Langley95c29f32014-06-20 12:00:00 -0700485 const size_t rsa_size = RSA_size(rsa);
486 uint8_t *buf = NULL;
487 int ret = 0;
488 uint8_t *signed_msg = NULL;
489 size_t signed_msg_len, len;
490 int signed_msg_is_alloced = 0;
491
Adam Langley95c29f32014-06-20 12:00:00 -0700492 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400493 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700494 return 0;
495 }
496
497 buf = OPENSSL_malloc(rsa_size);
498 if (!buf) {
David Benjamin3570d732015-06-29 00:28:17 -0400499 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700500 return 0;
501 }
502
503 if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len,
504 RSA_PKCS1_PADDING)) {
505 goto out;
506 }
507
David Benjaminb0acb772015-05-28 16:53:31 -0400508 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
509 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700510 goto out;
511 }
512
Steven Valdezc1966802017-04-10 15:52:19 -0400513 /* Check that no other information follows the hash value (FIPS 186-4 Section
514 * 5.5) and it matches the expected hash. */
David Benjamin17cf2cb2016-12-13 01:07:13 -0500515 if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400516 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700517 goto out;
518 }
519
520 ret = 1;
521
522out:
David Benjamind8b65c82015-04-22 16:09:09 -0400523 OPENSSL_free(buf);
Adam Langley95c29f32014-06-20 12:00:00 -0700524 if (signed_msg_is_alloced) {
525 OPENSSL_free(signed_msg);
526 }
527 return ret;
528}
Adam Langley409766d2014-06-20 12:00:00 -0700529
530static void bn_free_and_null(BIGNUM **bn) {
Adam Langley409766d2014-06-20 12:00:00 -0700531 BN_free(*bn);
532 *bn = NULL;
533}
534
Adam Langley05b73772014-07-25 12:03:51 -0700535int RSA_check_key(const RSA *key) {
Brian Smith7241ca52016-07-25 16:01:10 -1000536 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q;
Adam Langley05b73772014-07-25 12:03:51 -0700537 BN_CTX *ctx;
538 int ok = 0, has_crt_values;
539
540 if (RSA_is_opaque(key)) {
541 /* Opaque keys can't be checked. */
542 return 1;
543 }
544
545 if ((key->p != NULL) != (key->q != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400546 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langley05b73772014-07-25 12:03:51 -0700547 return 0;
548 }
549
550 if (!key->n || !key->e) {
David Benjamin3570d732015-06-29 00:28:17 -0400551 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langley05b73772014-07-25 12:03:51 -0700552 return 0;
553 }
554
555 if (!key->d || !key->p) {
556 /* For a public key, or without p and q, there's nothing that can be
557 * checked. */
558 return 1;
559 }
560
561 ctx = BN_CTX_new();
562 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400563 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley05b73772014-07-25 12:03:51 -0700564 return 0;
565 }
566
567 BN_init(&n);
568 BN_init(&pm1);
569 BN_init(&qm1);
570 BN_init(&lcm);
571 BN_init(&gcd);
572 BN_init(&de);
573 BN_init(&dmp1);
574 BN_init(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000575 BN_init(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700576
Adam Langley839b8812015-05-26 11:36:46 -0700577 if (!BN_mul(&n, key->p, key->q, ctx) ||
578 /* lcm = lcm(prime-1, for all primes) */
Adam Langley05b73772014-07-25 12:03:51 -0700579 !BN_sub(&pm1, key->p, BN_value_one()) ||
580 !BN_sub(&qm1, key->q, BN_value_one()) ||
581 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700582 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400583 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley839b8812015-05-26 11:36:46 -0700584 goto out;
585 }
586
587 size_t num_additional_primes = 0;
588 if (key->additional_primes != NULL) {
589 num_additional_primes = sk_RSA_additional_prime_num(key->additional_primes);
590 }
591
David Benjamin54091232016-09-05 12:47:25 -0400592 for (size_t i = 0; i < num_additional_primes; i++) {
Adam Langley839b8812015-05-26 11:36:46 -0700593 const RSA_additional_prime *ap =
594 sk_RSA_additional_prime_value(key->additional_primes, i);
595 if (!BN_mul(&n, &n, ap->prime, ctx) ||
596 !BN_sub(&pm1, ap->prime, BN_value_one()) ||
597 !BN_mul(&lcm, &lcm, &pm1, ctx) ||
598 !BN_gcd(&gcd, &gcd, &pm1, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400599 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley839b8812015-05-26 11:36:46 -0700600 goto out;
601 }
602 }
603
604 if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
Adam Langley05b73772014-07-25 12:03:51 -0700605 !BN_gcd(&gcd, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700606 /* de = d*e mod lcm(prime-1, for all primes). */
Adam Langley05b73772014-07-25 12:03:51 -0700607 !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400608 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700609 goto out;
610 }
611
612 if (BN_cmp(&n, key->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400613 OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
Adam Langley05b73772014-07-25 12:03:51 -0700614 goto out;
615 }
616
617 if (!BN_is_one(&de)) {
David Benjamin3570d732015-06-29 00:28:17 -0400618 OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
Adam Langley05b73772014-07-25 12:03:51 -0700619 goto out;
620 }
621
622 has_crt_values = key->dmp1 != NULL;
623 if (has_crt_values != (key->dmq1 != NULL) ||
624 has_crt_values != (key->iqmp != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400625 OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
Adam Langley05b73772014-07-25 12:03:51 -0700626 goto out;
627 }
628
Adam Langley839b8812015-05-26 11:36:46 -0700629 if (has_crt_values && num_additional_primes == 0) {
Adam Langley05b73772014-07-25 12:03:51 -0700630 if (/* dmp1 = d mod (p-1) */
631 !BN_mod(&dmp1, key->d, &pm1, ctx) ||
632 /* dmq1 = d mod (q-1) */
633 !BN_mod(&dmq1, key->d, &qm1, ctx) ||
634 /* iqmp = q^-1 mod p */
Brian Smith7241ca52016-07-25 16:01:10 -1000635 !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400636 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700637 goto out;
638 }
639
640 if (BN_cmp(&dmp1, key->dmp1) != 0 ||
641 BN_cmp(&dmq1, key->dmq1) != 0 ||
Brian Smith7241ca52016-07-25 16:01:10 -1000642 BN_cmp(key->iqmp, key->p) >= 0 ||
643 !BN_is_one(&iqmp_times_q)) {
David Benjamin3570d732015-06-29 00:28:17 -0400644 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langley05b73772014-07-25 12:03:51 -0700645 goto out;
646 }
647 }
648
649 ok = 1;
650
651out:
652 BN_free(&n);
653 BN_free(&pm1);
654 BN_free(&qm1);
655 BN_free(&lcm);
656 BN_free(&gcd);
657 BN_free(&de);
658 BN_free(&dmp1);
659 BN_free(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000660 BN_free(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700661 BN_CTX_free(ctx);
662
663 return ok;
664}
665
Steven Valdezd0b98822017-04-11 12:46:03 -0400666
667/* This is the product of the 132 smallest odd primes, from 3 to 751. */
668static const BN_ULONG kSmallFactorsLimbs[] = {
669 TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f),
670 TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b),
671 TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871),
672 TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3),
673 TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893),
674 TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e),
675 TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea),
676 TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727),
677 0x000017b1
678};
679static const BIGNUM kSmallFactors = STATIC_BIGNUM(kSmallFactorsLimbs);
680
681int RSA_check_fips(const RSA *key) {
682 if (RSA_is_opaque(key)) {
683 /* Opaque keys can't be checked. */
684 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
685 return 0;
686 }
687
688 if (!RSA_check_key(key)) {
689 return 0;
690 }
691
692 BN_CTX *ctx = BN_CTX_new();
693 if (ctx == NULL) {
694 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
695 return 0;
696 }
697
698 BIGNUM small_gcd;
699 BN_init(&small_gcd);
700
701 int ret = 1;
702
703 /* Perform partial public key validation of RSA keys (SP 800-89 5.3.3). */
704 /* TODO(svaldez): Check that n is composite and not a power of a prime using
705 * extended Miller-Rabin. */
706 if (BN_num_bits(key->e) < 16 ||
707 BN_num_bits(key->e) > 256 ||
708 !BN_is_odd(key->n) ||
709 !BN_is_odd(key->e) ||
710 !BN_gcd(&small_gcd, key->n, &kSmallFactors, ctx) ||
711 !BN_is_one(&small_gcd)) {
712 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
713 ret = 0;
714 }
715
716 BN_free(&small_gcd);
717 BN_CTX_free(ctx);
718
719 return ret;
720}
721
Adam Langley409766d2014-06-20 12:00:00 -0700722int RSA_recover_crt_params(RSA *rsa) {
723 BN_CTX *ctx;
724 BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q;
725 int ok = 0;
726
727 if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400728 OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
Adam Langley409766d2014-06-20 12:00:00 -0700729 return 0;
730 }
731
732 if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
David Benjamin3570d732015-06-29 00:28:17 -0400733 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
Adam Langley409766d2014-06-20 12:00:00 -0700734 return 0;
735 }
736
Adam Langley839b8812015-05-26 11:36:46 -0700737 if (rsa->additional_primes != NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400738 OPENSSL_PUT_ERROR(RSA, RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY);
Adam Langley839b8812015-05-26 11:36:46 -0700739 return 0;
740 }
741
Adam Langley409766d2014-06-20 12:00:00 -0700742 /* This uses the algorithm from section 9B of the RSA paper:
743 * http://people.csail.mit.edu/rivest/Rsapaper.pdf */
744
745 ctx = BN_CTX_new();
746 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400747 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700748 return 0;
749 }
750
751 BN_CTX_start(ctx);
752 totient = BN_CTX_get(ctx);
753 rem = BN_CTX_get(ctx);
754 multiple = BN_CTX_get(ctx);
755 p_plus_q = BN_CTX_get(ctx);
756 p_minus_q = BN_CTX_get(ctx);
757
758 if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
759 p_minus_q == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400760 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700761 goto err;
762 }
763
764 /* ed-1 is a small multiple of φ(n). */
765 if (!BN_mul(totient, rsa->e, rsa->d, ctx) ||
766 !BN_sub_word(totient, 1) ||
767 /* φ(n) =
768 * pq - p - q + 1 =
769 * n - (p + q) + 1
770 *
771 * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very
772 * close. But, when we calculate the quotient, we'll be truncating it
773 * because we discard the remainder. Thus (ed-1)/multiple will be >= n,
774 * which the totient cannot be. So we add one to the estimate.
775 *
776 * Consider ed-1 as:
777 *
778 * multiple * (n - (p+q) + 1) =
779 * multiple*n - multiple*(p+q) + multiple
780 *
781 * When we divide by n, the first term becomes multiple and, since
782 * multiple and p+q is tiny compared to n, the second and third terms can
783 * be ignored. Thus I claim that subtracting one from the estimate is
784 * sufficient. */
785 !BN_div(multiple, NULL, totient, rsa->n, ctx) ||
786 !BN_add_word(multiple, 1) ||
787 !BN_div(totient, rem, totient, multiple, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400788 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700789 goto err;
790 }
791
792 if (!BN_is_zero(rem)) {
David Benjamin3570d732015-06-29 00:28:17 -0400793 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
Adam Langley409766d2014-06-20 12:00:00 -0700794 goto err;
795 }
796
797 rsa->p = BN_new();
798 rsa->q = BN_new();
799 rsa->dmp1 = BN_new();
800 rsa->dmq1 = BN_new();
801 rsa->iqmp = BN_new();
802 if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
803 NULL || rsa->iqmp == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400804 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700805 goto err;
806 }
807
808 /* φ(n) = n - (p + q) + 1 =>
809 * n - totient + 1 = p + q */
810 if (!BN_sub(p_plus_q, rsa->n, totient) ||
811 !BN_add_word(p_plus_q, 1) ||
812 /* p - q = sqrt((p+q)^2 - 4n) */
813 !BN_sqr(rem, p_plus_q, ctx) ||
814 !BN_lshift(multiple, rsa->n, 2) ||
815 !BN_sub(rem, rem, multiple) ||
816 !BN_sqrt(p_minus_q, rem, ctx) ||
817 /* q is 1/2 (p+q)-(p-q) */
818 !BN_sub(rsa->q, p_plus_q, p_minus_q) ||
819 !BN_rshift1(rsa->q, rsa->q) ||
820 !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
821 !BN_mul(multiple, rsa->p, rsa->q, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400822 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700823 goto err;
824 }
825
826 if (BN_cmp(multiple, rsa->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400827 OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
Adam Langley409766d2014-06-20 12:00:00 -0700828 goto err;
829 }
830
831 if (!BN_sub(rem, rsa->p, BN_value_one()) ||
832 !BN_mod(rsa->dmp1, rsa->d, rem, ctx) ||
833 !BN_sub(rem, rsa->q, BN_value_one()) ||
834 !BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
835 !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400836 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700837 goto err;
838 }
839
840 ok = 1;
841
842err:
843 BN_CTX_end(ctx);
844 BN_CTX_free(ctx);
845 if (!ok) {
846 bn_free_and_null(&rsa->p);
847 bn_free_and_null(&rsa->q);
848 bn_free_and_null(&rsa->dmp1);
849 bn_free_and_null(&rsa->dmq1);
850 bn_free_and_null(&rsa->iqmp);
851 }
852 return ok;
853}
Adam Langley6bc658d2014-08-18 13:29:45 -0700854
855int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
856 size_t len) {
857 if (rsa->meth->private_transform) {
858 return rsa->meth->private_transform(rsa, out, in, len);
859 }
860
David Benjamind93831d2015-10-29 13:19:12 -0400861 return rsa_default_private_transform(rsa, out, in, len);
Adam Langley6bc658d2014-08-18 13:29:45 -0700862}
Adam Langleyc3ef76f2015-04-13 14:34:17 -0700863
864int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
865 return 1;
866}