blob: 21dcacdc49f8d0e87224b1ae6570aa589f8fcf31 [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
Adam Langleye9ada862015-05-11 17:20:37 -0700135 BN_clear_free(rsa->n);
136 BN_clear_free(rsa->e);
137 BN_clear_free(rsa->d);
138 BN_clear_free(rsa->p);
139 BN_clear_free(rsa->q);
140 BN_clear_free(rsa->dmp1);
141 BN_clear_free(rsa->dmq1);
142 BN_clear_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);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800146 for (u = 0; u < rsa->num_blindings; u++) {
147 BN_BLINDING_free(rsa->blindings[u]);
148 }
Adam Langleye9ada862015-05-11 17:20:37 -0700149 OPENSSL_free(rsa->blindings);
150 OPENSSL_free(rsa->blindings_inuse);
151 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800152 OPENSSL_free(rsa);
153}
154
155int RSA_up_ref(RSA *rsa) {
Adam Langleyf4e42722015-06-04 17:45:09 -0700156 CRYPTO_refcount_inc(&rsa->references);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800157 return 1;
158}
159
David Benjaminc895d6b2016-08-11 13:26:41 -0400160void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e,
161 const BIGNUM **out_d) {
162 if (out_n != NULL) {
163 *out_n = rsa->n;
164 }
165 if (out_e != NULL) {
166 *out_e = rsa->e;
167 }
168 if (out_d != NULL) {
169 *out_d = rsa->d;
170 }
171}
172
173void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p,
174 const BIGNUM **out_q) {
175 if (out_p != NULL) {
176 *out_p = rsa->p;
177 }
178 if (out_q != NULL) {
179 *out_q = rsa->q;
180 }
181}
182
183void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1,
184 const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) {
185 if (out_dmp1 != NULL) {
186 *out_dmp1 = rsa->dmp1;
187 }
188 if (out_dmq1 != NULL) {
189 *out_dmq1 = rsa->dmq1;
190 }
191 if (out_iqmp != NULL) {
192 *out_iqmp = rsa->iqmp;
193 }
194}
195
Kenny Roote99801b2015-11-06 15:31:15 -0800196int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800197 int padding) {
198 size_t out_len;
199
200 if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
201 return -1;
202 }
203
Kenny Roote99801b2015-11-06 15:31:15 -0800204 if (out_len > INT_MAX) {
205 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
206 return -1;
207 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800208 return out_len;
209}
210
211int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
212 const uint8_t *in, size_t in_len, int padding) {
213 if (rsa->meth->sign_raw) {
214 return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
215 }
216
Adam Langleyfad63272015-11-12 12:15:39 -0800217 return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800218}
219
Kenny Roote99801b2015-11-06 15:31:15 -0800220int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800221 int padding) {
222 size_t out_len;
223
224 if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
225 return -1;
226 }
227
Kenny Roote99801b2015-11-06 15:31:15 -0800228 if (out_len > INT_MAX) {
229 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
230 return -1;
231 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800232 return out_len;
233}
234
235int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
236 const uint8_t *in, size_t in_len, int padding) {
237 if (rsa->meth->decrypt) {
238 return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
239 }
240
Adam Langleyfad63272015-11-12 12:15:39 -0800241 return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800242}
243
Kenny Roote99801b2015-11-06 15:31:15 -0800244int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800245 int padding) {
246 size_t out_len;
247
248 if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
249 return -1;
250 }
251
Kenny Roote99801b2015-11-06 15:31:15 -0800252 if (out_len > INT_MAX) {
253 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
254 return -1;
255 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800256 return out_len;
257}
258
Kenny Roote99801b2015-11-06 15:31:15 -0800259int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800260 int padding) {
261 size_t out_len;
262
263 if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
264 return -1;
265 }
266
Kenny Roote99801b2015-11-06 15:31:15 -0800267 if (out_len > INT_MAX) {
268 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
269 return -1;
270 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800271 return out_len;
272}
273
274unsigned RSA_size(const RSA *rsa) {
275 if (rsa->meth->size) {
276 return rsa->meth->size(rsa);
277 }
278
Adam Langleyfad63272015-11-12 12:15:39 -0800279 return rsa_default_size(rsa);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800280}
281
282int RSA_is_opaque(const RSA *rsa) {
283 return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
284}
285
Adam Langley4139edb2016-01-13 15:00:54 -0800286int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Robert Sloan8ff03552017-06-14 12:40:58 -0700287 CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
Adam Langleye9ada862015-05-11 17:20:37 -0700288 int index;
Robert Sloan8ff03552017-06-14 12:40:58 -0700289 if (!CRYPTO_get_ex_new_index(g_rsa_ex_data_class_bss_get(), &index, argl,
290 argp, free_func)) {
Adam Langleye9ada862015-05-11 17:20:37 -0700291 return -1;
292 }
293 return index;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800294}
295
296int RSA_set_ex_data(RSA *d, int idx, void *arg) {
297 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
298}
299
300void *RSA_get_ex_data(const RSA *d, int idx) {
301 return CRYPTO_get_ex_data(&d->ex_data, idx);
302}
303
304/* SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
305 * the length of an MD5 and SHA1 hash. */
306static const unsigned SSL_SIG_LENGTH = 36;
307
308/* pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is
309 * to be signed with PKCS#1. */
310struct pkcs1_sig_prefix {
311 /* nid identifies the hash function. */
312 int nid;
Robert Sloan8ff03552017-06-14 12:40:58 -0700313 /* hash_len is the expected length of the hash function. */
314 uint8_t hash_len;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800315 /* len is the number of bytes of |bytes| which are valid. */
316 uint8_t len;
317 /* bytes contains the DER bytes. */
318 uint8_t bytes[19];
319};
320
321/* kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with
322 * different hash functions. */
323static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
324 {
325 NID_md5,
Robert Sloan8ff03552017-06-14 12:40:58 -0700326 MD5_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800327 18,
328 {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
329 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
330 },
331 {
332 NID_sha1,
Robert Sloan8ff03552017-06-14 12:40:58 -0700333 SHA_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800334 15,
335 {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
336 0x00, 0x04, 0x14},
337 },
338 {
339 NID_sha224,
Robert Sloan8ff03552017-06-14 12:40:58 -0700340 SHA224_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800341 19,
342 {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
343 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
344 },
345 {
346 NID_sha256,
Robert Sloan8ff03552017-06-14 12:40:58 -0700347 SHA256_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800348 19,
349 {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
350 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
351 },
352 {
353 NID_sha384,
Robert Sloan8ff03552017-06-14 12:40:58 -0700354 SHA384_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800355 19,
356 {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
357 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
358 },
359 {
360 NID_sha512,
Robert Sloan8ff03552017-06-14 12:40:58 -0700361 SHA512_DIGEST_LENGTH,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800362 19,
363 {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
364 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
365 },
366 {
Robert Sloan8ff03552017-06-14 12:40:58 -0700367 NID_undef, 0, 0, {0},
Adam Langleyd9e397b2015-01-22 14:27:53 -0800368 },
369};
370
Kenny Rootb8494592015-09-25 02:29:14 +0000371int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
372 int *is_alloced, int hash_nid, const uint8_t *msg,
373 size_t msg_len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800374 unsigned i;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800375
376 if (hash_nid == NID_md5_sha1) {
377 /* Special case: SSL signature, just check the length. */
378 if (msg_len != SSL_SIG_LENGTH) {
Kenny Rootb8494592015-09-25 02:29:14 +0000379 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800380 return 0;
381 }
382
383 *out_msg = (uint8_t*) msg;
384 *out_msg_len = SSL_SIG_LENGTH;
385 *is_alloced = 0;
386 return 1;
387 }
388
389 for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
390 const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
Adam Langleye9ada862015-05-11 17:20:37 -0700391 if (sig_prefix->nid != hash_nid) {
392 continue;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800393 }
Adam Langleye9ada862015-05-11 17:20:37 -0700394
Robert Sloan8ff03552017-06-14 12:40:58 -0700395 if (msg_len != sig_prefix->hash_len) {
396 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
397 return 0;
398 }
399
Adam Langleye9ada862015-05-11 17:20:37 -0700400 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;
Robert Sloan8ff03552017-06-14 12:40:58 -0700435 uint8_t *signed_msg = NULL;
436 size_t signed_msg_len = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800437 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
Robert Sloan8ff03552017-06-14 12:40:58 -0700461int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
462 const uint8_t *in, size_t in_len, const EVP_MD *md,
463 const EVP_MD *mgf1_md, int salt_len) {
464 if (in_len != EVP_MD_size(md)) {
465 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
466 return 0;
467 }
468
469 size_t padded_len = RSA_size(rsa);
470 uint8_t *padded = OPENSSL_malloc(padded_len);
471 if (padded == NULL) {
472 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
473 return 0;
474 }
475
476 int ret =
477 RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, in, md, mgf1_md, salt_len) &&
478 RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len,
479 RSA_NO_PADDING);
480 OPENSSL_free(padded);
481 return ret;
482}
483
Adam Langleyd9e397b2015-01-22 14:27:53 -0800484int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
485 const uint8_t *sig, size_t sig_len, RSA *rsa) {
David Benjamin4969cc92016-04-22 15:02:23 -0400486 if (rsa->n == NULL || rsa->e == NULL) {
487 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
488 return 0;
489 }
490
Adam Langleyd9e397b2015-01-22 14:27:53 -0800491 const size_t rsa_size = RSA_size(rsa);
492 uint8_t *buf = NULL;
493 int ret = 0;
494 uint8_t *signed_msg = NULL;
Robert Sloan8ff03552017-06-14 12:40:58 -0700495 size_t signed_msg_len = 0, len;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800496 int signed_msg_is_alloced = 0;
497
Adam Langleyd9e397b2015-01-22 14:27:53 -0800498 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
Kenny Rootb8494592015-09-25 02:29:14 +0000499 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800500 return 0;
501 }
502
503 buf = OPENSSL_malloc(rsa_size);
504 if (!buf) {
Kenny Rootb8494592015-09-25 02:29:14 +0000505 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800506 return 0;
507 }
508
509 if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len,
510 RSA_PKCS1_PADDING)) {
511 goto out;
512 }
513
Kenny Rootb8494592015-09-25 02:29:14 +0000514 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
515 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800516 goto out;
517 }
518
Robert Sloan572a4e22017-04-17 10:52:19 -0700519 /* Check that no other information follows the hash value (FIPS 186-4 Section
520 * 5.5) and it matches the expected hash. */
Robert Sloan69939df2017-01-09 10:53:07 -0800521 if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000522 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800523 goto out;
524 }
525
526 ret = 1;
527
528out:
Adam Langleye9ada862015-05-11 17:20:37 -0700529 OPENSSL_free(buf);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800530 if (signed_msg_is_alloced) {
531 OPENSSL_free(signed_msg);
532 }
533 return ret;
534}
535
Robert Sloan8ff03552017-06-14 12:40:58 -0700536int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, size_t msg_len,
537 const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len,
538 const uint8_t *sig, size_t sig_len) {
539 if (msg_len != EVP_MD_size(md)) {
540 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
541 return 0;
542 }
543
544 size_t em_len = RSA_size(rsa);
545 uint8_t *em = OPENSSL_malloc(em_len);
546 if (em == NULL) {
547 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
548 return 0;
549 }
550
551 int ret = 0;
552 if (!RSA_verify_raw(rsa, &em_len, em, em_len, sig, sig_len, RSA_NO_PADDING)) {
553 goto err;
554 }
555
556 if (em_len != RSA_size(rsa)) {
557 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
558 goto err;
559 }
560
561 ret = RSA_verify_PKCS1_PSS_mgf1(rsa, msg, md, mgf1_md, em, salt_len);
562
563err:
564 OPENSSL_free(em);
565 return ret;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800566}
567
568int RSA_check_key(const RSA *key) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400569 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800570 BN_CTX *ctx;
571 int ok = 0, has_crt_values;
572
573 if (RSA_is_opaque(key)) {
574 /* Opaque keys can't be checked. */
575 return 1;
576 }
577
578 if ((key->p != NULL) != (key->q != NULL)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000579 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800580 return 0;
581 }
582
583 if (!key->n || !key->e) {
Kenny Rootb8494592015-09-25 02:29:14 +0000584 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800585 return 0;
586 }
587
588 if (!key->d || !key->p) {
589 /* For a public key, or without p and q, there's nothing that can be
590 * checked. */
591 return 1;
592 }
593
594 ctx = BN_CTX_new();
595 if (ctx == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000596 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800597 return 0;
598 }
599
600 BN_init(&n);
601 BN_init(&pm1);
602 BN_init(&qm1);
603 BN_init(&lcm);
604 BN_init(&gcd);
605 BN_init(&de);
606 BN_init(&dmp1);
607 BN_init(&dmq1);
David Benjaminc895d6b2016-08-11 13:26:41 -0400608 BN_init(&iqmp_times_q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800609
Kenny Rootb8494592015-09-25 02:29:14 +0000610 if (!BN_mul(&n, key->p, key->q, ctx) ||
Robert Sloan8ff03552017-06-14 12:40:58 -0700611 /* lcm = lcm(p, q) */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800612 !BN_sub(&pm1, key->p, BN_value_one()) ||
613 !BN_sub(&qm1, key->q, BN_value_one()) ||
614 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Kenny Rootb8494592015-09-25 02:29:14 +0000615 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
616 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
617 goto out;
618 }
619
Kenny Rootb8494592015-09-25 02:29:14 +0000620 if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
Adam Langleyd9e397b2015-01-22 14:27:53 -0800621 !BN_gcd(&gcd, &pm1, &qm1, ctx) ||
Robert Sloan8ff03552017-06-14 12:40:58 -0700622 /* de = d*e mod lcm(p, q). */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800623 !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000624 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800625 goto out;
626 }
627
628 if (BN_cmp(&n, key->n) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000629 OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800630 goto out;
631 }
632
633 if (!BN_is_one(&de)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000634 OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800635 goto out;
636 }
637
638 has_crt_values = key->dmp1 != NULL;
639 if (has_crt_values != (key->dmq1 != NULL) ||
640 has_crt_values != (key->iqmp != NULL)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000641 OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800642 goto out;
643 }
644
Robert Sloan572a4e22017-04-17 10:52:19 -0700645 if (has_crt_values) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800646 if (/* dmp1 = d mod (p-1) */
647 !BN_mod(&dmp1, key->d, &pm1, ctx) ||
648 /* dmq1 = d mod (q-1) */
649 !BN_mod(&dmq1, key->d, &qm1, ctx) ||
650 /* iqmp = q^-1 mod p */
David Benjaminc895d6b2016-08-11 13:26:41 -0400651 !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000652 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800653 goto out;
654 }
655
656 if (BN_cmp(&dmp1, key->dmp1) != 0 ||
657 BN_cmp(&dmq1, key->dmq1) != 0 ||
David Benjaminc895d6b2016-08-11 13:26:41 -0400658 BN_cmp(key->iqmp, key->p) >= 0 ||
659 !BN_is_one(&iqmp_times_q)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000660 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800661 goto out;
662 }
663 }
664
665 ok = 1;
666
667out:
668 BN_free(&n);
669 BN_free(&pm1);
670 BN_free(&qm1);
671 BN_free(&lcm);
672 BN_free(&gcd);
673 BN_free(&de);
674 BN_free(&dmp1);
675 BN_free(&dmq1);
David Benjaminc895d6b2016-08-11 13:26:41 -0400676 BN_free(&iqmp_times_q);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800677 BN_CTX_free(ctx);
678
679 return ok;
680}
681
Robert Sloan572a4e22017-04-17 10:52:19 -0700682
683/* This is the product of the 132 smallest odd primes, from 3 to 751. */
684static const BN_ULONG kSmallFactorsLimbs[] = {
685 TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f),
686 TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b),
687 TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871),
688 TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3),
689 TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893),
690 TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e),
691 TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea),
692 TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727),
693 0x000017b1
694};
Robert Sloan8ff03552017-06-14 12:40:58 -0700695
696DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) {
697 out->d = (BN_ULONG *) kSmallFactorsLimbs;
698 out->top = OPENSSL_ARRAY_SIZE(kSmallFactorsLimbs);
699 out->dmax = out->top;
700 out->neg = 0;
701 out->flags = BN_FLG_STATIC_DATA;
702}
Robert Sloan572a4e22017-04-17 10:52:19 -0700703
704int RSA_check_fips(RSA *key) {
705 if (RSA_is_opaque(key)) {
706 /* Opaque keys can't be checked. */
707 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
708 return 0;
709 }
710
711 if (!RSA_check_key(key)) {
712 return 0;
713 }
714
715 BN_CTX *ctx = BN_CTX_new();
716 if (ctx == NULL) {
717 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
718 return 0;
719 }
720
721 BIGNUM small_gcd;
722 BN_init(&small_gcd);
723
724 int ret = 1;
725
726 /* Perform partial public key validation of RSA keys (SP 800-89 5.3.3). */
Robert Sloan9254e682017-04-24 09:42:06 -0700727 enum bn_primality_result_t primality_result;
728 if (BN_num_bits(key->e) <= 16 ||
Robert Sloan572a4e22017-04-17 10:52:19 -0700729 BN_num_bits(key->e) > 256 ||
730 !BN_is_odd(key->n) ||
731 !BN_is_odd(key->e) ||
Robert Sloan8ff03552017-06-14 12:40:58 -0700732 !BN_gcd(&small_gcd, key->n, g_small_factors(), ctx) ||
Robert Sloan9254e682017-04-24 09:42:06 -0700733 !BN_is_one(&small_gcd) ||
734 !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n,
735 BN_prime_checks, ctx, NULL) ||
736 primality_result != bn_non_prime_power_composite) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700737 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
738 ret = 0;
739 }
740
741 BN_free(&small_gcd);
742 BN_CTX_free(ctx);
743
744 if (!ret || key->d == NULL || key->p == NULL) {
745 /* On a failure or on only a public key, there's nothing else can be
746 * checked. */
747 return ret;
748 }
749
750 /* FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG,
751 * section 9.9, it is not known whether |rsa| will be used for signing or
752 * encryption, so either pair-wise consistency self-test is acceptable. We
753 * perform a signing test. */
754 uint8_t data[32] = {0};
755 unsigned sig_len = RSA_size(key);
756 uint8_t *sig = OPENSSL_malloc(sig_len);
757 if (sig == NULL) {
758 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
759 return 0;
760 }
761
Robert Sloan8ff03552017-06-14 12:40:58 -0700762 if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) {
763 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
764 ret = 0;
765 goto cleanup;
766 }
767#if defined(BORINGSSL_FIPS_BREAK_RSA_PWCT)
768 data[0] = ~data[0];
769#endif
770 if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700771 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
772 ret = 0;
773 }
774
Robert Sloan8ff03552017-06-14 12:40:58 -0700775cleanup:
Robert Sloan572a4e22017-04-17 10:52:19 -0700776 OPENSSL_free(sig);
777
778 return ret;
779}
780
Adam Langleyd9e397b2015-01-22 14:27:53 -0800781int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
782 size_t len) {
783 if (rsa->meth->private_transform) {
784 return rsa->meth->private_transform(rsa, out, in, len);
785 }
786
Adam Langleyfad63272015-11-12 12:15:39 -0800787 return rsa_default_private_transform(rsa, out, in, len);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800788}
Adam Langleyf7e890d2015-03-31 18:58:05 -0700789
790int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
791 return 1;
792}