/src/openssl31/crypto/ec/ec_mult.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.  | 
3  |  |  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved  | 
4  |  |  *  | 
5  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use  | 
6  |  |  * this file except in compliance with the License.  You can obtain a copy  | 
7  |  |  * in the file LICENSE in the source distribution or at  | 
8  |  |  * https://www.openssl.org/source/license.html  | 
9  |  |  */  | 
10  |  |  | 
11  |  | /*  | 
12  |  |  * ECDSA low level APIs are deprecated for public use, but still ok for  | 
13  |  |  * internal use.  | 
14  |  |  */  | 
15  |  | #include "internal/deprecated.h"  | 
16  |  |  | 
17  |  | #include <string.h>  | 
18  |  | #include <openssl/err.h>  | 
19  |  |  | 
20  |  | #include "internal/cryptlib.h"  | 
21  |  | #include "crypto/bn.h"  | 
22  |  | #include "ec_local.h"  | 
23  |  | #include "internal/refcount.h"  | 
24  |  |  | 
25  |  | /*  | 
26  |  |  * This file implements the wNAF-based interleaving multi-exponentiation method  | 
27  |  |  * Formerly at:  | 
28  |  |  *   http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp  | 
29  |  |  * You might now find it here:  | 
30  |  |  *   http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13  | 
31  |  |  *   http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf  | 
32  |  |  * For multiplication with precomputation, we use wNAF splitting, formerly at:  | 
33  |  |  *   http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp  | 
34  |  |  */  | 
35  |  |  | 
36  |  | /* structure for precomputed multiples of the generator */  | 
37  |  | struct ec_pre_comp_st { | 
38  |  |     const EC_GROUP *group;      /* parent EC_GROUP object */  | 
39  |  |     size_t blocksize;           /* block size for wNAF splitting */  | 
40  |  |     size_t numblocks;           /* max. number of blocks for which we have  | 
41  |  |                                  * precomputation */  | 
42  |  |     size_t w;                   /* window size */  | 
43  |  |     EC_POINT **points;          /* array with pre-calculated multiples of  | 
44  |  |                                  * generator: 'num' pointers to EC_POINT  | 
45  |  |                                  * objects followed by a NULL */  | 
46  |  |     size_t num;                 /* numblocks * 2^(w-1) */  | 
47  |  |     CRYPTO_REF_COUNT references;  | 
48  |  |     CRYPTO_RWLOCK *lock;  | 
49  |  | };  | 
50  |  |  | 
51  |  | static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)  | 
52  | 0  | { | 
53  | 0  |     EC_PRE_COMP *ret = NULL;  | 
54  |  | 
  | 
55  | 0  |     if (!group)  | 
56  | 0  |         return NULL;  | 
57  |  |  | 
58  | 0  |     ret = OPENSSL_zalloc(sizeof(*ret));  | 
59  | 0  |     if (ret == NULL) { | 
60  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
61  | 0  |         return ret;  | 
62  | 0  |     }  | 
63  |  |  | 
64  | 0  |     ret->group = group;  | 
65  | 0  |     ret->blocksize = 8;         /* default */  | 
66  | 0  |     ret->w = 4;                 /* default */  | 
67  | 0  |     ret->references = 1;  | 
68  |  | 
  | 
69  | 0  |     ret->lock = CRYPTO_THREAD_lock_new();  | 
70  | 0  |     if (ret->lock == NULL) { | 
71  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
72  | 0  |         OPENSSL_free(ret);  | 
73  | 0  |         return NULL;  | 
74  | 0  |     }  | 
75  | 0  |     return ret;  | 
76  | 0  | }  | 
77  |  |  | 
78  |  | EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre)  | 
79  | 0  | { | 
80  | 0  |     int i;  | 
81  | 0  |     if (pre != NULL)  | 
82  | 0  |         CRYPTO_UP_REF(&pre->references, &i, pre->lock);  | 
83  | 0  |     return pre;  | 
84  | 0  | }  | 
85  |  |  | 
86  |  | void EC_ec_pre_comp_free(EC_PRE_COMP *pre)  | 
87  | 0  | { | 
88  | 0  |     int i;  | 
89  |  | 
  | 
90  | 0  |     if (pre == NULL)  | 
91  | 0  |         return;  | 
92  |  |  | 
93  | 0  |     CRYPTO_DOWN_REF(&pre->references, &i, pre->lock);  | 
94  | 0  |     REF_PRINT_COUNT("EC_ec", pre); | 
95  | 0  |     if (i > 0)  | 
96  | 0  |         return;  | 
97  | 0  |     REF_ASSERT_ISNT(i < 0);  | 
98  |  | 
  | 
99  | 0  |     if (pre->points != NULL) { | 
100  | 0  |         EC_POINT **pts;  | 
101  |  | 
  | 
102  | 0  |         for (pts = pre->points; *pts != NULL; pts++)  | 
103  | 0  |             EC_POINT_free(*pts);  | 
104  | 0  |         OPENSSL_free(pre->points);  | 
105  | 0  |     }  | 
106  | 0  |     CRYPTO_THREAD_lock_free(pre->lock);  | 
107  | 0  |     OPENSSL_free(pre);  | 
108  | 0  | }  | 
109  |  |  | 
110  | 29.2k  | #define EC_POINT_BN_set_flags(P, flags) do { \ | 
111  | 29.2k  |     BN_set_flags((P)->X, (flags)); \  | 
112  | 29.2k  |     BN_set_flags((P)->Y, (flags)); \  | 
113  | 29.2k  |     BN_set_flags((P)->Z, (flags)); \  | 
114  | 29.2k  | } while(0)  | 
115  |  |  | 
116  |  | /*-  | 
117  |  |  * This functions computes a single point multiplication over the EC group,  | 
118  |  |  * using, at a high level, a Montgomery ladder with conditional swaps, with  | 
119  |  |  * various timing attack defenses.  | 
120  |  |  *  | 
121  |  |  * It performs either a fixed point multiplication  | 
122  |  |  *          (scalar * generator)  | 
123  |  |  * when point is NULL, or a variable point multiplication  | 
124  |  |  *          (scalar * point)  | 
125  |  |  * when point is not NULL.  | 
126  |  |  *  | 
127  |  |  * `scalar` cannot be NULL and should be in the range [0,n) otherwise all  | 
128  |  |  * constant time bets are off (where n is the cardinality of the EC group).  | 
129  |  |  *  | 
130  |  |  * This function expects `group->order` and `group->cardinality` to be well  | 
131  |  |  * defined and non-zero: it fails with an error code otherwise.  | 
132  |  |  *  | 
133  |  |  * NB: This says nothing about the constant-timeness of the ladder step  | 
134  |  |  * implementation (i.e., the default implementation is based on EC_POINT_add and  | 
135  |  |  * EC_POINT_dbl, which of course are not constant time themselves) or the  | 
136  |  |  * underlying multiprecision arithmetic.  | 
137  |  |  *  | 
138  |  |  * The product is stored in `r`.  | 
139  |  |  *  | 
140  |  |  * This is an internal function: callers are in charge of ensuring that the  | 
141  |  |  * input parameters `group`, `r`, `scalar` and `ctx` are not NULL.  | 
142  |  |  *  | 
143  |  |  * Returns 1 on success, 0 otherwise.  | 
144  |  |  */  | 
145  |  | int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,  | 
146  |  |                               const BIGNUM *scalar, const EC_POINT *point,  | 
147  |  |                               BN_CTX *ctx)  | 
148  | 9.75k  | { | 
149  | 9.75k  |     int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;  | 
150  | 9.75k  |     EC_POINT *p = NULL;  | 
151  | 9.75k  |     EC_POINT *s = NULL;  | 
152  | 9.75k  |     BIGNUM *k = NULL;  | 
153  | 9.75k  |     BIGNUM *lambda = NULL;  | 
154  | 9.75k  |     BIGNUM *cardinality = NULL;  | 
155  | 9.75k  |     int ret = 0;  | 
156  |  |  | 
157  |  |     /* early exit if the input point is the point at infinity */  | 
158  | 9.75k  |     if (point != NULL && EC_POINT_is_at_infinity(group, point))  | 
159  | 0  |         return EC_POINT_set_to_infinity(group, r);  | 
160  |  |  | 
161  | 9.75k  |     if (BN_is_zero(group->order)) { | 
162  | 0  |         ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER);  | 
163  | 0  |         return 0;  | 
164  | 0  |     }  | 
165  | 9.75k  |     if (BN_is_zero(group->cofactor)) { | 
166  | 0  |         ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR);  | 
167  | 0  |         return 0;  | 
168  | 0  |     }  | 
169  |  |  | 
170  | 9.75k  |     BN_CTX_start(ctx);  | 
171  |  |  | 
172  | 9.75k  |     if (((p = EC_POINT_new(group)) == NULL)  | 
173  | 9.75k  |         || ((s = EC_POINT_new(group)) == NULL)) { | 
174  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
175  | 0  |         goto err;  | 
176  | 0  |     }  | 
177  |  |  | 
178  | 9.75k  |     if (point == NULL) { | 
179  | 7.97k  |         if (!EC_POINT_copy(p, group->generator)) { | 
180  | 0  |             ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);  | 
181  | 0  |             goto err;  | 
182  | 0  |         }  | 
183  | 7.97k  |     } else { | 
184  | 1.78k  |         if (!EC_POINT_copy(p, point)) { | 
185  | 0  |             ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);  | 
186  | 0  |             goto err;  | 
187  | 0  |         }  | 
188  | 1.78k  |     }  | 
189  |  |  | 
190  | 9.75k  |     EC_POINT_BN_set_flags(p, BN_FLG_CONSTTIME);  | 
191  | 9.75k  |     EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);  | 
192  | 9.75k  |     EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);  | 
193  |  |  | 
194  | 9.75k  |     cardinality = BN_CTX_get(ctx);  | 
195  | 9.75k  |     lambda = BN_CTX_get(ctx);  | 
196  | 9.75k  |     k = BN_CTX_get(ctx);  | 
197  | 9.75k  |     if (k == NULL) { | 
198  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
199  | 0  |         goto err;  | 
200  | 0  |     }  | 
201  |  |  | 
202  | 9.75k  |     if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) { | 
203  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);  | 
204  | 0  |         goto err;  | 
205  | 0  |     }  | 
206  |  |  | 
207  |  |     /*  | 
208  |  |      * Group cardinalities are often on a word boundary.  | 
209  |  |      * So when we pad the scalar, some timing diff might  | 
210  |  |      * pop if it needs to be expanded due to carries.  | 
211  |  |      * So expand ahead of time.  | 
212  |  |      */  | 
213  | 9.75k  |     cardinality_bits = BN_num_bits(cardinality);  | 
214  | 9.75k  |     group_top = bn_get_top(cardinality);  | 
215  | 9.75k  |     if ((bn_wexpand(k, group_top + 2) == NULL)  | 
216  | 9.75k  |         || (bn_wexpand(lambda, group_top + 2) == NULL)) { | 
217  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);  | 
218  | 0  |         goto err;  | 
219  | 0  |     }  | 
220  |  |  | 
221  | 9.75k  |     if (!BN_copy(k, scalar)) { | 
222  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);  | 
223  | 0  |         goto err;  | 
224  | 0  |     }  | 
225  |  |  | 
226  | 9.75k  |     BN_set_flags(k, BN_FLG_CONSTTIME);  | 
227  |  |  | 
228  | 9.75k  |     if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) { | 
229  |  |         /*-  | 
230  |  |          * this is an unusual input, and we don't guarantee  | 
231  |  |          * constant-timeness  | 
232  |  |          */  | 
233  | 1.91k  |         if (!BN_nnmod(k, k, cardinality, ctx)) { | 
234  | 0  |             ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);  | 
235  | 0  |             goto err;  | 
236  | 0  |         }  | 
237  | 1.91k  |     }  | 
238  |  |  | 
239  | 9.75k  |     if (!BN_add(lambda, k, cardinality)) { | 
240  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);  | 
241  | 0  |         goto err;  | 
242  | 0  |     }  | 
243  | 9.75k  |     BN_set_flags(lambda, BN_FLG_CONSTTIME);  | 
244  | 9.75k  |     if (!BN_add(k, lambda, cardinality)) { | 
245  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);  | 
246  | 0  |         goto err;  | 
247  | 0  |     }  | 
248  |  |     /*  | 
249  |  |      * lambda := scalar + cardinality  | 
250  |  |      * k := scalar + 2*cardinality  | 
251  |  |      */  | 
252  | 9.75k  |     kbit = BN_is_bit_set(lambda, cardinality_bits);  | 
253  | 9.75k  |     BN_consttime_swap(kbit, k, lambda, group_top + 2);  | 
254  |  |  | 
255  | 9.75k  |     group_top = bn_get_top(group->field);  | 
256  | 9.75k  |     if ((bn_wexpand(s->X, group_top) == NULL)  | 
257  | 9.75k  |         || (bn_wexpand(s->Y, group_top) == NULL)  | 
258  | 9.75k  |         || (bn_wexpand(s->Z, group_top) == NULL)  | 
259  | 9.75k  |         || (bn_wexpand(r->X, group_top) == NULL)  | 
260  | 9.75k  |         || (bn_wexpand(r->Y, group_top) == NULL)  | 
261  | 9.75k  |         || (bn_wexpand(r->Z, group_top) == NULL)  | 
262  | 9.75k  |         || (bn_wexpand(p->X, group_top) == NULL)  | 
263  | 9.75k  |         || (bn_wexpand(p->Y, group_top) == NULL)  | 
264  | 9.75k  |         || (bn_wexpand(p->Z, group_top) == NULL)) { | 
265  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);  | 
266  | 0  |         goto err;  | 
267  | 0  |     }  | 
268  |  |  | 
269  |  |     /* ensure input point is in affine coords for ladder step efficiency */  | 
270  | 9.75k  |     if (!p->Z_is_one && (group->meth->make_affine == NULL  | 
271  | 0  |                          || !group->meth->make_affine(group, p, ctx))) { | 
272  | 0  |             ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);  | 
273  | 0  |             goto err;  | 
274  | 0  |     }  | 
275  |  |  | 
276  |  |     /* Initialize the Montgomery ladder */  | 
277  | 9.75k  |     if (!ec_point_ladder_pre(group, r, s, p, ctx)) { | 
278  | 0  |         ERR_raise(ERR_LIB_EC, EC_R_LADDER_PRE_FAILURE);  | 
279  | 0  |         goto err;  | 
280  | 0  |     }  | 
281  |  |  | 
282  |  |     /* top bit is a 1, in a fixed pos */  | 
283  | 9.75k  |     pbit = 1;  | 
284  |  |  | 
285  | 3.12M  | #define EC_POINT_CSWAP(c, a, b, w, t) do {         \ | 
286  | 3.12M  |         BN_consttime_swap(c, (a)->X, (b)->X, w);   \  | 
287  | 3.12M  |         BN_consttime_swap(c, (a)->Y, (b)->Y, w);   \  | 
288  | 3.12M  |         BN_consttime_swap(c, (a)->Z, (b)->Z, w);   \  | 
289  | 3.12M  |         t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \  | 
290  | 3.12M  |         (a)->Z_is_one ^= (t);                      \  | 
291  | 3.12M  |         (b)->Z_is_one ^= (t);                      \  | 
292  | 3.12M  | } while(0)  | 
293  |  |  | 
294  |  |     /*-  | 
295  |  |      * The ladder step, with branches, is  | 
296  |  |      *  | 
297  |  |      * k[i] == 0: S = add(R, S), R = dbl(R)  | 
298  |  |      * k[i] == 1: R = add(S, R), S = dbl(S)  | 
299  |  |      *  | 
300  |  |      * Swapping R, S conditionally on k[i] leaves you with state  | 
301  |  |      *  | 
302  |  |      * k[i] == 0: T, U = R, S  | 
303  |  |      * k[i] == 1: T, U = S, R  | 
304  |  |      *  | 
305  |  |      * Then perform the ECC ops.  | 
306  |  |      *  | 
307  |  |      * U = add(T, U)  | 
308  |  |      * T = dbl(T)  | 
309  |  |      *  | 
310  |  |      * Which leaves you with state  | 
311  |  |      *  | 
312  |  |      * k[i] == 0: U = add(R, S), T = dbl(R)  | 
313  |  |      * k[i] == 1: U = add(S, R), T = dbl(S)  | 
314  |  |      *  | 
315  |  |      * Swapping T, U conditionally on k[i] leaves you with state  | 
316  |  |      *  | 
317  |  |      * k[i] == 0: R, S = T, U  | 
318  |  |      * k[i] == 1: R, S = U, T  | 
319  |  |      *  | 
320  |  |      * Which leaves you with state  | 
321  |  |      *  | 
322  |  |      * k[i] == 0: S = add(R, S), R = dbl(R)  | 
323  |  |      * k[i] == 1: R = add(S, R), S = dbl(S)  | 
324  |  |      *  | 
325  |  |      * So we get the same logic, but instead of a branch it's a  | 
326  |  |      * conditional swap, followed by ECC ops, then another conditional swap.  | 
327  |  |      *  | 
328  |  |      * Optimization: The end of iteration i and start of i-1 looks like  | 
329  |  |      *  | 
330  |  |      * ...  | 
331  |  |      * CSWAP(k[i], R, S)  | 
332  |  |      * ECC  | 
333  |  |      * CSWAP(k[i], R, S)  | 
334  |  |      * (next iteration)  | 
335  |  |      * CSWAP(k[i-1], R, S)  | 
336  |  |      * ECC  | 
337  |  |      * CSWAP(k[i-1], R, S)  | 
338  |  |      * ...  | 
339  |  |      *  | 
340  |  |      * So instead of two contiguous swaps, you can merge the condition  | 
341  |  |      * bits and do a single swap.  | 
342  |  |      *  | 
343  |  |      * k[i]   k[i-1]    Outcome  | 
344  |  |      * 0      0         No Swap  | 
345  |  |      * 0      1         Swap  | 
346  |  |      * 1      0         Swap  | 
347  |  |      * 1      1         No Swap  | 
348  |  |      *  | 
349  |  |      * This is XOR. pbit tracks the previous bit of k.  | 
350  |  |      */  | 
351  |  |  | 
352  | 3.12M  |     for (i = cardinality_bits - 1; i >= 0; i--) { | 
353  | 3.11M  |         kbit = BN_is_bit_set(k, i) ^ pbit;  | 
354  | 3.11M  |         EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);  | 
355  |  |  | 
356  |  |         /* Perform a single step of the Montgomery ladder */  | 
357  | 3.11M  |         if (!ec_point_ladder_step(group, r, s, p, ctx)) { | 
358  | 0  |             ERR_raise(ERR_LIB_EC, EC_R_LADDER_STEP_FAILURE);  | 
359  | 0  |             goto err;  | 
360  | 0  |         }  | 
361  |  |         /*  | 
362  |  |          * pbit logic merges this cswap with that of the  | 
363  |  |          * next iteration  | 
364  |  |          */  | 
365  | 3.11M  |         pbit ^= kbit;  | 
366  | 3.11M  |     }  | 
367  |  |     /* one final cswap to move the right value into r */  | 
368  | 9.75k  |     EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);  | 
369  | 9.75k  | #undef EC_POINT_CSWAP  | 
370  |  |  | 
371  |  |     /* Finalize ladder (and recover full point coordinates) */  | 
372  | 9.75k  |     if (!ec_point_ladder_post(group, r, s, p, ctx)) { | 
373  | 0  |         ERR_raise(ERR_LIB_EC, EC_R_LADDER_POST_FAILURE);  | 
374  | 0  |         goto err;  | 
375  | 0  |     }  | 
376  |  |  | 
377  | 9.75k  |     ret = 1;  | 
378  |  |  | 
379  | 9.75k  |  err:  | 
380  | 9.75k  |     EC_POINT_free(p);  | 
381  | 9.75k  |     EC_POINT_clear_free(s);  | 
382  | 9.75k  |     BN_CTX_end(ctx);  | 
383  |  |  | 
384  | 9.75k  |     return ret;  | 
385  | 9.75k  | }  | 
386  |  |  | 
387  |  | #undef EC_POINT_BN_set_flags  | 
388  |  |  | 
389  |  | /*  | 
390  |  |  * Table could be optimised for the wNAF-based implementation,  | 
391  |  |  * sometimes smaller windows will give better performance (thus the  | 
392  |  |  * boundaries should be increased)  | 
393  |  |  */  | 
394  |  | #define EC_window_bits_for_scalar_size(b) \  | 
395  | 3.35k  |                 ((size_t) \  | 
396  | 3.35k  |                  ((b) >= 2000 ? 6 : \  | 
397  | 3.35k  |                   (b) >=  800 ? 5 : \  | 
398  | 3.32k  |                   (b) >=  300 ? 4 : \  | 
399  | 3.26k  |                   (b) >=   70 ? 3 : \  | 
400  | 2.39k  |                   (b) >=   20 ? 2 : \  | 
401  | 1.06k  |                   1))  | 
402  |  |  | 
403  |  | /*-  | 
404  |  |  * Compute  | 
405  |  |  *      \sum scalars[i]*points[i],  | 
406  |  |  * also including  | 
407  |  |  *      scalar*generator  | 
408  |  |  * in the addition if scalar != NULL  | 
409  |  |  */  | 
410  |  | int ossl_ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,  | 
411  |  |                      size_t num, const EC_POINT *points[],  | 
412  |  |                      const BIGNUM *scalars[], BN_CTX *ctx)  | 
413  | 7.18k  | { | 
414  | 7.18k  |     const EC_POINT *generator = NULL;  | 
415  | 7.18k  |     EC_POINT *tmp = NULL;  | 
416  | 7.18k  |     size_t totalnum;  | 
417  | 7.18k  |     size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */  | 
418  | 7.18k  |     size_t pre_points_per_block = 0;  | 
419  | 7.18k  |     size_t i, j;  | 
420  | 7.18k  |     int k;  | 
421  | 7.18k  |     int r_is_inverted = 0;  | 
422  | 7.18k  |     int r_is_at_infinity = 1;  | 
423  | 7.18k  |     size_t *wsize = NULL;       /* individual window sizes */  | 
424  | 7.18k  |     signed char **wNAF = NULL;  /* individual wNAFs */  | 
425  | 7.18k  |     size_t *wNAF_len = NULL;  | 
426  | 7.18k  |     size_t max_len = 0;  | 
427  | 7.18k  |     size_t num_val;  | 
428  | 7.18k  |     EC_POINT **val = NULL;      /* precomputation */  | 
429  | 7.18k  |     EC_POINT **v;  | 
430  | 7.18k  |     EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or  | 
431  |  |                                  * 'pre_comp->points' */  | 
432  | 7.18k  |     const EC_PRE_COMP *pre_comp = NULL;  | 
433  | 7.18k  |     int num_scalar = 0;         /* flag: will be set to 1 if 'scalar' must be  | 
434  |  |                                  * treated like other scalars, i.e.  | 
435  |  |                                  * precomputation is not available */  | 
436  | 7.18k  |     int ret = 0;  | 
437  |  |  | 
438  | 7.18k  |     if (!BN_is_zero(group->order) && !BN_is_zero(group->cofactor)) { | 
439  |  |         /*-  | 
440  |  |          * Handle the common cases where the scalar is secret, enforcing a  | 
441  |  |          * scalar multiplication implementation based on a Montgomery ladder,  | 
442  |  |          * with various timing attack defenses.  | 
443  |  |          */  | 
444  | 5.90k  |         if ((scalar != group->order) && (scalar != NULL) && (num == 0)) { | 
445  |  |             /*-  | 
446  |  |              * In this case we want to compute scalar * GeneratorPoint: this  | 
447  |  |              * codepath is reached most prominently by (ephemeral) key  | 
448  |  |              * generation of EC cryptosystems (i.e. ECDSA keygen and sign setup,  | 
449  |  |              * ECDH keygen/first half), where the scalar is always secret. This  | 
450  |  |              * is why we ignore if BN_FLG_CONSTTIME is actually set and we  | 
451  |  |              * always call the ladder version.  | 
452  |  |              */  | 
453  | 3.47k  |             return ossl_ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);  | 
454  | 3.47k  |         }  | 
455  | 2.43k  |         if ((scalar == NULL) && (num == 1) && (scalars[0] != group->order)) { | 
456  |  |             /*-  | 
457  |  |              * In this case we want to compute scalar * VariablePoint: this  | 
458  |  |              * codepath is reached most prominently by the second half of ECDH,  | 
459  |  |              * where the secret scalar is multiplied by the peer's public point.  | 
460  |  |              * To protect the secret scalar, we ignore if BN_FLG_CONSTTIME is  | 
461  |  |              * actually set and we always call the ladder version.  | 
462  |  |              */  | 
463  | 540  |             return ossl_ec_scalar_mul_ladder(group, r, scalars[0], points[0],  | 
464  | 540  |                                              ctx);  | 
465  | 540  |         }  | 
466  | 2.43k  |     }  | 
467  |  |  | 
468  | 3.17k  |     if (scalar != NULL) { | 
469  | 1.82k  |         generator = EC_GROUP_get0_generator(group);  | 
470  | 1.82k  |         if (generator == NULL) { | 
471  | 0  |             ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR);  | 
472  | 0  |             goto err;  | 
473  | 0  |         }  | 
474  |  |  | 
475  |  |         /* look if we can use precomputed multiples of generator */  | 
476  |  |  | 
477  | 1.82k  |         pre_comp = group->pre_comp.ec;  | 
478  | 1.82k  |         if (pre_comp && pre_comp->numblocks  | 
479  | 1.82k  |             && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==  | 
480  | 0  |                 0)) { | 
481  | 0  |             blocksize = pre_comp->blocksize;  | 
482  |  |  | 
483  |  |             /*  | 
484  |  |              * determine maximum number of blocks that wNAF splitting may  | 
485  |  |              * yield (NB: maximum wNAF length is bit length plus one)  | 
486  |  |              */  | 
487  | 0  |             numblocks = (BN_num_bits(scalar) / blocksize) + 1;  | 
488  |  |  | 
489  |  |             /*  | 
490  |  |              * we cannot use more blocks than we have precomputation for  | 
491  |  |              */  | 
492  | 0  |             if (numblocks > pre_comp->numblocks)  | 
493  | 0  |                 numblocks = pre_comp->numblocks;  | 
494  |  | 
  | 
495  | 0  |             pre_points_per_block = (size_t)1 << (pre_comp->w - 1);  | 
496  |  |  | 
497  |  |             /* check that pre_comp looks sane */  | 
498  | 0  |             if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) { | 
499  | 0  |                 ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);  | 
500  | 0  |                 goto err;  | 
501  | 0  |             }  | 
502  | 1.82k  |         } else { | 
503  |  |             /* can't use precomputation */  | 
504  | 1.82k  |             pre_comp = NULL;  | 
505  | 1.82k  |             numblocks = 1;  | 
506  | 1.82k  |             num_scalar = 1;     /* treat 'scalar' like 'num'-th element of  | 
507  |  |                                  * 'scalars' */  | 
508  | 1.82k  |         }  | 
509  | 1.82k  |     }  | 
510  |  |  | 
511  | 3.17k  |     totalnum = num + numblocks;  | 
512  |  |  | 
513  | 3.17k  |     wsize = OPENSSL_malloc(totalnum * sizeof(wsize[0]));  | 
514  | 3.17k  |     wNAF_len = OPENSSL_malloc(totalnum * sizeof(wNAF_len[0]));  | 
515  |  |     /* include space for pivot */  | 
516  | 3.17k  |     wNAF = OPENSSL_malloc((totalnum + 1) * sizeof(wNAF[0]));  | 
517  | 3.17k  |     val_sub = OPENSSL_malloc(totalnum * sizeof(val_sub[0]));  | 
518  |  |  | 
519  |  |     /* Ensure wNAF is initialised in case we end up going to err */  | 
520  | 3.17k  |     if (wNAF != NULL)  | 
521  | 3.17k  |         wNAF[0] = NULL;         /* preliminary pivot */  | 
522  |  |  | 
523  | 3.17k  |     if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) { | 
524  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
525  | 0  |         goto err;  | 
526  | 0  |     }  | 
527  |  |  | 
528  |  |     /*  | 
529  |  |      * num_val will be the total number of temporarily precomputed points  | 
530  |  |      */  | 
531  | 3.17k  |     num_val = 0;  | 
532  |  |  | 
533  | 6.52k  |     for (i = 0; i < num + num_scalar; i++) { | 
534  | 3.35k  |         size_t bits;  | 
535  |  |  | 
536  | 3.35k  |         bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);  | 
537  | 3.35k  |         wsize[i] = EC_window_bits_for_scalar_size(bits);  | 
538  | 3.35k  |         num_val += (size_t)1 << (wsize[i] - 1);  | 
539  | 3.35k  |         wNAF[i + 1] = NULL;     /* make sure we always have a pivot */  | 
540  | 3.35k  |         wNAF[i] =  | 
541  | 3.35k  |             bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],  | 
542  | 3.35k  |                             &wNAF_len[i]);  | 
543  | 3.35k  |         if (wNAF[i] == NULL)  | 
544  | 0  |             goto err;  | 
545  | 3.35k  |         if (wNAF_len[i] > max_len)  | 
546  | 3.28k  |             max_len = wNAF_len[i];  | 
547  | 3.35k  |     }  | 
548  |  |  | 
549  | 3.17k  |     if (numblocks) { | 
550  |  |         /* we go here iff scalar != NULL */  | 
551  |  |  | 
552  | 1.82k  |         if (pre_comp == NULL) { | 
553  | 1.82k  |             if (num_scalar != 1) { | 
554  | 0  |                 ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);  | 
555  | 0  |                 goto err;  | 
556  | 0  |             }  | 
557  |  |             /* we have already generated a wNAF for 'scalar' */  | 
558  | 1.82k  |         } else { | 
559  | 0  |             signed char *tmp_wNAF = NULL;  | 
560  | 0  |             size_t tmp_len = 0;  | 
561  |  | 
  | 
562  | 0  |             if (num_scalar != 0) { | 
563  | 0  |                 ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);  | 
564  | 0  |                 goto err;  | 
565  | 0  |             }  | 
566  |  |  | 
567  |  |             /*  | 
568  |  |              * use the window size for which we have precomputation  | 
569  |  |              */  | 
570  | 0  |             wsize[num] = pre_comp->w;  | 
571  | 0  |             tmp_wNAF = bn_compute_wNAF(scalar, wsize[num], &tmp_len);  | 
572  | 0  |             if (!tmp_wNAF)  | 
573  | 0  |                 goto err;  | 
574  |  |  | 
575  | 0  |             if (tmp_len <= max_len) { | 
576  |  |                 /*  | 
577  |  |                  * One of the other wNAFs is at least as long as the wNAF  | 
578  |  |                  * belonging to the generator, so wNAF splitting will not buy  | 
579  |  |                  * us anything.  | 
580  |  |                  */  | 
581  |  | 
  | 
582  | 0  |                 numblocks = 1;  | 
583  | 0  |                 totalnum = num + 1; /* don't use wNAF splitting */  | 
584  | 0  |                 wNAF[num] = tmp_wNAF;  | 
585  | 0  |                 wNAF[num + 1] = NULL;  | 
586  | 0  |                 wNAF_len[num] = tmp_len;  | 
587  |  |                 /*  | 
588  |  |                  * pre_comp->points starts with the points that we need here:  | 
589  |  |                  */  | 
590  | 0  |                 val_sub[num] = pre_comp->points;  | 
591  | 0  |             } else { | 
592  |  |                 /*  | 
593  |  |                  * don't include tmp_wNAF directly into wNAF array - use wNAF  | 
594  |  |                  * splitting and include the blocks  | 
595  |  |                  */  | 
596  |  | 
  | 
597  | 0  |                 signed char *pp;  | 
598  | 0  |                 EC_POINT **tmp_points;  | 
599  |  | 
  | 
600  | 0  |                 if (tmp_len < numblocks * blocksize) { | 
601  |  |                     /*  | 
602  |  |                      * possibly we can do with fewer blocks than estimated  | 
603  |  |                      */  | 
604  | 0  |                     numblocks = (tmp_len + blocksize - 1) / blocksize;  | 
605  | 0  |                     if (numblocks > pre_comp->numblocks) { | 
606  | 0  |                         ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);  | 
607  | 0  |                         OPENSSL_free(tmp_wNAF);  | 
608  | 0  |                         goto err;  | 
609  | 0  |                     }  | 
610  | 0  |                     totalnum = num + numblocks;  | 
611  | 0  |                 }  | 
612  |  |  | 
613  |  |                 /* split wNAF in 'numblocks' parts */  | 
614  | 0  |                 pp = tmp_wNAF;  | 
615  | 0  |                 tmp_points = pre_comp->points;  | 
616  |  | 
  | 
617  | 0  |                 for (i = num; i < totalnum; i++) { | 
618  | 0  |                     if (i < totalnum - 1) { | 
619  | 0  |                         wNAF_len[i] = blocksize;  | 
620  | 0  |                         if (tmp_len < blocksize) { | 
621  | 0  |                             ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);  | 
622  | 0  |                             OPENSSL_free(tmp_wNAF);  | 
623  | 0  |                             goto err;  | 
624  | 0  |                         }  | 
625  | 0  |                         tmp_len -= blocksize;  | 
626  | 0  |                     } else  | 
627  |  |                         /*  | 
628  |  |                          * last block gets whatever is left (this could be  | 
629  |  |                          * more or less than 'blocksize'!)  | 
630  |  |                          */  | 
631  | 0  |                         wNAF_len[i] = tmp_len;  | 
632  |  |  | 
633  | 0  |                     wNAF[i + 1] = NULL;  | 
634  | 0  |                     wNAF[i] = OPENSSL_malloc(wNAF_len[i]);  | 
635  | 0  |                     if (wNAF[i] == NULL) { | 
636  | 0  |                         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
637  | 0  |                         OPENSSL_free(tmp_wNAF);  | 
638  | 0  |                         goto err;  | 
639  | 0  |                     }  | 
640  | 0  |                     memcpy(wNAF[i], pp, wNAF_len[i]);  | 
641  | 0  |                     if (wNAF_len[i] > max_len)  | 
642  | 0  |                         max_len = wNAF_len[i];  | 
643  |  | 
  | 
644  | 0  |                     if (*tmp_points == NULL) { | 
645  | 0  |                         ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);  | 
646  | 0  |                         OPENSSL_free(tmp_wNAF);  | 
647  | 0  |                         goto err;  | 
648  | 0  |                     }  | 
649  | 0  |                     val_sub[i] = tmp_points;  | 
650  | 0  |                     tmp_points += pre_points_per_block;  | 
651  | 0  |                     pp += blocksize;  | 
652  | 0  |                 }  | 
653  | 0  |                 OPENSSL_free(tmp_wNAF);  | 
654  | 0  |             }  | 
655  | 0  |         }  | 
656  | 1.82k  |     }  | 
657  |  |  | 
658  |  |     /*  | 
659  |  |      * All points we precompute now go into a single array 'val'.  | 
660  |  |      * 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a  | 
661  |  |      * subarray of 'pre_comp->points' if we already have precomputation.  | 
662  |  |      */  | 
663  | 3.17k  |     val = OPENSSL_malloc((num_val + 1) * sizeof(val[0]));  | 
664  | 3.17k  |     if (val == NULL) { | 
665  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
666  | 0  |         goto err;  | 
667  | 0  |     }  | 
668  | 3.17k  |     val[num_val] = NULL;        /* pivot element */  | 
669  |  |  | 
670  |  |     /* allocate points for precomputation */  | 
671  | 3.17k  |     v = val;  | 
672  | 6.52k  |     for (i = 0; i < num + num_scalar; i++) { | 
673  | 3.35k  |         val_sub[i] = v;  | 
674  | 18.8k  |         for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) { | 
675  | 15.5k  |             *v = EC_POINT_new(group);  | 
676  | 15.5k  |             if (*v == NULL)  | 
677  | 0  |                 goto err;  | 
678  | 15.5k  |             v++;  | 
679  | 15.5k  |         }  | 
680  | 3.35k  |     }  | 
681  | 3.17k  |     if (!(v == val + num_val)) { | 
682  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);  | 
683  | 0  |         goto err;  | 
684  | 0  |     }  | 
685  |  |  | 
686  | 3.17k  |     if ((tmp = EC_POINT_new(group)) == NULL)  | 
687  | 0  |         goto err;  | 
688  |  |  | 
689  |  |     /*-  | 
690  |  |      * prepare precomputed values:  | 
691  |  |      *    val_sub[i][0] :=     points[i]  | 
692  |  |      *    val_sub[i][1] := 3 * points[i]  | 
693  |  |      *    val_sub[i][2] := 5 * points[i]  | 
694  |  |      *    ...  | 
695  |  |      */  | 
696  | 6.52k  |     for (i = 0; i < num + num_scalar; i++) { | 
697  | 3.35k  |         if (i < num) { | 
698  | 1.52k  |             if (!EC_POINT_copy(val_sub[i][0], points[i]))  | 
699  | 0  |                 goto err;  | 
700  | 1.82k  |         } else { | 
701  | 1.82k  |             if (!EC_POINT_copy(val_sub[i][0], generator))  | 
702  | 0  |                 goto err;  | 
703  | 1.82k  |         }  | 
704  |  |  | 
705  | 3.35k  |         if (wsize[i] > 1) { | 
706  | 2.63k  |             if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))  | 
707  | 0  |                 goto err;  | 
708  | 14.8k  |             for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) { | 
709  | 12.1k  |                 if (!EC_POINT_add  | 
710  | 12.1k  |                     (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))  | 
711  | 0  |                     goto err;  | 
712  | 12.1k  |             }  | 
713  | 2.63k  |         }  | 
714  | 3.35k  |     }  | 
715  |  |  | 
716  | 3.17k  |     if (group->meth->points_make_affine == NULL  | 
717  | 3.17k  |         || !group->meth->points_make_affine(group, num_val, val, ctx))  | 
718  | 0  |         goto err;  | 
719  |  |  | 
720  | 3.17k  |     r_is_at_infinity = 1;  | 
721  |  |  | 
722  | 639k  |     for (k = max_len - 1; k >= 0; k--) { | 
723  | 636k  |         if (!r_is_at_infinity) { | 
724  | 633k  |             if (!EC_POINT_dbl(group, r, r, ctx))  | 
725  | 0  |                 goto err;  | 
726  | 633k  |         }  | 
727  |  |  | 
728  | 1.33M  |         for (i = 0; i < totalnum; i++) { | 
729  | 696k  |             if (wNAF_len[i] > (size_t)k) { | 
730  | 675k  |                 int digit = wNAF[i][k];  | 
731  | 675k  |                 int is_neg;  | 
732  |  |  | 
733  | 675k  |                 if (digit) { | 
734  | 87.5k  |                     is_neg = digit < 0;  | 
735  |  |  | 
736  | 87.5k  |                     if (is_neg)  | 
737  | 41.4k  |                         digit = -digit;  | 
738  |  |  | 
739  | 87.5k  |                     if (is_neg != r_is_inverted) { | 
740  | 42.0k  |                         if (!r_is_at_infinity) { | 
741  | 42.0k  |                             if (!EC_POINT_invert(group, r, ctx))  | 
742  | 0  |                                 goto err;  | 
743  | 42.0k  |                         }  | 
744  | 42.0k  |                         r_is_inverted = !r_is_inverted;  | 
745  | 42.0k  |                     }  | 
746  |  |  | 
747  |  |                     /* digit > 0 */  | 
748  |  |  | 
749  | 87.5k  |                     if (r_is_at_infinity) { | 
750  | 3.12k  |                         if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))  | 
751  | 0  |                             goto err;  | 
752  |  |  | 
753  |  |                         /*-  | 
754  |  |                          * Apply coordinate blinding for EC_POINT.  | 
755  |  |                          *  | 
756  |  |                          * The underlying EC_METHOD can optionally implement this function:  | 
757  |  |                          * ossl_ec_point_blind_coordinates() returns 0 in case of errors or 1 on  | 
758  |  |                          * success or if coordinate blinding is not implemented for this  | 
759  |  |                          * group.  | 
760  |  |                          */  | 
761  | 3.12k  |                         if (!ossl_ec_point_blind_coordinates(group, r, ctx)) { | 
762  | 0  |                             ERR_raise(ERR_LIB_EC, EC_R_POINT_COORDINATES_BLIND_FAILURE);  | 
763  | 0  |                             goto err;  | 
764  | 0  |                         }  | 
765  |  |  | 
766  | 3.12k  |                         r_is_at_infinity = 0;  | 
767  | 84.4k  |                     } else { | 
768  | 84.4k  |                         if (!EC_POINT_add  | 
769  | 84.4k  |                             (group, r, r, val_sub[i][digit >> 1], ctx))  | 
770  | 0  |                             goto err;  | 
771  | 84.4k  |                     }  | 
772  | 87.5k  |                 }  | 
773  | 675k  |             }  | 
774  | 696k  |         }  | 
775  | 636k  |     }  | 
776  |  |  | 
777  | 3.17k  |     if (r_is_at_infinity) { | 
778  | 50  |         if (!EC_POINT_set_to_infinity(group, r))  | 
779  | 0  |             goto err;  | 
780  | 3.12k  |     } else { | 
781  | 3.12k  |         if (r_is_inverted)  | 
782  | 1.50k  |             if (!EC_POINT_invert(group, r, ctx))  | 
783  | 0  |                 goto err;  | 
784  | 3.12k  |     }  | 
785  |  |  | 
786  | 3.17k  |     ret = 1;  | 
787  |  |  | 
788  | 3.17k  |  err:  | 
789  | 3.17k  |     EC_POINT_free(tmp);  | 
790  | 3.17k  |     OPENSSL_free(wsize);  | 
791  | 3.17k  |     OPENSSL_free(wNAF_len);  | 
792  | 3.17k  |     if (wNAF != NULL) { | 
793  | 3.17k  |         signed char **w;  | 
794  |  |  | 
795  | 6.52k  |         for (w = wNAF; *w != NULL; w++)  | 
796  | 3.35k  |             OPENSSL_free(*w);  | 
797  |  |  | 
798  | 3.17k  |         OPENSSL_free(wNAF);  | 
799  | 3.17k  |     }  | 
800  | 3.17k  |     if (val != NULL) { | 
801  | 18.7k  |         for (v = val; *v != NULL; v++)  | 
802  | 15.5k  |             EC_POINT_clear_free(*v);  | 
803  |  |  | 
804  | 3.17k  |         OPENSSL_free(val);  | 
805  | 3.17k  |     }  | 
806  | 3.17k  |     OPENSSL_free(val_sub);  | 
807  | 3.17k  |     return ret;  | 
808  | 3.17k  | }  | 
809  |  |  | 
810  |  | /*-  | 
811  |  |  * ossl_ec_wNAF_precompute_mult()  | 
812  |  |  * creates an EC_PRE_COMP object with preprecomputed multiples of the generator  | 
813  |  |  * for use with wNAF splitting as implemented in ossl_ec_wNAF_mul().  | 
814  |  |  *  | 
815  |  |  * 'pre_comp->points' is an array of multiples of the generator  | 
816  |  |  * of the following form:  | 
817  |  |  * points[0] =     generator;  | 
818  |  |  * points[1] = 3 * generator;  | 
819  |  |  * ...  | 
820  |  |  * points[2^(w-1)-1] =     (2^(w-1)-1) * generator;  | 
821  |  |  * points[2^(w-1)]   =     2^blocksize * generator;  | 
822  |  |  * points[2^(w-1)+1] = 3 * 2^blocksize * generator;  | 
823  |  |  * ...  | 
824  |  |  * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) *  2^(blocksize*(numblocks-2)) * generator  | 
825  |  |  * points[2^(w-1)*(numblocks-1)]   =              2^(blocksize*(numblocks-1)) * generator  | 
826  |  |  * ...  | 
827  |  |  * points[2^(w-1)*numblocks-1]     = (2^(w-1)) *  2^(blocksize*(numblocks-1)) * generator  | 
828  |  |  * points[2^(w-1)*numblocks]       = NULL  | 
829  |  |  */  | 
830  |  | int ossl_ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)  | 
831  | 0  | { | 
832  | 0  |     const EC_POINT *generator;  | 
833  | 0  |     EC_POINT *tmp_point = NULL, *base = NULL, **var;  | 
834  | 0  |     const BIGNUM *order;  | 
835  | 0  |     size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;  | 
836  | 0  |     EC_POINT **points = NULL;  | 
837  | 0  |     EC_PRE_COMP *pre_comp;  | 
838  | 0  |     int ret = 0;  | 
839  | 0  |     int used_ctx = 0;  | 
840  | 0  | #ifndef FIPS_MODULE  | 
841  | 0  |     BN_CTX *new_ctx = NULL;  | 
842  | 0  | #endif  | 
843  |  |  | 
844  |  |     /* if there is an old EC_PRE_COMP object, throw it away */  | 
845  | 0  |     EC_pre_comp_free(group);  | 
846  | 0  |     if ((pre_comp = ec_pre_comp_new(group)) == NULL)  | 
847  | 0  |         return 0;  | 
848  |  |  | 
849  | 0  |     generator = EC_GROUP_get0_generator(group);  | 
850  | 0  |     if (generator == NULL) { | 
851  | 0  |         ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR);  | 
852  | 0  |         goto err;  | 
853  | 0  |     }  | 
854  |  |  | 
855  | 0  | #ifndef FIPS_MODULE  | 
856  | 0  |     if (ctx == NULL)  | 
857  | 0  |         ctx = new_ctx = BN_CTX_new();  | 
858  | 0  | #endif  | 
859  | 0  |     if (ctx == NULL)  | 
860  | 0  |         goto err;  | 
861  |  |  | 
862  | 0  |     BN_CTX_start(ctx);  | 
863  | 0  |     used_ctx = 1;  | 
864  |  | 
  | 
865  | 0  |     order = EC_GROUP_get0_order(group);  | 
866  | 0  |     if (order == NULL)  | 
867  | 0  |         goto err;  | 
868  | 0  |     if (BN_is_zero(order)) { | 
869  | 0  |         ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER);  | 
870  | 0  |         goto err;  | 
871  | 0  |     }  | 
872  |  |  | 
873  | 0  |     bits = BN_num_bits(order);  | 
874  |  |     /*  | 
875  |  |      * The following parameters mean we precompute (approximately) one point  | 
876  |  |      * per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other  | 
877  |  |      * bit lengths, other parameter combinations might provide better  | 
878  |  |      * efficiency.  | 
879  |  |      */  | 
880  | 0  |     blocksize = 8;  | 
881  | 0  |     w = 4;  | 
882  | 0  |     if (EC_window_bits_for_scalar_size(bits) > w) { | 
883  |  |         /* let's not make the window too small ... */  | 
884  | 0  |         w = EC_window_bits_for_scalar_size(bits);  | 
885  | 0  |     }  | 
886  |  | 
  | 
887  | 0  |     numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks  | 
888  |  |                                                      * to use for wNAF  | 
889  |  |                                                      * splitting */  | 
890  |  | 
  | 
891  | 0  |     pre_points_per_block = (size_t)1 << (w - 1);  | 
892  | 0  |     num = pre_points_per_block * numblocks; /* number of points to compute  | 
893  |  |                                              * and store */  | 
894  |  | 
  | 
895  | 0  |     points = OPENSSL_malloc(sizeof(*points) * (num + 1));  | 
896  | 0  |     if (points == NULL) { | 
897  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
898  | 0  |         goto err;  | 
899  | 0  |     }  | 
900  |  |  | 
901  | 0  |     var = points;  | 
902  | 0  |     var[num] = NULL;            /* pivot */  | 
903  | 0  |     for (i = 0; i < num; i++) { | 
904  | 0  |         if ((var[i] = EC_POINT_new(group)) == NULL) { | 
905  | 0  |             ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
906  | 0  |             goto err;  | 
907  | 0  |         }  | 
908  | 0  |     }  | 
909  |  |  | 
910  | 0  |     if ((tmp_point = EC_POINT_new(group)) == NULL  | 
911  | 0  |         || (base = EC_POINT_new(group)) == NULL) { | 
912  | 0  |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);  | 
913  | 0  |         goto err;  | 
914  | 0  |     }  | 
915  |  |  | 
916  | 0  |     if (!EC_POINT_copy(base, generator))  | 
917  | 0  |         goto err;  | 
918  |  |  | 
919  |  |     /* do the precomputation */  | 
920  | 0  |     for (i = 0; i < numblocks; i++) { | 
921  | 0  |         size_t j;  | 
922  |  | 
  | 
923  | 0  |         if (!EC_POINT_dbl(group, tmp_point, base, ctx))  | 
924  | 0  |             goto err;  | 
925  |  |  | 
926  | 0  |         if (!EC_POINT_copy(*var++, base))  | 
927  | 0  |             goto err;  | 
928  |  |  | 
929  | 0  |         for (j = 1; j < pre_points_per_block; j++, var++) { | 
930  |  |             /*  | 
931  |  |              * calculate odd multiples of the current base point  | 
932  |  |              */  | 
933  | 0  |             if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))  | 
934  | 0  |                 goto err;  | 
935  | 0  |         }  | 
936  |  |  | 
937  | 0  |         if (i < numblocks - 1) { | 
938  |  |             /*  | 
939  |  |              * get the next base (multiply current one by 2^blocksize)  | 
940  |  |              */  | 
941  | 0  |             size_t k;  | 
942  |  | 
  | 
943  | 0  |             if (blocksize <= 2) { | 
944  | 0  |                 ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);  | 
945  | 0  |                 goto err;  | 
946  | 0  |             }  | 
947  |  |  | 
948  | 0  |             if (!EC_POINT_dbl(group, base, tmp_point, ctx))  | 
949  | 0  |                 goto err;  | 
950  | 0  |             for (k = 2; k < blocksize; k++) { | 
951  | 0  |                 if (!EC_POINT_dbl(group, base, base, ctx))  | 
952  | 0  |                     goto err;  | 
953  | 0  |             }  | 
954  | 0  |         }  | 
955  | 0  |     }  | 
956  |  |  | 
957  | 0  |     if (group->meth->points_make_affine == NULL  | 
958  | 0  |         || !group->meth->points_make_affine(group, num, points, ctx))  | 
959  | 0  |         goto err;  | 
960  |  |  | 
961  | 0  |     pre_comp->group = group;  | 
962  | 0  |     pre_comp->blocksize = blocksize;  | 
963  | 0  |     pre_comp->numblocks = numblocks;  | 
964  | 0  |     pre_comp->w = w;  | 
965  | 0  |     pre_comp->points = points;  | 
966  | 0  |     points = NULL;  | 
967  | 0  |     pre_comp->num = num;  | 
968  | 0  |     SETPRECOMP(group, ec, pre_comp);  | 
969  | 0  |     pre_comp = NULL;  | 
970  | 0  |     ret = 1;  | 
971  |  | 
  | 
972  | 0  |  err:  | 
973  | 0  |     if (used_ctx)  | 
974  | 0  |         BN_CTX_end(ctx);  | 
975  | 0  | #ifndef FIPS_MODULE  | 
976  | 0  |     BN_CTX_free(new_ctx);  | 
977  | 0  | #endif  | 
978  | 0  |     EC_ec_pre_comp_free(pre_comp);  | 
979  | 0  |     if (points) { | 
980  | 0  |         EC_POINT **p;  | 
981  |  | 
  | 
982  | 0  |         for (p = points; *p != NULL; p++)  | 
983  | 0  |             EC_POINT_free(*p);  | 
984  | 0  |         OPENSSL_free(points);  | 
985  | 0  |     }  | 
986  | 0  |     EC_POINT_free(tmp_point);  | 
987  | 0  |     EC_POINT_free(base);  | 
988  | 0  |     return ret;  | 
989  | 0  | }  | 
990  |  |  | 
991  |  | int ossl_ec_wNAF_have_precompute_mult(const EC_GROUP *group)  | 
992  | 0  | { | 
993  | 0  |     return HAVEPRECOMP(group, ec);  | 
994  | 0  | }  |