blob: 6477a26e49b4274d784c2adcd19803dad220fa96 [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>
Robert Sloan8ff03552017-06-14 12:40:58 -070063#include <openssl/digest.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080064#include <openssl/engine.h>
65#include <openssl/err.h>
66#include <openssl/ex_data.h>
Robert Sloan8ff03552017-06-14 12:40:58 -070067#include <openssl/md5.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080068#include <openssl/mem.h>
David Benjamin4969cc92016-04-22 15:02:23 -040069#include <openssl/nid.h>
Robert Sloan8ff03552017-06-14 12:40:58 -070070#include <openssl/sha.h>
Adam Langleye9ada862015-05-11 17:20:37 -070071#include <openssl/thread.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080072
Robert Sloan572a4e22017-04-17 10:52:19 -070073#include "../bn/internal.h"
Robert Sloan8ff03552017-06-14 12:40:58 -070074#include "../delocate.h"
75#include "../../internal.h"
76#include "internal.h"
Adam Langleyd9e397b2015-01-22 14:27:53 -080077
78
Robert Sloan8ff03552017-06-14 12:40:58 -070079DEFINE_STATIC_EX_DATA_CLASS(g_rsa_ex_data_class);
Adam Langleye9ada862015-05-11 17:20:37 -070080
Adam Langleyd9e397b2015-01-22 14:27:53 -080081RSA *RSA_new(void) { return RSA_new_method(NULL); }
82
83RSA *RSA_new_method(const ENGINE *engine) {
David Benjamin4969cc92016-04-22 15:02:23 -040084 RSA *rsa = OPENSSL_malloc(sizeof(RSA));
Adam Langleyd9e397b2015-01-22 14:27:53 -080085 if (rsa == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +000086 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -080087 return NULL;
88 }
89
Robert Sloan69939df2017-01-09 10:53:07 -080090 OPENSSL_memset(rsa, 0, sizeof(RSA));
Adam Langleyd9e397b2015-01-22 14:27:53 -080091
92 if (engine) {
93 rsa->meth = ENGINE_get_RSA_method(engine);
94 }
95
96 if (rsa->meth == NULL) {
Robert Sloan8ff03552017-06-14 12:40:58 -070097 rsa->meth = (RSA_METHOD *) RSA_default_method();
Adam Langleyd9e397b2015-01-22 14:27:53 -080098 }
99 METHOD_ref(rsa->meth);
100
101 rsa->references = 1;
102 rsa->flags = rsa->meth->flags;
Adam Langleye9ada862015-05-11 17:20:37 -0700103 CRYPTO_MUTEX_init(&rsa->lock);
Adam Langley4139edb2016-01-13 15:00:54 -0800104 CRYPTO_new_ex_data(&rsa->ex_data);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800105
106 if (rsa->meth->init && !rsa->meth->init(rsa)) {
Robert Sloan8ff03552017-06-14 12:40:58 -0700107 CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data);
Kenny Roote99801b2015-11-06 15:31:15 -0800108 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800109 METHOD_unref(rsa->meth);
110 OPENSSL_free(rsa);
111 return NULL;
112 }
113
114 return rsa;
115}
116
117void RSA_free(RSA *rsa) {
118 unsigned u;
119
120 if (rsa == NULL) {
121 return;
122 }
123
Adam Langleyf4e42722015-06-04 17:45:09 -0700124 if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800125 return;
126 }
127
128 if (rsa->meth->finish) {
129 rsa->meth->finish(rsa);
130 }
131 METHOD_unref(rsa->meth);
132
Robert Sloan8ff03552017-06-14 12:40:58 -0700133 CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800134
Robert Sloanab8b8882018-03-26 11:39:51 -0700135 BN_free(rsa->n);
136 BN_free(rsa->e);
137 BN_free(rsa->d);
138 BN_free(rsa->p);
139 BN_free(rsa->q);
140 BN_free(rsa->dmp1);
141 BN_free(rsa->dmq1);
142 BN_free(rsa->iqmp);
Adam Langleyfad63272015-11-12 12:15:39 -0800143 BN_MONT_CTX_free(rsa->mont_n);
144 BN_MONT_CTX_free(rsa->mont_p);
145 BN_MONT_CTX_free(rsa->mont_q);
Robert Sloanab8b8882018-03-26 11:39:51 -0700146 BN_free(rsa->d_fixed);
147 BN_free(rsa->dmp1_fixed);
148 BN_free(rsa->dmq1_fixed);
149 BN_free(rsa->inv_small_mod_large_mont);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800150 for (u = 0; u < rsa->num_blindings; u++) {
151 BN_BLINDING_free(rsa->blindings[u]);
152 }
Adam Langleye9ada862015-05-11 17:20:37 -0700153 OPENSSL_free(rsa->blindings);
154 OPENSSL_free(rsa->blindings_inuse);
155 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800156 OPENSSL_free(rsa);
157}
158
159int RSA_up_ref(RSA *rsa) {
Adam Langleyf4e42722015-06-04 17:45:09 -0700160 CRYPTO_refcount_inc(&rsa->references);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800161 return 1;
162}
163
Robert Sloan99319a12017-11-27 10:32:46 -0800164unsigned RSA_bits(const RSA *rsa) { return BN_num_bits(rsa->n); }
165
David Benjaminc895d6b2016-08-11 13:26:41 -0400166void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e,
167 const BIGNUM **out_d) {
168 if (out_n != NULL) {
169 *out_n = rsa->n;
170 }
171 if (out_e != NULL) {
172 *out_e = rsa->e;
173 }
174 if (out_d != NULL) {
175 *out_d = rsa->d;
176 }
177}
178
179void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p,
180 const BIGNUM **out_q) {
181 if (out_p != NULL) {
182 *out_p = rsa->p;
183 }
184 if (out_q != NULL) {
185 *out_q = rsa->q;
186 }
187}
188
189void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1,
190 const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) {
191 if (out_dmp1 != NULL) {
192 *out_dmp1 = rsa->dmp1;
193 }
194 if (out_dmq1 != NULL) {
195 *out_dmq1 = rsa->dmq1;
196 }
197 if (out_iqmp != NULL) {
198 *out_iqmp = rsa->iqmp;
199 }
200}
201
Robert Sloan4562e9d2017-10-02 10:26:51 -0700202int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
203 if ((rsa->n == NULL && n == NULL) ||
204 (rsa->e == NULL && e == NULL)) {
205 return 0;
206 }
207
208 if (n != NULL) {
209 BN_free(rsa->n);
210 rsa->n = n;
211 }
212 if (e != NULL) {
213 BN_free(rsa->e);
214 rsa->e = e;
215 }
216 if (d != NULL) {
217 BN_free(rsa->d);
218 rsa->d = d;
219 }
220
221 return 1;
222}
223
224int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) {
225 if ((rsa->p == NULL && p == NULL) ||
226 (rsa->q == NULL && q == NULL)) {
227 return 0;
228 }
229
230 if (p != NULL) {
231 BN_free(rsa->p);
232 rsa->p = p;
233 }
234 if (q != NULL) {
235 BN_free(rsa->q);
236 rsa->q = q;
237 }
238
239 return 1;
240}
241
242int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) {
243 if ((rsa->dmp1 == NULL && dmp1 == NULL) ||
244 (rsa->dmq1 == NULL && dmq1 == NULL) ||
245 (rsa->iqmp == NULL && iqmp == NULL)) {
246 return 0;
247 }
248
249 if (dmp1 != NULL) {
250 BN_free(rsa->dmp1);
251 rsa->dmp1 = dmp1;
252 }
253 if (dmq1 != NULL) {
254 BN_free(rsa->dmq1);
255 rsa->dmq1 = dmq1;
256 }
257 if (iqmp != NULL) {
258 BN_free(rsa->iqmp);
259 rsa->iqmp = iqmp;
260 }
261
262 return 1;
263}
264
Kenny Roote99801b2015-11-06 15:31:15 -0800265int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800266 int padding) {
267 size_t out_len;
268
269 if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
270 return -1;
271 }
272
Kenny Roote99801b2015-11-06 15:31:15 -0800273 if (out_len > INT_MAX) {
274 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
275 return -1;
276 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800277 return out_len;
278}
279
280int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
281 const uint8_t *in, size_t in_len, int padding) {
282 if (rsa->meth->sign_raw) {
283 return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
284 }
285
Adam Langleyfad63272015-11-12 12:15:39 -0800286 return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800287}
288
Kenny Roote99801b2015-11-06 15:31:15 -0800289int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800290 int padding) {
291 size_t out_len;
292
293 if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
294 return -1;
295 }
296
Kenny Roote99801b2015-11-06 15:31:15 -0800297 if (out_len > INT_MAX) {
298 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
299 return -1;
300 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800301 return out_len;
302}
303
304int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
305 const uint8_t *in, size_t in_len, int padding) {
306 if (rsa->meth->decrypt) {
307 return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
308 }
309
Adam Langleyfad63272015-11-12 12:15:39 -0800310 return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800311}
312
Kenny Roote99801b2015-11-06 15:31:15 -0800313int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800314 int padding) {
315 size_t out_len;
316
317 if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
318 return -1;
319 }
320
Kenny Roote99801b2015-11-06 15:31:15 -0800321 if (out_len > INT_MAX) {
322 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
323 return -1;
324 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800325 return out_len;
326}
327
Kenny Roote99801b2015-11-06 15:31:15 -0800328int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800329 int padding) {
330 size_t out_len;
331
332 if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
333 return -1;
334 }
335
Kenny Roote99801b2015-11-06 15:31:15 -0800336 if (out_len > INT_MAX) {
337 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
338 return -1;
339 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800340 return out_len;
341}
342
343unsigned RSA_size(const RSA *rsa) {
344 if (rsa->meth->size) {
345 return rsa->meth->size(rsa);
346 }
347
Adam Langleyfad63272015-11-12 12:15:39 -0800348 return rsa_default_size(rsa);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800349}
350
351int RSA_is_opaque(const RSA *rsa) {
352 return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
353}
354
Adam Langley4139edb2016-01-13 15:00:54 -0800355int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Robert Sloan8ff03552017-06-14 12:40:58 -0700356 CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
Adam Langleye9ada862015-05-11 17:20:37 -0700357 int index;
Robert Sloan8ff03552017-06-14 12:40:58 -0700358 if (!CRYPTO_get_ex_new_index(g_rsa_ex_data_class_bss_get(), &index, argl,
359 argp, free_func)) {
Adam Langleye9ada862015-05-11 17:20:37 -0700360 return -1;
361 }
362 return index;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800363}
364
Robert Sloanfe7cd212017-08-07 09:03:39 -0700365int RSA_set_ex_data(RSA *rsa, int idx, void *arg) {
366 return CRYPTO_set_ex_data(&rsa->ex_data, idx, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800367}
368
Robert Sloanfe7cd212017-08-07 09:03:39 -0700369void *RSA_get_ex_data(const RSA *rsa, int idx) {
370 return CRYPTO_get_ex_data(&rsa->ex_data, idx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800371}
372
Robert Sloan8f860b12017-08-28 07:37:06 -0700373// SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
374// the length of an MD5 and SHA1 hash.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800375static const unsigned SSL_SIG_LENGTH = 36;
376
Robert Sloan8f860b12017-08-28 07:37:06 -0700377// pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is
378// to be signed with PKCS#1.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800379struct pkcs1_sig_prefix {
Robert Sloan8f860b12017-08-28 07:37:06 -0700380 // nid identifies the hash function.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800381 int nid;
Robert Sloan8f860b12017-08-28 07:37:06 -0700382 // hash_len is the expected length of the hash function.
Robert Sloan8ff03552017-06-14 12:40:58 -0700383 uint8_t hash_len;
Robert Sloan8f860b12017-08-28 07:37:06 -0700384 // len is the number of bytes of |bytes| which are valid.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800385 uint8_t len;
Robert Sloan8f860b12017-08-28 07:37:06 -0700386 // bytes contains the DER bytes.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800387 uint8_t bytes[19];
388};
389
Robert Sloan8f860b12017-08-28 07:37:06 -0700390// kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with
391// different hash functions.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800392static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
393 {
394 NID_md5,
Robert Sloan8ff03552017-06-14 12:40:58 -0700395 MD5_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800396 18,
397 {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
398 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
399 },
400 {
401 NID_sha1,
Robert Sloan8ff03552017-06-14 12:40:58 -0700402 SHA_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800403 15,
404 {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
405 0x00, 0x04, 0x14},
406 },
407 {
408 NID_sha224,
Robert Sloan8ff03552017-06-14 12:40:58 -0700409 SHA224_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800410 19,
411 {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
412 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
413 },
414 {
415 NID_sha256,
Robert Sloan8ff03552017-06-14 12:40:58 -0700416 SHA256_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800417 19,
418 {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
419 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
420 },
421 {
422 NID_sha384,
Robert Sloan8ff03552017-06-14 12:40:58 -0700423 SHA384_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800424 19,
425 {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
426 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
427 },
428 {
429 NID_sha512,
Robert Sloan8ff03552017-06-14 12:40:58 -0700430 SHA512_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800431 19,
432 {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
433 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
434 },
435 {
Robert Sloan8ff03552017-06-14 12:40:58 -0700436 NID_undef, 0, 0, {0},
Adam Langleyd9e397b2015-01-22 14:27:53 -0800437 },
438};
439
Kenny Rootb8494592015-09-25 02:29:14 +0000440int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
441 int *is_alloced, int hash_nid, const uint8_t *msg,
442 size_t msg_len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800443 unsigned i;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800444
445 if (hash_nid == NID_md5_sha1) {
Robert Sloan8f860b12017-08-28 07:37:06 -0700446 // Special case: SSL signature, just check the length.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800447 if (msg_len != SSL_SIG_LENGTH) {
Kenny Rootb8494592015-09-25 02:29:14 +0000448 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800449 return 0;
450 }
451
452 *out_msg = (uint8_t*) msg;
453 *out_msg_len = SSL_SIG_LENGTH;
454 *is_alloced = 0;
455 return 1;
456 }
457
458 for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
459 const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
Adam Langleye9ada862015-05-11 17:20:37 -0700460 if (sig_prefix->nid != hash_nid) {
461 continue;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800462 }
Adam Langleye9ada862015-05-11 17:20:37 -0700463
Robert Sloan8ff03552017-06-14 12:40:58 -0700464 if (msg_len != sig_prefix->hash_len) {
465 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
466 return 0;
467 }
468
Adam Langleye9ada862015-05-11 17:20:37 -0700469 const uint8_t* prefix = sig_prefix->bytes;
470 unsigned prefix_len = sig_prefix->len;
471 unsigned signed_msg_len;
472 uint8_t *signed_msg;
473
474 signed_msg_len = prefix_len + msg_len;
475 if (signed_msg_len < prefix_len) {
Kenny Rootb8494592015-09-25 02:29:14 +0000476 OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
Adam Langleye9ada862015-05-11 17:20:37 -0700477 return 0;
478 }
479
480 signed_msg = OPENSSL_malloc(signed_msg_len);
481 if (!signed_msg) {
Kenny Rootb8494592015-09-25 02:29:14 +0000482 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleye9ada862015-05-11 17:20:37 -0700483 return 0;
484 }
485
Robert Sloan69939df2017-01-09 10:53:07 -0800486 OPENSSL_memcpy(signed_msg, prefix, prefix_len);
487 OPENSSL_memcpy(signed_msg + prefix_len, msg, msg_len);
Adam Langleye9ada862015-05-11 17:20:37 -0700488
489 *out_msg = signed_msg;
490 *out_msg_len = signed_msg_len;
491 *is_alloced = 1;
492
493 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800494 }
495
Kenny Rootb8494592015-09-25 02:29:14 +0000496 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
Adam Langleye9ada862015-05-11 17:20:37 -0700497 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800498}
499
500int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out,
501 unsigned *out_len, RSA *rsa) {
502 const unsigned rsa_size = RSA_size(rsa);
503 int ret = 0;
Robert Sloan8ff03552017-06-14 12:40:58 -0700504 uint8_t *signed_msg = NULL;
505 size_t signed_msg_len = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800506 int signed_msg_is_alloced = 0;
507 size_t size_t_out_len;
508
509 if (rsa->meth->sign) {
510 return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa);
511 }
512
Kenny Rootb8494592015-09-25 02:29:14 +0000513 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
Robert Sloan572a4e22017-04-17 10:52:19 -0700514 &signed_msg_is_alloced, hash_nid, in, in_len) ||
515 !RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg,
516 signed_msg_len, RSA_PKCS1_PADDING)) {
517 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800518 }
519
Robert Sloan572a4e22017-04-17 10:52:19 -0700520 *out_len = size_t_out_len;
521 ret = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800522
Robert Sloan572a4e22017-04-17 10:52:19 -0700523err:
Adam Langleyd9e397b2015-01-22 14:27:53 -0800524 if (signed_msg_is_alloced) {
525 OPENSSL_free(signed_msg);
526 }
527 return ret;
528}
529
Robert Sloan8ff03552017-06-14 12:40:58 -0700530int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
531 const uint8_t *in, size_t in_len, const EVP_MD *md,
532 const EVP_MD *mgf1_md, int salt_len) {
533 if (in_len != EVP_MD_size(md)) {
534 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
535 return 0;
536 }
537
538 size_t padded_len = RSA_size(rsa);
539 uint8_t *padded = OPENSSL_malloc(padded_len);
540 if (padded == NULL) {
541 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
542 return 0;
543 }
544
545 int ret =
546 RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, in, md, mgf1_md, salt_len) &&
547 RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len,
548 RSA_NO_PADDING);
549 OPENSSL_free(padded);
550 return ret;
551}
552
Adam Langleyd9e397b2015-01-22 14:27:53 -0800553int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
554 const uint8_t *sig, size_t sig_len, RSA *rsa) {
David Benjamin4969cc92016-04-22 15:02:23 -0400555 if (rsa->n == NULL || rsa->e == NULL) {
556 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
557 return 0;
558 }
559
Adam Langleyd9e397b2015-01-22 14:27:53 -0800560 const size_t rsa_size = RSA_size(rsa);
561 uint8_t *buf = NULL;
562 int ret = 0;
563 uint8_t *signed_msg = NULL;
Robert Sloan8ff03552017-06-14 12:40:58 -0700564 size_t signed_msg_len = 0, len;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800565 int signed_msg_is_alloced = 0;
566
Adam Langleyd9e397b2015-01-22 14:27:53 -0800567 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
Kenny Rootb8494592015-09-25 02:29:14 +0000568 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800569 return 0;
570 }
571
572 buf = OPENSSL_malloc(rsa_size);
573 if (!buf) {
Kenny Rootb8494592015-09-25 02:29:14 +0000574 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800575 return 0;
576 }
577
578 if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len,
579 RSA_PKCS1_PADDING)) {
580 goto out;
581 }
582
Kenny Rootb8494592015-09-25 02:29:14 +0000583 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
584 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800585 goto out;
586 }
587
Robert Sloan8f860b12017-08-28 07:37:06 -0700588 // Check that no other information follows the hash value (FIPS 186-4 Section
589 // 5.5) and it matches the expected hash.
Robert Sloan69939df2017-01-09 10:53:07 -0800590 if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000591 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800592 goto out;
593 }
594
595 ret = 1;
596
597out:
Adam Langleye9ada862015-05-11 17:20:37 -0700598 OPENSSL_free(buf);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800599 if (signed_msg_is_alloced) {
600 OPENSSL_free(signed_msg);
601 }
602 return ret;
603}
604
Robert Sloan8ff03552017-06-14 12:40:58 -0700605int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, size_t msg_len,
606 const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len,
607 const uint8_t *sig, size_t sig_len) {
608 if (msg_len != EVP_MD_size(md)) {
609 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
610 return 0;
611 }
612
613 size_t em_len = RSA_size(rsa);
614 uint8_t *em = OPENSSL_malloc(em_len);
615 if (em == NULL) {
616 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
617 return 0;
618 }
619
620 int ret = 0;
621 if (!RSA_verify_raw(rsa, &em_len, em, em_len, sig, sig_len, RSA_NO_PADDING)) {
622 goto err;
623 }
624
625 if (em_len != RSA_size(rsa)) {
626 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
627 goto err;
628 }
629
630 ret = RSA_verify_PKCS1_PSS_mgf1(rsa, msg, md, mgf1_md, em, salt_len);
631
632err:
633 OPENSSL_free(em);
634 return ret;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800635}
636
637int RSA_check_key(const RSA *key) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400638 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800639 BN_CTX *ctx;
640 int ok = 0, has_crt_values;
641
642 if (RSA_is_opaque(key)) {
Robert Sloan8f860b12017-08-28 07:37:06 -0700643 // Opaque keys can't be checked.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800644 return 1;
645 }
646
647 if ((key->p != NULL) != (key->q != NULL)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000648 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800649 return 0;
650 }
651
652 if (!key->n || !key->e) {
Kenny Rootb8494592015-09-25 02:29:14 +0000653 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800654 return 0;
655 }
656
657 if (!key->d || !key->p) {
Robert Sloan8f860b12017-08-28 07:37:06 -0700658 // For a public key, or without p and q, there's nothing that can be
659 // checked.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800660 return 1;
661 }
662
663 ctx = BN_CTX_new();
664 if (ctx == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000665 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800666 return 0;
667 }
668
669 BN_init(&n);
670 BN_init(&pm1);
671 BN_init(&qm1);
672 BN_init(&lcm);
673 BN_init(&gcd);
674 BN_init(&de);
675 BN_init(&dmp1);
676 BN_init(&dmq1);
David Benjaminc895d6b2016-08-11 13:26:41 -0400677 BN_init(&iqmp_times_q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800678
Kenny Rootb8494592015-09-25 02:29:14 +0000679 if (!BN_mul(&n, key->p, key->q, ctx) ||
Robert Sloan8f860b12017-08-28 07:37:06 -0700680 // lcm = lcm(p, q)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800681 !BN_sub(&pm1, key->p, BN_value_one()) ||
682 !BN_sub(&qm1, key->q, BN_value_one()) ||
683 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Kenny Rootb8494592015-09-25 02:29:14 +0000684 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
685 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
686 goto out;
687 }
688
Kenny Rootb8494592015-09-25 02:29:14 +0000689 if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
Adam Langleyd9e397b2015-01-22 14:27:53 -0800690 !BN_gcd(&gcd, &pm1, &qm1, ctx) ||
Robert Sloan8f860b12017-08-28 07:37:06 -0700691 // de = d*e mod lcm(p, q).
Adam Langleyd9e397b2015-01-22 14:27:53 -0800692 !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000693 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800694 goto out;
695 }
696
697 if (BN_cmp(&n, key->n) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000698 OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800699 goto out;
700 }
701
702 if (!BN_is_one(&de)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000703 OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800704 goto out;
705 }
706
707 has_crt_values = key->dmp1 != NULL;
708 if (has_crt_values != (key->dmq1 != NULL) ||
709 has_crt_values != (key->iqmp != NULL)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000710 OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800711 goto out;
712 }
713
Robert Sloan572a4e22017-04-17 10:52:19 -0700714 if (has_crt_values) {
Robert Sloan8f860b12017-08-28 07:37:06 -0700715 if (// dmp1 = d mod (p-1)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800716 !BN_mod(&dmp1, key->d, &pm1, ctx) ||
Robert Sloan8f860b12017-08-28 07:37:06 -0700717 // dmq1 = d mod (q-1)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800718 !BN_mod(&dmq1, key->d, &qm1, ctx) ||
Robert Sloan8f860b12017-08-28 07:37:06 -0700719 // iqmp = q^-1 mod p
David Benjaminc895d6b2016-08-11 13:26:41 -0400720 !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000721 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800722 goto out;
723 }
724
725 if (BN_cmp(&dmp1, key->dmp1) != 0 ||
726 BN_cmp(&dmq1, key->dmq1) != 0 ||
David Benjaminc895d6b2016-08-11 13:26:41 -0400727 BN_cmp(key->iqmp, key->p) >= 0 ||
728 !BN_is_one(&iqmp_times_q)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000729 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800730 goto out;
731 }
732 }
733
734 ok = 1;
735
736out:
737 BN_free(&n);
738 BN_free(&pm1);
739 BN_free(&qm1);
740 BN_free(&lcm);
741 BN_free(&gcd);
742 BN_free(&de);
743 BN_free(&dmp1);
744 BN_free(&dmq1);
David Benjaminc895d6b2016-08-11 13:26:41 -0400745 BN_free(&iqmp_times_q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800746 BN_CTX_free(ctx);
747
748 return ok;
749}
750
Robert Sloan572a4e22017-04-17 10:52:19 -0700751
Robert Sloan8f860b12017-08-28 07:37:06 -0700752// This is the product of the 132 smallest odd primes, from 3 to 751.
Robert Sloan572a4e22017-04-17 10:52:19 -0700753static const BN_ULONG kSmallFactorsLimbs[] = {
754 TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f),
755 TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b),
756 TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871),
757 TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3),
758 TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893),
759 TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e),
760 TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea),
761 TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727),
762 0x000017b1
763};
Robert Sloan8ff03552017-06-14 12:40:58 -0700764
765DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) {
766 out->d = (BN_ULONG *) kSmallFactorsLimbs;
Robert Sloanab8b8882018-03-26 11:39:51 -0700767 out->width = OPENSSL_ARRAY_SIZE(kSmallFactorsLimbs);
768 out->dmax = out->width;
Robert Sloan8ff03552017-06-14 12:40:58 -0700769 out->neg = 0;
770 out->flags = BN_FLG_STATIC_DATA;
771}
Robert Sloan572a4e22017-04-17 10:52:19 -0700772
773int RSA_check_fips(RSA *key) {
774 if (RSA_is_opaque(key)) {
Robert Sloan8f860b12017-08-28 07:37:06 -0700775 // Opaque keys can't be checked.
Robert Sloan572a4e22017-04-17 10:52:19 -0700776 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
777 return 0;
778 }
779
780 if (!RSA_check_key(key)) {
781 return 0;
782 }
783
784 BN_CTX *ctx = BN_CTX_new();
785 if (ctx == NULL) {
786 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
787 return 0;
788 }
789
790 BIGNUM small_gcd;
791 BN_init(&small_gcd);
792
793 int ret = 1;
794
Robert Sloan8f860b12017-08-28 07:37:06 -0700795 // Perform partial public key validation of RSA keys (SP 800-89 5.3.3).
Robert Sloan9254e682017-04-24 09:42:06 -0700796 enum bn_primality_result_t primality_result;
797 if (BN_num_bits(key->e) <= 16 ||
Robert Sloan572a4e22017-04-17 10:52:19 -0700798 BN_num_bits(key->e) > 256 ||
799 !BN_is_odd(key->n) ||
800 !BN_is_odd(key->e) ||
Robert Sloan8ff03552017-06-14 12:40:58 -0700801 !BN_gcd(&small_gcd, key->n, g_small_factors(), ctx) ||
Robert Sloan9254e682017-04-24 09:42:06 -0700802 !BN_is_one(&small_gcd) ||
803 !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n,
804 BN_prime_checks, ctx, NULL) ||
805 primality_result != bn_non_prime_power_composite) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700806 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
807 ret = 0;
808 }
809
810 BN_free(&small_gcd);
811 BN_CTX_free(ctx);
812
813 if (!ret || key->d == NULL || key->p == NULL) {
Robert Sloan8f860b12017-08-28 07:37:06 -0700814 // On a failure or on only a public key, there's nothing else can be
815 // checked.
Robert Sloan572a4e22017-04-17 10:52:19 -0700816 return ret;
817 }
818
Robert Sloan8f860b12017-08-28 07:37:06 -0700819 // FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG,
820 // section 9.9, it is not known whether |rsa| will be used for signing or
821 // encryption, so either pair-wise consistency self-test is acceptable. We
822 // perform a signing test.
Robert Sloan572a4e22017-04-17 10:52:19 -0700823 uint8_t data[32] = {0};
824 unsigned sig_len = RSA_size(key);
825 uint8_t *sig = OPENSSL_malloc(sig_len);
826 if (sig == NULL) {
827 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
828 return 0;
829 }
830
Robert Sloan8ff03552017-06-14 12:40:58 -0700831 if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) {
832 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
833 ret = 0;
834 goto cleanup;
835 }
836#if defined(BORINGSSL_FIPS_BREAK_RSA_PWCT)
837 data[0] = ~data[0];
838#endif
839 if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700840 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
841 ret = 0;
842 }
843
Robert Sloan8ff03552017-06-14 12:40:58 -0700844cleanup:
Robert Sloan572a4e22017-04-17 10:52:19 -0700845 OPENSSL_free(sig);
846
847 return ret;
848}
849
Adam Langleyd9e397b2015-01-22 14:27:53 -0800850int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
851 size_t len) {
852 if (rsa->meth->private_transform) {
853 return rsa->meth->private_transform(rsa, out, in, len);
854 }
855
Adam Langleyfad63272015-11-12 12:15:39 -0800856 return rsa_default_private_transform(rsa, out, in, len);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800857}
Adam Langleyf7e890d2015-03-31 18:58:05 -0700858
Robert Sloan0da43952018-01-03 15:13:14 -0800859int RSA_flags(const RSA *rsa) { return rsa->flags; }
860
Adam Langleyf7e890d2015-03-31 18:58:05 -0700861int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
862 return 1;
863}