blob: 843e757d9d21552f5d187ce28db58967f94f76b2 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57#include <openssl/rsa.h>
58
David Benjamin79c59a32015-09-19 13:35:39 -040059#include <limits.h>
Adam Langley2b2d66d2015-01-30 17:08:37 -080060#include <string.h>
61
Adam Langley95c29f32014-06-20 12:00:00 -070062#include <openssl/bn.h>
David Benjamin79d18bc2017-05-02 14:34:09 -040063#include <openssl/digest.h>
Adam Langley95c29f32014-06-20 12:00:00 -070064#include <openssl/engine.h>
65#include <openssl/err.h>
66#include <openssl/ex_data.h>
David Benjamin05821b02017-05-02 14:15:21 -040067#include <openssl/md5.h>
Adam Langley95c29f32014-06-20 12:00:00 -070068#include <openssl/mem.h>
David Benjamin98193672016-03-25 18:07:11 -040069#include <openssl/nid.h>
David Benjamin05821b02017-05-02 14:15:21 -040070#include <openssl/sha.h>
Brian Smith054e6822015-03-27 21:12:01 -100071#include <openssl/thread.h>
Adam Langley95c29f32014-06-20 12:00:00 -070072
73#include "internal.h"
Adam Langley683d7bd2015-04-13 11:04:14 -070074#include "../internal.h"
Adam Langley5c38c052017-04-28 14:47:06 -070075#include "../fipsmodule/bn/internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -070076
77
David Benjamin9f33fc62015-04-15 17:29:53 -040078static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
79
Adam Langley95c29f32014-06-20 12:00:00 -070080RSA *RSA_new(void) { return RSA_new_method(NULL); }
81
82RSA *RSA_new_method(const ENGINE *engine) {
Brian Smith5ba06892016-02-07 09:36:04 -100083 RSA *rsa = OPENSSL_malloc(sizeof(RSA));
Adam Langley95c29f32014-06-20 12:00:00 -070084 if (rsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -040085 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -070086 return NULL;
87 }
88
David Benjamin17cf2cb2016-12-13 01:07:13 -050089 OPENSSL_memset(rsa, 0, sizeof(RSA));
Adam Langley95c29f32014-06-20 12:00:00 -070090
91 if (engine) {
92 rsa->meth = ENGINE_get_RSA_method(engine);
93 }
94
95 if (rsa->meth == NULL) {
96 rsa->meth = (RSA_METHOD*) &RSA_default_method;
97 }
98 METHOD_ref(rsa->meth);
99
100 rsa->references = 1;
101 rsa->flags = rsa->meth->flags;
Adam Langley683d7bd2015-04-13 11:04:14 -0700102 CRYPTO_MUTEX_init(&rsa->lock);
David Benjamin8a589332015-12-04 23:14:35 -0500103 CRYPTO_new_ex_data(&rsa->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700104
105 if (rsa->meth->init && !rsa->meth->init(rsa)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400106 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
David Benjamin79680ff2015-10-23 18:46:16 -0400107 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700108 METHOD_unref(rsa->meth);
109 OPENSSL_free(rsa);
110 return NULL;
111 }
112
113 return rsa;
114}
115
116void RSA_free(RSA *rsa) {
117 unsigned u;
118
119 if (rsa == NULL) {
120 return;
121 }
122
Adam Langley0da323a2015-05-15 12:49:30 -0700123 if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700124 return;
125 }
126
David Benjamin8fb0f522015-11-03 18:24:07 -0500127 if (rsa->meth->finish) {
Adam Langley95c29f32014-06-20 12:00:00 -0700128 rsa->meth->finish(rsa);
129 }
130 METHOD_unref(rsa->meth);
131
David Benjamin9f33fc62015-04-15 17:29:53 -0400132 CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700133
David Benjamind8b65c82015-04-22 16:09:09 -0400134 BN_clear_free(rsa->n);
135 BN_clear_free(rsa->e);
136 BN_clear_free(rsa->d);
137 BN_clear_free(rsa->p);
138 BN_clear_free(rsa->q);
139 BN_clear_free(rsa->dmp1);
140 BN_clear_free(rsa->dmq1);
141 BN_clear_free(rsa->iqmp);
David Benjamin8fb0f522015-11-03 18:24:07 -0500142 BN_MONT_CTX_free(rsa->mont_n);
143 BN_MONT_CTX_free(rsa->mont_p);
144 BN_MONT_CTX_free(rsa->mont_q);
Adam Langley95c29f32014-06-20 12:00:00 -0700145 for (u = 0; u < rsa->num_blindings; u++) {
146 BN_BLINDING_free(rsa->blindings[u]);
147 }
David Benjamind8b65c82015-04-22 16:09:09 -0400148 OPENSSL_free(rsa->blindings);
149 OPENSSL_free(rsa->blindings_inuse);
Adam Langley683d7bd2015-04-13 11:04:14 -0700150 CRYPTO_MUTEX_cleanup(&rsa->lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700151 OPENSSL_free(rsa);
152}
153
154int RSA_up_ref(RSA *rsa) {
Adam Langley0da323a2015-05-15 12:49:30 -0700155 CRYPTO_refcount_inc(&rsa->references);
Adam Langley95c29f32014-06-20 12:00:00 -0700156 return 1;
157}
158
David Benjamin5a915032016-08-09 11:04:24 -0400159void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e,
160 const BIGNUM **out_d) {
161 if (out_n != NULL) {
162 *out_n = rsa->n;
163 }
164 if (out_e != NULL) {
165 *out_e = rsa->e;
166 }
167 if (out_d != NULL) {
168 *out_d = rsa->d;
169 }
170}
171
172void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p,
173 const BIGNUM **out_q) {
174 if (out_p != NULL) {
175 *out_p = rsa->p;
176 }
177 if (out_q != NULL) {
178 *out_q = rsa->q;
179 }
180}
181
182void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1,
183 const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) {
184 if (out_dmp1 != NULL) {
185 *out_dmp1 = rsa->dmp1;
186 }
187 if (out_dmq1 != NULL) {
188 *out_dmq1 = rsa->dmq1;
189 }
190 if (out_iqmp != NULL) {
191 *out_iqmp = rsa->iqmp;
192 }
193}
194
Adam Langley95c29f32014-06-20 12:00:00 -0700195int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
196 if (rsa->meth->keygen) {
197 return rsa->meth->keygen(rsa, bits, e_value, cb);
198 }
199
David Benjamind93831d2015-10-29 13:19:12 -0400200 return rsa_default_keygen(rsa, bits, e_value, cb);
Adam Langley95c29f32014-06-20 12:00:00 -0700201}
202
203int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
204 const uint8_t *in, size_t in_len, int padding) {
205 if (rsa->meth->encrypt) {
206 return rsa->meth->encrypt(rsa, out_len, out, max_out, in, in_len, padding);
207 }
208
David Benjamind93831d2015-10-29 13:19:12 -0400209 return rsa_default_encrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700210}
211
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700212int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700213 int padding) {
214 size_t out_len;
215
216 if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
217 return -1;
218 }
219
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700220 if (out_len > INT_MAX) {
221 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
222 return -1;
223 }
Adam Langley95c29f32014-06-20 12:00:00 -0700224 return out_len;
225}
226
227int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
228 const uint8_t *in, size_t in_len, int padding) {
229 if (rsa->meth->sign_raw) {
230 return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
231 }
232
David Benjamind93831d2015-10-29 13:19:12 -0400233 return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700234}
235
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700236int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700237 int padding) {
238 size_t out_len;
239
240 if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
241 return -1;
242 }
243
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700244 if (out_len > INT_MAX) {
245 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
246 return -1;
247 }
Adam Langley95c29f32014-06-20 12:00:00 -0700248 return out_len;
249}
250
251int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
252 const uint8_t *in, size_t in_len, int padding) {
253 if (rsa->meth->decrypt) {
254 return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
255 }
256
David Benjamind93831d2015-10-29 13:19:12 -0400257 return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700258}
259
David Benjamin79c59a32015-09-19 13:35:39 -0400260int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700261 int padding) {
262 size_t out_len;
263
264 if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
265 return -1;
266 }
267
David Benjamin79c59a32015-09-19 13:35:39 -0400268 if (out_len > INT_MAX) {
269 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
270 return -1;
271 }
Adam Langley95c29f32014-06-20 12:00:00 -0700272 return out_len;
273}
274
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700275int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700276 int padding) {
277 size_t out_len;
278
279 if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
280 return -1;
281 }
282
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700283 if (out_len > INT_MAX) {
284 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
285 return -1;
286 }
Adam Langley95c29f32014-06-20 12:00:00 -0700287 return out_len;
288}
289
290unsigned RSA_size(const RSA *rsa) {
David Benjamin925fee32014-07-11 14:14:08 -0400291 if (rsa->meth->size) {
292 return rsa->meth->size(rsa);
293 }
294
David Benjamind93831d2015-10-29 13:19:12 -0400295 return rsa_default_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700296}
297
David Benjaminecc0ce72014-07-18 18:39:42 -0400298int RSA_is_opaque(const RSA *rsa) {
299 return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
300}
301
David Benjamin8a589332015-12-04 23:14:35 -0500302int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langley95c29f32014-06-20 12:00:00 -0700303 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400304 int index;
David Benjamin8a589332015-12-04 23:14:35 -0500305 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
306 free_func)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400307 return -1;
308 }
309 return index;
Adam Langley95c29f32014-06-20 12:00:00 -0700310}
311
312int RSA_set_ex_data(RSA *d, int idx, void *arg) {
313 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
314}
315
316void *RSA_get_ex_data(const RSA *d, int idx) {
317 return CRYPTO_get_ex_data(&d->ex_data, idx);
318}
319
320/* SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
321 * the length of an MD5 and SHA1 hash. */
322static const unsigned SSL_SIG_LENGTH = 36;
323
324/* pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is
325 * to be signed with PKCS#1. */
326struct pkcs1_sig_prefix {
327 /* nid identifies the hash function. */
328 int nid;
David Benjamin05821b02017-05-02 14:15:21 -0400329 /* hash_len is the expected length of the hash function. */
330 uint8_t hash_len;
Adam Langley95c29f32014-06-20 12:00:00 -0700331 /* len is the number of bytes of |bytes| which are valid. */
332 uint8_t len;
333 /* bytes contains the DER bytes. */
334 uint8_t bytes[19];
335};
336
337/* kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with
338 * different hash functions. */
339static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
340 {
341 NID_md5,
David Benjamin05821b02017-05-02 14:15:21 -0400342 MD5_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700343 18,
344 {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
345 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
346 },
347 {
348 NID_sha1,
David Benjamin05821b02017-05-02 14:15:21 -0400349 SHA_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700350 15,
351 {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
352 0x00, 0x04, 0x14},
353 },
354 {
355 NID_sha224,
David Benjamin05821b02017-05-02 14:15:21 -0400356 SHA224_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700357 19,
358 {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
359 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
360 },
361 {
362 NID_sha256,
David Benjamin05821b02017-05-02 14:15:21 -0400363 SHA256_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700364 19,
365 {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
366 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
367 },
368 {
369 NID_sha384,
David Benjamin05821b02017-05-02 14:15:21 -0400370 SHA384_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700371 19,
372 {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
373 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
374 },
375 {
376 NID_sha512,
David Benjamin05821b02017-05-02 14:15:21 -0400377 SHA512_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700378 19,
379 {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
380 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
381 },
382 {
David Benjamin05821b02017-05-02 14:15:21 -0400383 NID_undef, 0, 0, {0},
Adam Langley95c29f32014-06-20 12:00:00 -0700384 },
385};
386
David Benjaminb0acb772015-05-28 16:53:31 -0400387int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
388 int *is_alloced, int hash_nid, const uint8_t *msg,
389 size_t msg_len) {
Adam Langley95c29f32014-06-20 12:00:00 -0700390 unsigned i;
Adam Langley95c29f32014-06-20 12:00:00 -0700391
392 if (hash_nid == NID_md5_sha1) {
393 /* Special case: SSL signature, just check the length. */
394 if (msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400395 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700396 return 0;
397 }
398
399 *out_msg = (uint8_t*) msg;
400 *out_msg_len = SSL_SIG_LENGTH;
401 *is_alloced = 0;
402 return 1;
403 }
404
405 for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
406 const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
Brian Smitha039d702015-01-29 15:03:18 -0800407 if (sig_prefix->nid != hash_nid) {
408 continue;
Adam Langley95c29f32014-06-20 12:00:00 -0700409 }
Brian Smitha039d702015-01-29 15:03:18 -0800410
David Benjamin05821b02017-05-02 14:15:21 -0400411 if (msg_len != sig_prefix->hash_len) {
412 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
413 return 0;
414 }
415
Brian Smitha039d702015-01-29 15:03:18 -0800416 const uint8_t* prefix = sig_prefix->bytes;
417 unsigned prefix_len = sig_prefix->len;
418 unsigned signed_msg_len;
419 uint8_t *signed_msg;
420
421 signed_msg_len = prefix_len + msg_len;
422 if (signed_msg_len < prefix_len) {
David Benjamin3570d732015-06-29 00:28:17 -0400423 OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
Brian Smitha039d702015-01-29 15:03:18 -0800424 return 0;
425 }
426
427 signed_msg = OPENSSL_malloc(signed_msg_len);
428 if (!signed_msg) {
David Benjamin3570d732015-06-29 00:28:17 -0400429 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Brian Smitha039d702015-01-29 15:03:18 -0800430 return 0;
431 }
432
David Benjamin17cf2cb2016-12-13 01:07:13 -0500433 OPENSSL_memcpy(signed_msg, prefix, prefix_len);
434 OPENSSL_memcpy(signed_msg + prefix_len, msg, msg_len);
Brian Smitha039d702015-01-29 15:03:18 -0800435
436 *out_msg = signed_msg;
437 *out_msg_len = signed_msg_len;
438 *is_alloced = 1;
439
440 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700441 }
442
David Benjamin3570d732015-06-29 00:28:17 -0400443 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
Brian Smitha039d702015-01-29 15:03:18 -0800444 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700445}
446
447int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out,
448 unsigned *out_len, RSA *rsa) {
449 const unsigned rsa_size = RSA_size(rsa);
450 int ret = 0;
451 uint8_t *signed_msg;
452 size_t signed_msg_len;
453 int signed_msg_is_alloced = 0;
454 size_t size_t_out_len;
455
456 if (rsa->meth->sign) {
457 return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa);
458 }
459
David Benjaminb0acb772015-05-28 16:53:31 -0400460 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
David Benjaminddd5ba72017-04-11 12:54:06 -0400461 &signed_msg_is_alloced, hash_nid, in, in_len) ||
462 !RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg,
463 signed_msg_len, RSA_PKCS1_PADDING)) {
464 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700465 }
466
David Benjaminddd5ba72017-04-11 12:54:06 -0400467 *out_len = size_t_out_len;
468 ret = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700469
David Benjaminddd5ba72017-04-11 12:54:06 -0400470err:
Adam Langley95c29f32014-06-20 12:00:00 -0700471 if (signed_msg_is_alloced) {
472 OPENSSL_free(signed_msg);
473 }
474 return ret;
475}
476
David Benjamin79d18bc2017-05-02 14:34:09 -0400477int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
478 const uint8_t *in, size_t in_len, const EVP_MD *md,
479 const EVP_MD *mgf1_md, int salt_len) {
480 if (in_len != EVP_MD_size(md)) {
481 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
482 return 0;
483 }
484
485 size_t padded_len = RSA_size(rsa);
486 uint8_t *padded = OPENSSL_malloc(padded_len);
487 if (padded == NULL) {
488 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
489 return 0;
490 }
491
492 int ret =
493 RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, in, md, mgf1_md, salt_len) &&
494 RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len,
495 RSA_NO_PADDING);
496 OPENSSL_free(padded);
497 return ret;
498}
499
Adam Langley95c29f32014-06-20 12:00:00 -0700500int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
501 const uint8_t *sig, size_t sig_len, RSA *rsa) {
Brian Smithc0b196d2016-03-04 08:54:07 -1000502 if (rsa->n == NULL || rsa->e == NULL) {
503 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
504 return 0;
505 }
506
Adam Langley95c29f32014-06-20 12:00:00 -0700507 const size_t rsa_size = RSA_size(rsa);
508 uint8_t *buf = NULL;
509 int ret = 0;
510 uint8_t *signed_msg = NULL;
511 size_t signed_msg_len, len;
512 int signed_msg_is_alloced = 0;
513
Adam Langley95c29f32014-06-20 12:00:00 -0700514 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400515 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700516 return 0;
517 }
518
519 buf = OPENSSL_malloc(rsa_size);
520 if (!buf) {
David Benjamin3570d732015-06-29 00:28:17 -0400521 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700522 return 0;
523 }
524
525 if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len,
526 RSA_PKCS1_PADDING)) {
527 goto out;
528 }
529
David Benjaminb0acb772015-05-28 16:53:31 -0400530 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
531 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700532 goto out;
533 }
534
Steven Valdezc1966802017-04-10 15:52:19 -0400535 /* Check that no other information follows the hash value (FIPS 186-4 Section
536 * 5.5) and it matches the expected hash. */
David Benjamin17cf2cb2016-12-13 01:07:13 -0500537 if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400538 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700539 goto out;
540 }
541
542 ret = 1;
543
544out:
David Benjamind8b65c82015-04-22 16:09:09 -0400545 OPENSSL_free(buf);
Adam Langley95c29f32014-06-20 12:00:00 -0700546 if (signed_msg_is_alloced) {
547 OPENSSL_free(signed_msg);
548 }
549 return ret;
550}
Adam Langley409766d2014-06-20 12:00:00 -0700551
David Benjamin79d18bc2017-05-02 14:34:09 -0400552int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, size_t msg_len,
553 const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len,
554 const uint8_t *sig, size_t sig_len) {
555 if (msg_len != EVP_MD_size(md)) {
556 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
557 return 0;
558 }
559
560 size_t em_len = RSA_size(rsa);
561 uint8_t *em = OPENSSL_malloc(em_len);
562 if (em == NULL) {
563 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
564 return 0;
565 }
566
567 int ret = 0;
568 if (!RSA_verify_raw(rsa, &em_len, em, em_len, sig, sig_len, RSA_NO_PADDING)) {
569 goto err;
570 }
571
572 if (em_len != RSA_size(rsa)) {
573 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
574 goto err;
575 }
576
577 ret = RSA_verify_PKCS1_PSS_mgf1(rsa, msg, md, mgf1_md, em, salt_len);
578
579err:
580 OPENSSL_free(em);
581 return ret;
582}
583
Adam Langley409766d2014-06-20 12:00:00 -0700584static void bn_free_and_null(BIGNUM **bn) {
Adam Langley409766d2014-06-20 12:00:00 -0700585 BN_free(*bn);
586 *bn = NULL;
587}
588
Adam Langley05b73772014-07-25 12:03:51 -0700589int RSA_check_key(const RSA *key) {
Brian Smith7241ca52016-07-25 16:01:10 -1000590 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q;
Adam Langley05b73772014-07-25 12:03:51 -0700591 BN_CTX *ctx;
592 int ok = 0, has_crt_values;
593
594 if (RSA_is_opaque(key)) {
595 /* Opaque keys can't be checked. */
596 return 1;
597 }
598
599 if ((key->p != NULL) != (key->q != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400600 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langley05b73772014-07-25 12:03:51 -0700601 return 0;
602 }
603
604 if (!key->n || !key->e) {
David Benjamin3570d732015-06-29 00:28:17 -0400605 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langley05b73772014-07-25 12:03:51 -0700606 return 0;
607 }
608
609 if (!key->d || !key->p) {
610 /* For a public key, or without p and q, there's nothing that can be
611 * checked. */
612 return 1;
613 }
614
615 ctx = BN_CTX_new();
616 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400617 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley05b73772014-07-25 12:03:51 -0700618 return 0;
619 }
620
621 BN_init(&n);
622 BN_init(&pm1);
623 BN_init(&qm1);
624 BN_init(&lcm);
625 BN_init(&gcd);
626 BN_init(&de);
627 BN_init(&dmp1);
628 BN_init(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000629 BN_init(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700630
Adam Langley839b8812015-05-26 11:36:46 -0700631 if (!BN_mul(&n, key->p, key->q, ctx) ||
632 /* lcm = lcm(prime-1, for all primes) */
Adam Langley05b73772014-07-25 12:03:51 -0700633 !BN_sub(&pm1, key->p, BN_value_one()) ||
634 !BN_sub(&qm1, key->q, BN_value_one()) ||
635 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700636 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400637 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley839b8812015-05-26 11:36:46 -0700638 goto out;
639 }
640
Adam Langley839b8812015-05-26 11:36:46 -0700641 if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
Adam Langley05b73772014-07-25 12:03:51 -0700642 !BN_gcd(&gcd, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700643 /* de = d*e mod lcm(prime-1, for all primes). */
Adam Langley05b73772014-07-25 12:03:51 -0700644 !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400645 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700646 goto out;
647 }
648
649 if (BN_cmp(&n, key->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400650 OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
Adam Langley05b73772014-07-25 12:03:51 -0700651 goto out;
652 }
653
654 if (!BN_is_one(&de)) {
David Benjamin3570d732015-06-29 00:28:17 -0400655 OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
Adam Langley05b73772014-07-25 12:03:51 -0700656 goto out;
657 }
658
659 has_crt_values = key->dmp1 != NULL;
660 if (has_crt_values != (key->dmq1 != NULL) ||
661 has_crt_values != (key->iqmp != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400662 OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
Adam Langley05b73772014-07-25 12:03:51 -0700663 goto out;
664 }
665
David Benjamin82b2b852017-04-12 18:28:48 -0400666 if (has_crt_values) {
Adam Langley05b73772014-07-25 12:03:51 -0700667 if (/* dmp1 = d mod (p-1) */
668 !BN_mod(&dmp1, key->d, &pm1, ctx) ||
669 /* dmq1 = d mod (q-1) */
670 !BN_mod(&dmq1, key->d, &qm1, ctx) ||
671 /* iqmp = q^-1 mod p */
Brian Smith7241ca52016-07-25 16:01:10 -1000672 !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400673 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700674 goto out;
675 }
676
677 if (BN_cmp(&dmp1, key->dmp1) != 0 ||
678 BN_cmp(&dmq1, key->dmq1) != 0 ||
Brian Smith7241ca52016-07-25 16:01:10 -1000679 BN_cmp(key->iqmp, key->p) >= 0 ||
680 !BN_is_one(&iqmp_times_q)) {
David Benjamin3570d732015-06-29 00:28:17 -0400681 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langley05b73772014-07-25 12:03:51 -0700682 goto out;
683 }
684 }
685
686 ok = 1;
687
688out:
689 BN_free(&n);
690 BN_free(&pm1);
691 BN_free(&qm1);
692 BN_free(&lcm);
693 BN_free(&gcd);
694 BN_free(&de);
695 BN_free(&dmp1);
696 BN_free(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000697 BN_free(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700698 BN_CTX_free(ctx);
699
700 return ok;
701}
702
Steven Valdezd0b98822017-04-11 12:46:03 -0400703
704/* This is the product of the 132 smallest odd primes, from 3 to 751. */
705static const BN_ULONG kSmallFactorsLimbs[] = {
706 TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f),
707 TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b),
708 TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871),
709 TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3),
710 TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893),
711 TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e),
712 TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea),
713 TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727),
714 0x000017b1
715};
716static const BIGNUM kSmallFactors = STATIC_BIGNUM(kSmallFactorsLimbs);
717
Steven Valdez400d0b72017-04-06 14:55:18 -0400718int RSA_check_fips(RSA *key) {
Steven Valdezd0b98822017-04-11 12:46:03 -0400719 if (RSA_is_opaque(key)) {
720 /* Opaque keys can't be checked. */
721 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
722 return 0;
723 }
724
725 if (!RSA_check_key(key)) {
726 return 0;
727 }
728
729 BN_CTX *ctx = BN_CTX_new();
730 if (ctx == NULL) {
731 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
732 return 0;
733 }
734
735 BIGNUM small_gcd;
736 BN_init(&small_gcd);
737
738 int ret = 1;
739
740 /* Perform partial public key validation of RSA keys (SP 800-89 5.3.3). */
Steven Valdezb1ffe0b2017-04-20 10:45:25 -0400741 enum bn_primality_result_t primality_result;
Adam Langleya54ebff2017-04-20 12:36:18 -0700742 if (BN_num_bits(key->e) <= 16 ||
Steven Valdezd0b98822017-04-11 12:46:03 -0400743 BN_num_bits(key->e) > 256 ||
744 !BN_is_odd(key->n) ||
745 !BN_is_odd(key->e) ||
746 !BN_gcd(&small_gcd, key->n, &kSmallFactors, ctx) ||
Steven Valdezb1ffe0b2017-04-20 10:45:25 -0400747 !BN_is_one(&small_gcd) ||
748 !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n,
749 BN_prime_checks, ctx, NULL) ||
750 primality_result != bn_non_prime_power_composite) {
Steven Valdezd0b98822017-04-11 12:46:03 -0400751 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
752 ret = 0;
753 }
754
755 BN_free(&small_gcd);
756 BN_CTX_free(ctx);
757
Steven Valdezb15143f2017-04-13 13:14:12 -0400758 if (!ret || key->d == NULL || key->p == NULL) {
759 /* On a failure or on only a public key, there's nothing else can be
760 * checked. */
Steven Valdez400d0b72017-04-06 14:55:18 -0400761 return ret;
762 }
763
764 /* FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG,
765 * section 9.9, it is not known whether |rsa| will be used for signing or
766 * encryption, so either pair-wise consistency self-test is acceptable. We
767 * perform a signing test. */
768 uint8_t data[32] = {0};
769 unsigned sig_len = RSA_size(key);
770 uint8_t *sig = OPENSSL_malloc(sig_len);
771 if (sig == NULL) {
Steven Valdezb15143f2017-04-13 13:14:12 -0400772 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Steven Valdez400d0b72017-04-06 14:55:18 -0400773 return 0;
774 }
775
776 if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key) ||
777 !RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
Steven Valdezb15143f2017-04-13 13:14:12 -0400778 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
Steven Valdez400d0b72017-04-06 14:55:18 -0400779 ret = 0;
780 }
781
782 OPENSSL_free(sig);
783
Steven Valdezd0b98822017-04-11 12:46:03 -0400784 return ret;
785}
786
Adam Langley409766d2014-06-20 12:00:00 -0700787int RSA_recover_crt_params(RSA *rsa) {
788 BN_CTX *ctx;
789 BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q;
790 int ok = 0;
791
792 if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400793 OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
Adam Langley409766d2014-06-20 12:00:00 -0700794 return 0;
795 }
796
797 if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
David Benjamin3570d732015-06-29 00:28:17 -0400798 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
Adam Langley409766d2014-06-20 12:00:00 -0700799 return 0;
800 }
801
802 /* This uses the algorithm from section 9B of the RSA paper:
803 * http://people.csail.mit.edu/rivest/Rsapaper.pdf */
804
805 ctx = BN_CTX_new();
806 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400807 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700808 return 0;
809 }
810
811 BN_CTX_start(ctx);
812 totient = BN_CTX_get(ctx);
813 rem = BN_CTX_get(ctx);
814 multiple = BN_CTX_get(ctx);
815 p_plus_q = BN_CTX_get(ctx);
816 p_minus_q = BN_CTX_get(ctx);
817
818 if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
819 p_minus_q == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400820 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700821 goto err;
822 }
823
824 /* ed-1 is a small multiple of φ(n). */
825 if (!BN_mul(totient, rsa->e, rsa->d, ctx) ||
826 !BN_sub_word(totient, 1) ||
827 /* φ(n) =
828 * pq - p - q + 1 =
829 * n - (p + q) + 1
830 *
831 * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very
832 * close. But, when we calculate the quotient, we'll be truncating it
833 * because we discard the remainder. Thus (ed-1)/multiple will be >= n,
834 * which the totient cannot be. So we add one to the estimate.
835 *
836 * Consider ed-1 as:
837 *
838 * multiple * (n - (p+q) + 1) =
839 * multiple*n - multiple*(p+q) + multiple
840 *
841 * When we divide by n, the first term becomes multiple and, since
842 * multiple and p+q is tiny compared to n, the second and third terms can
843 * be ignored. Thus I claim that subtracting one from the estimate is
844 * sufficient. */
845 !BN_div(multiple, NULL, totient, rsa->n, ctx) ||
846 !BN_add_word(multiple, 1) ||
847 !BN_div(totient, rem, totient, multiple, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400848 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700849 goto err;
850 }
851
852 if (!BN_is_zero(rem)) {
David Benjamin3570d732015-06-29 00:28:17 -0400853 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
Adam Langley409766d2014-06-20 12:00:00 -0700854 goto err;
855 }
856
857 rsa->p = BN_new();
858 rsa->q = BN_new();
859 rsa->dmp1 = BN_new();
860 rsa->dmq1 = BN_new();
861 rsa->iqmp = BN_new();
862 if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
863 NULL || rsa->iqmp == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400864 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700865 goto err;
866 }
867
868 /* φ(n) = n - (p + q) + 1 =>
869 * n - totient + 1 = p + q */
870 if (!BN_sub(p_plus_q, rsa->n, totient) ||
871 !BN_add_word(p_plus_q, 1) ||
872 /* p - q = sqrt((p+q)^2 - 4n) */
873 !BN_sqr(rem, p_plus_q, ctx) ||
874 !BN_lshift(multiple, rsa->n, 2) ||
875 !BN_sub(rem, rem, multiple) ||
876 !BN_sqrt(p_minus_q, rem, ctx) ||
877 /* q is 1/2 (p+q)-(p-q) */
878 !BN_sub(rsa->q, p_plus_q, p_minus_q) ||
879 !BN_rshift1(rsa->q, rsa->q) ||
880 !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
881 !BN_mul(multiple, rsa->p, rsa->q, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400882 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700883 goto err;
884 }
885
886 if (BN_cmp(multiple, rsa->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400887 OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
Adam Langley409766d2014-06-20 12:00:00 -0700888 goto err;
889 }
890
891 if (!BN_sub(rem, rsa->p, BN_value_one()) ||
892 !BN_mod(rsa->dmp1, rsa->d, rem, ctx) ||
893 !BN_sub(rem, rsa->q, BN_value_one()) ||
894 !BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
895 !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400896 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700897 goto err;
898 }
899
900 ok = 1;
901
902err:
903 BN_CTX_end(ctx);
904 BN_CTX_free(ctx);
905 if (!ok) {
906 bn_free_and_null(&rsa->p);
907 bn_free_and_null(&rsa->q);
908 bn_free_and_null(&rsa->dmp1);
909 bn_free_and_null(&rsa->dmq1);
910 bn_free_and_null(&rsa->iqmp);
911 }
912 return ok;
913}
Adam Langley6bc658d2014-08-18 13:29:45 -0700914
915int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
916 size_t len) {
917 if (rsa->meth->private_transform) {
918 return rsa->meth->private_transform(rsa, out, in, len);
919 }
920
David Benjamind93831d2015-10-29 13:19:12 -0400921 return rsa_default_private_transform(rsa, out, in, len);
Adam Langley6bc658d2014-08-18 13:29:45 -0700922}
Adam Langleyc3ef76f2015-04-13 14:34:17 -0700923
924int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
925 return 1;
926}