1206b73d0SCy Schubert /*
2206b73d0SCy Schubert * Shared Dragonfly functionality
3206b73d0SCy Schubert * Copyright (c) 2012-2016, Jouni Malinen <j@w1.fi>
4206b73d0SCy Schubert * Copyright (c) 2019, The Linux Foundation
5206b73d0SCy Schubert *
6206b73d0SCy Schubert * This software may be distributed under the terms of the BSD license.
7206b73d0SCy Schubert * See README for more details.
8206b73d0SCy Schubert */
9206b73d0SCy Schubert
10206b73d0SCy Schubert #include "utils/includes.h"
11206b73d0SCy Schubert
12206b73d0SCy Schubert #include "utils/common.h"
13206b73d0SCy Schubert #include "utils/const_time.h"
14206b73d0SCy Schubert #include "crypto/crypto.h"
15206b73d0SCy Schubert #include "dragonfly.h"
16206b73d0SCy Schubert
17206b73d0SCy Schubert
dragonfly_suitable_group(int group,int ecc_only)18206b73d0SCy Schubert int dragonfly_suitable_group(int group, int ecc_only)
19206b73d0SCy Schubert {
20206b73d0SCy Schubert /* Enforce REVmd rules on which SAE groups are suitable for production
21206b73d0SCy Schubert * purposes: FFC groups whose prime is >= 3072 bits and ECC groups
22206b73d0SCy Schubert * defined over a prime field whose prime is >= 256 bits. Furthermore,
23206b73d0SCy Schubert * ECC groups defined over a characteristic 2 finite field and ECC
24206b73d0SCy Schubert * groups with a co-factor greater than 1 are not suitable. Disable
25206b73d0SCy Schubert * groups that use Brainpool curves as well for now since they leak more
26206b73d0SCy Schubert * timing information due to the prime not being close to a power of
27206b73d0SCy Schubert * two. */
28206b73d0SCy Schubert return group == 19 || group == 20 || group == 21 ||
29206b73d0SCy Schubert (!ecc_only &&
30206b73d0SCy Schubert (group == 15 || group == 16 || group == 17 || group == 18));
31206b73d0SCy Schubert }
32206b73d0SCy Schubert
33206b73d0SCy Schubert
dragonfly_min_pwe_loop_iter(int group)34206b73d0SCy Schubert unsigned int dragonfly_min_pwe_loop_iter(int group)
35206b73d0SCy Schubert {
36206b73d0SCy Schubert if (group == 22 || group == 23 || group == 24) {
37206b73d0SCy Schubert /* FFC groups for which pwd-value is likely to be >= p
38206b73d0SCy Schubert * frequently */
39206b73d0SCy Schubert return 40;
40206b73d0SCy Schubert }
41206b73d0SCy Schubert
42206b73d0SCy Schubert if (group == 1 || group == 2 || group == 5 || group == 14 ||
43206b73d0SCy Schubert group == 15 || group == 16 || group == 17 || group == 18) {
44206b73d0SCy Schubert /* FFC groups that have prime that is close to a power of two */
45206b73d0SCy Schubert return 1;
46206b73d0SCy Schubert }
47206b73d0SCy Schubert
48206b73d0SCy Schubert /* Default to 40 (this covers most ECC groups) */
49206b73d0SCy Schubert return 40;
50206b73d0SCy Schubert }
51206b73d0SCy Schubert
52206b73d0SCy Schubert
dragonfly_get_random_qr_qnr(const struct crypto_bignum * prime,struct crypto_bignum ** qr,struct crypto_bignum ** qnr)53206b73d0SCy Schubert int dragonfly_get_random_qr_qnr(const struct crypto_bignum *prime,
54206b73d0SCy Schubert struct crypto_bignum **qr,
55206b73d0SCy Schubert struct crypto_bignum **qnr)
56206b73d0SCy Schubert {
57206b73d0SCy Schubert *qr = *qnr = NULL;
58206b73d0SCy Schubert
59206b73d0SCy Schubert while (!(*qr) || !(*qnr)) {
60206b73d0SCy Schubert struct crypto_bignum *tmp;
61206b73d0SCy Schubert int res;
62206b73d0SCy Schubert
63206b73d0SCy Schubert tmp = crypto_bignum_init();
64206b73d0SCy Schubert if (!tmp || crypto_bignum_rand(tmp, prime) < 0) {
65206b73d0SCy Schubert crypto_bignum_deinit(tmp, 0);
66206b73d0SCy Schubert break;
67206b73d0SCy Schubert }
68206b73d0SCy Schubert
69206b73d0SCy Schubert res = crypto_bignum_legendre(tmp, prime);
70*a90b9d01SCy Schubert if (res == 1 && !(*qr)) {
71206b73d0SCy Schubert *qr = tmp;
72*a90b9d01SCy Schubert } else if (res == -1 && !(*qnr)) {
73206b73d0SCy Schubert *qnr = tmp;
74*a90b9d01SCy Schubert } else {
75206b73d0SCy Schubert crypto_bignum_deinit(tmp, 0);
76*a90b9d01SCy Schubert if (res == -2)
77*a90b9d01SCy Schubert break;
78*a90b9d01SCy Schubert }
79206b73d0SCy Schubert }
80206b73d0SCy Schubert
81206b73d0SCy Schubert if (*qr && *qnr)
82206b73d0SCy Schubert return 0;
83206b73d0SCy Schubert crypto_bignum_deinit(*qr, 0);
84206b73d0SCy Schubert crypto_bignum_deinit(*qnr, 0);
85206b73d0SCy Schubert *qr = *qnr = NULL;
86206b73d0SCy Schubert return -1;
87206b73d0SCy Schubert }
88206b73d0SCy Schubert
89206b73d0SCy Schubert
90206b73d0SCy Schubert static struct crypto_bignum *
dragonfly_get_rand_1_to_p_1(const struct crypto_bignum * prime)91206b73d0SCy Schubert dragonfly_get_rand_1_to_p_1(const struct crypto_bignum *prime)
92206b73d0SCy Schubert {
93206b73d0SCy Schubert struct crypto_bignum *tmp, *pm1, *one;
94206b73d0SCy Schubert
95206b73d0SCy Schubert tmp = crypto_bignum_init();
96206b73d0SCy Schubert pm1 = crypto_bignum_init();
97206b73d0SCy Schubert one = crypto_bignum_init_set((const u8 *) "\x01", 1);
98206b73d0SCy Schubert if (!tmp || !pm1 || !one ||
99206b73d0SCy Schubert crypto_bignum_sub(prime, one, pm1) < 0 ||
100206b73d0SCy Schubert crypto_bignum_rand(tmp, pm1) < 0 ||
101206b73d0SCy Schubert crypto_bignum_add(tmp, one, tmp) < 0) {
102206b73d0SCy Schubert crypto_bignum_deinit(tmp, 0);
103206b73d0SCy Schubert tmp = NULL;
104206b73d0SCy Schubert }
105206b73d0SCy Schubert
106206b73d0SCy Schubert crypto_bignum_deinit(pm1, 0);
107206b73d0SCy Schubert crypto_bignum_deinit(one, 0);
108206b73d0SCy Schubert return tmp;
109206b73d0SCy Schubert }
110206b73d0SCy Schubert
111206b73d0SCy Schubert
dragonfly_is_quadratic_residue_blind(struct crypto_ec * ec,const u8 * qr,const u8 * qnr,const struct crypto_bignum * val)112206b73d0SCy Schubert int dragonfly_is_quadratic_residue_blind(struct crypto_ec *ec,
113206b73d0SCy Schubert const u8 *qr, const u8 *qnr,
114206b73d0SCy Schubert const struct crypto_bignum *val)
115206b73d0SCy Schubert {
116206b73d0SCy Schubert struct crypto_bignum *r, *num, *qr_or_qnr = NULL;
117206b73d0SCy Schubert int check, res = -1;
118206b73d0SCy Schubert u8 qr_or_qnr_bin[DRAGONFLY_MAX_ECC_PRIME_LEN];
119206b73d0SCy Schubert const struct crypto_bignum *prime;
120206b73d0SCy Schubert size_t prime_len;
121206b73d0SCy Schubert unsigned int mask;
122206b73d0SCy Schubert
123206b73d0SCy Schubert prime = crypto_ec_get_prime(ec);
124206b73d0SCy Schubert prime_len = crypto_ec_prime_len(ec);
125206b73d0SCy Schubert
126206b73d0SCy Schubert /*
127206b73d0SCy Schubert * Use a blinding technique to mask val while determining whether it is
128206b73d0SCy Schubert * a quadratic residue modulo p to avoid leaking timing information
129206b73d0SCy Schubert * while determining the Legendre symbol.
130206b73d0SCy Schubert *
131206b73d0SCy Schubert * v = val
132206b73d0SCy Schubert * r = a random number between 1 and p-1, inclusive
133206b73d0SCy Schubert * num = (v * r * r) modulo p
134206b73d0SCy Schubert */
135206b73d0SCy Schubert r = dragonfly_get_rand_1_to_p_1(prime);
136206b73d0SCy Schubert if (!r)
137206b73d0SCy Schubert return -1;
138206b73d0SCy Schubert
139206b73d0SCy Schubert num = crypto_bignum_init();
140206b73d0SCy Schubert if (!num ||
141206b73d0SCy Schubert crypto_bignum_mulmod(val, r, prime, num) < 0 ||
142206b73d0SCy Schubert crypto_bignum_mulmod(num, r, prime, num) < 0)
143206b73d0SCy Schubert goto fail;
144206b73d0SCy Schubert
145206b73d0SCy Schubert /*
146206b73d0SCy Schubert * Need to minimize differences in handling different cases, so try to
147206b73d0SCy Schubert * avoid branches and timing differences.
148206b73d0SCy Schubert *
149206b73d0SCy Schubert * If r is odd:
150206b73d0SCy Schubert * num = (num * qr) module p
151206b73d0SCy Schubert * LGR(num, p) = 1 ==> quadratic residue
152206b73d0SCy Schubert * else:
153206b73d0SCy Schubert * num = (num * qnr) module p
154206b73d0SCy Schubert * LGR(num, p) = -1 ==> quadratic residue
155206b73d0SCy Schubert *
156206b73d0SCy Schubert * mask is set to !odd(r)
157206b73d0SCy Schubert */
158206b73d0SCy Schubert mask = const_time_is_zero(crypto_bignum_is_odd(r));
159206b73d0SCy Schubert const_time_select_bin(mask, qnr, qr, prime_len, qr_or_qnr_bin);
160206b73d0SCy Schubert qr_or_qnr = crypto_bignum_init_set(qr_or_qnr_bin, prime_len);
161206b73d0SCy Schubert if (!qr_or_qnr ||
162206b73d0SCy Schubert crypto_bignum_mulmod(num, qr_or_qnr, prime, num) < 0)
163206b73d0SCy Schubert goto fail;
164206b73d0SCy Schubert /* branchless version of check = odd(r) ? 1 : -1, */
165206b73d0SCy Schubert check = const_time_select_int(mask, -1, 1);
166206b73d0SCy Schubert
167206b73d0SCy Schubert /* Determine the Legendre symbol on the masked value */
168206b73d0SCy Schubert res = crypto_bignum_legendre(num, prime);
169206b73d0SCy Schubert if (res == -2) {
170206b73d0SCy Schubert res = -1;
171206b73d0SCy Schubert goto fail;
172206b73d0SCy Schubert }
173206b73d0SCy Schubert /* branchless version of res = res == check
174206b73d0SCy Schubert * (res is -1, 0, or 1; check is -1 or 1) */
175206b73d0SCy Schubert mask = const_time_eq(res, check);
176206b73d0SCy Schubert res = const_time_select_int(mask, 1, 0);
177206b73d0SCy Schubert fail:
178206b73d0SCy Schubert crypto_bignum_deinit(num, 1);
179206b73d0SCy Schubert crypto_bignum_deinit(r, 1);
180206b73d0SCy Schubert crypto_bignum_deinit(qr_or_qnr, 1);
181206b73d0SCy Schubert return res;
182206b73d0SCy Schubert }
183206b73d0SCy Schubert
184206b73d0SCy Schubert
dragonfly_get_rand_2_to_r_1(struct crypto_bignum * val,const struct crypto_bignum * order)185206b73d0SCy Schubert static int dragonfly_get_rand_2_to_r_1(struct crypto_bignum *val,
186206b73d0SCy Schubert const struct crypto_bignum *order)
187206b73d0SCy Schubert {
188206b73d0SCy Schubert return crypto_bignum_rand(val, order) == 0 &&
189206b73d0SCy Schubert !crypto_bignum_is_zero(val) &&
190206b73d0SCy Schubert !crypto_bignum_is_one(val);
191206b73d0SCy Schubert }
192206b73d0SCy Schubert
193206b73d0SCy Schubert
dragonfly_generate_scalar(const struct crypto_bignum * order,struct crypto_bignum * _rand,struct crypto_bignum * _mask,struct crypto_bignum * scalar)194206b73d0SCy Schubert int dragonfly_generate_scalar(const struct crypto_bignum *order,
195206b73d0SCy Schubert struct crypto_bignum *_rand,
196206b73d0SCy Schubert struct crypto_bignum *_mask,
197206b73d0SCy Schubert struct crypto_bignum *scalar)
198206b73d0SCy Schubert {
199206b73d0SCy Schubert int count;
200206b73d0SCy Schubert
201206b73d0SCy Schubert /* Select two random values rand,mask such that 1 < rand,mask < r and
202206b73d0SCy Schubert * rand + mask mod r > 1. */
203206b73d0SCy Schubert for (count = 0; count < 100; count++) {
204206b73d0SCy Schubert if (dragonfly_get_rand_2_to_r_1(_rand, order) &&
205206b73d0SCy Schubert dragonfly_get_rand_2_to_r_1(_mask, order) &&
206206b73d0SCy Schubert crypto_bignum_add(_rand, _mask, scalar) == 0 &&
207206b73d0SCy Schubert crypto_bignum_mod(scalar, order, scalar) == 0 &&
208206b73d0SCy Schubert !crypto_bignum_is_zero(scalar) &&
209206b73d0SCy Schubert !crypto_bignum_is_one(scalar))
210206b73d0SCy Schubert return 0;
211206b73d0SCy Schubert }
212206b73d0SCy Schubert
213206b73d0SCy Schubert /* This should not be reachable in practice if the random number
214206b73d0SCy Schubert * generation is working. */
215206b73d0SCy Schubert wpa_printf(MSG_INFO,
216206b73d0SCy Schubert "dragonfly: Unable to get randomness for own scalar");
217206b73d0SCy Schubert return -1;
218206b73d0SCy Schubert }
219ec080394SCy Schubert
220ec080394SCy Schubert
221ec080394SCy Schubert /* res = sqrt(val) */
dragonfly_sqrt(struct crypto_ec * ec,const struct crypto_bignum * val,struct crypto_bignum * res)222ec080394SCy Schubert int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val,
223ec080394SCy Schubert struct crypto_bignum *res)
224ec080394SCy Schubert {
225ec080394SCy Schubert const struct crypto_bignum *prime;
226ec080394SCy Schubert struct crypto_bignum *tmp, *one;
227ec080394SCy Schubert int ret = 0;
228ec080394SCy Schubert u8 prime_bin[DRAGONFLY_MAX_ECC_PRIME_LEN];
229ec080394SCy Schubert size_t prime_len;
230ec080394SCy Schubert
231ec080394SCy Schubert /* For prime p such that p = 3 mod 4, sqrt(w) = w^((p+1)/4) mod p */
232ec080394SCy Schubert
233ec080394SCy Schubert prime = crypto_ec_get_prime(ec);
234ec080394SCy Schubert prime_len = crypto_ec_prime_len(ec);
235ec080394SCy Schubert tmp = crypto_bignum_init();
236ec080394SCy Schubert one = crypto_bignum_init_uint(1);
237ec080394SCy Schubert
238ec080394SCy Schubert if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin),
239ec080394SCy Schubert prime_len) < 0 ||
240ec080394SCy Schubert (prime_bin[prime_len - 1] & 0x03) != 3 ||
241ec080394SCy Schubert !tmp || !one ||
242ec080394SCy Schubert /* tmp = (p+1)/4 */
243ec080394SCy Schubert crypto_bignum_add(prime, one, tmp) < 0 ||
244ec080394SCy Schubert crypto_bignum_rshift(tmp, 2, tmp) < 0 ||
245ec080394SCy Schubert /* res = sqrt(val) */
246ec080394SCy Schubert crypto_bignum_exptmod(val, tmp, prime, res) < 0)
247ec080394SCy Schubert ret = -1;
248ec080394SCy Schubert
249ec080394SCy Schubert crypto_bignum_deinit(tmp, 0);
250ec080394SCy Schubert crypto_bignum_deinit(one, 0);
251ec080394SCy Schubert return ret;
252ec080394SCy Schubert }
253