blob: afc1432e3c45101068cab20c7bcb132898a572f5 [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
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700195int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700196 int padding) {
197 size_t out_len;
198
199 if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
200 return -1;
201 }
202
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700203 if (out_len > INT_MAX) {
204 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
205 return -1;
206 }
Adam Langley95c29f32014-06-20 12:00:00 -0700207 return out_len;
208}
209
210int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
211 const uint8_t *in, size_t in_len, int padding) {
212 if (rsa->meth->sign_raw) {
213 return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
214 }
215
David Benjamind93831d2015-10-29 13:19:12 -0400216 return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700217}
218
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700219int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700220 int padding) {
221 size_t out_len;
222
223 if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
224 return -1;
225 }
226
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700227 if (out_len > INT_MAX) {
228 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
229 return -1;
230 }
Adam Langley95c29f32014-06-20 12:00:00 -0700231 return out_len;
232}
233
234int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
235 const uint8_t *in, size_t in_len, int padding) {
236 if (rsa->meth->decrypt) {
237 return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
238 }
239
David Benjamind93831d2015-10-29 13:19:12 -0400240 return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
Adam Langley95c29f32014-06-20 12:00:00 -0700241}
242
David Benjamin79c59a32015-09-19 13:35:39 -0400243int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700244 int padding) {
245 size_t out_len;
246
247 if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
248 return -1;
249 }
250
David Benjamin79c59a32015-09-19 13:35:39 -0400251 if (out_len > INT_MAX) {
252 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
253 return -1;
254 }
Adam Langley95c29f32014-06-20 12:00:00 -0700255 return out_len;
256}
257
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700258int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
Adam Langley95c29f32014-06-20 12:00:00 -0700259 int padding) {
260 size_t out_len;
261
262 if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
263 return -1;
264 }
265
Matt Braithwaite978f16e2015-10-19 13:38:36 -0700266 if (out_len > INT_MAX) {
267 OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
268 return -1;
269 }
Adam Langley95c29f32014-06-20 12:00:00 -0700270 return out_len;
271}
272
273unsigned RSA_size(const RSA *rsa) {
David Benjamin925fee32014-07-11 14:14:08 -0400274 if (rsa->meth->size) {
275 return rsa->meth->size(rsa);
276 }
277
David Benjamind93831d2015-10-29 13:19:12 -0400278 return rsa_default_size(rsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700279}
280
David Benjaminecc0ce72014-07-18 18:39:42 -0400281int RSA_is_opaque(const RSA *rsa) {
282 return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
283}
284
David Benjamin8a589332015-12-04 23:14:35 -0500285int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langley95c29f32014-06-20 12:00:00 -0700286 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400287 int index;
David Benjamin8a589332015-12-04 23:14:35 -0500288 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
289 free_func)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400290 return -1;
291 }
292 return index;
Adam Langley95c29f32014-06-20 12:00:00 -0700293}
294
295int RSA_set_ex_data(RSA *d, int idx, void *arg) {
296 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
297}
298
299void *RSA_get_ex_data(const RSA *d, int idx) {
300 return CRYPTO_get_ex_data(&d->ex_data, idx);
301}
302
303/* SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
304 * the length of an MD5 and SHA1 hash. */
305static const unsigned SSL_SIG_LENGTH = 36;
306
307/* pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is
308 * to be signed with PKCS#1. */
309struct pkcs1_sig_prefix {
310 /* nid identifies the hash function. */
311 int nid;
David Benjamin05821b02017-05-02 14:15:21 -0400312 /* hash_len is the expected length of the hash function. */
313 uint8_t hash_len;
Adam Langley95c29f32014-06-20 12:00:00 -0700314 /* len is the number of bytes of |bytes| which are valid. */
315 uint8_t len;
316 /* bytes contains the DER bytes. */
317 uint8_t bytes[19];
318};
319
320/* kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with
321 * different hash functions. */
322static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
323 {
324 NID_md5,
David Benjamin05821b02017-05-02 14:15:21 -0400325 MD5_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700326 18,
327 {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
328 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
329 },
330 {
331 NID_sha1,
David Benjamin05821b02017-05-02 14:15:21 -0400332 SHA_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700333 15,
334 {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
335 0x00, 0x04, 0x14},
336 },
337 {
338 NID_sha224,
David Benjamin05821b02017-05-02 14:15:21 -0400339 SHA224_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700340 19,
341 {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
342 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
343 },
344 {
345 NID_sha256,
David Benjamin05821b02017-05-02 14:15:21 -0400346 SHA256_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700347 19,
348 {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
349 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
350 },
351 {
352 NID_sha384,
David Benjamin05821b02017-05-02 14:15:21 -0400353 SHA384_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700354 19,
355 {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
356 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
357 },
358 {
359 NID_sha512,
David Benjamin05821b02017-05-02 14:15:21 -0400360 SHA512_DIGEST_LENGTH,
Adam Langley95c29f32014-06-20 12:00:00 -0700361 19,
362 {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
363 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
364 },
365 {
David Benjamin05821b02017-05-02 14:15:21 -0400366 NID_undef, 0, 0, {0},
Adam Langley95c29f32014-06-20 12:00:00 -0700367 },
368};
369
David Benjaminb0acb772015-05-28 16:53:31 -0400370int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
371 int *is_alloced, int hash_nid, const uint8_t *msg,
372 size_t msg_len) {
Adam Langley95c29f32014-06-20 12:00:00 -0700373 unsigned i;
Adam Langley95c29f32014-06-20 12:00:00 -0700374
375 if (hash_nid == NID_md5_sha1) {
376 /* Special case: SSL signature, just check the length. */
377 if (msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400378 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700379 return 0;
380 }
381
382 *out_msg = (uint8_t*) msg;
383 *out_msg_len = SSL_SIG_LENGTH;
384 *is_alloced = 0;
385 return 1;
386 }
387
388 for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
389 const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
Brian Smitha039d702015-01-29 15:03:18 -0800390 if (sig_prefix->nid != hash_nid) {
391 continue;
Adam Langley95c29f32014-06-20 12:00:00 -0700392 }
Brian Smitha039d702015-01-29 15:03:18 -0800393
David Benjamin05821b02017-05-02 14:15:21 -0400394 if (msg_len != sig_prefix->hash_len) {
395 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
396 return 0;
397 }
398
Brian Smitha039d702015-01-29 15:03:18 -0800399 const uint8_t* prefix = sig_prefix->bytes;
400 unsigned prefix_len = sig_prefix->len;
401 unsigned signed_msg_len;
402 uint8_t *signed_msg;
403
404 signed_msg_len = prefix_len + msg_len;
405 if (signed_msg_len < prefix_len) {
David Benjamin3570d732015-06-29 00:28:17 -0400406 OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
Brian Smitha039d702015-01-29 15:03:18 -0800407 return 0;
408 }
409
410 signed_msg = OPENSSL_malloc(signed_msg_len);
411 if (!signed_msg) {
David Benjamin3570d732015-06-29 00:28:17 -0400412 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Brian Smitha039d702015-01-29 15:03:18 -0800413 return 0;
414 }
415
David Benjamin17cf2cb2016-12-13 01:07:13 -0500416 OPENSSL_memcpy(signed_msg, prefix, prefix_len);
417 OPENSSL_memcpy(signed_msg + prefix_len, msg, msg_len);
Brian Smitha039d702015-01-29 15:03:18 -0800418
419 *out_msg = signed_msg;
420 *out_msg_len = signed_msg_len;
421 *is_alloced = 1;
422
423 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700424 }
425
David Benjamin3570d732015-06-29 00:28:17 -0400426 OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
Brian Smitha039d702015-01-29 15:03:18 -0800427 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700428}
429
430int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out,
431 unsigned *out_len, RSA *rsa) {
432 const unsigned rsa_size = RSA_size(rsa);
433 int ret = 0;
David Benjamin5eb75e22017-05-02 17:21:15 -0400434 uint8_t *signed_msg = NULL;
435 size_t signed_msg_len = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700436 int signed_msg_is_alloced = 0;
437 size_t size_t_out_len;
438
439 if (rsa->meth->sign) {
440 return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa);
441 }
442
David Benjaminb0acb772015-05-28 16:53:31 -0400443 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
David Benjaminddd5ba72017-04-11 12:54:06 -0400444 &signed_msg_is_alloced, hash_nid, in, in_len) ||
445 !RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg,
446 signed_msg_len, RSA_PKCS1_PADDING)) {
447 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700448 }
449
David Benjaminddd5ba72017-04-11 12:54:06 -0400450 *out_len = size_t_out_len;
451 ret = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700452
David Benjaminddd5ba72017-04-11 12:54:06 -0400453err:
Adam Langley95c29f32014-06-20 12:00:00 -0700454 if (signed_msg_is_alloced) {
455 OPENSSL_free(signed_msg);
456 }
457 return ret;
458}
459
David Benjamin79d18bc2017-05-02 14:34:09 -0400460int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
461 const uint8_t *in, size_t in_len, const EVP_MD *md,
462 const EVP_MD *mgf1_md, int salt_len) {
463 if (in_len != EVP_MD_size(md)) {
464 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
465 return 0;
466 }
467
468 size_t padded_len = RSA_size(rsa);
469 uint8_t *padded = OPENSSL_malloc(padded_len);
470 if (padded == NULL) {
471 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
472 return 0;
473 }
474
475 int ret =
476 RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, in, md, mgf1_md, salt_len) &&
477 RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len,
478 RSA_NO_PADDING);
479 OPENSSL_free(padded);
480 return ret;
481}
482
Adam Langley95c29f32014-06-20 12:00:00 -0700483int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
484 const uint8_t *sig, size_t sig_len, RSA *rsa) {
Brian Smithc0b196d2016-03-04 08:54:07 -1000485 if (rsa->n == NULL || rsa->e == NULL) {
486 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
487 return 0;
488 }
489
Adam Langley95c29f32014-06-20 12:00:00 -0700490 const size_t rsa_size = RSA_size(rsa);
491 uint8_t *buf = NULL;
492 int ret = 0;
493 uint8_t *signed_msg = NULL;
David Benjamin5eb75e22017-05-02 17:21:15 -0400494 size_t signed_msg_len = 0, len;
Adam Langley95c29f32014-06-20 12:00:00 -0700495 int signed_msg_is_alloced = 0;
496
Adam Langley95c29f32014-06-20 12:00:00 -0700497 if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400498 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Adam Langley95c29f32014-06-20 12:00:00 -0700499 return 0;
500 }
501
502 buf = OPENSSL_malloc(rsa_size);
503 if (!buf) {
David Benjamin3570d732015-06-29 00:28:17 -0400504 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700505 return 0;
506 }
507
508 if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len,
509 RSA_PKCS1_PADDING)) {
510 goto out;
511 }
512
David Benjaminb0acb772015-05-28 16:53:31 -0400513 if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
514 &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700515 goto out;
516 }
517
Steven Valdezc1966802017-04-10 15:52:19 -0400518 /* Check that no other information follows the hash value (FIPS 186-4 Section
519 * 5.5) and it matches the expected hash. */
David Benjamin17cf2cb2016-12-13 01:07:13 -0500520 if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400521 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700522 goto out;
523 }
524
525 ret = 1;
526
527out:
David Benjamind8b65c82015-04-22 16:09:09 -0400528 OPENSSL_free(buf);
Adam Langley95c29f32014-06-20 12:00:00 -0700529 if (signed_msg_is_alloced) {
530 OPENSSL_free(signed_msg);
531 }
532 return ret;
533}
Adam Langley409766d2014-06-20 12:00:00 -0700534
David Benjamin79d18bc2017-05-02 14:34:09 -0400535int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, size_t msg_len,
536 const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len,
537 const uint8_t *sig, size_t sig_len) {
538 if (msg_len != EVP_MD_size(md)) {
539 OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
540 return 0;
541 }
542
543 size_t em_len = RSA_size(rsa);
544 uint8_t *em = OPENSSL_malloc(em_len);
545 if (em == NULL) {
546 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
547 return 0;
548 }
549
550 int ret = 0;
551 if (!RSA_verify_raw(rsa, &em_len, em, em_len, sig, sig_len, RSA_NO_PADDING)) {
552 goto err;
553 }
554
555 if (em_len != RSA_size(rsa)) {
556 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
557 goto err;
558 }
559
560 ret = RSA_verify_PKCS1_PSS_mgf1(rsa, msg, md, mgf1_md, em, salt_len);
561
562err:
563 OPENSSL_free(em);
564 return ret;
565}
566
Adam Langley409766d2014-06-20 12:00:00 -0700567static void bn_free_and_null(BIGNUM **bn) {
Adam Langley409766d2014-06-20 12:00:00 -0700568 BN_free(*bn);
569 *bn = NULL;
570}
571
Adam Langley05b73772014-07-25 12:03:51 -0700572int RSA_check_key(const RSA *key) {
Brian Smith7241ca52016-07-25 16:01:10 -1000573 BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q;
Adam Langley05b73772014-07-25 12:03:51 -0700574 BN_CTX *ctx;
575 int ok = 0, has_crt_values;
576
577 if (RSA_is_opaque(key)) {
578 /* Opaque keys can't be checked. */
579 return 1;
580 }
581
582 if ((key->p != NULL) != (key->q != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400583 OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
Adam Langley05b73772014-07-25 12:03:51 -0700584 return 0;
585 }
586
587 if (!key->n || !key->e) {
David Benjamin3570d732015-06-29 00:28:17 -0400588 OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
Adam Langley05b73772014-07-25 12:03:51 -0700589 return 0;
590 }
591
592 if (!key->d || !key->p) {
593 /* For a public key, or without p and q, there's nothing that can be
594 * checked. */
595 return 1;
596 }
597
598 ctx = BN_CTX_new();
599 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400600 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley05b73772014-07-25 12:03:51 -0700601 return 0;
602 }
603
604 BN_init(&n);
605 BN_init(&pm1);
606 BN_init(&qm1);
607 BN_init(&lcm);
608 BN_init(&gcd);
609 BN_init(&de);
610 BN_init(&dmp1);
611 BN_init(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000612 BN_init(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700613
Adam Langley839b8812015-05-26 11:36:46 -0700614 if (!BN_mul(&n, key->p, key->q, ctx) ||
615 /* lcm = lcm(prime-1, for all primes) */
Adam Langley05b73772014-07-25 12:03:51 -0700616 !BN_sub(&pm1, key->p, BN_value_one()) ||
617 !BN_sub(&qm1, key->q, BN_value_one()) ||
618 !BN_mul(&lcm, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700619 !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400620 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley839b8812015-05-26 11:36:46 -0700621 goto out;
622 }
623
Adam Langley839b8812015-05-26 11:36:46 -0700624 if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
Adam Langley05b73772014-07-25 12:03:51 -0700625 !BN_gcd(&gcd, &pm1, &qm1, ctx) ||
Adam Langley839b8812015-05-26 11:36:46 -0700626 /* de = d*e mod lcm(prime-1, for all primes). */
Adam Langley05b73772014-07-25 12:03:51 -0700627 !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400628 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700629 goto out;
630 }
631
632 if (BN_cmp(&n, key->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400633 OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
Adam Langley05b73772014-07-25 12:03:51 -0700634 goto out;
635 }
636
637 if (!BN_is_one(&de)) {
David Benjamin3570d732015-06-29 00:28:17 -0400638 OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
Adam Langley05b73772014-07-25 12:03:51 -0700639 goto out;
640 }
641
642 has_crt_values = key->dmp1 != NULL;
643 if (has_crt_values != (key->dmq1 != NULL) ||
644 has_crt_values != (key->iqmp != NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400645 OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
Adam Langley05b73772014-07-25 12:03:51 -0700646 goto out;
647 }
648
David Benjamin82b2b852017-04-12 18:28:48 -0400649 if (has_crt_values) {
Adam Langley05b73772014-07-25 12:03:51 -0700650 if (/* dmp1 = d mod (p-1) */
651 !BN_mod(&dmp1, key->d, &pm1, ctx) ||
652 /* dmq1 = d mod (q-1) */
653 !BN_mod(&dmq1, key->d, &qm1, ctx) ||
654 /* iqmp = q^-1 mod p */
Brian Smith7241ca52016-07-25 16:01:10 -1000655 !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400656 OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
Adam Langley05b73772014-07-25 12:03:51 -0700657 goto out;
658 }
659
660 if (BN_cmp(&dmp1, key->dmp1) != 0 ||
661 BN_cmp(&dmq1, key->dmq1) != 0 ||
Brian Smith7241ca52016-07-25 16:01:10 -1000662 BN_cmp(key->iqmp, key->p) >= 0 ||
663 !BN_is_one(&iqmp_times_q)) {
David Benjamin3570d732015-06-29 00:28:17 -0400664 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
Adam Langley05b73772014-07-25 12:03:51 -0700665 goto out;
666 }
667 }
668
669 ok = 1;
670
671out:
672 BN_free(&n);
673 BN_free(&pm1);
674 BN_free(&qm1);
675 BN_free(&lcm);
676 BN_free(&gcd);
677 BN_free(&de);
678 BN_free(&dmp1);
679 BN_free(&dmq1);
Brian Smith7241ca52016-07-25 16:01:10 -1000680 BN_free(&iqmp_times_q);
Adam Langley05b73772014-07-25 12:03:51 -0700681 BN_CTX_free(ctx);
682
683 return ok;
684}
685
Steven Valdezd0b98822017-04-11 12:46:03 -0400686
687/* This is the product of the 132 smallest odd primes, from 3 to 751. */
688static const BN_ULONG kSmallFactorsLimbs[] = {
689 TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f),
690 TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b),
691 TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871),
692 TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3),
693 TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893),
694 TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e),
695 TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea),
696 TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727),
697 0x000017b1
698};
699static const BIGNUM kSmallFactors = STATIC_BIGNUM(kSmallFactorsLimbs);
700
Steven Valdez400d0b72017-04-06 14:55:18 -0400701int RSA_check_fips(RSA *key) {
Steven Valdezd0b98822017-04-11 12:46:03 -0400702 if (RSA_is_opaque(key)) {
703 /* Opaque keys can't be checked. */
704 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
705 return 0;
706 }
707
708 if (!RSA_check_key(key)) {
709 return 0;
710 }
711
712 BN_CTX *ctx = BN_CTX_new();
713 if (ctx == NULL) {
714 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
715 return 0;
716 }
717
718 BIGNUM small_gcd;
719 BN_init(&small_gcd);
720
721 int ret = 1;
722
723 /* Perform partial public key validation of RSA keys (SP 800-89 5.3.3). */
Steven Valdezb1ffe0b2017-04-20 10:45:25 -0400724 enum bn_primality_result_t primality_result;
Adam Langleya54ebff2017-04-20 12:36:18 -0700725 if (BN_num_bits(key->e) <= 16 ||
Steven Valdezd0b98822017-04-11 12:46:03 -0400726 BN_num_bits(key->e) > 256 ||
727 !BN_is_odd(key->n) ||
728 !BN_is_odd(key->e) ||
729 !BN_gcd(&small_gcd, key->n, &kSmallFactors, ctx) ||
Steven Valdezb1ffe0b2017-04-20 10:45:25 -0400730 !BN_is_one(&small_gcd) ||
731 !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n,
732 BN_prime_checks, ctx, NULL) ||
733 primality_result != bn_non_prime_power_composite) {
Steven Valdezd0b98822017-04-11 12:46:03 -0400734 OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
735 ret = 0;
736 }
737
738 BN_free(&small_gcd);
739 BN_CTX_free(ctx);
740
Steven Valdezb15143f2017-04-13 13:14:12 -0400741 if (!ret || key->d == NULL || key->p == NULL) {
742 /* On a failure or on only a public key, there's nothing else can be
743 * checked. */
Steven Valdez400d0b72017-04-06 14:55:18 -0400744 return ret;
745 }
746
747 /* FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG,
748 * section 9.9, it is not known whether |rsa| will be used for signing or
749 * encryption, so either pair-wise consistency self-test is acceptable. We
750 * perform a signing test. */
751 uint8_t data[32] = {0};
752 unsigned sig_len = RSA_size(key);
753 uint8_t *sig = OPENSSL_malloc(sig_len);
754 if (sig == NULL) {
Steven Valdezb15143f2017-04-13 13:14:12 -0400755 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Steven Valdez400d0b72017-04-06 14:55:18 -0400756 return 0;
757 }
758
759 if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key) ||
760 !RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
Steven Valdezb15143f2017-04-13 13:14:12 -0400761 OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
Steven Valdez400d0b72017-04-06 14:55:18 -0400762 ret = 0;
763 }
764
765 OPENSSL_free(sig);
766
Steven Valdezd0b98822017-04-11 12:46:03 -0400767 return ret;
768}
769
Adam Langley409766d2014-06-20 12:00:00 -0700770int RSA_recover_crt_params(RSA *rsa) {
771 BN_CTX *ctx;
772 BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q;
773 int ok = 0;
774
775 if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400776 OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
Adam Langley409766d2014-06-20 12:00:00 -0700777 return 0;
778 }
779
780 if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
David Benjamin3570d732015-06-29 00:28:17 -0400781 OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
Adam Langley409766d2014-06-20 12:00:00 -0700782 return 0;
783 }
784
785 /* This uses the algorithm from section 9B of the RSA paper:
786 * http://people.csail.mit.edu/rivest/Rsapaper.pdf */
787
788 ctx = BN_CTX_new();
789 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400790 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700791 return 0;
792 }
793
794 BN_CTX_start(ctx);
795 totient = BN_CTX_get(ctx);
796 rem = BN_CTX_get(ctx);
797 multiple = BN_CTX_get(ctx);
798 p_plus_q = BN_CTX_get(ctx);
799 p_minus_q = BN_CTX_get(ctx);
800
801 if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
802 p_minus_q == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400803 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700804 goto err;
805 }
806
807 /* ed-1 is a small multiple of φ(n). */
808 if (!BN_mul(totient, rsa->e, rsa->d, ctx) ||
809 !BN_sub_word(totient, 1) ||
810 /* φ(n) =
811 * pq - p - q + 1 =
812 * n - (p + q) + 1
813 *
814 * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very
815 * close. But, when we calculate the quotient, we'll be truncating it
816 * because we discard the remainder. Thus (ed-1)/multiple will be >= n,
817 * which the totient cannot be. So we add one to the estimate.
818 *
819 * Consider ed-1 as:
820 *
821 * multiple * (n - (p+q) + 1) =
822 * multiple*n - multiple*(p+q) + multiple
823 *
824 * When we divide by n, the first term becomes multiple and, since
825 * multiple and p+q is tiny compared to n, the second and third terms can
826 * be ignored. Thus I claim that subtracting one from the estimate is
827 * sufficient. */
828 !BN_div(multiple, NULL, totient, rsa->n, ctx) ||
829 !BN_add_word(multiple, 1) ||
830 !BN_div(totient, rem, totient, multiple, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400831 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700832 goto err;
833 }
834
835 if (!BN_is_zero(rem)) {
David Benjamin3570d732015-06-29 00:28:17 -0400836 OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
Adam Langley409766d2014-06-20 12:00:00 -0700837 goto err;
838 }
839
840 rsa->p = BN_new();
841 rsa->q = BN_new();
842 rsa->dmp1 = BN_new();
843 rsa->dmq1 = BN_new();
844 rsa->iqmp = BN_new();
845 if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
846 NULL || rsa->iqmp == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400847 OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
Adam Langley409766d2014-06-20 12:00:00 -0700848 goto err;
849 }
850
851 /* φ(n) = n - (p + q) + 1 =>
852 * n - totient + 1 = p + q */
853 if (!BN_sub(p_plus_q, rsa->n, totient) ||
854 !BN_add_word(p_plus_q, 1) ||
855 /* p - q = sqrt((p+q)^2 - 4n) */
856 !BN_sqr(rem, p_plus_q, ctx) ||
857 !BN_lshift(multiple, rsa->n, 2) ||
858 !BN_sub(rem, rem, multiple) ||
859 !BN_sqrt(p_minus_q, rem, ctx) ||
860 /* q is 1/2 (p+q)-(p-q) */
861 !BN_sub(rsa->q, p_plus_q, p_minus_q) ||
862 !BN_rshift1(rsa->q, rsa->q) ||
863 !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
864 !BN_mul(multiple, rsa->p, rsa->q, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400865 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700866 goto err;
867 }
868
869 if (BN_cmp(multiple, rsa->n) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -0400870 OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
Adam Langley409766d2014-06-20 12:00:00 -0700871 goto err;
872 }
873
874 if (!BN_sub(rem, rsa->p, BN_value_one()) ||
875 !BN_mod(rsa->dmp1, rsa->d, rem, ctx) ||
876 !BN_sub(rem, rsa->q, BN_value_one()) ||
877 !BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
878 !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400879 OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
Adam Langley409766d2014-06-20 12:00:00 -0700880 goto err;
881 }
882
883 ok = 1;
884
885err:
886 BN_CTX_end(ctx);
887 BN_CTX_free(ctx);
888 if (!ok) {
889 bn_free_and_null(&rsa->p);
890 bn_free_and_null(&rsa->q);
891 bn_free_and_null(&rsa->dmp1);
892 bn_free_and_null(&rsa->dmq1);
893 bn_free_and_null(&rsa->iqmp);
894 }
895 return ok;
896}
Adam Langley6bc658d2014-08-18 13:29:45 -0700897
898int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
899 size_t len) {
900 if (rsa->meth->private_transform) {
901 return rsa->meth->private_transform(rsa, out, in, len);
902 }
903
David Benjamind93831d2015-10-29 13:19:12 -0400904 return rsa_default_private_transform(rsa, out, in, len);
Adam Langley6bc658d2014-08-18 13:29:45 -0700905}
Adam Langleyc3ef76f2015-04-13 14:34:17 -0700906
907int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
908 return 1;
909}