Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/bn/bn_prime.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/bn/bn_prime.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
/* ====================================================================
59
 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
60
 *
61
 * Redistribution and use in source and binary forms, with or without
62
 * modification, are permitted provided that the following conditions
63
 * are met:
64
 *
65
 * 1. Redistributions of source code must retain the above copyright
66
 *    notice, this list of conditions and the following disclaimer.
67
 *
68
 * 2. Redistributions in binary form must reproduce the above copyright
69
 *    notice, this list of conditions and the following disclaimer in
70
 *    the documentation and/or other materials provided with the
71
 *    distribution.
72
 *
73
 * 3. All advertising materials mentioning features or use of this
74
 *    software must display the following acknowledgment:
75
 *    "This product includes software developed by the OpenSSL Project
76
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77
 *
78
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79
 *    endorse or promote products derived from this software without
80
 *    prior written permission. For written permission, please contact
81
 *    openssl-core@openssl.org.
82
 *
83
 * 5. Products derived from this software may not be called "OpenSSL"
84
 *    nor may "OpenSSL" appear in their names without prior written
85
 *    permission of the OpenSSL Project.
86
 *
87
 * 6. Redistributions of any form whatsoever must retain the following
88
 *    acknowledgment:
89
 *    "This product includes software developed by the OpenSSL Project
90
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91
 *
92
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103
 * OF THE POSSIBILITY OF SUCH DAMAGE.
104
 * ====================================================================
105
 *
106
 * This product includes cryptographic software written by Eric Young
107
 * (eay@cryptsoft.com).  This product includes software written by Tim
108
 * Hudson (tjh@cryptsoft.com).
109
 *
110
 */
111
112
#include <stdio.h>
113
#include <time.h>
114
#include "cryptlib.h"
115
#include "bn_lcl.h"
116
#include <openssl/rand.h>
117
118
/*
119
 * NB: these functions have been "upgraded", the deprecated versions (which
120
 * are compatibility wrappers using these functions) are in bn_depr.c. -
121
 * Geoff
122
 */
123
124
/*
125
 * The quick sieve algorithm approach to weeding out primes is Philip
126
 * Zimmermann's, as implemented in PGP.  I have had a read of his comments
127
 * and implemented my own version.
128
 */
129
#include "bn_prime.h"
130
131
static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
132
                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
133
                   BN_MONT_CTX *mont);
134
static int probable_prime(BIGNUM *rnd, int bits);
135
static int probable_prime_dh(BIGNUM *rnd, int bits,
136
                             const BIGNUM *add, const BIGNUM *rem,
137
                             BN_CTX *ctx);
138
static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add,
139
                                  const BIGNUM *rem, BN_CTX *ctx);
140
141
int BN_GENCB_call(BN_GENCB *cb, int a, int b)
142
0
{
143
    /* No callback means continue */
144
0
    if (!cb)
145
0
        return 1;
146
0
    switch (cb->ver) {
147
0
    case 1:
148
        /* Deprecated-style callbacks */
149
0
        if (!cb->cb.cb_1)
150
0
            return 1;
151
0
        cb->cb.cb_1(a, b, cb->arg);
152
0
        return 1;
153
0
    case 2:
154
        /* New-style callbacks */
155
0
        return cb->cb.cb_2(a, b, cb);
156
0
    default:
157
0
        break;
158
0
    }
159
    /* Unrecognised callback type */
160
0
    return 0;
161
0
}
162
163
int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
164
                         const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
165
0
{
166
0
    BIGNUM *t;
167
0
    int found = 0;
168
0
    int i, j, c1 = 0;
169
0
    BN_CTX *ctx;
170
0
    int checks = BN_prime_checks_for_size(bits);
171
172
0
    ctx = BN_CTX_new();
173
0
    if (ctx == NULL)
174
0
        goto err;
175
0
    BN_CTX_start(ctx);
176
0
    t = BN_CTX_get(ctx);
177
0
    if (!t)
178
0
        goto err;
179
0
 loop:
180
    /* make a random number and set the top and bottom bits */
181
0
    if (add == NULL) {
182
0
        if (!probable_prime(ret, bits))
183
0
            goto err;
184
0
    } else {
185
0
        if (safe) {
186
0
            if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
187
0
                goto err;
188
0
        } else {
189
0
            if (!probable_prime_dh(ret, bits, add, rem, ctx))
190
0
                goto err;
191
0
        }
192
0
    }
193
    /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
194
0
    if (!BN_GENCB_call(cb, 0, c1++))
195
        /* aborted */
196
0
        goto err;
197
198
0
    if (!safe) {
199
0
        i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
200
0
        if (i == -1)
201
0
            goto err;
202
0
        if (i == 0)
203
0
            goto loop;
204
0
    } else {
205
        /*
206
         * for "safe prime" generation, check that (p-1)/2 is prime. Since a
207
         * prime is odd, We just need to divide by 2
208
         */
209
0
        if (!BN_rshift1(t, ret))
210
0
            goto err;
211
212
0
        for (i = 0; i < checks; i++) {
213
0
            j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
214
0
            if (j == -1)
215
0
                goto err;
216
0
            if (j == 0)
217
0
                goto loop;
218
219
0
            j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
220
0
            if (j == -1)
221
0
                goto err;
222
0
            if (j == 0)
223
0
                goto loop;
224
225
0
            if (!BN_GENCB_call(cb, 2, c1 - 1))
226
0
                goto err;
227
            /* We have a safe prime test pass */
228
0
        }
229
0
    }
230
    /* we have a prime :-) */
231
0
    found = 1;
232
0
 err:
233
0
    if (ctx != NULL) {
234
0
        BN_CTX_end(ctx);
235
0
        BN_CTX_free(ctx);
236
0
    }
237
0
    bn_check_top(ret);
238
0
    return found;
239
0
}
240
241
int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
242
                   BN_GENCB *cb)
243
0
{
244
0
    return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
245
0
}
246
247
int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
248
                            int do_trial_division, BN_GENCB *cb)
249
0
{
250
0
    int i, j, ret = -1;
251
0
    int k;
252
0
    BN_CTX *ctx = NULL;
253
0
    BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
254
0
    BN_MONT_CTX *mont = NULL;
255
256
0
    if (BN_cmp(a, BN_value_one()) <= 0)
257
0
        return 0;
258
259
0
    if (checks == BN_prime_checks)
260
0
        checks = BN_prime_checks_for_size(BN_num_bits(a));
261
262
    /* first look for small factors */
263
0
    if (!BN_is_odd(a))
264
        /* a is even => a is prime if and only if a == 2 */
265
0
        return BN_is_word(a, 2);
266
0
    if (do_trial_division) {
267
0
        for (i = 1; i < NUMPRIMES; i++)
268
0
            if (BN_mod_word(a, primes[i]) == 0)
269
0
                return 0;
270
0
        if (!BN_GENCB_call(cb, 1, -1))
271
0
            goto err;
272
0
    }
273
274
0
    if (ctx_passed != NULL)
275
0
        ctx = ctx_passed;
276
0
    else if ((ctx = BN_CTX_new()) == NULL)
277
0
        goto err;
278
0
    BN_CTX_start(ctx);
279
280
0
    A1 = BN_CTX_get(ctx);
281
0
    A1_odd = BN_CTX_get(ctx);
282
0
    check = BN_CTX_get(ctx);
283
0
    if (check == NULL)
284
0
        goto err;
285
286
    /* compute A1 := a - 1 */
287
0
    if (!BN_copy(A1, a))
288
0
        goto err;
289
0
    if (!BN_sub_word(A1, 1))
290
0
        goto err;
291
0
    if (BN_is_zero(A1)) {
292
0
        ret = 0;
293
0
        goto err;
294
0
    }
295
296
    /* write  A1  as  A1_odd * 2^k */
297
0
    k = 1;
298
0
    while (!BN_is_bit_set(A1, k))
299
0
        k++;
300
0
    if (!BN_rshift(A1_odd, A1, k))
301
0
        goto err;
302
303
    /* Montgomery setup for computations mod a */
304
0
    mont = BN_MONT_CTX_new();
305
0
    if (mont == NULL)
306
0
        goto err;
307
0
    if (!BN_MONT_CTX_set(mont, a, ctx))
308
0
        goto err;
309
310
0
    for (i = 0; i < checks; i++) {
311
0
        if (!BN_pseudo_rand_range(check, A1))
312
0
            goto err;
313
0
        if (!BN_add_word(check, 1))
314
0
            goto err;
315
        /* now 1 <= check < a */
316
317
0
        j = witness(check, a, A1, A1_odd, k, ctx, mont);
318
0
        if (j == -1)
319
0
            goto err;
320
0
        if (j) {
321
0
            ret = 0;
322
0
            goto err;
323
0
        }
324
0
        if (!BN_GENCB_call(cb, 1, i))
325
0
            goto err;
326
0
    }
327
0
    ret = 1;
328
0
 err:
329
0
    if (ctx != NULL) {
330
0
        BN_CTX_end(ctx);
331
0
        if (ctx_passed == NULL)
332
0
            BN_CTX_free(ctx);
333
0
    }
334
0
    if (mont != NULL)
335
0
        BN_MONT_CTX_free(mont);
336
337
0
    return (ret);
338
0
}
339
340
static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
341
                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
342
                   BN_MONT_CTX *mont)
343
0
{
344
0
    if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
345
0
        return -1;
346
0
    if (BN_is_one(w))
347
0
        return 0;               /* probably prime */
348
0
    if (BN_cmp(w, a1) == 0)
349
0
        return 0;               /* w == -1 (mod a), 'a' is probably prime */
350
0
    while (--k) {
351
0
        if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
352
0
            return -1;
353
0
        if (BN_is_one(w))
354
0
            return 1;           /* 'a' is composite, otherwise a previous 'w'
355
                                 * would have been == -1 (mod 'a') */
356
0
        if (BN_cmp(w, a1) == 0)
357
0
            return 0;           /* w == -1 (mod a), 'a' is probably prime */
358
0
    }
359
    /*
360
     * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and
361
     * it is neither -1 nor +1 -- so 'a' cannot be prime
362
     */
363
0
    bn_check_top(w);
364
0
    return 1;
365
0
}
366
367
static int probable_prime(BIGNUM *rnd, int bits)
368
0
{
369
0
    int i;
370
0
    prime_t mods[NUMPRIMES];
371
0
    BN_ULONG delta, maxdelta;
372
373
0
 again:
374
0
    if (!BN_rand(rnd, bits, 1, 1))
375
0
        return (0);
376
    /* we now have a random number 'rand' to test. */
377
0
    for (i = 1; i < NUMPRIMES; i++)
378
0
        mods[i] = (prime_t) BN_mod_word(rnd, (BN_ULONG)primes[i]);
379
0
    maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
380
0
    delta = 0;
381
0
 loop:for (i = 1; i < NUMPRIMES; i++) {
382
        /*
383
         * check that rnd is not a prime and also that gcd(rnd-1,primes) == 1
384
         * (except for 2)
385
         */
386
0
        if (((mods[i] + delta) % primes[i]) <= 1) {
387
0
            delta += 2;
388
0
            if (delta > maxdelta)
389
0
                goto again;
390
0
            goto loop;
391
0
        }
392
0
    }
393
0
    if (!BN_add_word(rnd, delta))
394
0
        return (0);
395
0
    bn_check_top(rnd);
396
0
    return (1);
397
0
}
398
399
static int probable_prime_dh(BIGNUM *rnd, int bits,
400
                             const BIGNUM *add, const BIGNUM *rem,
401
                             BN_CTX *ctx)
402
0
{
403
0
    int i, ret = 0;
404
0
    BIGNUM *t1;
405
406
0
    BN_CTX_start(ctx);
407
0
    if ((t1 = BN_CTX_get(ctx)) == NULL)
408
0
        goto err;
409
410
0
    if (!BN_rand(rnd, bits, 0, 1))
411
0
        goto err;
412
413
    /* we need ((rnd-rem) % add) == 0 */
414
415
0
    if (!BN_mod(t1, rnd, add, ctx))
416
0
        goto err;
417
0
    if (!BN_sub(rnd, rnd, t1))
418
0
        goto err;
419
0
    if (rem == NULL) {
420
0
        if (!BN_add_word(rnd, 1))
421
0
            goto err;
422
0
    } else {
423
0
        if (!BN_add(rnd, rnd, rem))
424
0
            goto err;
425
0
    }
426
427
    /* we now have a random number 'rand' to test. */
428
429
0
 loop:for (i = 1; i < NUMPRIMES; i++) {
430
        /* check that rnd is a prime */
431
0
        if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) {
432
0
            if (!BN_add(rnd, rnd, add))
433
0
                goto err;
434
0
            goto loop;
435
0
        }
436
0
    }
437
0
    ret = 1;
438
0
 err:
439
0
    BN_CTX_end(ctx);
440
0
    bn_check_top(rnd);
441
0
    return (ret);
442
0
}
443
444
static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
445
                                  const BIGNUM *rem, BN_CTX *ctx)
446
0
{
447
0
    int i, ret = 0;
448
0
    BIGNUM *t1, *qadd, *q;
449
450
0
    bits--;
451
0
    BN_CTX_start(ctx);
452
0
    t1 = BN_CTX_get(ctx);
453
0
    q = BN_CTX_get(ctx);
454
0
    qadd = BN_CTX_get(ctx);
455
0
    if (qadd == NULL)
456
0
        goto err;
457
458
0
    if (!BN_rshift1(qadd, padd))
459
0
        goto err;
460
461
0
    if (!BN_rand(q, bits, 0, 1))
462
0
        goto err;
463
464
    /* we need ((rnd-rem) % add) == 0 */
465
0
    if (!BN_mod(t1, q, qadd, ctx))
466
0
        goto err;
467
0
    if (!BN_sub(q, q, t1))
468
0
        goto err;
469
0
    if (rem == NULL) {
470
0
        if (!BN_add_word(q, 1))
471
0
            goto err;
472
0
    } else {
473
0
        if (!BN_rshift1(t1, rem))
474
0
            goto err;
475
0
        if (!BN_add(q, q, t1))
476
0
            goto err;
477
0
    }
478
479
    /* we now have a random number 'rand' to test. */
480
0
    if (!BN_lshift1(p, q))
481
0
        goto err;
482
0
    if (!BN_add_word(p, 1))
483
0
        goto err;
484
485
0
 loop:for (i = 1; i < NUMPRIMES; i++) {
486
        /* check that p and q are prime */
487
        /*
488
         * check that for p and q gcd(p-1,primes) == 1 (except for 2)
489
         */
490
0
        if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) ||
491
0
            (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) {
492
0
            if (!BN_add(p, p, padd))
493
0
                goto err;
494
0
            if (!BN_add(q, q, qadd))
495
0
                goto err;
496
0
            goto loop;
497
0
        }
498
0
    }
499
0
    ret = 1;
500
0
 err:
501
0
    BN_CTX_end(ctx);
502
0
    bn_check_top(p);
503
0
    return (ret);
504
0
}