Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/bn/bn_gcd.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the OpenSSL license (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include "internal/cryptlib.h"
11
#include "bn_lcl.h"
12
13
static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
14
15
int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
16
0
{
17
0
    BIGNUM *a, *b, *t;
18
0
    int ret = 0;
19
0
20
0
    bn_check_top(in_a);
21
0
    bn_check_top(in_b);
22
0
23
0
    BN_CTX_start(ctx);
24
0
    a = BN_CTX_get(ctx);
25
0
    b = BN_CTX_get(ctx);
26
0
    if (b == NULL)
27
0
        goto err;
28
0
29
0
    if (BN_copy(a, in_a) == NULL)
30
0
        goto err;
31
0
    if (BN_copy(b, in_b) == NULL)
32
0
        goto err;
33
0
    a->neg = 0;
34
0
    b->neg = 0;
35
0
36
0
    if (BN_cmp(a, b) < 0) {
37
0
        t = a;
38
0
        a = b;
39
0
        b = t;
40
0
    }
41
0
    t = euclid(a, b);
42
0
    if (t == NULL)
43
0
        goto err;
44
0
45
0
    if (BN_copy(r, t) == NULL)
46
0
        goto err;
47
0
    ret = 1;
48
0
 err:
49
0
    BN_CTX_end(ctx);
50
0
    bn_check_top(r);
51
0
    return ret;
52
0
}
53
54
static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
55
0
{
56
0
    BIGNUM *t;
57
0
    int shifts = 0;
58
0
59
0
    bn_check_top(a);
60
0
    bn_check_top(b);
61
0
62
0
    /* 0 <= b <= a */
63
0
    while (!BN_is_zero(b)) {
64
0
        /* 0 < b <= a */
65
0
66
0
        if (BN_is_odd(a)) {
67
0
            if (BN_is_odd(b)) {
68
0
                if (!BN_sub(a, a, b))
69
0
                    goto err;
70
0
                if (!BN_rshift1(a, a))
71
0
                    goto err;
72
0
                if (BN_cmp(a, b) < 0) {
73
0
                    t = a;
74
0
                    a = b;
75
0
                    b = t;
76
0
                }
77
0
            } else {            /* a odd - b even */
78
0
79
0
                if (!BN_rshift1(b, b))
80
0
                    goto err;
81
0
                if (BN_cmp(a, b) < 0) {
82
0
                    t = a;
83
0
                    a = b;
84
0
                    b = t;
85
0
                }
86
0
            }
87
0
        } else {                /* a is even */
88
0
89
0
            if (BN_is_odd(b)) {
90
0
                if (!BN_rshift1(a, a))
91
0
                    goto err;
92
0
                if (BN_cmp(a, b) < 0) {
93
0
                    t = a;
94
0
                    a = b;
95
0
                    b = t;
96
0
                }
97
0
            } else {            /* a even - b even */
98
0
99
0
                if (!BN_rshift1(a, a))
100
0
                    goto err;
101
0
                if (!BN_rshift1(b, b))
102
0
                    goto err;
103
0
                shifts++;
104
0
            }
105
0
        }
106
0
        /* 0 <= b <= a */
107
0
    }
108
0
109
0
    if (shifts) {
110
0
        if (!BN_lshift(a, a, shifts))
111
0
            goto err;
112
0
    }
113
0
    bn_check_top(a);
114
0
    return a;
115
0
 err:
116
0
    return NULL;
117
0
}
118
119
/* solves ax == 1 (mod n) */
120
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
121
                                        const BIGNUM *a, const BIGNUM *n,
122
                                        BN_CTX *ctx);
123
124
BIGNUM *BN_mod_inverse(BIGNUM *in,
125
                       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
126
0
{
127
0
    BIGNUM *rv;
128
0
    int noinv;
129
0
    rv = int_bn_mod_inverse(in, a, n, ctx, &noinv);
130
0
    if (noinv)
131
0
        BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE);
132
0
    return rv;
133
0
}
134
135
BIGNUM *int_bn_mod_inverse(BIGNUM *in,
136
                           const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
137
                           int *pnoinv)
138
0
{
139
0
    BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
140
0
    BIGNUM *ret = NULL;
141
0
    int sign;
142
0
143
0
    /* This is invalid input so we don't worry about constant time here */
144
0
    if (BN_abs_is_word(n, 1) || BN_is_zero(n)) {
145
0
        if (pnoinv != NULL)
146
0
            *pnoinv = 1;
147
0
        return NULL;
148
0
    }
149
0
150
0
    if (pnoinv != NULL)
151
0
        *pnoinv = 0;
152
0
153
0
    if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0)
154
0
        || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) {
155
0
        return BN_mod_inverse_no_branch(in, a, n, ctx);
156
0
    }
157
0
158
0
    bn_check_top(a);
159
0
    bn_check_top(n);
160
0
161
0
    BN_CTX_start(ctx);
162
0
    A = BN_CTX_get(ctx);
163
0
    B = BN_CTX_get(ctx);
164
0
    X = BN_CTX_get(ctx);
165
0
    D = BN_CTX_get(ctx);
166
0
    M = BN_CTX_get(ctx);
167
0
    Y = BN_CTX_get(ctx);
168
0
    T = BN_CTX_get(ctx);
169
0
    if (T == NULL)
170
0
        goto err;
171
0
172
0
    if (in == NULL)
173
0
        R = BN_new();
174
0
    else
175
0
        R = in;
176
0
    if (R == NULL)
177
0
        goto err;
178
0
179
0
    BN_one(X);
180
0
    BN_zero(Y);
181
0
    if (BN_copy(B, a) == NULL)
182
0
        goto err;
183
0
    if (BN_copy(A, n) == NULL)
184
0
        goto err;
185
0
    A->neg = 0;
186
0
    if (B->neg || (BN_ucmp(B, A) >= 0)) {
187
0
        if (!BN_nnmod(B, B, A, ctx))
188
0
            goto err;
189
0
    }
190
0
    sign = -1;
191
0
    /*-
192
0
     * From  B = a mod |n|,  A = |n|  it follows that
193
0
     *
194
0
     *      0 <= B < A,
195
0
     *     -sign*X*a  ==  B   (mod |n|),
196
0
     *      sign*Y*a  ==  A   (mod |n|).
197
0
     */
198
0
199
0
    if (BN_is_odd(n) && (BN_num_bits(n) <= 2048)) {
200
0
        /*
201
0
         * Binary inversion algorithm; requires odd modulus. This is faster
202
0
         * than the general algorithm if the modulus is sufficiently small
203
0
         * (about 400 .. 500 bits on 32-bit systems, but much more on 64-bit
204
0
         * systems)
205
0
         */
206
0
        int shift;
207
0
208
0
        while (!BN_is_zero(B)) {
209
0
            /*-
210
0
             *      0 < B < |n|,
211
0
             *      0 < A <= |n|,
212
0
             * (1) -sign*X*a  ==  B   (mod |n|),
213
0
             * (2)  sign*Y*a  ==  A   (mod |n|)
214
0
             */
215
0
216
0
            /*
217
0
             * Now divide B by the maximum possible power of two in the
218
0
             * integers, and divide X by the same value mod |n|. When we're
219
0
             * done, (1) still holds.
220
0
             */
221
0
            shift = 0;
222
0
            while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */
223
0
                shift++;
224
0
225
0
                if (BN_is_odd(X)) {
226
0
                    if (!BN_uadd(X, X, n))
227
0
                        goto err;
228
0
                }
229
0
                /*
230
0
                 * now X is even, so we can easily divide it by two
231
0
                 */
232
0
                if (!BN_rshift1(X, X))
233
0
                    goto err;
234
0
            }
235
0
            if (shift > 0) {
236
0
                if (!BN_rshift(B, B, shift))
237
0
                    goto err;
238
0
            }
239
0
240
0
            /*
241
0
             * Same for A and Y.  Afterwards, (2) still holds.
242
0
             */
243
0
            shift = 0;
244
0
            while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */
245
0
                shift++;
246
0
247
0
                if (BN_is_odd(Y)) {
248
0
                    if (!BN_uadd(Y, Y, n))
249
0
                        goto err;
250
0
                }
251
0
                /* now Y is even */
252
0
                if (!BN_rshift1(Y, Y))
253
0
                    goto err;
254
0
            }
255
0
            if (shift > 0) {
256
0
                if (!BN_rshift(A, A, shift))
257
0
                    goto err;
258
0
            }
259
0
260
0
            /*-
261
0
             * We still have (1) and (2).
262
0
             * Both  A  and  B  are odd.
263
0
             * The following computations ensure that
264
0
             *
265
0
             *     0 <= B < |n|,
266
0
             *      0 < A < |n|,
267
0
             * (1) -sign*X*a  ==  B   (mod |n|),
268
0
             * (2)  sign*Y*a  ==  A   (mod |n|),
269
0
             *
270
0
             * and that either  A  or  B  is even in the next iteration.
271
0
             */
272
0
            if (BN_ucmp(B, A) >= 0) {
273
0
                /* -sign*(X + Y)*a == B - A  (mod |n|) */
274
0
                if (!BN_uadd(X, X, Y))
275
0
                    goto err;
276
0
                /*
277
0
                 * NB: we could use BN_mod_add_quick(X, X, Y, n), but that
278
0
                 * actually makes the algorithm slower
279
0
                 */
280
0
                if (!BN_usub(B, B, A))
281
0
                    goto err;
282
0
            } else {
283
0
                /*  sign*(X + Y)*a == A - B  (mod |n|) */
284
0
                if (!BN_uadd(Y, Y, X))
285
0
                    goto err;
286
0
                /*
287
0
                 * as above, BN_mod_add_quick(Y, Y, X, n) would slow things down
288
0
                 */
289
0
                if (!BN_usub(A, A, B))
290
0
                    goto err;
291
0
            }
292
0
        }
293
0
    } else {
294
0
        /* general inversion algorithm */
295
0
296
0
        while (!BN_is_zero(B)) {
297
0
            BIGNUM *tmp;
298
0
299
0
            /*-
300
0
             *      0 < B < A,
301
0
             * (*) -sign*X*a  ==  B   (mod |n|),
302
0
             *      sign*Y*a  ==  A   (mod |n|)
303
0
             */
304
0
305
0
            /* (D, M) := (A/B, A%B) ... */
306
0
            if (BN_num_bits(A) == BN_num_bits(B)) {
307
0
                if (!BN_one(D))
308
0
                    goto err;
309
0
                if (!BN_sub(M, A, B))
310
0
                    goto err;
311
0
            } else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
312
0
                /* A/B is 1, 2, or 3 */
313
0
                if (!BN_lshift1(T, B))
314
0
                    goto err;
315
0
                if (BN_ucmp(A, T) < 0) {
316
0
                    /* A < 2*B, so D=1 */
317
0
                    if (!BN_one(D))
318
0
                        goto err;
319
0
                    if (!BN_sub(M, A, B))
320
0
                        goto err;
321
0
                } else {
322
0
                    /* A >= 2*B, so D=2 or D=3 */
323
0
                    if (!BN_sub(M, A, T))
324
0
                        goto err;
325
0
                    if (!BN_add(D, T, B))
326
0
                        goto err; /* use D (:= 3*B) as temp */
327
0
                    if (BN_ucmp(A, D) < 0) {
328
0
                        /* A < 3*B, so D=2 */
329
0
                        if (!BN_set_word(D, 2))
330
0
                            goto err;
331
0
                        /*
332
0
                         * M (= A - 2*B) already has the correct value
333
0
                         */
334
0
                    } else {
335
0
                        /* only D=3 remains */
336
0
                        if (!BN_set_word(D, 3))
337
0
                            goto err;
338
0
                        /*
339
0
                         * currently M = A - 2*B, but we need M = A - 3*B
340
0
                         */
341
0
                        if (!BN_sub(M, M, B))
342
0
                            goto err;
343
0
                    }
344
0
                }
345
0
            } else {
346
0
                if (!BN_div(D, M, A, B, ctx))
347
0
                    goto err;
348
0
            }
349
0
350
0
            /*-
351
0
             * Now
352
0
             *      A = D*B + M;
353
0
             * thus we have
354
0
             * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
355
0
             */
356
0
357
0
            tmp = A;    /* keep the BIGNUM object, the value does not matter */
358
0
359
0
            /* (A, B) := (B, A mod B) ... */
360
0
            A = B;
361
0
            B = M;
362
0
            /* ... so we have  0 <= B < A  again */
363
0
364
0
            /*-
365
0
             * Since the former  M  is now  B  and the former  B  is now  A,
366
0
             * (**) translates into
367
0
             *       sign*Y*a  ==  D*A + B    (mod |n|),
368
0
             * i.e.
369
0
             *       sign*Y*a - D*A  ==  B    (mod |n|).
370
0
             * Similarly, (*) translates into
371
0
             *      -sign*X*a  ==  A          (mod |n|).
372
0
             *
373
0
             * Thus,
374
0
             *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
375
0
             * i.e.
376
0
             *        sign*(Y + D*X)*a  ==  B  (mod |n|).
377
0
             *
378
0
             * So if we set  (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
379
0
             *      -sign*X*a  ==  B   (mod |n|),
380
0
             *       sign*Y*a  ==  A   (mod |n|).
381
0
             * Note that  X  and  Y  stay non-negative all the time.
382
0
             */
383
0
384
0
            /*
385
0
             * most of the time D is very small, so we can optimize tmp := D*X+Y
386
0
             */
387
0
            if (BN_is_one(D)) {
388
0
                if (!BN_add(tmp, X, Y))
389
0
                    goto err;
390
0
            } else {
391
0
                if (BN_is_word(D, 2)) {
392
0
                    if (!BN_lshift1(tmp, X))
393
0
                        goto err;
394
0
                } else if (BN_is_word(D, 4)) {
395
0
                    if (!BN_lshift(tmp, X, 2))
396
0
                        goto err;
397
0
                } else if (D->top == 1) {
398
0
                    if (!BN_copy(tmp, X))
399
0
                        goto err;
400
0
                    if (!BN_mul_word(tmp, D->d[0]))
401
0
                        goto err;
402
0
                } else {
403
0
                    if (!BN_mul(tmp, D, X, ctx))
404
0
                        goto err;
405
0
                }
406
0
                if (!BN_add(tmp, tmp, Y))
407
0
                    goto err;
408
0
            }
409
0
410
0
            M = Y;      /* keep the BIGNUM object, the value does not matter */
411
0
            Y = X;
412
0
            X = tmp;
413
0
            sign = -sign;
414
0
        }
415
0
    }
416
0
417
0
    /*-
418
0
     * The while loop (Euclid's algorithm) ends when
419
0
     *      A == gcd(a,n);
420
0
     * we have
421
0
     *       sign*Y*a  ==  A  (mod |n|),
422
0
     * where  Y  is non-negative.
423
0
     */
424
0
425
0
    if (sign < 0) {
426
0
        if (!BN_sub(Y, n, Y))
427
0
            goto err;
428
0
    }
429
0
    /* Now  Y*a  ==  A  (mod |n|).  */
430
0
431
0
    if (BN_is_one(A)) {
432
0
        /* Y*a == 1  (mod |n|) */
433
0
        if (!Y->neg && BN_ucmp(Y, n) < 0) {
434
0
            if (!BN_copy(R, Y))
435
0
                goto err;
436
0
        } else {
437
0
            if (!BN_nnmod(R, Y, n, ctx))
438
0
                goto err;
439
0
        }
440
0
    } else {
441
0
        if (pnoinv)
442
0
            *pnoinv = 1;
443
0
        goto err;
444
0
    }
445
0
    ret = R;
446
0
 err:
447
0
    if ((ret == NULL) && (in == NULL))
448
0
        BN_free(R);
449
0
    BN_CTX_end(ctx);
450
0
    bn_check_top(ret);
451
0
    return ret;
452
0
}
453
454
/*
455
 * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does
456
 * not contain branches that may leak sensitive information.
457
 */
458
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
459
                                        const BIGNUM *a, const BIGNUM *n,
460
                                        BN_CTX *ctx)
461
0
{
462
0
    BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
463
0
    BIGNUM *ret = NULL;
464
0
    int sign;
465
0
466
0
    bn_check_top(a);
467
0
    bn_check_top(n);
468
0
469
0
    BN_CTX_start(ctx);
470
0
    A = BN_CTX_get(ctx);
471
0
    B = BN_CTX_get(ctx);
472
0
    X = BN_CTX_get(ctx);
473
0
    D = BN_CTX_get(ctx);
474
0
    M = BN_CTX_get(ctx);
475
0
    Y = BN_CTX_get(ctx);
476
0
    T = BN_CTX_get(ctx);
477
0
    if (T == NULL)
478
0
        goto err;
479
0
480
0
    if (in == NULL)
481
0
        R = BN_new();
482
0
    else
483
0
        R = in;
484
0
    if (R == NULL)
485
0
        goto err;
486
0
487
0
    BN_one(X);
488
0
    BN_zero(Y);
489
0
    if (BN_copy(B, a) == NULL)
490
0
        goto err;
491
0
    if (BN_copy(A, n) == NULL)
492
0
        goto err;
493
0
    A->neg = 0;
494
0
495
0
    if (B->neg || (BN_ucmp(B, A) >= 0)) {
496
0
        /*
497
0
         * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
498
0
         * BN_div_no_branch will be called eventually.
499
0
         */
500
0
         {
501
0
            BIGNUM local_B;
502
0
            bn_init(&local_B);
503
0
            BN_with_flags(&local_B, B, BN_FLG_CONSTTIME);
504
0
            if (!BN_nnmod(B, &local_B, A, ctx))
505
0
                goto err;
506
0
            /* Ensure local_B goes out of scope before any further use of B */
507
0
        }
508
0
    }
509
0
    sign = -1;
510
0
    /*-
511
0
     * From  B = a mod |n|,  A = |n|  it follows that
512
0
     *
513
0
     *      0 <= B < A,
514
0
     *     -sign*X*a  ==  B   (mod |n|),
515
0
     *      sign*Y*a  ==  A   (mod |n|).
516
0
     */
517
0
518
0
    while (!BN_is_zero(B)) {
519
0
        BIGNUM *tmp;
520
0
521
0
        /*-
522
0
         *      0 < B < A,
523
0
         * (*) -sign*X*a  ==  B   (mod |n|),
524
0
         *      sign*Y*a  ==  A   (mod |n|)
525
0
         */
526
0
527
0
        /*
528
0
         * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
529
0
         * BN_div_no_branch will be called eventually.
530
0
         */
531
0
        {
532
0
            BIGNUM local_A;
533
0
            bn_init(&local_A);
534
0
            BN_with_flags(&local_A, A, BN_FLG_CONSTTIME);
535
0
536
0
            /* (D, M) := (A/B, A%B) ... */
537
0
            if (!BN_div(D, M, &local_A, B, ctx))
538
0
                goto err;
539
0
            /* Ensure local_A goes out of scope before any further use of A */
540
0
        }
541
0
542
0
        /*-
543
0
         * Now
544
0
         *      A = D*B + M;
545
0
         * thus we have
546
0
         * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
547
0
         */
548
0
549
0
        tmp = A;                /* keep the BIGNUM object, the value does not
550
0
                                 * matter */
551
0
552
0
        /* (A, B) := (B, A mod B) ... */
553
0
        A = B;
554
0
        B = M;
555
0
        /* ... so we have  0 <= B < A  again */
556
0
557
0
        /*-
558
0
         * Since the former  M  is now  B  and the former  B  is now  A,
559
0
         * (**) translates into
560
0
         *       sign*Y*a  ==  D*A + B    (mod |n|),
561
0
         * i.e.
562
0
         *       sign*Y*a - D*A  ==  B    (mod |n|).
563
0
         * Similarly, (*) translates into
564
0
         *      -sign*X*a  ==  A          (mod |n|).
565
0
         *
566
0
         * Thus,
567
0
         *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
568
0
         * i.e.
569
0
         *        sign*(Y + D*X)*a  ==  B  (mod |n|).
570
0
         *
571
0
         * So if we set  (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
572
0
         *      -sign*X*a  ==  B   (mod |n|),
573
0
         *       sign*Y*a  ==  A   (mod |n|).
574
0
         * Note that  X  and  Y  stay non-negative all the time.
575
0
         */
576
0
577
0
        if (!BN_mul(tmp, D, X, ctx))
578
0
            goto err;
579
0
        if (!BN_add(tmp, tmp, Y))
580
0
            goto err;
581
0
582
0
        M = Y;                  /* keep the BIGNUM object, the value does not
583
0
                                 * matter */
584
0
        Y = X;
585
0
        X = tmp;
586
0
        sign = -sign;
587
0
    }
588
0
589
0
    /*-
590
0
     * The while loop (Euclid's algorithm) ends when
591
0
     *      A == gcd(a,n);
592
0
     * we have
593
0
     *       sign*Y*a  ==  A  (mod |n|),
594
0
     * where  Y  is non-negative.
595
0
     */
596
0
597
0
    if (sign < 0) {
598
0
        if (!BN_sub(Y, n, Y))
599
0
            goto err;
600
0
    }
601
0
    /* Now  Y*a  ==  A  (mod |n|).  */
602
0
603
0
    if (BN_is_one(A)) {
604
0
        /* Y*a == 1  (mod |n|) */
605
0
        if (!Y->neg && BN_ucmp(Y, n) < 0) {
606
0
            if (!BN_copy(R, Y))
607
0
                goto err;
608
0
        } else {
609
0
            if (!BN_nnmod(R, Y, n, ctx))
610
0
                goto err;
611
0
        }
612
0
    } else {
613
0
        BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE);
614
0
        goto err;
615
0
    }
616
0
    ret = R;
617
0
 err:
618
0
    if ((ret == NULL) && (in == NULL))
619
0
        BN_free(R);
620
0
    BN_CTX_end(ctx);
621
0
    bn_check_top(ret);
622
0
    return ret;
623
0
}