diff options
Diffstat (limited to 'src/lib/libcrypto/ec/ecp_nistz256.c')
-rw-r--r-- | src/lib/libcrypto/ec/ecp_nistz256.c | 1191 |
1 files changed, 0 insertions, 1191 deletions
diff --git a/src/lib/libcrypto/ec/ecp_nistz256.c b/src/lib/libcrypto/ec/ecp_nistz256.c deleted file mode 100644 index 62aac44c64..0000000000 --- a/src/lib/libcrypto/ec/ecp_nistz256.c +++ /dev/null | |||
@@ -1,1191 +0,0 @@ | |||
1 | /* $OpenBSD: ecp_nistz256.c,v 1.14 2022/11/26 16:08:52 tb Exp $ */ | ||
2 | /* Copyright (c) 2014, Intel Corporation. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ | ||
15 | |||
16 | /* Developers and authors: | ||
17 | * Shay Gueron (1, 2), and Vlad Krasnov (1) | ||
18 | * (1) Intel Corporation, Israel Development Center | ||
19 | * (2) University of Haifa | ||
20 | * Reference: | ||
21 | * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with | ||
22 | * 256 Bit Primes" */ | ||
23 | |||
24 | /* | ||
25 | * The following license applies to _booth_recode_w5() and | ||
26 | * _booth_recode_w7(): | ||
27 | */ | ||
28 | /* Copyright (c) 2015, Google Inc. | ||
29 | * | ||
30 | * Permission to use, copy, modify, and/or distribute this software for any | ||
31 | * purpose with or without fee is hereby granted, provided that the above | ||
32 | * copyright notice and this permission notice appear in all copies. | ||
33 | * | ||
34 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
35 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
36 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
37 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
38 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
39 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
40 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ | ||
41 | |||
42 | #include <string.h> | ||
43 | |||
44 | #include <openssl/crypto.h> | ||
45 | #include <openssl/bn.h> | ||
46 | #include <openssl/ec.h> | ||
47 | #include <openssl/err.h> | ||
48 | |||
49 | #include "ec_local.h" | ||
50 | |||
51 | #if BN_BITS2 != 64 | ||
52 | #define TOBN(hi,lo) lo,hi | ||
53 | #else | ||
54 | #define TOBN(hi,lo) ((BN_ULONG)hi << 32 | lo) | ||
55 | #endif | ||
56 | |||
57 | #if defined(__GNUC__) | ||
58 | #define ALIGN32 __attribute((aligned(32))) | ||
59 | #elif defined(_MSC_VER) | ||
60 | #define ALIGN32 __declspec(align(32)) | ||
61 | #else | ||
62 | #define ALIGN32 | ||
63 | #endif | ||
64 | |||
65 | #define P256_LIMBS (256 / BN_BITS2) | ||
66 | |||
67 | typedef struct { | ||
68 | BN_ULONG X[P256_LIMBS]; | ||
69 | BN_ULONG Y[P256_LIMBS]; | ||
70 | BN_ULONG Z[P256_LIMBS]; | ||
71 | } P256_POINT; | ||
72 | |||
73 | typedef struct { | ||
74 | BN_ULONG X[P256_LIMBS]; | ||
75 | BN_ULONG Y[P256_LIMBS]; | ||
76 | } P256_POINT_AFFINE; | ||
77 | |||
78 | typedef P256_POINT_AFFINE PRECOMP256_ROW[64]; | ||
79 | |||
80 | /* structure for precomputed multiples of the generator */ | ||
81 | typedef struct ec_pre_comp_st { | ||
82 | const EC_GROUP *group; /* Parent EC_GROUP object */ | ||
83 | size_t w; /* Window size */ | ||
84 | /* | ||
85 | * Constant time access to the X and Y coordinates of the pre-computed, | ||
86 | * generator multiplies, in the Montgomery domain. Pre-calculated | ||
87 | * multiplies are stored in affine form. | ||
88 | */ | ||
89 | PRECOMP256_ROW *precomp; | ||
90 | int references; | ||
91 | } EC_PRE_COMP; | ||
92 | |||
93 | /* | ||
94 | * Arithmetic on field elements using Almost Montgomery Multiplication. The | ||
95 | * "almost" means, in particular, that the inputs and outputs of these | ||
96 | * functions are in the range [0, 2**BN_BITS2), not [0, P). Only | ||
97 | * |ecp_nistz256_from_mont| outputs a fully reduced value in [0, P). Almost | ||
98 | * Montgomery Arithmetic is described clearly in "Efficient Software | ||
99 | * Implementations of Modular Exponentiation" by Shay Gueron. | ||
100 | */ | ||
101 | |||
102 | /* Modular neg: res = -a mod P, where res is not fully reduced. */ | ||
103 | void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], | ||
104 | const BN_ULONG a[P256_LIMBS]); | ||
105 | /* Montgomery mul: res = a*b*2^-256 mod P, where res is not fully reduced. */ | ||
106 | void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS], | ||
107 | const BN_ULONG a[P256_LIMBS], const BN_ULONG b[P256_LIMBS]); | ||
108 | /* Montgomery sqr: res = a*a*2^-256 mod P, where res is not fully reduced. */ | ||
109 | void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS], | ||
110 | const BN_ULONG a[P256_LIMBS]); | ||
111 | /* Convert a number from Montgomery domain, by multiplying with 1, where res | ||
112 | * will be fully reduced mod P. */ | ||
113 | void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS], | ||
114 | const BN_ULONG in[P256_LIMBS]); | ||
115 | |||
116 | /* Functions that perform constant time access to the precomputed tables */ | ||
117 | void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT *in_t, | ||
118 | int index); | ||
119 | void ecp_nistz256_select_w7(P256_POINT_AFFINE *val, | ||
120 | const P256_POINT_AFFINE *in_t, int index); | ||
121 | |||
122 | /* One converted into the Montgomery domain */ | ||
123 | static const BN_ULONG ONE[P256_LIMBS] = { | ||
124 | TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000), | ||
125 | TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe) | ||
126 | }; | ||
127 | |||
128 | static void *ecp_nistz256_pre_comp_dup(void *); | ||
129 | static void ecp_nistz256_pre_comp_free(void *); | ||
130 | static void ecp_nistz256_pre_comp_clear_free(void *); | ||
131 | static EC_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group); | ||
132 | |||
133 | /* Precomputed tables for the default generator */ | ||
134 | #include "ecp_nistz256_table.h" | ||
135 | |||
136 | /* This function looks at 5+1 scalar bits (5 current, 1 adjacent less | ||
137 | * significant bit), and recodes them into a signed digit for use in fast point | ||
138 | * multiplication: the use of signed rather than unsigned digits means that | ||
139 | * fewer points need to be precomputed, given that point inversion is easy (a | ||
140 | * precomputed point dP makes -dP available as well). | ||
141 | * | ||
142 | * BACKGROUND: | ||
143 | * | ||
144 | * Signed digits for multiplication were introduced by Booth ("A signed binary | ||
145 | * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV, | ||
146 | * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers. | ||
147 | * Booth's original encoding did not generally improve the density of nonzero | ||
148 | * digits over the binary representation, and was merely meant to simplify the | ||
149 | * handling of signed factors given in two's complement; but it has since been | ||
150 | * shown to be the basis of various signed-digit representations that do have | ||
151 | * further advantages, including the wNAF, using the following general | ||
152 | * approach: | ||
153 | * | ||
154 | * (1) Given a binary representation | ||
155 | * | ||
156 | * b_k ... b_2 b_1 b_0, | ||
157 | * | ||
158 | * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1 | ||
159 | * by using bit-wise subtraction as follows: | ||
160 | * | ||
161 | * b_k b_(k-1) ... b_2 b_1 b_0 | ||
162 | * - b_k ... b_3 b_2 b_1 b_0 | ||
163 | * ------------------------------------- | ||
164 | * s_k b_(k-1) ... s_3 s_2 s_1 s_0 | ||
165 | * | ||
166 | * A left-shift followed by subtraction of the original value yields a new | ||
167 | * representation of the same value, using signed bits s_i = b_(i+1) - b_i. | ||
168 | * This representation from Booth's paper has since appeared in the | ||
169 | * literature under a variety of different names including "reversed binary | ||
170 | * form", "alternating greedy expansion", "mutual opposite form", and | ||
171 | * "sign-alternating {+-1}-representation". | ||
172 | * | ||
173 | * An interesting property is that among the nonzero bits, values 1 and -1 | ||
174 | * strictly alternate. | ||
175 | * | ||
176 | * (2) Various window schemes can be applied to the Booth representation of | ||
177 | * integers: for example, right-to-left sliding windows yield the wNAF | ||
178 | * (a signed-digit encoding independently discovered by various researchers | ||
179 | * in the 1990s), and left-to-right sliding windows yield a left-to-right | ||
180 | * equivalent of the wNAF (independently discovered by various researchers | ||
181 | * around 2004). | ||
182 | * | ||
183 | * To prevent leaking information through side channels in point multiplication, | ||
184 | * we need to recode the given integer into a regular pattern: sliding windows | ||
185 | * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few | ||
186 | * decades older: we'll be using the so-called "modified Booth encoding" due to | ||
187 | * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49 | ||
188 | * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five | ||
189 | * signed bits into a signed digit: | ||
190 | * | ||
191 | * s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j) | ||
192 | * | ||
193 | * The sign-alternating property implies that the resulting digit values are | ||
194 | * integers from -16 to 16. | ||
195 | * | ||
196 | * Of course, we don't actually need to compute the signed digits s_i as an | ||
197 | * intermediate step (that's just a nice way to see how this scheme relates | ||
198 | * to the wNAF): a direct computation obtains the recoded digit from the | ||
199 | * six bits b_(4j + 4) ... b_(4j - 1). | ||
200 | * | ||
201 | * This function takes those five bits as an integer (0 .. 63), writing the | ||
202 | * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute | ||
203 | * value, in the range 0 .. 8). Note that this integer essentially provides the | ||
204 | * input bits "shifted to the left" by one position: for example, the input to | ||
205 | * compute the least significant recoded digit, given that there's no bit b_-1, | ||
206 | * has to be b_4 b_3 b_2 b_1 b_0 0. */ | ||
207 | |||
208 | static unsigned int | ||
209 | _booth_recode_w5(unsigned int in) | ||
210 | { | ||
211 | unsigned int s, d; | ||
212 | |||
213 | /* sets all bits to MSB(in), 'in' seen as 6-bit value */ | ||
214 | s = ~((in >> 5) - 1); | ||
215 | d = (1 << 6) - in - 1; | ||
216 | d = (d & s) | (in & ~s); | ||
217 | d = (d >> 1) + (d & 1); | ||
218 | |||
219 | return (d << 1) + (s & 1); | ||
220 | } | ||
221 | |||
222 | static unsigned int | ||
223 | _booth_recode_w7(unsigned int in) | ||
224 | { | ||
225 | unsigned int s, d; | ||
226 | |||
227 | /* sets all bits to MSB(in), 'in' seen as 8-bit value */ | ||
228 | s = ~((in >> 7) - 1); | ||
229 | d = (1 << 8) - in - 1; | ||
230 | d = (d & s) | (in & ~s); | ||
231 | d = (d >> 1) + (d & 1); | ||
232 | |||
233 | return (d << 1) + (s & 1); | ||
234 | } | ||
235 | |||
236 | static void | ||
237 | copy_conditional(BN_ULONG dst[P256_LIMBS], const BN_ULONG src[P256_LIMBS], | ||
238 | BN_ULONG move) | ||
239 | { | ||
240 | BN_ULONG mask1 = -move; | ||
241 | BN_ULONG mask2 = ~mask1; | ||
242 | |||
243 | dst[0] = (src[0] & mask1) ^ (dst[0] & mask2); | ||
244 | dst[1] = (src[1] & mask1) ^ (dst[1] & mask2); | ||
245 | dst[2] = (src[2] & mask1) ^ (dst[2] & mask2); | ||
246 | dst[3] = (src[3] & mask1) ^ (dst[3] & mask2); | ||
247 | if (P256_LIMBS == 8) { | ||
248 | dst[4] = (src[4] & mask1) ^ (dst[4] & mask2); | ||
249 | dst[5] = (src[5] & mask1) ^ (dst[5] & mask2); | ||
250 | dst[6] = (src[6] & mask1) ^ (dst[6] & mask2); | ||
251 | dst[7] = (src[7] & mask1) ^ (dst[7] & mask2); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | static BN_ULONG | ||
256 | is_zero(BN_ULONG in) | ||
257 | { | ||
258 | in |= (0 - in); | ||
259 | in = ~in; | ||
260 | in &= BN_MASK2; | ||
261 | in >>= BN_BITS2 - 1; | ||
262 | return in; | ||
263 | } | ||
264 | |||
265 | static BN_ULONG | ||
266 | is_equal(const BN_ULONG a[P256_LIMBS], const BN_ULONG b[P256_LIMBS]) | ||
267 | { | ||
268 | BN_ULONG res; | ||
269 | |||
270 | res = a[0] ^ b[0]; | ||
271 | res |= a[1] ^ b[1]; | ||
272 | res |= a[2] ^ b[2]; | ||
273 | res |= a[3] ^ b[3]; | ||
274 | if (P256_LIMBS == 8) { | ||
275 | res |= a[4] ^ b[4]; | ||
276 | res |= a[5] ^ b[5]; | ||
277 | res |= a[6] ^ b[6]; | ||
278 | res |= a[7] ^ b[7]; | ||
279 | } | ||
280 | |||
281 | return is_zero(res); | ||
282 | } | ||
283 | |||
284 | static BN_ULONG | ||
285 | is_one(const BIGNUM *z) | ||
286 | { | ||
287 | BN_ULONG res = 0; | ||
288 | BN_ULONG *a = z->d; | ||
289 | |||
290 | if (z->top == (P256_LIMBS - P256_LIMBS / 8)) { | ||
291 | res = a[0] ^ ONE[0]; | ||
292 | res |= a[1] ^ ONE[1]; | ||
293 | res |= a[2] ^ ONE[2]; | ||
294 | res |= a[3] ^ ONE[3]; | ||
295 | if (P256_LIMBS == 8) { | ||
296 | res |= a[4] ^ ONE[4]; | ||
297 | res |= a[5] ^ ONE[5]; | ||
298 | res |= a[6] ^ ONE[6]; | ||
299 | /* | ||
300 | * No check for a[7] (being zero) on 32-bit platforms, | ||
301 | * because value of "one" takes only 7 limbs. | ||
302 | */ | ||
303 | } | ||
304 | res = is_zero(res); | ||
305 | } | ||
306 | |||
307 | return res; | ||
308 | } | ||
309 | |||
310 | static int | ||
311 | ecp_nistz256_set_words(BIGNUM *a, BN_ULONG words[P256_LIMBS]) | ||
312 | { | ||
313 | if (!bn_wexpand(a, P256_LIMBS)) { | ||
314 | ECerror(ERR_R_MALLOC_FAILURE); | ||
315 | return 0; | ||
316 | } | ||
317 | memcpy(a->d, words, sizeof(BN_ULONG) * P256_LIMBS); | ||
318 | a->top = P256_LIMBS; | ||
319 | bn_correct_top(a); | ||
320 | return 1; | ||
321 | } | ||
322 | |||
323 | void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a); | ||
324 | void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a, | ||
325 | const P256_POINT *b); | ||
326 | void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a, | ||
327 | const P256_POINT_AFFINE *b); | ||
328 | |||
329 | /* r = in^-1 mod p */ | ||
330 | static void | ||
331 | ecp_nistz256_mod_inverse(BN_ULONG r[P256_LIMBS], const BN_ULONG in[P256_LIMBS]) | ||
332 | { | ||
333 | /* | ||
334 | * The poly is ffffffff 00000001 00000000 00000000 00000000 ffffffff | ||
335 | * ffffffff ffffffff. We use FLT and use poly-2 as exponent. | ||
336 | */ | ||
337 | BN_ULONG p2[P256_LIMBS]; | ||
338 | BN_ULONG p4[P256_LIMBS]; | ||
339 | BN_ULONG p8[P256_LIMBS]; | ||
340 | BN_ULONG p16[P256_LIMBS]; | ||
341 | BN_ULONG p32[P256_LIMBS]; | ||
342 | BN_ULONG res[P256_LIMBS]; | ||
343 | unsigned int i; | ||
344 | |||
345 | ecp_nistz256_sqr_mont(res, in); | ||
346 | ecp_nistz256_mul_mont(p2, res, in); /* 3*p */ | ||
347 | |||
348 | ecp_nistz256_sqr_mont(res, p2); | ||
349 | ecp_nistz256_sqr_mont(res, res); | ||
350 | ecp_nistz256_mul_mont(p4, res, p2); /* f*p */ | ||
351 | |||
352 | ecp_nistz256_sqr_mont(res, p4); | ||
353 | ecp_nistz256_sqr_mont(res, res); | ||
354 | ecp_nistz256_sqr_mont(res, res); | ||
355 | ecp_nistz256_sqr_mont(res, res); | ||
356 | ecp_nistz256_mul_mont(p8, res, p4); /* ff*p */ | ||
357 | |||
358 | ecp_nistz256_sqr_mont(res, p8); | ||
359 | for (i = 0; i < 7; i++) | ||
360 | ecp_nistz256_sqr_mont(res, res); | ||
361 | ecp_nistz256_mul_mont(p16, res, p8); /* ffff*p */ | ||
362 | |||
363 | ecp_nistz256_sqr_mont(res, p16); | ||
364 | for (i = 0; i < 15; i++) | ||
365 | ecp_nistz256_sqr_mont(res, res); | ||
366 | ecp_nistz256_mul_mont(p32, res, p16); /* ffffffff*p */ | ||
367 | |||
368 | ecp_nistz256_sqr_mont(res, p32); | ||
369 | for (i = 0; i < 31; i++) | ||
370 | ecp_nistz256_sqr_mont(res, res); | ||
371 | ecp_nistz256_mul_mont(res, res, in); | ||
372 | |||
373 | for (i = 0; i < 32 * 4; i++) | ||
374 | ecp_nistz256_sqr_mont(res, res); | ||
375 | ecp_nistz256_mul_mont(res, res, p32); | ||
376 | |||
377 | for (i = 0; i < 32; i++) | ||
378 | ecp_nistz256_sqr_mont(res, res); | ||
379 | ecp_nistz256_mul_mont(res, res, p32); | ||
380 | |||
381 | for (i = 0; i < 16; i++) | ||
382 | ecp_nistz256_sqr_mont(res, res); | ||
383 | ecp_nistz256_mul_mont(res, res, p16); | ||
384 | |||
385 | for (i = 0; i < 8; i++) | ||
386 | ecp_nistz256_sqr_mont(res, res); | ||
387 | ecp_nistz256_mul_mont(res, res, p8); | ||
388 | |||
389 | ecp_nistz256_sqr_mont(res, res); | ||
390 | ecp_nistz256_sqr_mont(res, res); | ||
391 | ecp_nistz256_sqr_mont(res, res); | ||
392 | ecp_nistz256_sqr_mont(res, res); | ||
393 | ecp_nistz256_mul_mont(res, res, p4); | ||
394 | |||
395 | ecp_nistz256_sqr_mont(res, res); | ||
396 | ecp_nistz256_sqr_mont(res, res); | ||
397 | ecp_nistz256_mul_mont(res, res, p2); | ||
398 | |||
399 | ecp_nistz256_sqr_mont(res, res); | ||
400 | ecp_nistz256_sqr_mont(res, res); | ||
401 | ecp_nistz256_mul_mont(res, res, in); | ||
402 | |||
403 | memcpy(r, res, sizeof(res)); | ||
404 | } | ||
405 | |||
406 | /* | ||
407 | * ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and | ||
408 | * returns one if it fits. Otherwise it returns zero. | ||
409 | */ | ||
410 | static int | ||
411 | ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS], const BIGNUM *in) | ||
412 | { | ||
413 | if (in->top > P256_LIMBS) | ||
414 | return 0; | ||
415 | |||
416 | memset(out, 0, sizeof(BN_ULONG) * P256_LIMBS); | ||
417 | memcpy(out, in->d, sizeof(BN_ULONG) * in->top); | ||
418 | return 1; | ||
419 | } | ||
420 | |||
421 | /* r = sum(scalar[i]*point[i]) */ | ||
422 | static int | ||
423 | ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, | ||
424 | const BIGNUM **scalar, const EC_POINT **point, size_t num, BN_CTX *ctx) | ||
425 | { | ||
426 | int ret = 0; | ||
427 | unsigned int i, j, index; | ||
428 | unsigned char (*p_str)[33] = NULL; | ||
429 | const unsigned int window_size = 5; | ||
430 | const unsigned int mask = (1 << (window_size + 1)) - 1; | ||
431 | unsigned int wvalue; | ||
432 | BN_ULONG tmp[P256_LIMBS]; | ||
433 | /* avoid warning about ignored alignment for stack variable */ | ||
434 | #if defined(__GNUC__) && !defined(__OpenBSD__) | ||
435 | ALIGN32 | ||
436 | #endif | ||
437 | P256_POINT h; | ||
438 | const BIGNUM **scalars = NULL; | ||
439 | P256_POINT (*table)[16] = NULL; | ||
440 | |||
441 | if (posix_memalign((void **)&table, 64, num * sizeof(*table)) != 0 || | ||
442 | (p_str = reallocarray(NULL, num, sizeof(*p_str))) == NULL || | ||
443 | (scalars = reallocarray(NULL, num, sizeof(*scalars))) == NULL) { | ||
444 | ECerror(ERR_R_MALLOC_FAILURE); | ||
445 | goto err; | ||
446 | } | ||
447 | |||
448 | for (i = 0; i < num; i++) { | ||
449 | P256_POINT *row = table[i]; | ||
450 | |||
451 | /* | ||
452 | * This is an unusual input, we don't guarantee | ||
453 | * constant-timeness. | ||
454 | */ | ||
455 | if (BN_num_bits(scalar[i]) > 256 || BN_is_negative(scalar[i])) { | ||
456 | BIGNUM *mod; | ||
457 | |||
458 | if ((mod = BN_CTX_get(ctx)) == NULL) | ||
459 | goto err; | ||
460 | if (!BN_nnmod(mod, scalar[i], &group->order, ctx)) { | ||
461 | ECerror(ERR_R_BN_LIB); | ||
462 | goto err; | ||
463 | } | ||
464 | scalars[i] = mod; | ||
465 | } else | ||
466 | scalars[i] = scalar[i]; | ||
467 | |||
468 | for (j = 0; j < scalars[i]->top * BN_BYTES; j += BN_BYTES) { | ||
469 | BN_ULONG d = scalars[i]->d[j / BN_BYTES]; | ||
470 | |||
471 | p_str[i][j + 0] = d & 0xff; | ||
472 | p_str[i][j + 1] = (d >> 8) & 0xff; | ||
473 | p_str[i][j + 2] = (d >> 16) & 0xff; | ||
474 | p_str[i][j + 3] = (d >> 24) & 0xff; | ||
475 | if (BN_BYTES == 8) { | ||
476 | d >>= 32; | ||
477 | p_str[i][j + 4] = d & 0xff; | ||
478 | p_str[i][j + 5] = (d >> 8) & 0xff; | ||
479 | p_str[i][j + 6] = (d >> 16) & 0xff; | ||
480 | p_str[i][j + 7] = (d >> 24) & 0xff; | ||
481 | } | ||
482 | } | ||
483 | for (; j < 33; j++) | ||
484 | p_str[i][j] = 0; | ||
485 | |||
486 | /* | ||
487 | * table[0] is implicitly (0,0,0) (the point at infinity), | ||
488 | * therefore it is not stored. All other values are actually | ||
489 | * stored with an offset of -1 in table. | ||
490 | */ | ||
491 | |||
492 | if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, | ||
493 | &point[i]->X) || | ||
494 | !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, | ||
495 | &point[i]->Y) || | ||
496 | !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, | ||
497 | &point[i]->Z)) { | ||
498 | ECerror(EC_R_COORDINATES_OUT_OF_RANGE); | ||
499 | goto err; | ||
500 | } | ||
501 | |||
502 | ecp_nistz256_point_double(&row[ 2 - 1], &row[ 1 - 1]); | ||
503 | ecp_nistz256_point_add(&row[ 3 - 1], &row[ 2 - 1], &row[1 - 1]); | ||
504 | ecp_nistz256_point_double(&row[ 4 - 1], &row[ 2 - 1]); | ||
505 | ecp_nistz256_point_double(&row[ 6 - 1], &row[ 3 - 1]); | ||
506 | ecp_nistz256_point_double(&row[ 8 - 1], &row[ 4 - 1]); | ||
507 | ecp_nistz256_point_double(&row[12 - 1], &row[ 6 - 1]); | ||
508 | ecp_nistz256_point_add(&row[ 5 - 1], &row[ 4 - 1], &row[1 - 1]); | ||
509 | ecp_nistz256_point_add(&row[ 7 - 1], &row[ 6 - 1], &row[1 - 1]); | ||
510 | ecp_nistz256_point_add(&row[ 9 - 1], &row[ 8 - 1], &row[1 - 1]); | ||
511 | ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]); | ||
512 | ecp_nistz256_point_double(&row[14 - 1], &row[ 7 - 1]); | ||
513 | ecp_nistz256_point_double(&row[10 - 1], &row[ 5 - 1]); | ||
514 | ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]); | ||
515 | ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]); | ||
516 | ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]); | ||
517 | } | ||
518 | |||
519 | index = 255; | ||
520 | |||
521 | wvalue = p_str[0][(index - 1) / 8]; | ||
522 | wvalue = (wvalue >> ((index - 1) % 8)) & mask; | ||
523 | |||
524 | ecp_nistz256_select_w5(r, table[0], _booth_recode_w5(wvalue) >> 1); | ||
525 | |||
526 | while (index >= 5) { | ||
527 | for (i = (index == 255 ? 1 : 0); i < num; i++) { | ||
528 | unsigned int off = (index - 1) / 8; | ||
529 | |||
530 | wvalue = p_str[i][off] | p_str[i][off + 1] << 8; | ||
531 | wvalue = (wvalue >> ((index - 1) % 8)) & mask; | ||
532 | |||
533 | wvalue = _booth_recode_w5(wvalue); | ||
534 | |||
535 | ecp_nistz256_select_w5(&h, table[i], wvalue >> 1); | ||
536 | |||
537 | ecp_nistz256_neg(tmp, h.Y); | ||
538 | copy_conditional(h.Y, tmp, (wvalue & 1)); | ||
539 | |||
540 | ecp_nistz256_point_add(r, r, &h); | ||
541 | } | ||
542 | |||
543 | index -= window_size; | ||
544 | |||
545 | ecp_nistz256_point_double(r, r); | ||
546 | ecp_nistz256_point_double(r, r); | ||
547 | ecp_nistz256_point_double(r, r); | ||
548 | ecp_nistz256_point_double(r, r); | ||
549 | ecp_nistz256_point_double(r, r); | ||
550 | } | ||
551 | |||
552 | /* Final window */ | ||
553 | for (i = 0; i < num; i++) { | ||
554 | wvalue = p_str[i][0]; | ||
555 | wvalue = (wvalue << 1) & mask; | ||
556 | |||
557 | wvalue = _booth_recode_w5(wvalue); | ||
558 | |||
559 | ecp_nistz256_select_w5(&h, table[i], wvalue >> 1); | ||
560 | |||
561 | ecp_nistz256_neg(tmp, h.Y); | ||
562 | copy_conditional(h.Y, tmp, wvalue & 1); | ||
563 | |||
564 | ecp_nistz256_point_add(r, r, &h); | ||
565 | } | ||
566 | |||
567 | ret = 1; | ||
568 | err: | ||
569 | free(table); | ||
570 | free(p_str); | ||
571 | free(scalars); | ||
572 | return ret; | ||
573 | } | ||
574 | |||
575 | /* Coordinates of G, for which we have precomputed tables */ | ||
576 | static const BN_ULONG def_xG[P256_LIMBS] = { | ||
577 | TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601), | ||
578 | TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6) | ||
579 | }; | ||
580 | |||
581 | static const BN_ULONG def_yG[P256_LIMBS] = { | ||
582 | TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c), | ||
583 | TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85) | ||
584 | }; | ||
585 | |||
586 | /* | ||
587 | * ecp_nistz256_is_affine_G returns one if |generator| is the standard, P-256 | ||
588 | * generator. | ||
589 | */ | ||
590 | static int | ||
591 | ecp_nistz256_is_affine_G(const EC_POINT *generator) | ||
592 | { | ||
593 | return generator->X.top == P256_LIMBS && | ||
594 | generator->Y.top == P256_LIMBS && | ||
595 | is_equal(generator->X.d, def_xG) && | ||
596 | is_equal(generator->Y.d, def_yG) && | ||
597 | is_one(&generator->Z); | ||
598 | } | ||
599 | |||
600 | static int | ||
601 | ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) | ||
602 | { | ||
603 | /* | ||
604 | * We precompute a table for a Booth encoded exponent (wNAF) based | ||
605 | * computation. Each table holds 64 values for safe access, with an | ||
606 | * implicit value of infinity at index zero. We use a window of size 7, | ||
607 | * and therefore require ceil(256/7) = 37 tables. | ||
608 | */ | ||
609 | EC_POINT *P = NULL, *T = NULL; | ||
610 | BN_CTX *new_ctx = NULL; | ||
611 | const EC_POINT *generator; | ||
612 | EC_PRE_COMP *ec_pre_comp; | ||
613 | BIGNUM *order; | ||
614 | int ret = 0; | ||
615 | unsigned int i, j, k; | ||
616 | PRECOMP256_ROW *precomp = NULL; | ||
617 | |||
618 | /* if there is an old EC_PRE_COMP object, throw it away */ | ||
619 | EC_EX_DATA_free_data(&group->extra_data, ecp_nistz256_pre_comp_dup, | ||
620 | ecp_nistz256_pre_comp_free, ecp_nistz256_pre_comp_clear_free); | ||
621 | |||
622 | generator = EC_GROUP_get0_generator(group); | ||
623 | if (generator == NULL) { | ||
624 | ECerror(EC_R_UNDEFINED_GENERATOR); | ||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | if (ecp_nistz256_is_affine_G(generator)) { | ||
629 | /* | ||
630 | * No need to calculate tables for the standard generator | ||
631 | * because we have them statically. | ||
632 | */ | ||
633 | return 1; | ||
634 | } | ||
635 | |||
636 | if ((ec_pre_comp = ecp_nistz256_pre_comp_new(group)) == NULL) | ||
637 | return 0; | ||
638 | |||
639 | if (ctx == NULL) { | ||
640 | ctx = new_ctx = BN_CTX_new(); | ||
641 | if (ctx == NULL) | ||
642 | goto err; | ||
643 | } | ||
644 | |||
645 | BN_CTX_start(ctx); | ||
646 | order = BN_CTX_get(ctx); | ||
647 | |||
648 | if (order == NULL) | ||
649 | goto err; | ||
650 | |||
651 | if (!EC_GROUP_get_order(group, order, ctx)) | ||
652 | goto err; | ||
653 | |||
654 | if (BN_is_zero(order)) { | ||
655 | ECerror(EC_R_UNKNOWN_ORDER); | ||
656 | goto err; | ||
657 | } | ||
658 | |||
659 | if (posix_memalign((void **)&precomp, 64, 37 * sizeof(*precomp)) != 0) { | ||
660 | ECerror(ERR_R_MALLOC_FAILURE); | ||
661 | goto err; | ||
662 | } | ||
663 | |||
664 | P = EC_POINT_new(group); | ||
665 | T = EC_POINT_new(group); | ||
666 | if (P == NULL || T == NULL) | ||
667 | goto err; | ||
668 | |||
669 | /* | ||
670 | * The zero entry is implicitly infinity, and we skip it, storing other | ||
671 | * values with -1 offset. | ||
672 | */ | ||
673 | if (!EC_POINT_copy(T, generator)) | ||
674 | goto err; | ||
675 | |||
676 | for (k = 0; k < 64; k++) { | ||
677 | if (!EC_POINT_copy(P, T)) | ||
678 | goto err; | ||
679 | for (j = 0; j < 37; j++) { | ||
680 | /* | ||
681 | * It would be faster to use EC_POINTs_make_affine and | ||
682 | * make multiple points affine at the same time. | ||
683 | */ | ||
684 | if (!EC_POINT_make_affine(group, P, ctx)) | ||
685 | goto err; | ||
686 | if (!ecp_nistz256_bignum_to_field_elem( | ||
687 | precomp[j][k].X, &P->X) || | ||
688 | !ecp_nistz256_bignum_to_field_elem( | ||
689 | precomp[j][k].Y, &P->Y)) { | ||
690 | ECerror(EC_R_COORDINATES_OUT_OF_RANGE); | ||
691 | goto err; | ||
692 | } | ||
693 | for (i = 0; i < 7; i++) { | ||
694 | if (!EC_POINT_dbl(group, P, P, ctx)) | ||
695 | goto err; | ||
696 | } | ||
697 | } | ||
698 | if (!EC_POINT_add(group, T, T, generator, ctx)) | ||
699 | goto err; | ||
700 | } | ||
701 | |||
702 | ec_pre_comp->group = group; | ||
703 | ec_pre_comp->w = 7; | ||
704 | ec_pre_comp->precomp = precomp; | ||
705 | |||
706 | if (!EC_EX_DATA_set_data(&group->extra_data, ec_pre_comp, | ||
707 | ecp_nistz256_pre_comp_dup, ecp_nistz256_pre_comp_free, | ||
708 | ecp_nistz256_pre_comp_clear_free)) { | ||
709 | goto err; | ||
710 | } | ||
711 | |||
712 | ec_pre_comp = NULL; | ||
713 | ret = 1; | ||
714 | |||
715 | err: | ||
716 | if (ctx != NULL) | ||
717 | BN_CTX_end(ctx); | ||
718 | BN_CTX_free(new_ctx); | ||
719 | |||
720 | ecp_nistz256_pre_comp_free(ec_pre_comp); | ||
721 | free(precomp); | ||
722 | EC_POINT_free(P); | ||
723 | EC_POINT_free(T); | ||
724 | return ret; | ||
725 | } | ||
726 | |||
727 | static int | ||
728 | ecp_nistz256_set_from_affine(EC_POINT *out, const EC_GROUP *group, | ||
729 | const P256_POINT_AFFINE *in, BN_CTX *ctx) | ||
730 | { | ||
731 | BIGNUM x, y; | ||
732 | BN_ULONG d_x[P256_LIMBS], d_y[P256_LIMBS]; | ||
733 | int ret = 0; | ||
734 | |||
735 | memcpy(d_x, in->X, sizeof(d_x)); | ||
736 | x.d = d_x; | ||
737 | x.dmax = x.top = P256_LIMBS; | ||
738 | x.neg = 0; | ||
739 | x.flags = BN_FLG_STATIC_DATA; | ||
740 | |||
741 | memcpy(d_y, in->Y, sizeof(d_y)); | ||
742 | y.d = d_y; | ||
743 | y.dmax = y.top = P256_LIMBS; | ||
744 | y.neg = 0; | ||
745 | y.flags = BN_FLG_STATIC_DATA; | ||
746 | |||
747 | ret = EC_POINT_set_affine_coordinates(group, out, &x, &y, ctx); | ||
748 | |||
749 | return ret; | ||
750 | } | ||
751 | |||
752 | /* r = scalar*G + sum(scalars[i]*points[i]) */ | ||
753 | static int | ||
754 | ecp_nistz256_points_mul(const EC_GROUP *group, EC_POINT *r, | ||
755 | const BIGNUM *scalar, size_t num, const EC_POINT *points[], | ||
756 | const BIGNUM *scalars[], BN_CTX *ctx) | ||
757 | { | ||
758 | int ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0; | ||
759 | size_t j; | ||
760 | unsigned char p_str[33] = { 0 }; | ||
761 | const PRECOMP256_ROW *precomp = NULL; | ||
762 | const EC_PRE_COMP *ec_pre_comp = NULL; | ||
763 | const EC_POINT *generator = NULL; | ||
764 | unsigned int i = 0, index = 0; | ||
765 | BN_CTX *new_ctx = NULL; | ||
766 | const BIGNUM **new_scalars = NULL; | ||
767 | const EC_POINT **new_points = NULL; | ||
768 | const unsigned int window_size = 7; | ||
769 | const unsigned int mask = (1 << (window_size + 1)) - 1; | ||
770 | unsigned int wvalue; | ||
771 | /* avoid warning about ignored alignment for stack variable */ | ||
772 | #if defined(__GNUC__) && !defined(__OpenBSD__) | ||
773 | ALIGN32 | ||
774 | #endif | ||
775 | union { | ||
776 | P256_POINT p; | ||
777 | P256_POINT_AFFINE a; | ||
778 | } t, p; | ||
779 | BIGNUM *tmp_scalar; | ||
780 | |||
781 | if (group->meth != r->meth) { | ||
782 | ECerror(EC_R_INCOMPATIBLE_OBJECTS); | ||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | if (scalar == NULL && num == 0) | ||
787 | return EC_POINT_set_to_infinity(group, r); | ||
788 | |||
789 | for (j = 0; j < num; j++) { | ||
790 | if (group->meth != points[j]->meth) { | ||
791 | ECerror(EC_R_INCOMPATIBLE_OBJECTS); | ||
792 | return 0; | ||
793 | } | ||
794 | } | ||
795 | |||
796 | if (ctx == NULL) { | ||
797 | ctx = new_ctx = BN_CTX_new(); | ||
798 | if (ctx == NULL) | ||
799 | goto err; | ||
800 | } | ||
801 | |||
802 | BN_CTX_start(ctx); | ||
803 | |||
804 | if (scalar) { | ||
805 | generator = EC_GROUP_get0_generator(group); | ||
806 | if (generator == NULL) { | ||
807 | ECerror(EC_R_UNDEFINED_GENERATOR); | ||
808 | goto err; | ||
809 | } | ||
810 | |||
811 | /* look if we can use precomputed multiples of generator */ | ||
812 | ec_pre_comp = EC_EX_DATA_get_data(group->extra_data, | ||
813 | ecp_nistz256_pre_comp_dup, ecp_nistz256_pre_comp_free, | ||
814 | ecp_nistz256_pre_comp_clear_free); | ||
815 | if (ec_pre_comp != NULL) { | ||
816 | /* | ||
817 | * If there is a precomputed table for the generator, | ||
818 | * check that it was generated with the same generator. | ||
819 | */ | ||
820 | EC_POINT *pre_comp_generator = EC_POINT_new(group); | ||
821 | if (pre_comp_generator == NULL) | ||
822 | goto err; | ||
823 | |||
824 | if (!ecp_nistz256_set_from_affine(pre_comp_generator, | ||
825 | group, ec_pre_comp->precomp[0], ctx)) { | ||
826 | EC_POINT_free(pre_comp_generator); | ||
827 | goto err; | ||
828 | } | ||
829 | |||
830 | if (0 == EC_POINT_cmp(group, generator, | ||
831 | pre_comp_generator, ctx)) | ||
832 | precomp = (const PRECOMP256_ROW *) | ||
833 | ec_pre_comp->precomp; | ||
834 | |||
835 | EC_POINT_free(pre_comp_generator); | ||
836 | } | ||
837 | |||
838 | if (precomp == NULL && ecp_nistz256_is_affine_G(generator)) { | ||
839 | /* | ||
840 | * If there is no precomputed data, but the generator | ||
841 | * is the default, a hardcoded table of precomputed | ||
842 | * data is used. This is because applications, such as | ||
843 | * Apache, do not use EC_KEY_precompute_mult. | ||
844 | */ | ||
845 | precomp = | ||
846 | (const PRECOMP256_ROW *)ecp_nistz256_precomputed; | ||
847 | } | ||
848 | |||
849 | if (precomp) { | ||
850 | if (BN_num_bits(scalar) > 256 || | ||
851 | BN_is_negative(scalar)) { | ||
852 | if ((tmp_scalar = BN_CTX_get(ctx)) == NULL) | ||
853 | goto err; | ||
854 | |||
855 | if (!BN_nnmod(tmp_scalar, scalar, &group->order, | ||
856 | ctx)) { | ||
857 | ECerror(ERR_R_BN_LIB); | ||
858 | goto err; | ||
859 | } | ||
860 | scalar = tmp_scalar; | ||
861 | } | ||
862 | |||
863 | for (i = 0; i < scalar->top * BN_BYTES; i += BN_BYTES) { | ||
864 | BN_ULONG d = scalar->d[i / BN_BYTES]; | ||
865 | |||
866 | p_str[i + 0] = d & 0xff; | ||
867 | p_str[i + 1] = (d >> 8) & 0xff; | ||
868 | p_str[i + 2] = (d >> 16) & 0xff; | ||
869 | p_str[i + 3] = (d >> 24) & 0xff; | ||
870 | if (BN_BYTES == 8) { | ||
871 | d >>= 32; | ||
872 | p_str[i + 4] = d & 0xff; | ||
873 | p_str[i + 5] = (d >> 8) & 0xff; | ||
874 | p_str[i + 6] = (d >> 16) & 0xff; | ||
875 | p_str[i + 7] = (d >> 24) & 0xff; | ||
876 | } | ||
877 | } | ||
878 | |||
879 | for (; i < 33; i++) | ||
880 | p_str[i] = 0; | ||
881 | |||
882 | /* First window */ | ||
883 | wvalue = (p_str[0] << 1) & mask; | ||
884 | index += window_size; | ||
885 | |||
886 | wvalue = _booth_recode_w7(wvalue); | ||
887 | |||
888 | ecp_nistz256_select_w7(&p.a, precomp[0], wvalue >> 1); | ||
889 | |||
890 | ecp_nistz256_neg(p.p.Z, p.p.Y); | ||
891 | copy_conditional(p.p.Y, p.p.Z, wvalue & 1); | ||
892 | |||
893 | /* | ||
894 | * Since affine infinity is encoded as (0,0) and | ||
895 | * Jacobian is (,,0), we need to harmonize them | ||
896 | * by assigning "one" or zero to Z. | ||
897 | */ | ||
898 | BN_ULONG infty; | ||
899 | infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] | | ||
900 | p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]); | ||
901 | if (P256_LIMBS == 8) | ||
902 | infty |= | ||
903 | (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] | | ||
904 | p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]); | ||
905 | |||
906 | infty = 0 - is_zero(infty); | ||
907 | infty = ~infty; | ||
908 | |||
909 | p.p.Z[0] = ONE[0] & infty; | ||
910 | p.p.Z[1] = ONE[1] & infty; | ||
911 | p.p.Z[2] = ONE[2] & infty; | ||
912 | p.p.Z[3] = ONE[3] & infty; | ||
913 | if (P256_LIMBS == 8) { | ||
914 | p.p.Z[4] = ONE[4] & infty; | ||
915 | p.p.Z[5] = ONE[5] & infty; | ||
916 | p.p.Z[6] = ONE[6] & infty; | ||
917 | p.p.Z[7] = ONE[7] & infty; | ||
918 | } | ||
919 | |||
920 | for (i = 1; i < 37; i++) { | ||
921 | unsigned int off = (index - 1) / 8; | ||
922 | wvalue = p_str[off] | p_str[off + 1] << 8; | ||
923 | wvalue = (wvalue >> ((index - 1) % 8)) & mask; | ||
924 | index += window_size; | ||
925 | |||
926 | wvalue = _booth_recode_w7(wvalue); | ||
927 | |||
928 | ecp_nistz256_select_w7(&t.a, precomp[i], | ||
929 | wvalue >> 1); | ||
930 | |||
931 | ecp_nistz256_neg(t.p.Z, t.a.Y); | ||
932 | copy_conditional(t.a.Y, t.p.Z, wvalue & 1); | ||
933 | |||
934 | ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); | ||
935 | } | ||
936 | } else { | ||
937 | p_is_infinity = 1; | ||
938 | no_precomp_for_generator = 1; | ||
939 | } | ||
940 | } else | ||
941 | p_is_infinity = 1; | ||
942 | |||
943 | if (no_precomp_for_generator) { | ||
944 | /* | ||
945 | * Without a precomputed table for the generator, it has to be | ||
946 | * handled like a normal point. | ||
947 | */ | ||
948 | new_scalars = reallocarray(NULL, num + 1, sizeof(BIGNUM *)); | ||
949 | new_points = reallocarray(NULL, num + 1, sizeof(EC_POINT *)); | ||
950 | if (new_scalars == NULL || new_points == NULL) { | ||
951 | ECerror(ERR_R_MALLOC_FAILURE); | ||
952 | goto err; | ||
953 | } | ||
954 | |||
955 | memcpy(new_scalars, scalars, num * sizeof(BIGNUM *)); | ||
956 | new_scalars[num] = scalar; | ||
957 | memcpy(new_points, points, num * sizeof(EC_POINT *)); | ||
958 | new_points[num] = generator; | ||
959 | |||
960 | scalars = new_scalars; | ||
961 | points = new_points; | ||
962 | num++; | ||
963 | } | ||
964 | |||
965 | if (num != 0) { | ||
966 | P256_POINT *out = &t.p; | ||
967 | if (p_is_infinity) | ||
968 | out = &p.p; | ||
969 | |||
970 | if (!ecp_nistz256_windowed_mul(group, out, scalars, points, num, | ||
971 | ctx)) | ||
972 | goto err; | ||
973 | |||
974 | if (!p_is_infinity) | ||
975 | ecp_nistz256_point_add(&p.p, &p.p, out); | ||
976 | } | ||
977 | |||
978 | /* Not constant-time, but we're only operating on the public output. */ | ||
979 | if (!ecp_nistz256_set_words(&r->X, p.p.X) || | ||
980 | !ecp_nistz256_set_words(&r->Y, p.p.Y) || | ||
981 | !ecp_nistz256_set_words(&r->Z, p.p.Z)) { | ||
982 | goto err; | ||
983 | } | ||
984 | r->Z_is_one = is_one(&r->Z) & 1; | ||
985 | |||
986 | ret = 1; | ||
987 | |||
988 | err: | ||
989 | if (ctx) | ||
990 | BN_CTX_end(ctx); | ||
991 | BN_CTX_free(new_ctx); | ||
992 | free(new_points); | ||
993 | free(new_scalars); | ||
994 | return ret; | ||
995 | } | ||
996 | |||
997 | static int | ||
998 | ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point, | ||
999 | BIGNUM *x, BIGNUM *y, BN_CTX *ctx) | ||
1000 | { | ||
1001 | BN_ULONG z_inv2[P256_LIMBS]; | ||
1002 | BN_ULONG z_inv3[P256_LIMBS]; | ||
1003 | BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS]; | ||
1004 | |||
1005 | if (EC_POINT_is_at_infinity(group, point)) { | ||
1006 | ECerror(EC_R_POINT_AT_INFINITY); | ||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | if (!ecp_nistz256_bignum_to_field_elem(point_x, &point->X) || | ||
1011 | !ecp_nistz256_bignum_to_field_elem(point_y, &point->Y) || | ||
1012 | !ecp_nistz256_bignum_to_field_elem(point_z, &point->Z)) { | ||
1013 | ECerror(EC_R_COORDINATES_OUT_OF_RANGE); | ||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | ecp_nistz256_mod_inverse(z_inv3, point_z); | ||
1018 | ecp_nistz256_sqr_mont(z_inv2, z_inv3); | ||
1019 | |||
1020 | /* | ||
1021 | * Unlike the |BN_mod_mul_montgomery|-based implementation, we cannot | ||
1022 | * factor out the two calls to |ecp_nistz256_from_mont| into one call, | ||
1023 | * because |ecp_nistz256_from_mont| must be the last operation to | ||
1024 | * ensure that the result is fully reduced mod P. | ||
1025 | */ | ||
1026 | if (x != NULL) { | ||
1027 | BN_ULONG x_aff[P256_LIMBS]; | ||
1028 | BN_ULONG x_ret[P256_LIMBS]; | ||
1029 | |||
1030 | ecp_nistz256_mul_mont(x_aff, z_inv2, point_x); | ||
1031 | ecp_nistz256_from_mont(x_ret, x_aff); | ||
1032 | if (!ecp_nistz256_set_words(x, x_ret)) | ||
1033 | return 0; | ||
1034 | } | ||
1035 | |||
1036 | if (y != NULL) { | ||
1037 | BN_ULONG y_aff[P256_LIMBS]; | ||
1038 | BN_ULONG y_ret[P256_LIMBS]; | ||
1039 | |||
1040 | ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2); | ||
1041 | ecp_nistz256_mul_mont(y_aff, z_inv3, point_y); | ||
1042 | ecp_nistz256_from_mont(y_ret, y_aff); | ||
1043 | if (!ecp_nistz256_set_words(y, y_ret)) | ||
1044 | return 0; | ||
1045 | } | ||
1046 | |||
1047 | return 1; | ||
1048 | } | ||
1049 | |||
1050 | static EC_PRE_COMP * | ||
1051 | ecp_nistz256_pre_comp_new(const EC_GROUP *group) | ||
1052 | { | ||
1053 | EC_PRE_COMP *ret; | ||
1054 | |||
1055 | if (group == NULL) | ||
1056 | return NULL; | ||
1057 | |||
1058 | ret = (EC_PRE_COMP *)malloc(sizeof(EC_PRE_COMP)); | ||
1059 | if (ret == NULL) { | ||
1060 | ECerror(ERR_R_MALLOC_FAILURE); | ||
1061 | return ret; | ||
1062 | } | ||
1063 | |||
1064 | ret->group = group; | ||
1065 | ret->w = 6; /* default */ | ||
1066 | ret->precomp = NULL; | ||
1067 | ret->references = 1; | ||
1068 | return ret; | ||
1069 | } | ||
1070 | |||
1071 | static void * | ||
1072 | ecp_nistz256_pre_comp_dup(void *src_) | ||
1073 | { | ||
1074 | EC_PRE_COMP *src = src_; | ||
1075 | |||
1076 | /* no need to actually copy, these objects never change! */ | ||
1077 | CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); | ||
1078 | |||
1079 | return src_; | ||
1080 | } | ||
1081 | |||
1082 | static void | ||
1083 | ecp_nistz256_pre_comp_free(void *pre_) | ||
1084 | { | ||
1085 | int i; | ||
1086 | EC_PRE_COMP *pre = pre_; | ||
1087 | |||
1088 | if (pre == NULL) | ||
1089 | return; | ||
1090 | |||
1091 | i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); | ||
1092 | if (i > 0) | ||
1093 | return; | ||
1094 | |||
1095 | free(pre->precomp); | ||
1096 | free(pre); | ||
1097 | } | ||
1098 | |||
1099 | static void | ||
1100 | ecp_nistz256_pre_comp_clear_free(void *pre_) | ||
1101 | { | ||
1102 | int i; | ||
1103 | EC_PRE_COMP *pre = pre_; | ||
1104 | |||
1105 | if (pre == NULL) | ||
1106 | return; | ||
1107 | |||
1108 | i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); | ||
1109 | if (i > 0) | ||
1110 | return; | ||
1111 | |||
1112 | if (pre->precomp != NULL) { | ||
1113 | /* | ||
1114 | * LSSL XXX | ||
1115 | * The original OpenSSL code uses an obfuscated | ||
1116 | * computation which is intended to be | ||
1117 | * 37 * (1 << pre->w) * sizeof(P256_POINT_AFFINE) | ||
1118 | * here, but the only place where we allocate this uses | ||
1119 | * PRECOMP256_ROW (i.e. 64 P256_POINT_AFFINE) but sets w == 7. | ||
1120 | */ | ||
1121 | freezero(pre->precomp, 37 * sizeof(PRECOMP256_ROW)); | ||
1122 | } | ||
1123 | freezero(pre, sizeof *pre); | ||
1124 | } | ||
1125 | |||
1126 | static int | ||
1127 | ecp_nistz256_window_have_precompute_mult(const EC_GROUP *group) | ||
1128 | { | ||
1129 | /* There is a hard-coded table for the default generator. */ | ||
1130 | const EC_POINT *generator = EC_GROUP_get0_generator(group); | ||
1131 | if (generator != NULL && ecp_nistz256_is_affine_G(generator)) { | ||
1132 | /* There is a hard-coded table for the default generator. */ | ||
1133 | return 1; | ||
1134 | } | ||
1135 | |||
1136 | return | ||
1137 | EC_EX_DATA_get_data(group->extra_data, ecp_nistz256_pre_comp_dup, | ||
1138 | ecp_nistz256_pre_comp_free, ecp_nistz256_pre_comp_clear_free) != | ||
1139 | NULL; | ||
1140 | } | ||
1141 | |||
1142 | const EC_METHOD * | ||
1143 | EC_GFp_nistz256_method(void) | ||
1144 | { | ||
1145 | static const EC_METHOD ret = { | ||
1146 | .flags = EC_FLAGS_DEFAULT_OCT, | ||
1147 | .field_type = NID_X9_62_prime_field, | ||
1148 | .group_init = ec_GFp_mont_group_init, | ||
1149 | .group_finish = ec_GFp_mont_group_finish, | ||
1150 | .group_clear_finish = ec_GFp_mont_group_clear_finish, | ||
1151 | .group_copy = ec_GFp_mont_group_copy, | ||
1152 | .group_set_curve = ec_GFp_mont_group_set_curve, | ||
1153 | .group_get_curve = ec_GFp_simple_group_get_curve, | ||
1154 | .group_get_degree = ec_GFp_simple_group_get_degree, | ||
1155 | .group_order_bits = ec_group_simple_order_bits, | ||
1156 | .group_check_discriminant = | ||
1157 | ec_GFp_simple_group_check_discriminant, | ||
1158 | .point_init = ec_GFp_simple_point_init, | ||
1159 | .point_finish = ec_GFp_simple_point_finish, | ||
1160 | .point_clear_finish = ec_GFp_simple_point_clear_finish, | ||
1161 | .point_copy = ec_GFp_simple_point_copy, | ||
1162 | .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity, | ||
1163 | .point_set_Jprojective_coordinates = | ||
1164 | ec_GFp_simple_set_Jprojective_coordinates, | ||
1165 | .point_get_Jprojective_coordinates = | ||
1166 | ec_GFp_simple_get_Jprojective_coordinates, | ||
1167 | .point_set_affine_coordinates = | ||
1168 | ec_GFp_simple_point_set_affine_coordinates, | ||
1169 | .point_get_affine_coordinates = ecp_nistz256_get_affine, | ||
1170 | .add = ec_GFp_simple_add, | ||
1171 | .dbl = ec_GFp_simple_dbl, | ||
1172 | .invert = ec_GFp_simple_invert, | ||
1173 | .is_at_infinity = ec_GFp_simple_is_at_infinity, | ||
1174 | .is_on_curve = ec_GFp_simple_is_on_curve, | ||
1175 | .point_cmp = ec_GFp_simple_cmp, | ||
1176 | .make_affine = ec_GFp_simple_make_affine, | ||
1177 | .points_make_affine = ec_GFp_simple_points_make_affine, | ||
1178 | .mul = ecp_nistz256_points_mul, | ||
1179 | .precompute_mult = ecp_nistz256_mult_precompute, | ||
1180 | .have_precompute_mult = | ||
1181 | ecp_nistz256_window_have_precompute_mult, | ||
1182 | .field_mul = ec_GFp_mont_field_mul, | ||
1183 | .field_sqr = ec_GFp_mont_field_sqr, | ||
1184 | .field_encode = ec_GFp_mont_field_encode, | ||
1185 | .field_decode = ec_GFp_mont_field_decode, | ||
1186 | .field_set_to_one = ec_GFp_mont_field_set_to_one, | ||
1187 | .blind_coordinates = NULL, | ||
1188 | }; | ||
1189 | |||
1190 | return &ret; | ||
1191 | } | ||