1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ci#include <stdio.h>
13e1051a39Sopenharmony_ci#include <openssl/bn.h>
14e1051a39Sopenharmony_ci#include "bn_local.h"
15e1051a39Sopenharmony_ci
16e1051a39Sopenharmony_ci/* X9.31 routines for prime derivation */
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ci/*
19e1051a39Sopenharmony_ci * X9.31 prime derivation. This is used to generate the primes pi (p1, p2,
20e1051a39Sopenharmony_ci * q1, q2) from a parameter Xpi by checking successive odd integers.
21e1051a39Sopenharmony_ci */
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_cistatic int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
24e1051a39Sopenharmony_ci                             BN_GENCB *cb)
25e1051a39Sopenharmony_ci{
26e1051a39Sopenharmony_ci    int i = 0, is_prime;
27e1051a39Sopenharmony_ci    if (!BN_copy(pi, Xpi))
28e1051a39Sopenharmony_ci        return 0;
29e1051a39Sopenharmony_ci    if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
30e1051a39Sopenharmony_ci        return 0;
31e1051a39Sopenharmony_ci    for (;;) {
32e1051a39Sopenharmony_ci        i++;
33e1051a39Sopenharmony_ci        BN_GENCB_call(cb, 0, i);
34e1051a39Sopenharmony_ci        /* NB 27 MR is specified in X9.31 */
35e1051a39Sopenharmony_ci        is_prime = BN_check_prime(pi, ctx, cb);
36e1051a39Sopenharmony_ci        if (is_prime < 0)
37e1051a39Sopenharmony_ci            return 0;
38e1051a39Sopenharmony_ci        if (is_prime)
39e1051a39Sopenharmony_ci            break;
40e1051a39Sopenharmony_ci        if (!BN_add_word(pi, 2))
41e1051a39Sopenharmony_ci            return 0;
42e1051a39Sopenharmony_ci    }
43e1051a39Sopenharmony_ci    BN_GENCB_call(cb, 2, i);
44e1051a39Sopenharmony_ci    return 1;
45e1051a39Sopenharmony_ci}
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_ci/*
48e1051a39Sopenharmony_ci * This is the main X9.31 prime derivation function. From parameters Xp1, Xp2
49e1051a39Sopenharmony_ci * and Xp derive the prime p. If the parameters p1 or p2 are not NULL they
50e1051a39Sopenharmony_ci * will be returned too: this is needed for testing.
51e1051a39Sopenharmony_ci */
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ciint BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
54e1051a39Sopenharmony_ci                            const BIGNUM *Xp, const BIGNUM *Xp1,
55e1051a39Sopenharmony_ci                            const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
56e1051a39Sopenharmony_ci                            BN_GENCB *cb)
57e1051a39Sopenharmony_ci{
58e1051a39Sopenharmony_ci    int ret = 0;
59e1051a39Sopenharmony_ci
60e1051a39Sopenharmony_ci    BIGNUM *t, *p1p2, *pm1;
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci    /* Only even e supported */
63e1051a39Sopenharmony_ci    if (!BN_is_odd(e))
64e1051a39Sopenharmony_ci        return 0;
65e1051a39Sopenharmony_ci
66e1051a39Sopenharmony_ci    BN_CTX_start(ctx);
67e1051a39Sopenharmony_ci    if (p1 == NULL)
68e1051a39Sopenharmony_ci        p1 = BN_CTX_get(ctx);
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_ci    if (p2 == NULL)
71e1051a39Sopenharmony_ci        p2 = BN_CTX_get(ctx);
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_ci    t = BN_CTX_get(ctx);
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci    p1p2 = BN_CTX_get(ctx);
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci    pm1 = BN_CTX_get(ctx);
78e1051a39Sopenharmony_ci
79e1051a39Sopenharmony_ci    if (pm1 == NULL)
80e1051a39Sopenharmony_ci        goto err;
81e1051a39Sopenharmony_ci
82e1051a39Sopenharmony_ci    if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
83e1051a39Sopenharmony_ci        goto err;
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_ci    if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
86e1051a39Sopenharmony_ci        goto err;
87e1051a39Sopenharmony_ci
88e1051a39Sopenharmony_ci    if (!BN_mul(p1p2, p1, p2, ctx))
89e1051a39Sopenharmony_ci        goto err;
90e1051a39Sopenharmony_ci
91e1051a39Sopenharmony_ci    /* First set p to value of Rp */
92e1051a39Sopenharmony_ci
93e1051a39Sopenharmony_ci    if (!BN_mod_inverse(p, p2, p1, ctx))
94e1051a39Sopenharmony_ci        goto err;
95e1051a39Sopenharmony_ci
96e1051a39Sopenharmony_ci    if (!BN_mul(p, p, p2, ctx))
97e1051a39Sopenharmony_ci        goto err;
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ci    if (!BN_mod_inverse(t, p1, p2, ctx))
100e1051a39Sopenharmony_ci        goto err;
101e1051a39Sopenharmony_ci
102e1051a39Sopenharmony_ci    if (!BN_mul(t, t, p1, ctx))
103e1051a39Sopenharmony_ci        goto err;
104e1051a39Sopenharmony_ci
105e1051a39Sopenharmony_ci    if (!BN_sub(p, p, t))
106e1051a39Sopenharmony_ci        goto err;
107e1051a39Sopenharmony_ci
108e1051a39Sopenharmony_ci    if (p->neg && !BN_add(p, p, p1p2))
109e1051a39Sopenharmony_ci        goto err;
110e1051a39Sopenharmony_ci
111e1051a39Sopenharmony_ci    /* p now equals Rp */
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_ci    if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
114e1051a39Sopenharmony_ci        goto err;
115e1051a39Sopenharmony_ci
116e1051a39Sopenharmony_ci    if (!BN_add(p, p, Xp))
117e1051a39Sopenharmony_ci        goto err;
118e1051a39Sopenharmony_ci
119e1051a39Sopenharmony_ci    /* p now equals Yp0 */
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci    for (;;) {
122e1051a39Sopenharmony_ci        int i = 1;
123e1051a39Sopenharmony_ci        BN_GENCB_call(cb, 0, i++);
124e1051a39Sopenharmony_ci        if (!BN_copy(pm1, p))
125e1051a39Sopenharmony_ci            goto err;
126e1051a39Sopenharmony_ci        if (!BN_sub_word(pm1, 1))
127e1051a39Sopenharmony_ci            goto err;
128e1051a39Sopenharmony_ci        if (!BN_gcd(t, pm1, e, ctx))
129e1051a39Sopenharmony_ci            goto err;
130e1051a39Sopenharmony_ci        if (BN_is_one(t)) {
131e1051a39Sopenharmony_ci            /*
132e1051a39Sopenharmony_ci             * X9.31 specifies 8 MR and 1 Lucas test or any prime test
133e1051a39Sopenharmony_ci             * offering similar or better guarantees 50 MR is considerably
134e1051a39Sopenharmony_ci             * better.
135e1051a39Sopenharmony_ci             */
136e1051a39Sopenharmony_ci            int r = BN_check_prime(p, ctx, cb);
137e1051a39Sopenharmony_ci            if (r < 0)
138e1051a39Sopenharmony_ci                goto err;
139e1051a39Sopenharmony_ci            if (r)
140e1051a39Sopenharmony_ci                break;
141e1051a39Sopenharmony_ci        }
142e1051a39Sopenharmony_ci        if (!BN_add(p, p, p1p2))
143e1051a39Sopenharmony_ci            goto err;
144e1051a39Sopenharmony_ci    }
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_ci    BN_GENCB_call(cb, 3, 0);
147e1051a39Sopenharmony_ci
148e1051a39Sopenharmony_ci    ret = 1;
149e1051a39Sopenharmony_ci
150e1051a39Sopenharmony_ci err:
151e1051a39Sopenharmony_ci
152e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
153e1051a39Sopenharmony_ci
154e1051a39Sopenharmony_ci    return ret;
155e1051a39Sopenharmony_ci}
156e1051a39Sopenharmony_ci
157e1051a39Sopenharmony_ci/*
158e1051a39Sopenharmony_ci * Generate pair of parameters Xp, Xq for X9.31 prime generation. Note: nbits
159e1051a39Sopenharmony_ci * parameter is sum of number of bits in both.
160e1051a39Sopenharmony_ci */
161e1051a39Sopenharmony_ci
162e1051a39Sopenharmony_ciint BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
163e1051a39Sopenharmony_ci{
164e1051a39Sopenharmony_ci    BIGNUM *t;
165e1051a39Sopenharmony_ci    int i;
166e1051a39Sopenharmony_ci    /*
167e1051a39Sopenharmony_ci     * Number of bits for each prime is of the form 512+128s for s = 0, 1,
168e1051a39Sopenharmony_ci     * ...
169e1051a39Sopenharmony_ci     */
170e1051a39Sopenharmony_ci    if ((nbits < 1024) || (nbits & 0xff))
171e1051a39Sopenharmony_ci        return 0;
172e1051a39Sopenharmony_ci    nbits >>= 1;
173e1051a39Sopenharmony_ci    /*
174e1051a39Sopenharmony_ci     * The random value Xp must be between sqrt(2) * 2^(nbits-1) and 2^nbits
175e1051a39Sopenharmony_ci     * - 1. By setting the top two bits we ensure that the lower bound is
176e1051a39Sopenharmony_ci     * exceeded.
177e1051a39Sopenharmony_ci     */
178e1051a39Sopenharmony_ci    if (!BN_priv_rand_ex(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, 0,
179e1051a39Sopenharmony_ci                         ctx))
180e1051a39Sopenharmony_ci        return 0;
181e1051a39Sopenharmony_ci
182e1051a39Sopenharmony_ci    BN_CTX_start(ctx);
183e1051a39Sopenharmony_ci    t = BN_CTX_get(ctx);
184e1051a39Sopenharmony_ci    if (t == NULL)
185e1051a39Sopenharmony_ci        goto err;
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_ci    for (i = 0; i < 1000; i++) {
188e1051a39Sopenharmony_ci        if (!BN_priv_rand_ex(Xq, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, 0,
189e1051a39Sopenharmony_ci                             ctx))
190e1051a39Sopenharmony_ci            goto err;
191e1051a39Sopenharmony_ci
192e1051a39Sopenharmony_ci        /* Check that |Xp - Xq| > 2^(nbits - 100) */
193e1051a39Sopenharmony_ci        if (!BN_sub(t, Xp, Xq))
194e1051a39Sopenharmony_ci            goto err;
195e1051a39Sopenharmony_ci        if (BN_num_bits(t) > (nbits - 100))
196e1051a39Sopenharmony_ci            break;
197e1051a39Sopenharmony_ci    }
198e1051a39Sopenharmony_ci
199e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
200e1051a39Sopenharmony_ci
201e1051a39Sopenharmony_ci    if (i < 1000)
202e1051a39Sopenharmony_ci        return 1;
203e1051a39Sopenharmony_ci
204e1051a39Sopenharmony_ci    return 0;
205e1051a39Sopenharmony_ci
206e1051a39Sopenharmony_ci err:
207e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
208e1051a39Sopenharmony_ci    return 0;
209e1051a39Sopenharmony_ci}
210e1051a39Sopenharmony_ci
211e1051a39Sopenharmony_ci/*
212e1051a39Sopenharmony_ci * Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 and
213e1051a39Sopenharmony_ci * Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL the
214e1051a39Sopenharmony_ci * relevant parameter will be stored in it. Due to the fact that |Xp - Xq| >
215e1051a39Sopenharmony_ci * 2^(nbits - 100) must be satisfied Xp and Xq are generated using the
216e1051a39Sopenharmony_ci * previous function and supplied as input.
217e1051a39Sopenharmony_ci */
218e1051a39Sopenharmony_ci
219e1051a39Sopenharmony_ciint BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
220e1051a39Sopenharmony_ci                              BIGNUM *Xp1, BIGNUM *Xp2,
221e1051a39Sopenharmony_ci                              const BIGNUM *Xp,
222e1051a39Sopenharmony_ci                              const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
223e1051a39Sopenharmony_ci{
224e1051a39Sopenharmony_ci    int ret = 0;
225e1051a39Sopenharmony_ci
226e1051a39Sopenharmony_ci    BN_CTX_start(ctx);
227e1051a39Sopenharmony_ci    if (Xp1 == NULL)
228e1051a39Sopenharmony_ci        Xp1 = BN_CTX_get(ctx);
229e1051a39Sopenharmony_ci    if (Xp2 == NULL)
230e1051a39Sopenharmony_ci        Xp2 = BN_CTX_get(ctx);
231e1051a39Sopenharmony_ci    if (Xp1 == NULL || Xp2 == NULL)
232e1051a39Sopenharmony_ci        goto error;
233e1051a39Sopenharmony_ci
234e1051a39Sopenharmony_ci    if (!BN_priv_rand_ex(Xp1, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, 0, ctx))
235e1051a39Sopenharmony_ci        goto error;
236e1051a39Sopenharmony_ci    if (!BN_priv_rand_ex(Xp2, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, 0, ctx))
237e1051a39Sopenharmony_ci        goto error;
238e1051a39Sopenharmony_ci    if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
239e1051a39Sopenharmony_ci        goto error;
240e1051a39Sopenharmony_ci
241e1051a39Sopenharmony_ci    ret = 1;
242e1051a39Sopenharmony_ci
243e1051a39Sopenharmony_ci error:
244e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
245e1051a39Sopenharmony_ci
246e1051a39Sopenharmony_ci    return ret;
247e1051a39Sopenharmony_ci
248e1051a39Sopenharmony_ci}
249