blob: aec8935e9c2a9cd7683de43c8ce67a2d435edaf7 [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001/* 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
Kenny Roote99801b2015-11-06 15:31:15 -080059#include <limits.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080060#include <string.h>
61
62#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 Benjamin4969cc92016-04-22 15:02:23 -040067#include <openssl/nid.h>
Adam Langleye9ada862015-05-11 17:20:37 -070068#include <openssl/thread.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080069
70#include "internal.h"
Adam Langleye9ada862015-05-11 17:20:37 -070071#include "../internal.h"
Robert Sloan572a4e22017-04-17 10:52:19 -070072#include "../bn/internal.h"
Adam Langleyd9e397b2015-01-22 14:27:53 -080073
74
Adam Langleye9ada862015-05-11 17:20:37 -070075static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
76
Adam Langleyd9e397b2015-01-22 14:27:53 -080077RSA *RSA_new(void) { return RSA_new_method(NULL); }
78
79RSA *RSA_new_method(const ENGINE *engine) {
David Benjamin4969cc92016-04-22 15:02:23 -040080 RSA *rsa = OPENSSL_malloc(sizeof(RSA));
Adam Langleyd9e397b2015-01-22 14:27:53 -080081 if (rsa == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +000082 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -080083 return NULL;
84 }
85
Robert Sloan69939df2017-01-09 10:53:07 -080086 OPENSSL_memset(rsa, 0, sizeof(RSA));
Adam Langleyd9e397b2015-01-22 14:27:53 -080087
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 Langleye9ada862015-05-11 17:20:37 -070099 CRYPTO_MUTEX_init(&rsa->lock);
Adam Langley4139edb2016-01-13 15:00:54 -0800100 CRYPTO_new_ex_data(&rsa->ex_data);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800101
102 if (rsa->meth->init && !rsa->meth->init(rsa)) {
Adam Langleye9ada862015-05-11 17:20:37 -0700103 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
Kenny Roote99801b2015-11-06 15:31:15 -0800104 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800105 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 Langleyf4e42722015-06-04 17:45:09 -0700120 if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800121 return;
122 }
123
124 if (rsa->meth->finish) {
125 rsa->meth->finish(rsa);
126 }
127 METHOD_unref(rsa->meth);
128
Adam Langleye9ada862015-05-11 17:20:37 -0700129 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800130
Adam Langleye9ada862015-05-11 17:20:37 -0700131 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);
Adam Langleyfad63272015-11-12 12:15:39 -0800139 BN_MONT_CTX_free(rsa->mont_n);
140 BN_MONT_CTX_free(rsa->mont_p);
141 BN_MONT_CTX_free(rsa->mont_q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800142 for (u = 0; u < rsa->num_blindings; u++) {
143 BN_BLINDING_free(rsa->blindings[u]);
144 }
Adam Langleye9ada862015-05-11 17:20:37 -0700145 OPENSSL_free(rsa->blindings);
146 OPENSSL_free(rsa->blindings_inuse);
147 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800148 OPENSSL_free(rsa);
149}
150
151int RSA_up_ref(RSA *rsa) {
Adam Langleyf4e42722015-06-04 17:45:09 -0700152 CRYPTO_refcount_inc(&rsa->references);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800153 return 1;
154}
155
David Benjaminc895d6b2016-08-11 13:26:41 -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 Langleyd9e397b2015-01-22 14:27:53 -0800192int 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
Adam Langleyfad63272015-11-12 12:15:39 -0800197 return rsa_default_keygen(rsa, bits, e_value, cb);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800198}
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
Adam Langleyfad63272015-11-12 12:15:39 -0800206 return rsa_default_encrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800207}
208
Kenny Roote99801b2015-11-06 15:31:15 -0800209int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800210 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
Kenny Roote99801b2015-11-06 15:31:15 -0800217 if (out_len > INT_MAX) {
218 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
219 return -1;
220 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800221 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
Adam Langleyfad63272015-11-12 12:15:39 -0800230 return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800231}
232
Kenny Roote99801b2015-11-06 15:31:15 -0800233int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800234 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
Kenny Roote99801b2015-11-06 15:31:15 -0800241 if (out_len > INT_MAX) {
242 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
243 return -1;
244 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800245 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
Adam Langleyfad63272015-11-12 12:15:39 -0800254 return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800255}
256
Kenny Roote99801b2015-11-06 15:31:15 -0800257int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800258 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
Kenny Roote99801b2015-11-06 15:31:15 -0800265 if (out_len > INT_MAX) {
266 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
267 return -1;
268 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800269 return out_len;
270}
271
Kenny Roote99801b2015-11-06 15:31:15 -0800272int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800273 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
Kenny Roote99801b2015-11-06 15:31:15 -0800280 if (out_len > INT_MAX) {
281 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
282 return -1;
283 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800284 return out_len;
285}
286
287unsigned RSA_size(const RSA *rsa) {
288 if (rsa->meth->size) {
289 return rsa->meth->size(rsa);
290 }
291
Adam Langleyfad63272015-11-12 12:15:39 -0800292 return rsa_default_size(rsa);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800293}
294
295int RSA_is_opaque(const RSA *rsa) {
296 return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
297}
298
Adam Langley4139edb2016-01-13 15:00:54 -0800299int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800300 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
Adam Langleye9ada862015-05-11 17:20:37 -0700301 int index;
Adam Langley4139edb2016-01-13 15:00:54 -0800302 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
303 free_func)) {
Adam Langleye9ada862015-05-11 17:20:37 -0700304 return -1;
305 }
306 return index;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800307}
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 Langleyd9e397b2015-01-22 14:27:53 -0800372 NID_undef, 0, {0},
373 },
374};
375
Kenny Rootb8494592015-09-25 02:29:14 +0000376int 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 Langleyd9e397b2015-01-22 14:27:53 -0800379 unsigned i;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800380
381 if (hash_nid == NID_md5_sha1) {
382 /* Special case: SSL signature, just check the length. */
383 if (msg_len != SSL_SIG_LENGTH) {
Kenny Rootb8494592015-09-25 02:29:14 +0000384 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800385 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];
Adam Langleye9ada862015-05-11 17:20:37 -0700396 if (sig_prefix->nid != hash_nid) {
397 continue;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800398 }
Adam Langleye9ada862015-05-11 17:20:37 -0700399
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) {
Kenny Rootb8494592015-09-25 02:29:14 +0000407 OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
Adam Langleye9ada862015-05-11 17:20:37 -0700408 return 0;
409 }
410
411 signed_msg = OPENSSL_malloc(signed_msg_len);
412 if (!signed_msg) {
Kenny Rootb8494592015-09-25 02:29:14 +0000413 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleye9ada862015-05-11 17:20:37 -0700414 return 0;
415 }
416
Robert Sloan69939df2017-01-09 10:53:07 -0800417 OPENSSL_memcpy(signed_msg, prefix, prefix_len);
418 OPENSSL_memcpy(signed_msg + prefix_len, msg, msg_len);
Adam Langleye9ada862015-05-11 17:20:37 -0700419
420 *out_msg = signed_msg;
421 *out_msg_len = signed_msg_len;
422 *is_alloced = 1;
423
424 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800425 }
426
Kenny Rootb8494592015-09-25 02:29:14 +0000427 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
Adam Langleye9ada862015-05-11 17:20:37 -0700428 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800429}
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
Kenny Rootb8494592015-09-25 02:29:14 +0000444 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
Robert Sloan572a4e22017-04-17 10:52:19 -0700445 &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 Langleyd9e397b2015-01-22 14:27:53 -0800449 }
450
Robert Sloan572a4e22017-04-17 10:52:19 -0700451 *out_len = size_t_out_len;
452 ret = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800453
Robert Sloan572a4e22017-04-17 10:52:19 -0700454err:
Adam Langleyd9e397b2015-01-22 14:27:53 -0800455 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) {
David Benjamin4969cc92016-04-22 15:02:23 -0400463 if (rsa->n == NULL || rsa->e == NULL) {
464 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
465 return 0;
466 }
467
Adam Langleyd9e397b2015-01-22 14:27:53 -0800468 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 Langleyd9e397b2015-01-22 14:27:53 -0800475 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
Kenny Rootb8494592015-09-25 02:29:14 +0000476 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800477 return 0;
478 }
479
480 buf = OPENSSL_malloc(rsa_size);
481 if (!buf) {
Kenny Rootb8494592015-09-25 02:29:14 +0000482 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800483 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
Kenny Rootb8494592015-09-25 02:29:14 +0000491 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
492 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800493 goto out;
494 }
495
Robert Sloan572a4e22017-04-17 10:52:19 -0700496 /* Check that no other information follows the hash value (FIPS 186-4 Section
497 * 5.5) and it matches the expected hash. */
Robert Sloan69939df2017-01-09 10:53:07 -0800498 if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000499 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800500 goto out;
501 }
502
503 ret = 1;
504
505out:
Adam Langleye9ada862015-05-11 17:20:37 -0700506 OPENSSL_free(buf);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800507 if (signed_msg_is_alloced) {
508 OPENSSL_free(signed_msg);
509 }
510 return ret;
511}
512
513static void bn_free_and_null(BIGNUM **bn) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800514 BN_free(*bn);
515 *bn = NULL;
516}
517
518int RSA_check_key(const RSA *key) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400519 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800520 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)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000529 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800530 return 0;
531 }
532
533 if (!key->n || !key->e) {
Kenny Rootb8494592015-09-25 02:29:14 +0000534 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800535 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) {
Kenny Rootb8494592015-09-25 02:29:14 +0000546 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800547 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);
David Benjaminc895d6b2016-08-11 13:26:41 -0400558 BN_init(&iqmp_times_q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800559
Kenny Rootb8494592015-09-25 02:29:14 +0000560 if (!BN_mul(&n, key->p, key->q, ctx) ||
561 /* lcm = lcm(prime-1, for all primes) */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800562 !BN_sub(&pm1, key->p, BN_value_one()) ||
563 !BN_sub(&qm1, key->q, BN_value_one()) ||
564 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Kenny Rootb8494592015-09-25 02:29:14 +0000565 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
566 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
567 goto out;
568 }
569
Kenny Rootb8494592015-09-25 02:29:14 +0000570 if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
Adam Langleyd9e397b2015-01-22 14:27:53 -0800571 !BN_gcd(&gcd, &pm1, &qm1, ctx) ||
Kenny Rootb8494592015-09-25 02:29:14 +0000572 /* de = d*e mod lcm(prime-1, for all primes). */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800573 !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000574 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800575 goto out;
576 }
577
578 if (BN_cmp(&n, key->n) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000579 OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800580 goto out;
581 }
582
583 if (!BN_is_one(&de)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000584 OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800585 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)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000591 OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800592 goto out;
593 }
594
Robert Sloan572a4e22017-04-17 10:52:19 -0700595 if (has_crt_values) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800596 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 */
David Benjaminc895d6b2016-08-11 13:26:41 -0400601 !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000602 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800603 goto out;
604 }
605
606 if (BN_cmp(&dmp1, key->dmp1) != 0 ||
607 BN_cmp(&dmq1, key->dmq1) != 0 ||
David Benjaminc895d6b2016-08-11 13:26:41 -0400608 BN_cmp(key->iqmp, key->p) >= 0 ||
609 !BN_is_one(&iqmp_times_q)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000610 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800611 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);
David Benjaminc895d6b2016-08-11 13:26:41 -0400626 BN_free(&iqmp_times_q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800627 BN_CTX_free(ctx);
628
629 return ok;
630}
631
Robert Sloan572a4e22017-04-17 10:52:19 -0700632
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
647int RSA_check_fips(RSA *key) {
648 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). */
Robert Sloan9254e682017-04-24 09:42:06 -0700670 enum bn_primality_result_t primality_result;
671 if (BN_num_bits(key->e) <= 16 ||
Robert Sloan572a4e22017-04-17 10:52:19 -0700672 BN_num_bits(key->e) > 256 ||
673 !BN_is_odd(key->n) ||
674 !BN_is_odd(key->e) ||
675 !BN_gcd(&small_gcd, key->n, &kSmallFactors, ctx) ||
Robert Sloan9254e682017-04-24 09:42:06 -0700676 !BN_is_one(&small_gcd) ||
677 !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n,
678 BN_prime_checks, ctx, NULL) ||
679 primality_result != bn_non_prime_power_composite) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700680 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
681 ret = 0;
682 }
683
684 BN_free(&small_gcd);
685 BN_CTX_free(ctx);
686
687 if (!ret || key->d == NULL || key->p == NULL) {
688 /* On a failure or on only a public key, there's nothing else can be
689 * checked. */
690 return ret;
691 }
692
693 /* FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG,
694 * section 9.9, it is not known whether |rsa| will be used for signing or
695 * encryption, so either pair-wise consistency self-test is acceptable. We
696 * perform a signing test. */
697 uint8_t data[32] = {0};
698 unsigned sig_len = RSA_size(key);
699 uint8_t *sig = OPENSSL_malloc(sig_len);
700 if (sig == NULL) {
701 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
702 return 0;
703 }
704
705 if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key) ||
706 !RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
707 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
708 ret = 0;
709 }
710
711 OPENSSL_free(sig);
712
713 return ret;
714}
715
Adam Langleyd9e397b2015-01-22 14:27:53 -0800716int RSA_recover_crt_params(RSA *rsa) {
717 BN_CTX *ctx;
718 BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q;
719 int ok = 0;
720
721 if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000722 OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800723 return 0;
724 }
725
726 if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
Kenny Rootb8494592015-09-25 02:29:14 +0000727 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
728 return 0;
729 }
730
Adam Langleyd9e397b2015-01-22 14:27:53 -0800731 /* This uses the algorithm from section 9B of the RSA paper:
732 * http://people.csail.mit.edu/rivest/Rsapaper.pdf */
733
734 ctx = BN_CTX_new();
735 if (ctx == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000736 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800737 return 0;
738 }
739
740 BN_CTX_start(ctx);
741 totient = BN_CTX_get(ctx);
742 rem = BN_CTX_get(ctx);
743 multiple = BN_CTX_get(ctx);
744 p_plus_q = BN_CTX_get(ctx);
745 p_minus_q = BN_CTX_get(ctx);
746
747 if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
748 p_minus_q == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000749 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800750 goto err;
751 }
752
753 /* ed-1 is a small multiple of φ(n). */
754 if (!BN_mul(totient, rsa->e, rsa->d, ctx) ||
755 !BN_sub_word(totient, 1) ||
756 /* φ(n) =
757 * pq - p - q + 1 =
758 * n - (p + q) + 1
759 *
760 * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very
761 * close. But, when we calculate the quotient, we'll be truncating it
762 * because we discard the remainder. Thus (ed-1)/multiple will be >= n,
763 * which the totient cannot be. So we add one to the estimate.
764 *
765 * Consider ed-1 as:
766 *
767 * multiple * (n - (p+q) + 1) =
768 * multiple*n - multiple*(p+q) + multiple
769 *
770 * When we divide by n, the first term becomes multiple and, since
771 * multiple and p+q is tiny compared to n, the second and third terms can
772 * be ignored. Thus I claim that subtracting one from the estimate is
773 * sufficient. */
774 !BN_div(multiple, NULL, totient, rsa->n, ctx) ||
775 !BN_add_word(multiple, 1) ||
776 !BN_div(totient, rem, totient, multiple, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000777 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800778 goto err;
779 }
780
781 if (!BN_is_zero(rem)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000782 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800783 goto err;
784 }
785
786 rsa->p = BN_new();
787 rsa->q = BN_new();
788 rsa->dmp1 = BN_new();
789 rsa->dmq1 = BN_new();
790 rsa->iqmp = BN_new();
791 if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
792 NULL || rsa->iqmp == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000793 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800794 goto err;
795 }
796
797 /* φ(n) = n - (p + q) + 1 =>
798 * n - totient + 1 = p + q */
799 if (!BN_sub(p_plus_q, rsa->n, totient) ||
800 !BN_add_word(p_plus_q, 1) ||
801 /* p - q = sqrt((p+q)^2 - 4n) */
802 !BN_sqr(rem, p_plus_q, ctx) ||
803 !BN_lshift(multiple, rsa->n, 2) ||
804 !BN_sub(rem, rem, multiple) ||
805 !BN_sqrt(p_minus_q, rem, ctx) ||
806 /* q is 1/2 (p+q)-(p-q) */
807 !BN_sub(rsa->q, p_plus_q, p_minus_q) ||
808 !BN_rshift1(rsa->q, rsa->q) ||
809 !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
810 !BN_mul(multiple, rsa->p, rsa->q, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000811 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800812 goto err;
813 }
814
815 if (BN_cmp(multiple, rsa->n) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000816 OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800817 goto err;
818 }
819
820 if (!BN_sub(rem, rsa->p, BN_value_one()) ||
821 !BN_mod(rsa->dmp1, rsa->d, rem, ctx) ||
822 !BN_sub(rem, rsa->q, BN_value_one()) ||
823 !BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
824 !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000825 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800826 goto err;
827 }
828
829 ok = 1;
830
831err:
832 BN_CTX_end(ctx);
833 BN_CTX_free(ctx);
834 if (!ok) {
835 bn_free_and_null(&rsa->p);
836 bn_free_and_null(&rsa->q);
837 bn_free_and_null(&rsa->dmp1);
838 bn_free_and_null(&rsa->dmq1);
839 bn_free_and_null(&rsa->iqmp);
840 }
841 return ok;
842}
843
844int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
845 size_t len) {
846 if (rsa->meth->private_transform) {
847 return rsa->meth->private_transform(rsa, out, in, len);
848 }
849
Adam Langleyfad63272015-11-12 12:15:39 -0800850 return rsa_default_private_transform(rsa, out, in, len);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800851}
Adam Langleyf7e890d2015-03-31 18:58:05 -0700852
853int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
854 return 1;
855}