1 /* 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 
111 #include <openssl/err.h>
112 
113 #include "internal.h"
114 
euclid(BIGNUM * a,BIGNUM * b)115 static BIGNUM *euclid(BIGNUM *a, BIGNUM *b) {
116   BIGNUM *t;
117   int shifts = 0;
118 
119   /* 0 <= b <= a */
120   while (!BN_is_zero(b)) {
121     /* 0 < b <= a */
122 
123     if (BN_is_odd(a)) {
124       if (BN_is_odd(b)) {
125         if (!BN_sub(a, a, b)) {
126           goto err;
127         }
128         if (!BN_rshift1(a, a)) {
129           goto err;
130         }
131         if (BN_cmp(a, b) < 0) {
132           t = a;
133           a = b;
134           b = t;
135         }
136       } else {
137         /* a odd - b even */
138         if (!BN_rshift1(b, b)) {
139           goto err;
140         }
141         if (BN_cmp(a, b) < 0) {
142           t = a;
143           a = b;
144           b = t;
145         }
146       }
147     } else {
148       /* a is even */
149       if (BN_is_odd(b)) {
150         if (!BN_rshift1(a, a)) {
151           goto err;
152         }
153         if (BN_cmp(a, b) < 0) {
154           t = a;
155           a = b;
156           b = t;
157         }
158       } else {
159         /* a even - b even */
160         if (!BN_rshift1(a, a)) {
161           goto err;
162         }
163         if (!BN_rshift1(b, b)) {
164           goto err;
165         }
166         shifts++;
167       }
168     }
169     /* 0 <= b <= a */
170   }
171 
172   if (shifts) {
173     if (!BN_lshift(a, a, shifts)) {
174       goto err;
175     }
176   }
177 
178   return a;
179 
180 err:
181   return NULL;
182 }
183 
BN_gcd(BIGNUM * r,const BIGNUM * in_a,const BIGNUM * in_b,BN_CTX * ctx)184 int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) {
185   BIGNUM *a, *b, *t;
186   int ret = 0;
187 
188   BN_CTX_start(ctx);
189   a = BN_CTX_get(ctx);
190   b = BN_CTX_get(ctx);
191 
192   if (a == NULL || b == NULL) {
193     goto err;
194   }
195   if (BN_copy(a, in_a) == NULL) {
196     goto err;
197   }
198   if (BN_copy(b, in_b) == NULL) {
199     goto err;
200   }
201 
202   a->neg = 0;
203   b->neg = 0;
204 
205   if (BN_cmp(a, b) < 0) {
206     t = a;
207     a = b;
208     b = t;
209   }
210   t = euclid(a, b);
211   if (t == NULL) {
212     goto err;
213   }
214 
215   if (BN_copy(r, t) == NULL) {
216     goto err;
217   }
218   ret = 1;
219 
220 err:
221   BN_CTX_end(ctx);
222   return ret;
223 }
224 
225 /* solves ax == 1 (mod n) */
226 static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
227                                         const BIGNUM *a, const BIGNUM *n,
228                                         BN_CTX *ctx);
229 
BN_mod_inverse_ex(BIGNUM * out,int * out_no_inverse,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)230 BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
231                           const BIGNUM *n, BN_CTX *ctx) {
232   BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
233   BIGNUM *ret = NULL;
234   int sign;
235 
236   if ((a->flags & BN_FLG_CONSTTIME) != 0 ||
237       (n->flags & BN_FLG_CONSTTIME) != 0) {
238     return BN_mod_inverse_no_branch(out, out_no_inverse, a, n, ctx);
239   }
240 
241   *out_no_inverse = 0;
242 
243   BN_CTX_start(ctx);
244   A = BN_CTX_get(ctx);
245   B = BN_CTX_get(ctx);
246   X = BN_CTX_get(ctx);
247   D = BN_CTX_get(ctx);
248   M = BN_CTX_get(ctx);
249   Y = BN_CTX_get(ctx);
250   T = BN_CTX_get(ctx);
251   if (T == NULL) {
252     goto err;
253   }
254 
255   if (out == NULL) {
256     R = BN_new();
257   } else {
258     R = out;
259   }
260   if (R == NULL) {
261     goto err;
262   }
263 
264   BN_zero(Y);
265   if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
266     goto err;
267   }
268   A->neg = 0;
269   if (B->neg || (BN_ucmp(B, A) >= 0)) {
270     if (!BN_nnmod(B, B, A, ctx)) {
271       goto err;
272     }
273   }
274   sign = -1;
275   /* From  B = a mod |n|,  A = |n|  it follows that
276    *
277    *      0 <= B < A,
278    *     -sign*X*a  ==  B   (mod |n|),
279    *      sign*Y*a  ==  A   (mod |n|).
280    */
281 
282   if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS2 <= 32 ? 450 : 2048))) {
283     /* Binary inversion algorithm; requires odd modulus.
284      * This is faster than the general algorithm if the modulus
285      * is sufficiently small (about 400 .. 500 bits on 32-bit
286      * sytems, but much more on 64-bit systems) */
287     int shift;
288 
289     while (!BN_is_zero(B)) {
290       /*      0 < B < |n|,
291        *      0 < A <= |n|,
292        * (1) -sign*X*a  ==  B   (mod |n|),
293        * (2)  sign*Y*a  ==  A   (mod |n|) */
294 
295       /* Now divide  B  by the maximum possible power of two in the integers,
296        * and divide  X  by the same value mod |n|.
297        * When we're done, (1) still holds. */
298       shift = 0;
299       while (!BN_is_bit_set(B, shift)) {
300         /* note that 0 < B */
301         shift++;
302 
303         if (BN_is_odd(X)) {
304           if (!BN_uadd(X, X, n)) {
305             goto err;
306           }
307         }
308         /* now X is even, so we can easily divide it by two */
309         if (!BN_rshift1(X, X)) {
310           goto err;
311         }
312       }
313       if (shift > 0) {
314         if (!BN_rshift(B, B, shift)) {
315           goto err;
316         }
317       }
318 
319       /* Same for A and Y. Afterwards, (2) still holds. */
320       shift = 0;
321       while (!BN_is_bit_set(A, shift)) {
322         /* note that 0 < A */
323         shift++;
324 
325         if (BN_is_odd(Y)) {
326           if (!BN_uadd(Y, Y, n)) {
327             goto err;
328           }
329         }
330         /* now Y is even */
331         if (!BN_rshift1(Y, Y)) {
332           goto err;
333         }
334       }
335       if (shift > 0) {
336         if (!BN_rshift(A, A, shift)) {
337           goto err;
338         }
339       }
340 
341       /* We still have (1) and (2).
342        * Both  A  and  B  are odd.
343        * The following computations ensure that
344        *
345        *     0 <= B < |n|,
346        *      0 < A < |n|,
347        * (1) -sign*X*a  ==  B   (mod |n|),
348        * (2)  sign*Y*a  ==  A   (mod |n|),
349        *
350        * and that either  A  or  B  is even in the next iteration. */
351       if (BN_ucmp(B, A) >= 0) {
352         /* -sign*(X + Y)*a == B - A  (mod |n|) */
353         if (!BN_uadd(X, X, Y)) {
354           goto err;
355         }
356         /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
357          * actually makes the algorithm slower */
358         if (!BN_usub(B, B, A)) {
359           goto err;
360         }
361       } else {
362         /*  sign*(X + Y)*a == A - B  (mod |n|) */
363         if (!BN_uadd(Y, Y, X)) {
364           goto err;
365         }
366         /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
367         if (!BN_usub(A, A, B)) {
368           goto err;
369         }
370       }
371     }
372   } else {
373     /* general inversion algorithm */
374 
375     while (!BN_is_zero(B)) {
376       BIGNUM *tmp;
377 
378       /*
379        *      0 < B < A,
380        * (*) -sign*X*a  ==  B   (mod |n|),
381        *      sign*Y*a  ==  A   (mod |n|) */
382 
383       /* (D, M) := (A/B, A%B) ... */
384       if (BN_num_bits(A) == BN_num_bits(B)) {
385         if (!BN_one(D)) {
386           goto err;
387         }
388         if (!BN_sub(M, A, B)) {
389           goto err;
390         }
391       } else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
392         /* A/B is 1, 2, or 3 */
393         if (!BN_lshift1(T, B)) {
394           goto err;
395         }
396         if (BN_ucmp(A, T) < 0) {
397           /* A < 2*B, so D=1 */
398           if (!BN_one(D)) {
399             goto err;
400           }
401           if (!BN_sub(M, A, B)) {
402             goto err;
403           }
404         } else {
405           /* A >= 2*B, so D=2 or D=3 */
406           if (!BN_sub(M, A, T)) {
407             goto err;
408           }
409           if (!BN_add(D, T, B)) {
410             goto err; /* use D (:= 3*B) as temp */
411           }
412           if (BN_ucmp(A, D) < 0) {
413             /* A < 3*B, so D=2 */
414             if (!BN_set_word(D, 2)) {
415               goto err;
416             }
417             /* M (= A - 2*B) already has the correct value */
418           } else {
419             /* only D=3 remains */
420             if (!BN_set_word(D, 3)) {
421               goto err;
422             }
423             /* currently  M = A - 2*B,  but we need  M = A - 3*B */
424             if (!BN_sub(M, M, B)) {
425               goto err;
426             }
427           }
428         }
429       } else {
430         if (!BN_div(D, M, A, B, ctx)) {
431           goto err;
432         }
433       }
434 
435       /* Now
436        *      A = D*B + M;
437        * thus we have
438        * (**)  sign*Y*a  ==  D*B + M   (mod |n|). */
439 
440       tmp = A; /* keep the BIGNUM object, the value does not matter */
441 
442       /* (A, B) := (B, A mod B) ... */
443       A = B;
444       B = M;
445       /* ... so we have  0 <= B < A  again */
446 
447       /* Since the former  M  is now  B  and the former  B  is now  A,
448        * (**) translates into
449        *       sign*Y*a  ==  D*A + B    (mod |n|),
450        * i.e.
451        *       sign*Y*a - D*A  ==  B    (mod |n|).
452        * Similarly, (*) translates into
453        *      -sign*X*a  ==  A          (mod |n|).
454        *
455        * Thus,
456        *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
457        * i.e.
458        *        sign*(Y + D*X)*a  ==  B  (mod |n|).
459        *
460        * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
461        *      -sign*X*a  ==  B   (mod |n|),
462        *       sign*Y*a  ==  A   (mod |n|).
463        * Note that  X  and  Y  stay non-negative all the time. */
464 
465       /* most of the time D is very small, so we can optimize tmp := D*X+Y */
466       if (BN_is_one(D)) {
467         if (!BN_add(tmp, X, Y)) {
468           goto err;
469         }
470       } else {
471         if (BN_is_word(D, 2)) {
472           if (!BN_lshift1(tmp, X)) {
473             goto err;
474           }
475         } else if (BN_is_word(D, 4)) {
476           if (!BN_lshift(tmp, X, 2)) {
477             goto err;
478           }
479         } else if (D->top == 1) {
480           if (!BN_copy(tmp, X)) {
481             goto err;
482           }
483           if (!BN_mul_word(tmp, D->d[0])) {
484             goto err;
485           }
486         } else {
487           if (!BN_mul(tmp, D, X, ctx)) {
488             goto err;
489           }
490         }
491         if (!BN_add(tmp, tmp, Y)) {
492           goto err;
493         }
494       }
495 
496       M = Y; /* keep the BIGNUM object, the value does not matter */
497       Y = X;
498       X = tmp;
499       sign = -sign;
500     }
501   }
502 
503   /* The while loop (Euclid's algorithm) ends when
504    *      A == gcd(a,n);
505    * we have
506    *       sign*Y*a  ==  A  (mod |n|),
507    * where  Y  is non-negative. */
508 
509   if (sign < 0) {
510     if (!BN_sub(Y, n, Y)) {
511       goto err;
512     }
513   }
514   /* Now  Y*a  ==  A  (mod |n|).  */
515 
516   if (BN_is_one(A)) {
517     /* Y*a == 1  (mod |n|) */
518     if (!Y->neg && BN_ucmp(Y, n) < 0) {
519       if (!BN_copy(R, Y)) {
520         goto err;
521       }
522     } else {
523       if (!BN_nnmod(R, Y, n, ctx)) {
524         goto err;
525       }
526     }
527   } else {
528     *out_no_inverse = 1;
529     OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
530     goto err;
531   }
532   ret = R;
533 
534 err:
535   if (ret == NULL && out == NULL) {
536     BN_free(R);
537   }
538   BN_CTX_end(ctx);
539   return ret;
540 }
541 
BN_mod_inverse(BIGNUM * out,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)542 BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
543                        BN_CTX *ctx) {
544   int no_inverse;
545   return BN_mod_inverse_ex(out, &no_inverse, a, n, ctx);
546 }
547 
548 /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
549  * It does not contain branches that may leak sensitive information. */
BN_mod_inverse_no_branch(BIGNUM * out,int * out_no_inverse,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)550 static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
551                                         const BIGNUM *a, const BIGNUM *n,
552                                         BN_CTX *ctx) {
553   BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
554   BIGNUM local_A, local_B;
555   BIGNUM *pA, *pB;
556   BIGNUM *ret = NULL;
557   int sign;
558 
559   *out_no_inverse = 0;
560 
561   BN_CTX_start(ctx);
562   A = BN_CTX_get(ctx);
563   B = BN_CTX_get(ctx);
564   X = BN_CTX_get(ctx);
565   D = BN_CTX_get(ctx);
566   M = BN_CTX_get(ctx);
567   Y = BN_CTX_get(ctx);
568   T = BN_CTX_get(ctx);
569   if (T == NULL) {
570     goto err;
571   }
572 
573   if (out == NULL) {
574     R = BN_new();
575   } else {
576     R = out;
577   }
578   if (R == NULL) {
579     goto err;
580   }
581 
582   BN_zero(Y);
583   if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
584     goto err;
585   }
586   A->neg = 0;
587 
588   if (B->neg || (BN_ucmp(B, A) >= 0)) {
589     /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
590      * BN_div_no_branch will be called eventually.
591      */
592     pB = &local_B;
593     BN_with_flags(pB, B, BN_FLG_CONSTTIME);
594     if (!BN_nnmod(B, pB, A, ctx)) {
595       goto err;
596     }
597   }
598   sign = -1;
599   /* From  B = a mod |n|,  A = |n|  it follows that
600    *
601    *      0 <= B < A,
602    *     -sign*X*a  ==  B   (mod |n|),
603    *      sign*Y*a  ==  A   (mod |n|).
604    */
605 
606   while (!BN_is_zero(B)) {
607     BIGNUM *tmp;
608 
609     /*
610      *      0 < B < A,
611      * (*) -sign*X*a  ==  B   (mod |n|),
612      *      sign*Y*a  ==  A   (mod |n|)
613      */
614 
615     /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
616      * BN_div_no_branch will be called eventually.
617      */
618     pA = &local_A;
619     BN_with_flags(pA, A, BN_FLG_CONSTTIME);
620 
621     /* (D, M) := (A/B, A%B) ... */
622     if (!BN_div(D, M, pA, B, ctx)) {
623       goto err;
624     }
625 
626     /* Now
627      *      A = D*B + M;
628      * thus we have
629      * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
630      */
631 
632     tmp = A; /* keep the BIGNUM object, the value does not matter */
633 
634     /* (A, B) := (B, A mod B) ... */
635     A = B;
636     B = M;
637     /* ... so we have  0 <= B < A  again */
638 
639     /* Since the former  M  is now  B  and the former  B  is now  A,
640      * (**) translates into
641      *       sign*Y*a  ==  D*A + B    (mod |n|),
642      * i.e.
643      *       sign*Y*a - D*A  ==  B    (mod |n|).
644      * Similarly, (*) translates into
645      *      -sign*X*a  ==  A          (mod |n|).
646      *
647      * Thus,
648      *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
649      * i.e.
650      *        sign*(Y + D*X)*a  ==  B  (mod |n|).
651      *
652      * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
653      *      -sign*X*a  ==  B   (mod |n|),
654      *       sign*Y*a  ==  A   (mod |n|).
655      * Note that  X  and  Y  stay non-negative all the time.
656      */
657 
658     if (!BN_mul(tmp, D, X, ctx)) {
659       goto err;
660     }
661     if (!BN_add(tmp, tmp, Y)) {
662       goto err;
663     }
664 
665     M = Y; /* keep the BIGNUM object, the value does not matter */
666     Y = X;
667     X = tmp;
668     sign = -sign;
669   }
670 
671   /*
672    * The while loop (Euclid's algorithm) ends when
673    *      A == gcd(a,n);
674    * we have
675    *       sign*Y*a  ==  A  (mod |n|),
676    * where  Y  is non-negative.
677    */
678 
679   if (sign < 0) {
680     if (!BN_sub(Y, n, Y)) {
681       goto err;
682     }
683   }
684   /* Now  Y*a  ==  A  (mod |n|).  */
685 
686   if (BN_is_one(A)) {
687     /* Y*a == 1  (mod |n|) */
688     if (!Y->neg && BN_ucmp(Y, n) < 0) {
689       if (!BN_copy(R, Y)) {
690         goto err;
691       }
692     } else {
693       if (!BN_nnmod(R, Y, n, ctx)) {
694         goto err;
695       }
696     }
697   } else {
698     *out_no_inverse = 1;
699     OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
700     goto err;
701   }
702   ret = R;
703 
704 err:
705   if (ret == NULL && out == NULL) {
706     BN_free(R);
707   }
708 
709   BN_CTX_end(ctx);
710   return ret;
711 }
712