blob: a27bde3fbba613ef1a735b5213d16dfffec67962 [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 }
426 if (no_branch) {
427 BN_set_flags(a_reduced, BN_FLG_CONSTTIME);
428 }
429 if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) {
430 goto err;
431 }
432 a = a_reduced;
433 }
434
435 if (no_branch || !BN_is_odd(n)) {
436 if (!bn_mod_inverse_general(out, &no_inverse, a, n, ctx)) {
437 OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR);
438 goto err;
439 }
440 } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) {
441 OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR);
442 goto err;
443 }
444
445 ok = 1;
446
447err:
448 if (!ok) {
449 BN_free(new_out);
450 out = NULL;
451 }
452 BN_free(a_reduced);
453 return out;
Kenny Rootb8494592015-09-25 02:29:14 +0000454}
455
David Benjaminc895d6b2016-08-11 13:26:41 -0400456int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
457 const BN_MONT_CTX *mont, BN_CTX *ctx) {
458 *out_no_inverse = 0;
459
460 if (BN_is_negative(a) || BN_cmp(a, &mont->N) >= 0) {
461 OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
462 return 0;
463 }
464
465 int ret = 0;
466 BIGNUM blinding_factor;
467 BN_init(&blinding_factor);
468
469 if (!BN_rand_range_ex(&blinding_factor, 1, &mont->N) ||
470 !BN_mod_mul_montgomery(out, &blinding_factor, a, mont, ctx) ||
471 !BN_mod_inverse_odd(out, out_no_inverse, out, &mont->N, ctx) ||
472 !BN_mod_mul_montgomery(out, &blinding_factor, out, mont, ctx)) {
473 OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB);
474 goto err;
475 }
476
477 ret = 1;
478
479err:
480 BN_free(&blinding_factor);
481 return ret;
482}
483
484/* bn_mod_inverse_general is the general inversion algorithm that works for
485 * both even and odd |n|. It was specifically designed to contain fewer
486 * branches that may leak sensitive information. See "New Branch Prediction
487 * Vulnerabilities in OpenSSL and Necessary Software Countermeasures" by
488 * Onur Acıçmez, Shay Gueron, and Jean-Pierre Seifert. */
489static int bn_mod_inverse_general(BIGNUM *out, int *out_no_inverse,
490 const BIGNUM *a, const BIGNUM *n,
491 BN_CTX *ctx) {
492 BIGNUM *A, *B, *X, *Y, *M, *D, *T;
493 BIGNUM local_A;
494 BIGNUM *pA;
495 int ret = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800496 int sign;
497
Kenny Rootb8494592015-09-25 02:29:14 +0000498 *out_no_inverse = 0;
499
Adam Langleyd9e397b2015-01-22 14:27:53 -0800500 BN_CTX_start(ctx);
501 A = BN_CTX_get(ctx);
502 B = BN_CTX_get(ctx);
503 X = BN_CTX_get(ctx);
504 D = BN_CTX_get(ctx);
505 M = BN_CTX_get(ctx);
506 Y = BN_CTX_get(ctx);
507 T = BN_CTX_get(ctx);
508 if (T == NULL) {
509 goto err;
510 }
511
David Benjaminc895d6b2016-08-11 13:26:41 -0400512 BIGNUM *R = out;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800513
Adam Langleyd9e397b2015-01-22 14:27:53 -0800514 BN_zero(Y);
Adam Langleye9ada862015-05-11 17:20:37 -0700515 if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800516 goto err;
517 }
518 A->neg = 0;
519
Adam Langleyd9e397b2015-01-22 14:27:53 -0800520 sign = -1;
521 /* From B = a mod |n|, A = |n| it follows that
522 *
523 * 0 <= B < A,
524 * -sign*X*a == B (mod |n|),
525 * sign*Y*a == A (mod |n|).
526 */
527
528 while (!BN_is_zero(B)) {
529 BIGNUM *tmp;
530
531 /*
532 * 0 < B < A,
533 * (*) -sign*X*a == B (mod |n|),
534 * sign*Y*a == A (mod |n|)
535 */
536
537 /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
538 * BN_div_no_branch will be called eventually.
539 */
540 pA = &local_A;
541 BN_with_flags(pA, A, BN_FLG_CONSTTIME);
542
543 /* (D, M) := (A/B, A%B) ... */
544 if (!BN_div(D, M, pA, B, ctx)) {
545 goto err;
546 }
547
548 /* Now
549 * A = D*B + M;
550 * thus we have
551 * (**) sign*Y*a == D*B + M (mod |n|).
552 */
553
554 tmp = A; /* keep the BIGNUM object, the value does not matter */
555
556 /* (A, B) := (B, A mod B) ... */
557 A = B;
558 B = M;
559 /* ... so we have 0 <= B < A again */
560
561 /* Since the former M is now B and the former B is now A,
562 * (**) translates into
563 * sign*Y*a == D*A + B (mod |n|),
564 * i.e.
565 * sign*Y*a - D*A == B (mod |n|).
566 * Similarly, (*) translates into
567 * -sign*X*a == A (mod |n|).
568 *
569 * Thus,
570 * sign*Y*a + D*sign*X*a == B (mod |n|),
571 * i.e.
572 * sign*(Y + D*X)*a == B (mod |n|).
573 *
574 * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
575 * -sign*X*a == B (mod |n|),
576 * sign*Y*a == A (mod |n|).
577 * Note that X and Y stay non-negative all the time.
578 */
579
580 if (!BN_mul(tmp, D, X, ctx)) {
581 goto err;
582 }
583 if (!BN_add(tmp, tmp, Y)) {
584 goto err;
585 }
586
587 M = Y; /* keep the BIGNUM object, the value does not matter */
588 Y = X;
589 X = tmp;
590 sign = -sign;
591 }
592
David Benjaminc895d6b2016-08-11 13:26:41 -0400593 if (!BN_is_one(A)) {
594 *out_no_inverse = 1;
595 OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
596 goto err;
597 }
598
Adam Langleyd9e397b2015-01-22 14:27:53 -0800599 /*
600 * The while loop (Euclid's algorithm) ends when
601 * A == gcd(a,n);
602 * we have
603 * sign*Y*a == A (mod |n|),
604 * where Y is non-negative.
605 */
606
607 if (sign < 0) {
608 if (!BN_sub(Y, n, Y)) {
609 goto err;
610 }
611 }
612 /* Now Y*a == A (mod |n|). */
613
David Benjaminc895d6b2016-08-11 13:26:41 -0400614 /* Y*a == 1 (mod |n|) */
615 if (!Y->neg && BN_ucmp(Y, n) < 0) {
616 if (!BN_copy(R, Y)) {
617 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800618 }
619 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400620 if (!BN_nnmod(R, Y, n, ctx)) {
621 goto err;
622 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800623 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400624
625 ret = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800626
627err:
Adam Langleyd9e397b2015-01-22 14:27:53 -0800628 BN_CTX_end(ctx);
629 return ret;
630}