blob: 9e62da00dc9a7ba3b60cba1ba0c218b44ee6b94d [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/* ====================================================================
58 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com). */
108
109#include <openssl/bn.h>
110
David Benjaminc895d6b2016-08-11 13:26:41 -0400111#include <assert.h>
112
Adam Langleyd9e397b2015-01-22 14:27:53 -0800113#include <openssl/err.h>
114
115#include "internal.h"
116
117static BIGNUM *euclid(BIGNUM *a, BIGNUM *b) {
118 BIGNUM *t;
119 int shifts = 0;
120
121 /* 0 <= b <= a */
122 while (!BN_is_zero(b)) {
123 /* 0 < b <= a */
124
125 if (BN_is_odd(a)) {
126 if (BN_is_odd(b)) {
127 if (!BN_sub(a, a, b)) {
128 goto err;
129 }
130 if (!BN_rshift1(a, a)) {
131 goto err;
132 }
133 if (BN_cmp(a, b) < 0) {
134 t = a;
135 a = b;
136 b = t;
137 }
138 } else {
139 /* a odd - b even */
140 if (!BN_rshift1(b, b)) {
141 goto err;
142 }
143 if (BN_cmp(a, b) < 0) {
144 t = a;
145 a = b;
146 b = t;
147 }
148 }
149 } else {
150 /* a is even */
151 if (BN_is_odd(b)) {
152 if (!BN_rshift1(a, a)) {
153 goto err;
154 }
155 if (BN_cmp(a, b) < 0) {
156 t = a;
157 a = b;
158 b = t;
159 }
160 } else {
161 /* a even - b even */
162 if (!BN_rshift1(a, a)) {
163 goto err;
164 }
165 if (!BN_rshift1(b, b)) {
166 goto err;
167 }
168 shifts++;
169 }
170 }
171 /* 0 <= b <= a */
172 }
173
174 if (shifts) {
175 if (!BN_lshift(a, a, shifts)) {
176 goto err;
177 }
178 }
179
180 return a;
181
182err:
183 return NULL;
184}
185
186int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) {
187 BIGNUM *a, *b, *t;
188 int ret = 0;
189
190 BN_CTX_start(ctx);
191 a = BN_CTX_get(ctx);
192 b = BN_CTX_get(ctx);
193
194 if (a == NULL || b == NULL) {
195 goto err;
196 }
197 if (BN_copy(a, in_a) == NULL) {
198 goto err;
199 }
200 if (BN_copy(b, in_b) == NULL) {
201 goto err;
202 }
203
204 a->neg = 0;
205 b->neg = 0;
206
207 if (BN_cmp(a, b) < 0) {
208 t = a;
209 a = b;
210 b = t;
211 }
212 t = euclid(a, b);
213 if (t == NULL) {
214 goto err;
215 }
216
217 if (BN_copy(r, t) == NULL) {
218 goto err;
219 }
220 ret = 1;
221
222err:
223 BN_CTX_end(ctx);
224 return ret;
225}
226
227/* solves ax == 1 (mod n) */
David Benjaminc895d6b2016-08-11 13:26:41 -0400228static int bn_mod_inverse_general(BIGNUM *out, int *out_no_inverse,
229 const BIGNUM *a, const BIGNUM *n,
230 BN_CTX *ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800231
David Benjaminc895d6b2016-08-11 13:26:41 -0400232int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
233 const BIGNUM *n, BN_CTX *ctx) {
234 *out_no_inverse = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800235
David Benjaminc895d6b2016-08-11 13:26:41 -0400236 if (!BN_is_odd(n)) {
237 OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
238 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800239 }
240
David Benjaminc895d6b2016-08-11 13:26:41 -0400241 if (BN_is_negative(a) || BN_cmp(a, n) >= 0) {
242 OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
243 return 0;
244 }
245
246 BIGNUM *A, *B, *X, *Y;
247 int ret = 0;
248 int sign;
Kenny Rootb8494592015-09-25 02:29:14 +0000249
Adam Langleyd9e397b2015-01-22 14:27:53 -0800250 BN_CTX_start(ctx);
251 A = BN_CTX_get(ctx);
252 B = BN_CTX_get(ctx);
253 X = BN_CTX_get(ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800254 Y = BN_CTX_get(ctx);
David Benjaminc895d6b2016-08-11 13:26:41 -0400255 if (Y == NULL) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800256 goto err;
257 }
258
David Benjaminc895d6b2016-08-11 13:26:41 -0400259 BIGNUM *R = out;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800260
Adam Langleyd9e397b2015-01-22 14:27:53 -0800261 BN_zero(Y);
Adam Langleye9ada862015-05-11 17:20:37 -0700262 if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800263 goto err;
264 }
265 A->neg = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800266 sign = -1;
267 /* From B = a mod |n|, A = |n| it follows that
268 *
269 * 0 <= B < A,
270 * -sign*X*a == B (mod |n|),
271 * sign*Y*a == A (mod |n|).
272 */
273
David Benjaminc895d6b2016-08-11 13:26:41 -0400274 /* Binary inversion algorithm; requires odd modulus. This is faster than the
275 * general algorithm if the modulus is sufficiently small (about 400 .. 500
276 * bits on 32-bit systems, but much more on 64-bit systems) */
277 int shift;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800278
David Benjaminc895d6b2016-08-11 13:26:41 -0400279 while (!BN_is_zero(B)) {
280 /* 0 < B < |n|,
281 * 0 < A <= |n|,
282 * (1) -sign*X*a == B (mod |n|),
283 * (2) sign*Y*a == A (mod |n|) */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800284
David Benjaminc895d6b2016-08-11 13:26:41 -0400285 /* Now divide B by the maximum possible power of two in the integers,
286 * and divide X by the same value mod |n|.
287 * When we're done, (1) still holds. */
288 shift = 0;
289 while (!BN_is_bit_set(B, shift)) {
290 /* note that 0 < B */
291 shift++;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800292
David Benjaminc895d6b2016-08-11 13:26:41 -0400293 if (BN_is_odd(X)) {
294 if (!BN_uadd(X, X, n)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800295 goto err;
296 }
297 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400298 /* now X is even, so we can easily divide it by two */
299 if (!BN_rshift1(X, X)) {
300 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800301 }
302 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400303 if (shift > 0) {
304 if (!BN_rshift(B, B, shift)) {
305 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800306 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800307 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400308
309 /* Same for A and Y. Afterwards, (2) still holds. */
310 shift = 0;
311 while (!BN_is_bit_set(A, shift)) {
312 /* note that 0 < A */
313 shift++;
314
315 if (BN_is_odd(Y)) {
316 if (!BN_uadd(Y, Y, n)) {
317 goto err;
318 }
319 }
320 /* now Y is even */
321 if (!BN_rshift1(Y, Y)) {
322 goto err;
323 }
324 }
325 if (shift > 0) {
326 if (!BN_rshift(A, A, shift)) {
327 goto err;
328 }
329 }
330
331 /* We still have (1) and (2).
332 * Both A and B are odd.
333 * The following computations ensure that
334 *
335 * 0 <= B < |n|,
336 * 0 < A < |n|,
337 * (1) -sign*X*a == B (mod |n|),
338 * (2) sign*Y*a == A (mod |n|),
339 *
340 * and that either A or B is even in the next iteration. */
341 if (BN_ucmp(B, A) >= 0) {
342 /* -sign*(X + Y)*a == B - A (mod |n|) */
343 if (!BN_uadd(X, X, Y)) {
344 goto err;
345 }
346 /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
347 * actually makes the algorithm slower */
348 if (!BN_usub(B, B, A)) {
349 goto err;
350 }
351 } else {
352 /* sign*(X + Y)*a == A - B (mod |n|) */
353 if (!BN_uadd(Y, Y, X)) {
354 goto err;
355 }
356 /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
357 if (!BN_usub(A, A, B)) {
358 goto err;
359 }
360 }
361 }
362
363 if (!BN_is_one(A)) {
364 *out_no_inverse = 1;
365 OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
366 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800367 }
368
369 /* The while loop (Euclid's algorithm) ends when
370 * A == gcd(a,n);
371 * we have
372 * sign*Y*a == A (mod |n|),
373 * where Y is non-negative. */
374
375 if (sign < 0) {
376 if (!BN_sub(Y, n, Y)) {
377 goto err;
378 }
379 }
380 /* Now Y*a == A (mod |n|). */
381
David Benjaminc895d6b2016-08-11 13:26:41 -0400382 /* Y*a == 1 (mod |n|) */
383 if (!Y->neg && BN_ucmp(Y, n) < 0) {
384 if (!BN_copy(R, Y)) {
385 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800386 }
387 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400388 if (!BN_nnmod(R, Y, n, ctx)) {
389 goto err;
390 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800391 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400392
393 ret = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800394
395err:
Adam Langleyd9e397b2015-01-22 14:27:53 -0800396 BN_CTX_end(ctx);
397 return ret;
398}
399
Kenny Rootb8494592015-09-25 02:29:14 +0000400BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
401 BN_CTX *ctx) {
402 int no_inverse;
David Benjaminc895d6b2016-08-11 13:26:41 -0400403
404 BIGNUM *a_reduced = NULL;
405
406 BIGNUM *new_out = NULL;
407 if (out == NULL) {
408 new_out = BN_new();
409 if (new_out == NULL) {
410 OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
411 return NULL;
412 }
413 out = new_out;
414 }
415
416 int ok = 0;
417
418 int no_branch =
419 (a->flags & BN_FLG_CONSTTIME) != 0 || (n->flags & BN_FLG_CONSTTIME) != 0;
420
421 if (a->neg || BN_ucmp(a, n) >= 0) {
422 a_reduced = BN_dup(a);
423 if (a_reduced == NULL) {
424 goto err;
425 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400426 if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) {
427 goto err;
428 }
429 a = a_reduced;
430 }
431
432 if (no_branch || !BN_is_odd(n)) {
433 if (!bn_mod_inverse_general(out, &no_inverse, a, n, ctx)) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400434 goto err;
435 }
436 } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400437 goto err;
438 }
439
440 ok = 1;
441
442err:
443 if (!ok) {
444 BN_free(new_out);
445 out = NULL;
446 }
447 BN_free(a_reduced);
448 return out;
Kenny Rootb8494592015-09-25 02:29:14 +0000449}
450
David Benjaminc895d6b2016-08-11 13:26:41 -0400451int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
452 const BN_MONT_CTX *mont, BN_CTX *ctx) {
453 *out_no_inverse = 0;
454
455 if (BN_is_negative(a) || BN_cmp(a, &mont->N) >= 0) {
456 OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
457 return 0;
458 }
459
460 int ret = 0;
461 BIGNUM blinding_factor;
462 BN_init(&blinding_factor);
463
464 if (!BN_rand_range_ex(&blinding_factor, 1, &mont->N) ||
465 !BN_mod_mul_montgomery(out, &blinding_factor, a, mont, ctx) ||
466 !BN_mod_inverse_odd(out, out_no_inverse, out, &mont->N, ctx) ||
467 !BN_mod_mul_montgomery(out, &blinding_factor, out, mont, ctx)) {
468 OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB);
469 goto err;
470 }
471
472 ret = 1;
473
474err:
475 BN_free(&blinding_factor);
476 return ret;
477}
478
479/* bn_mod_inverse_general is the general inversion algorithm that works for
480 * both even and odd |n|. It was specifically designed to contain fewer
Robert Sloan69939df2017-01-09 10:53:07 -0800481 * branches that may leak sensitive information; see "New Branch Prediction
David Benjaminc895d6b2016-08-11 13:26:41 -0400482 * Vulnerabilities in OpenSSL and Necessary Software Countermeasures" by
483 * Onur Acıçmez, Shay Gueron, and Jean-Pierre Seifert. */
484static int bn_mod_inverse_general(BIGNUM *out, int *out_no_inverse,
485 const BIGNUM *a, const BIGNUM *n,
486 BN_CTX *ctx) {
487 BIGNUM *A, *B, *X, *Y, *M, *D, *T;
David Benjaminc895d6b2016-08-11 13:26:41 -0400488 int ret = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800489 int sign;
490
Kenny Rootb8494592015-09-25 02:29:14 +0000491 *out_no_inverse = 0;
492
Adam Langleyd9e397b2015-01-22 14:27:53 -0800493 BN_CTX_start(ctx);
494 A = BN_CTX_get(ctx);
495 B = BN_CTX_get(ctx);
496 X = BN_CTX_get(ctx);
497 D = BN_CTX_get(ctx);
498 M = BN_CTX_get(ctx);
499 Y = BN_CTX_get(ctx);
500 T = BN_CTX_get(ctx);
501 if (T == NULL) {
502 goto err;
503 }
504
David Benjaminc895d6b2016-08-11 13:26:41 -0400505 BIGNUM *R = out;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800506
Adam Langleyd9e397b2015-01-22 14:27:53 -0800507 BN_zero(Y);
Adam Langleye9ada862015-05-11 17:20:37 -0700508 if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800509 goto err;
510 }
511 A->neg = 0;
512
Adam Langleyd9e397b2015-01-22 14:27:53 -0800513 sign = -1;
514 /* From B = a mod |n|, A = |n| it follows that
515 *
516 * 0 <= B < A,
517 * -sign*X*a == B (mod |n|),
518 * sign*Y*a == A (mod |n|).
519 */
520
521 while (!BN_is_zero(B)) {
522 BIGNUM *tmp;
523
524 /*
525 * 0 < B < A,
526 * (*) -sign*X*a == B (mod |n|),
527 * sign*Y*a == A (mod |n|)
528 */
529
Adam Langleyd9e397b2015-01-22 14:27:53 -0800530 /* (D, M) := (A/B, A%B) ... */
Robert Sloan69939df2017-01-09 10:53:07 -0800531 if (!BN_div(D, M, A, B, ctx)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800532 goto err;
533 }
534
535 /* Now
536 * A = D*B + M;
537 * thus we have
538 * (**) sign*Y*a == D*B + M (mod |n|).
539 */
540
541 tmp = A; /* keep the BIGNUM object, the value does not matter */
542
543 /* (A, B) := (B, A mod B) ... */
544 A = B;
545 B = M;
546 /* ... so we have 0 <= B < A again */
547
548 /* Since the former M is now B and the former B is now A,
549 * (**) translates into
550 * sign*Y*a == D*A + B (mod |n|),
551 * i.e.
552 * sign*Y*a - D*A == B (mod |n|).
553 * Similarly, (*) translates into
554 * -sign*X*a == A (mod |n|).
555 *
556 * Thus,
557 * sign*Y*a + D*sign*X*a == B (mod |n|),
558 * i.e.
559 * sign*(Y + D*X)*a == B (mod |n|).
560 *
561 * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
562 * -sign*X*a == B (mod |n|),
563 * sign*Y*a == A (mod |n|).
564 * Note that X and Y stay non-negative all the time.
565 */
566
567 if (!BN_mul(tmp, D, X, ctx)) {
568 goto err;
569 }
570 if (!BN_add(tmp, tmp, Y)) {
571 goto err;
572 }
573
574 M = Y; /* keep the BIGNUM object, the value does not matter */
575 Y = X;
576 X = tmp;
577 sign = -sign;
578 }
579
David Benjaminc895d6b2016-08-11 13:26:41 -0400580 if (!BN_is_one(A)) {
581 *out_no_inverse = 1;
582 OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
583 goto err;
584 }
585
Adam Langleyd9e397b2015-01-22 14:27:53 -0800586 /*
587 * The while loop (Euclid's algorithm) ends when
588 * A == gcd(a,n);
589 * we have
590 * sign*Y*a == A (mod |n|),
591 * where Y is non-negative.
592 */
593
594 if (sign < 0) {
595 if (!BN_sub(Y, n, Y)) {
596 goto err;
597 }
598 }
599 /* Now Y*a == A (mod |n|). */
600
David Benjaminc895d6b2016-08-11 13:26:41 -0400601 /* Y*a == 1 (mod |n|) */
602 if (!Y->neg && BN_ucmp(Y, n) < 0) {
603 if (!BN_copy(R, Y)) {
604 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800605 }
606 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400607 if (!BN_nnmod(R, Y, n, ctx)) {
608 goto err;
609 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800610 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400611
612 ret = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800613
614err:
Adam Langleyd9e397b2015-01-22 14:27:53 -0800615 BN_CTX_end(ctx);
616 return ret;
617}
Robert Sloan69939df2017-01-09 10:53:07 -0800618
619int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
620 BN_CTX *ctx, const BN_MONT_CTX *mont_p) {
621 BN_CTX_start(ctx);
622 BIGNUM *p_minus_2 = BN_CTX_get(ctx);
623 int ok = p_minus_2 != NULL &&
624 BN_copy(p_minus_2, p) &&
625 BN_sub_word(p_minus_2, 2) &&
626 BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p);
627 BN_CTX_end(ctx);
628 return ok;
629}
630
631int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
632 BN_CTX *ctx, const BN_MONT_CTX *mont_p) {
633 BN_CTX_start(ctx);
634 BIGNUM *p_minus_2 = BN_CTX_get(ctx);
635 int ok = p_minus_2 != NULL &&
636 BN_copy(p_minus_2, p) &&
637 BN_sub_word(p_minus_2, 2) &&
638 BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p);
639 BN_CTX_end(ctx);
640 return ok;
641}