blob: cc4aa75f3a37ee913c03dddd791f35b7f672bd76 [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
113void RSA_free(RSA *rsa) {
114 unsigned u;
115
116 if (rsa == NULL) {
117 return;
118 }
119
Adam Langley0da323a2015-05-15 12:49:30 -0700120 if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700121 return;
122 }
123
David Benjamin8fb0f522015-11-03 18:24:07 -0500124 if (rsa->meth->finish) {
Adam Langley95c29f32014-06-20 12:00:00 -0700125 rsa->meth->finish(rsa);
126 }
127 METHOD_unref(rsa->meth);
128
David Benjamin9f33fc62015-04-15 17:29:53 -0400129 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700130
David Benjamind8b65c82015-04-22 16:09:09 -0400131 BN_clear_free(rsa->n);
132 BN_clear_free(rsa->e);
133 BN_clear_free(rsa->d);
134 BN_clear_free(rsa->p);
135 BN_clear_free(rsa->q);
136 BN_clear_free(rsa->dmp1);
137 BN_clear_free(rsa->dmq1);
138 BN_clear_free(rsa->iqmp);
David Benjamin8fb0f522015-11-03 18:24:07 -0500139 BN_MONT_CTX_free(rsa->mont_n);
140 BN_MONT_CTX_free(rsa->mont_p);
141 BN_MONT_CTX_free(rsa->mont_q);
Adam Langley95c29f32014-06-20 12:00:00 -0700142 for (u = 0; u < rsa->num_blindings; u++) {
143 BN_BLINDING_free(rsa->blindings[u]);
144 }
David Benjamind8b65c82015-04-22 16:09:09 -0400145 OPENSSL_free(rsa->blindings);
146 OPENSSL_free(rsa->blindings_inuse);
Adam Langley683d7bd2015-04-13 11:04:14 -0700147 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700148 OPENSSL_free(rsa);
149}
150
151int RSA_up_ref(RSA *rsa) {
Adam Langley0da323a2015-05-15 12:49:30 -0700152 CRYPTO_refcount_inc(&rsa->references);
Adam Langley95c29f32014-06-20 12:00:00 -0700153 return 1;
154}
155
David Benjamin5a915032016-08-09 11:04:24 -0400156void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e,
157 const BIGNUM **out_d) {
158 if (out_n != NULL) {
159 *out_n = rsa->n;
160 }
161 if (out_e != NULL) {
162 *out_e = rsa->e;
163 }
164 if (out_d != NULL) {
165 *out_d = rsa->d;
166 }
167}
168
169void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p,
170 const BIGNUM **out_q) {
171 if (out_p != NULL) {
172 *out_p = rsa->p;
173 }
174 if (out_q != NULL) {
175 *out_q = rsa->q;
176 }
177}
178
179void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1,
180 const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) {
181 if (out_dmp1 != NULL) {
182 *out_dmp1 = rsa->dmp1;
183 }
184 if (out_dmq1 != NULL) {
185 *out_dmq1 = rsa->dmq1;
186 }
187 if (out_iqmp != NULL) {
188 *out_iqmp = rsa->iqmp;
189 }
190}
191
Adam Langley95c29f32014-06-20 12:00:00 -0700192int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
193 if (rsa->meth->keygen) {
194 return rsa->meth->keygen(rsa, bits, e_value, cb);
195 }
196
David Benjamind93831d2015-10-29 13:19:12 -0400197 return rsa_default_keygen(rsa, bits, e_value, cb);
Adam Langley95c29f32014-06-20 12:00:00 -0700198}
199
200int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
201 const uint8_t *in, size_t in_len, int padding) {
202 if (rsa->meth->encrypt) {
203 return rsa->meth->encrypt(rsa, out_len, out, max_out, in, in_len, padding);
204 }
205
David Benjamind93831d2015-10-29 13:19:12 -0400206 return rsa_default_encrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700207}
208
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700209int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700210 int padding) {
211 size_t out_len;
212
213 if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
214 return -1;
215 }
216
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700217 if (out_len > INT_MAX) {
218 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
219 return -1;
220 }
Adam Langley95c29f32014-06-20 12:00:00 -0700221 return out_len;
222}
223
224int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
225 const uint8_t *in, size_t in_len, int padding) {
226 if (rsa->meth->sign_raw) {
227 return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
228 }
229
David Benjamind93831d2015-10-29 13:19:12 -0400230 return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700231}
232
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700233int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700234 int padding) {
235 size_t out_len;
236
237 if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
238 return -1;
239 }
240
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700241 if (out_len > INT_MAX) {
242 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
243 return -1;
244 }
Adam Langley95c29f32014-06-20 12:00:00 -0700245 return out_len;
246}
247
248int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
249 const uint8_t *in, size_t in_len, int padding) {
250 if (rsa->meth->decrypt) {
251 return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
252 }
253
David Benjamind93831d2015-10-29 13:19:12 -0400254 return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700255}
256
David Benjamin79c59a32015-09-19 13:35:39 -0400257int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700258 int padding) {
259 size_t out_len;
260
261 if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
262 return -1;
263 }
264
David Benjamin79c59a32015-09-19 13:35:39 -0400265 if (out_len > INT_MAX) {
266 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
267 return -1;
268 }
Adam Langley95c29f32014-06-20 12:00:00 -0700269 return out_len;
270}
271
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700272int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700273 int padding) {
274 size_t out_len;
275
276 if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
277 return -1;
278 }
279
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700280 if (out_len > INT_MAX) {
281 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
282 return -1;
283 }
Adam Langley95c29f32014-06-20 12:00:00 -0700284 return out_len;
285}
286
287unsigned RSA_size(const RSA *rsa) {
David Benjamin925fee32014-07-11 14:14:08 -0400288 if (rsa->meth->size) {
289 return rsa->meth->size(rsa);
290 }
291
David Benjamind93831d2015-10-29 13:19:12 -0400292 return rsa_default_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700293}
294
David Benjaminecc0ce72014-07-18 18:39:42 -0400295int RSA_is_opaque(const RSA *rsa) {
296 return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
297}
298
David Benjamin8a589332015-12-04 23:14:35 -0500299int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langley95c29f32014-06-20 12:00:00 -0700300 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400301 int index;
David Benjamin8a589332015-12-04 23:14:35 -0500302 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
303 free_func)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400304 return -1;
305 }
306 return index;
Adam Langley95c29f32014-06-20 12:00:00 -0700307}
308
309int RSA_set_ex_data(RSA *d, int idx, void *arg) {
310 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
311}
312
313void *RSA_get_ex_data(const RSA *d, int idx) {
314 return CRYPTO_get_ex_data(&d->ex_data, idx);
315}
316
317/* SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
318 * the length of an MD5 and SHA1 hash. */
319static const unsigned SSL_SIG_LENGTH = 36;
320
321/* pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is
322 * to be signed with PKCS#1. */
323struct pkcs1_sig_prefix {
324 /* nid identifies the hash function. */
325 int nid;
326 /* len is the number of bytes of |bytes| which are valid. */
327 uint8_t len;
328 /* bytes contains the DER bytes. */
329 uint8_t bytes[19];
330};
331
332/* kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with
333 * different hash functions. */
334static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
335 {
336 NID_md5,
337 18,
338 {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
339 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
340 },
341 {
342 NID_sha1,
343 15,
344 {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
345 0x00, 0x04, 0x14},
346 },
347 {
348 NID_sha224,
349 19,
350 {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
351 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
352 },
353 {
354 NID_sha256,
355 19,
356 {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
357 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
358 },
359 {
360 NID_sha384,
361 19,
362 {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
363 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
364 },
365 {
366 NID_sha512,
367 19,
368 {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
369 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
370 },
371 {
Adam Langley95c29f32014-06-20 12:00:00 -0700372 NID_undef, 0, {0},
373 },
374};
375
David Benjaminb0acb772015-05-28 16:53:31 -0400376int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
377 int *is_alloced, int hash_nid, const uint8_t *msg,
378 size_t msg_len) {
Adam Langley95c29f32014-06-20 12:00:00 -0700379 unsigned i;
Adam Langley95c29f32014-06-20 12:00:00 -0700380
381 if (hash_nid == NID_md5_sha1) {
382 /* Special case: SSL signature, just check the length. */
383 if (msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400384 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700385 return 0;
386 }
387
388 *out_msg = (uint8_t*) msg;
389 *out_msg_len = SSL_SIG_LENGTH;
390 *is_alloced = 0;
391 return 1;
392 }
393
394 for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
395 const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
Brian Smitha039d702015-01-29 15:03:18 -0800396 if (sig_prefix->nid != hash_nid) {
397 continue;
Adam Langley95c29f32014-06-20 12:00:00 -0700398 }
Brian Smitha039d702015-01-29 15:03:18 -0800399
400 const uint8_t* prefix = sig_prefix->bytes;
401 unsigned prefix_len = sig_prefix->len;
402 unsigned signed_msg_len;
403 uint8_t *signed_msg;
404
405 signed_msg_len = prefix_len + msg_len;
406 if (signed_msg_len < prefix_len) {
David Benjamin3570d732015-06-29 00:28:17 -0400407 OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
Brian Smitha039d702015-01-29 15:03:18 -0800408 return 0;
409 }
410
411 signed_msg = OPENSSL_malloc(signed_msg_len);
412 if (!signed_msg) {
David Benjamin3570d732015-06-29 00:28:17 -0400413 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Brian Smitha039d702015-01-29 15:03:18 -0800414 return 0;
415 }
416
David Benjamin17cf2cb2016-12-13 01:07:13 -0500417 OPENSSL_memcpy(signed_msg, prefix, prefix_len);
418 OPENSSL_memcpy(signed_msg + prefix_len, msg, msg_len);
Brian Smitha039d702015-01-29 15:03:18 -0800419
420 *out_msg = signed_msg;
421 *out_msg_len = signed_msg_len;
422 *is_alloced = 1;
423
424 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700425 }
426
David Benjamin3570d732015-06-29 00:28:17 -0400427 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
Brian Smitha039d702015-01-29 15:03:18 -0800428 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700429}
430
431int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out,
432 unsigned *out_len, RSA *rsa) {
433 const unsigned rsa_size = RSA_size(rsa);
434 int ret = 0;
435 uint8_t *signed_msg;
436 size_t signed_msg_len;
437 int signed_msg_is_alloced = 0;
438 size_t size_t_out_len;
439
440 if (rsa->meth->sign) {
441 return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa);
442 }
443
David Benjaminb0acb772015-05-28 16:53:31 -0400444 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
David Benjaminddd5ba72017-04-11 12:54:06 -0400445 &signed_msg_is_alloced, hash_nid, in, in_len) ||
446 !RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg,
447 signed_msg_len, RSA_PKCS1_PADDING)) {
448 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700449 }
450
David Benjaminddd5ba72017-04-11 12:54:06 -0400451 *out_len = size_t_out_len;
452 ret = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700453
David Benjaminddd5ba72017-04-11 12:54:06 -0400454err:
Adam Langley95c29f32014-06-20 12:00:00 -0700455 if (signed_msg_is_alloced) {
456 OPENSSL_free(signed_msg);
457 }
458 return ret;
459}
460
461int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
462 const uint8_t *sig, size_t sig_len, RSA *rsa) {
Brian Smithc0b196d2016-03-04 08:54:07 -1000463 if (rsa->n == NULL || rsa->e == NULL) {
464 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
465 return 0;
466 }
467
Adam Langley95c29f32014-06-20 12:00:00 -0700468 const size_t rsa_size = RSA_size(rsa);
469 uint8_t *buf = NULL;
470 int ret = 0;
471 uint8_t *signed_msg = NULL;
472 size_t signed_msg_len, len;
473 int signed_msg_is_alloced = 0;
474
Adam Langley95c29f32014-06-20 12:00:00 -0700475 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400476 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700477 return 0;
478 }
479
480 buf = OPENSSL_malloc(rsa_size);
481 if (!buf) {
David Benjamin3570d732015-06-29 00:28:17 -0400482 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700483 return 0;
484 }
485
486 if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len,
487 RSA_PKCS1_PADDING)) {
488 goto out;
489 }
490
David Benjaminb0acb772015-05-28 16:53:31 -0400491 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
492 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700493 goto out;
494 }
495
Steven Valdezc1966802017-04-10 15:52:19 -0400496 /* Check that no other information follows the hash value (FIPS 186-4 Section
497 * 5.5) and it matches the expected hash. */
David Benjamin17cf2cb2016-12-13 01:07:13 -0500498 if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400499 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700500 goto out;
501 }
502
503 ret = 1;
504
505out:
David Benjamind8b65c82015-04-22 16:09:09 -0400506 OPENSSL_free(buf);
Adam Langley95c29f32014-06-20 12:00:00 -0700507 if (signed_msg_is_alloced) {
508 OPENSSL_free(signed_msg);
509 }
510 return ret;
511}
Adam Langley409766d2014-06-20 12:00:00 -0700512
513static void bn_free_and_null(BIGNUM **bn) {
Adam Langley409766d2014-06-20 12:00:00 -0700514 BN_free(*bn);
515 *bn = NULL;
516}
517
Adam Langley05b73772014-07-25 12:03:51 -0700518int RSA_check_key(const RSA *key) {
Brian Smith7241ca52016-07-25 16:01:10 -1000519 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q;
Adam Langley05b73772014-07-25 12:03:51 -0700520 BN_CTX *ctx;
521 int ok = 0, has_crt_values;
522
523 if (RSA_is_opaque(key)) {
524 /* Opaque keys can't be checked. */
525 return 1;
526 }
527
528 if ((key->p != NULL) != (key->q != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400529 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langley05b73772014-07-25 12:03:51 -0700530 return 0;
531 }
532
533 if (!key->n || !key->e) {
David Benjamin3570d732015-06-29 00:28:17 -0400534 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langley05b73772014-07-25 12:03:51 -0700535 return 0;
536 }
537
538 if (!key->d || !key->p) {
539 /* For a public key, or without p and q, there's nothing that can be
540 * checked. */
541 return 1;
542 }
543
544 ctx = BN_CTX_new();
545 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400546 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley05b73772014-07-25 12:03:51 -0700547 return 0;
548 }
549
550 BN_init(&n);
551 BN_init(&pm1);
552 BN_init(&qm1);
553 BN_init(&lcm);
554 BN_init(&gcd);
555 BN_init(&de);
556 BN_init(&dmp1);
557 BN_init(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000558 BN_init(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700559
Adam Langley839b8812015-05-26 11:36:46 -0700560 if (!BN_mul(&n, key->p, key->q, ctx) ||
561 /* lcm = lcm(prime-1, for all primes) */
Adam Langley05b73772014-07-25 12:03:51 -0700562 !BN_sub(&pm1, key->p, BN_value_one()) ||
563 !BN_sub(&qm1, key->q, BN_value_one()) ||
564 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700565 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400566 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley839b8812015-05-26 11:36:46 -0700567 goto out;
568 }
569
Adam Langley839b8812015-05-26 11:36:46 -0700570 if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
Adam Langley05b73772014-07-25 12:03:51 -0700571 !BN_gcd(&gcd, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700572 /* de = d*e mod lcm(prime-1, for all primes). */
Adam Langley05b73772014-07-25 12:03:51 -0700573 !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400574 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700575 goto out;
576 }
577
578 if (BN_cmp(&n, key->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400579 OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
Adam Langley05b73772014-07-25 12:03:51 -0700580 goto out;
581 }
582
583 if (!BN_is_one(&de)) {
David Benjamin3570d732015-06-29 00:28:17 -0400584 OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
Adam Langley05b73772014-07-25 12:03:51 -0700585 goto out;
586 }
587
588 has_crt_values = key->dmp1 != NULL;
589 if (has_crt_values != (key->dmq1 != NULL) ||
590 has_crt_values != (key->iqmp != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400591 OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
Adam Langley05b73772014-07-25 12:03:51 -0700592 goto out;
593 }
594
David Benjamin82b2b852017-04-12 18:28:48 -0400595 if (has_crt_values) {
Adam Langley05b73772014-07-25 12:03:51 -0700596 if (/* dmp1 = d mod (p-1) */
597 !BN_mod(&dmp1, key->d, &pm1, ctx) ||
598 /* dmq1 = d mod (q-1) */
599 !BN_mod(&dmq1, key->d, &qm1, ctx) ||
600 /* iqmp = q^-1 mod p */
Brian Smith7241ca52016-07-25 16:01:10 -1000601 !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400602 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700603 goto out;
604 }
605
606 if (BN_cmp(&dmp1, key->dmp1) != 0 ||
607 BN_cmp(&dmq1, key->dmq1) != 0 ||
Brian Smith7241ca52016-07-25 16:01:10 -1000608 BN_cmp(key->iqmp, key->p) >= 0 ||
609 !BN_is_one(&iqmp_times_q)) {
David Benjamin3570d732015-06-29 00:28:17 -0400610 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langley05b73772014-07-25 12:03:51 -0700611 goto out;
612 }
613 }
614
615 ok = 1;
616
617out:
618 BN_free(&n);
619 BN_free(&pm1);
620 BN_free(&qm1);
621 BN_free(&lcm);
622 BN_free(&gcd);
623 BN_free(&de);
624 BN_free(&dmp1);
625 BN_free(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000626 BN_free(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700627 BN_CTX_free(ctx);
628
629 return ok;
630}
631
Steven Valdezd0b98822017-04-11 12:46:03 -0400632
633/* This is the product of the 132 smallest odd primes, from 3 to 751. */
634static const BN_ULONG kSmallFactorsLimbs[] = {
635 TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f),
636 TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b),
637 TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871),
638 TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3),
639 TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893),
640 TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e),
641 TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea),
642 TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727),
643 0x000017b1
644};
645static const BIGNUM kSmallFactors = STATIC_BIGNUM(kSmallFactorsLimbs);
646
Steven Valdez400d0b72017-04-06 14:55:18 -0400647int RSA_check_fips(RSA *key) {
Steven Valdezd0b98822017-04-11 12:46:03 -0400648 if (RSA_is_opaque(key)) {
649 /* Opaque keys can't be checked. */
650 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
651 return 0;
652 }
653
654 if (!RSA_check_key(key)) {
655 return 0;
656 }
657
658 BN_CTX *ctx = BN_CTX_new();
659 if (ctx == NULL) {
660 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
661 return 0;
662 }
663
664 BIGNUM small_gcd;
665 BN_init(&small_gcd);
666
667 int ret = 1;
668
669 /* Perform partial public key validation of RSA keys (SP 800-89 5.3.3). */
670 /* TODO(svaldez): Check that n is composite and not a power of a prime using
671 * extended Miller-Rabin. */
Adam Langleya54ebff2017-04-20 12:36:18 -0700672 if (BN_num_bits(key->e) <= 16 ||
Steven Valdezd0b98822017-04-11 12:46:03 -0400673 BN_num_bits(key->e) > 256 ||
674 !BN_is_odd(key->n) ||
675 !BN_is_odd(key->e) ||
676 !BN_gcd(&small_gcd, key->n, &kSmallFactors, ctx) ||
677 !BN_is_one(&small_gcd)) {
678 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
679 ret = 0;
680 }
681
682 BN_free(&small_gcd);
683 BN_CTX_free(ctx);
684
Steven Valdezb15143f2017-04-13 13:14:12 -0400685 if (!ret || key->d == NULL || key->p == NULL) {
686 /* On a failure or on only a public key, there's nothing else can be
687 * checked. */
Steven Valdez400d0b72017-04-06 14:55:18 -0400688 return ret;
689 }
690
691 /* FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG,
692 * section 9.9, it is not known whether |rsa| will be used for signing or
693 * encryption, so either pair-wise consistency self-test is acceptable. We
694 * perform a signing test. */
695 uint8_t data[32] = {0};
696 unsigned sig_len = RSA_size(key);
697 uint8_t *sig = OPENSSL_malloc(sig_len);
698 if (sig == NULL) {
Steven Valdezb15143f2017-04-13 13:14:12 -0400699 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Steven Valdez400d0b72017-04-06 14:55:18 -0400700 return 0;
701 }
702
703 if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key) ||
704 !RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
Steven Valdezb15143f2017-04-13 13:14:12 -0400705 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
Steven Valdez400d0b72017-04-06 14:55:18 -0400706 ret = 0;
707 }
708
709 OPENSSL_free(sig);
710
Steven Valdezd0b98822017-04-11 12:46:03 -0400711 return ret;
712}
713
Adam Langley409766d2014-06-20 12:00:00 -0700714int RSA_recover_crt_params(RSA *rsa) {
715 BN_CTX *ctx;
716 BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q;
717 int ok = 0;
718
719 if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400720 OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
Adam Langley409766d2014-06-20 12:00:00 -0700721 return 0;
722 }
723
724 if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
David Benjamin3570d732015-06-29 00:28:17 -0400725 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
Adam Langley409766d2014-06-20 12:00:00 -0700726 return 0;
727 }
728
729 /* This uses the algorithm from section 9B of the RSA paper:
730 * http://people.csail.mit.edu/rivest/Rsapaper.pdf */
731
732 ctx = BN_CTX_new();
733 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400734 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700735 return 0;
736 }
737
738 BN_CTX_start(ctx);
739 totient = BN_CTX_get(ctx);
740 rem = BN_CTX_get(ctx);
741 multiple = BN_CTX_get(ctx);
742 p_plus_q = BN_CTX_get(ctx);
743 p_minus_q = BN_CTX_get(ctx);
744
745 if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
746 p_minus_q == 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 goto err;
749 }
750
751 /* ed-1 is a small multiple of φ(n). */
752 if (!BN_mul(totient, rsa->e, rsa->d, ctx) ||
753 !BN_sub_word(totient, 1) ||
754 /* φ(n) =
755 * pq - p - q + 1 =
756 * n - (p + q) + 1
757 *
758 * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very
759 * close. But, when we calculate the quotient, we'll be truncating it
760 * because we discard the remainder. Thus (ed-1)/multiple will be >= n,
761 * which the totient cannot be. So we add one to the estimate.
762 *
763 * Consider ed-1 as:
764 *
765 * multiple * (n - (p+q) + 1) =
766 * multiple*n - multiple*(p+q) + multiple
767 *
768 * When we divide by n, the first term becomes multiple and, since
769 * multiple and p+q is tiny compared to n, the second and third terms can
770 * be ignored. Thus I claim that subtracting one from the estimate is
771 * sufficient. */
772 !BN_div(multiple, NULL, totient, rsa->n, ctx) ||
773 !BN_add_word(multiple, 1) ||
774 !BN_div(totient, rem, totient, multiple, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400775 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700776 goto err;
777 }
778
779 if (!BN_is_zero(rem)) {
David Benjamin3570d732015-06-29 00:28:17 -0400780 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
Adam Langley409766d2014-06-20 12:00:00 -0700781 goto err;
782 }
783
784 rsa->p = BN_new();
785 rsa->q = BN_new();
786 rsa->dmp1 = BN_new();
787 rsa->dmq1 = BN_new();
788 rsa->iqmp = BN_new();
789 if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
790 NULL || rsa->iqmp == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400791 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700792 goto err;
793 }
794
795 /* φ(n) = n - (p + q) + 1 =>
796 * n - totient + 1 = p + q */
797 if (!BN_sub(p_plus_q, rsa->n, totient) ||
798 !BN_add_word(p_plus_q, 1) ||
799 /* p - q = sqrt((p+q)^2 - 4n) */
800 !BN_sqr(rem, p_plus_q, ctx) ||
801 !BN_lshift(multiple, rsa->n, 2) ||
802 !BN_sub(rem, rem, multiple) ||
803 !BN_sqrt(p_minus_q, rem, ctx) ||
804 /* q is 1/2 (p+q)-(p-q) */
805 !BN_sub(rsa->q, p_plus_q, p_minus_q) ||
806 !BN_rshift1(rsa->q, rsa->q) ||
807 !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
808 !BN_mul(multiple, rsa->p, rsa->q, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400809 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700810 goto err;
811 }
812
813 if (BN_cmp(multiple, rsa->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400814 OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
Adam Langley409766d2014-06-20 12:00:00 -0700815 goto err;
816 }
817
818 if (!BN_sub(rem, rsa->p, BN_value_one()) ||
819 !BN_mod(rsa->dmp1, rsa->d, rem, ctx) ||
820 !BN_sub(rem, rsa->q, BN_value_one()) ||
821 !BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
822 !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400823 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700824 goto err;
825 }
826
827 ok = 1;
828
829err:
830 BN_CTX_end(ctx);
831 BN_CTX_free(ctx);
832 if (!ok) {
833 bn_free_and_null(&rsa->p);
834 bn_free_and_null(&rsa->q);
835 bn_free_and_null(&rsa->dmp1);
836 bn_free_and_null(&rsa->dmq1);
837 bn_free_and_null(&rsa->iqmp);
838 }
839 return ok;
840}
Adam Langley6bc658d2014-08-18 13:29:45 -0700841
842int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
843 size_t len) {
844 if (rsa->meth->private_transform) {
845 return rsa->meth->private_transform(rsa, out, in, len);
846 }
847
David Benjamind93831d2015-10-29 13:19:12 -0400848 return rsa_default_private_transform(rsa, out, in, len);
Adam Langley6bc658d2014-08-18 13:29:45 -0700849}
Adam Langleyc3ef76f2015-04-13 14:34:17 -0700850
851int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
852 return 1;
853}