/src/openssl30/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 | 0 | #define EC_POINT_BN_set_flags(P, flags) do { \ | 
| 111 | 0 |     BN_set_flags((P)->X, (flags)); \ | 
| 112 | 0 |     BN_set_flags((P)->Y, (flags)); \ | 
| 113 | 0 |     BN_set_flags((P)->Z, (flags)); \ | 
| 114 | 0 | } 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 | 0 | { | 
| 149 | 0 |     int i, cardinality_bits, group_top, kbit, pbit, Z_is_one; | 
| 150 | 0 |     EC_POINT *p = NULL; | 
| 151 | 0 |     EC_POINT *s = NULL; | 
| 152 | 0 |     BIGNUM *k = NULL; | 
| 153 | 0 |     BIGNUM *lambda = NULL; | 
| 154 | 0 |     BIGNUM *cardinality = NULL; | 
| 155 | 0 |     int ret = 0; | 
| 156 |  |  | 
| 157 |  |     /* early exit if the input point is the point at infinity */ | 
| 158 | 0 |     if (point != NULL && EC_POINT_is_at_infinity(group, point)) | 
| 159 | 0 |         return EC_POINT_set_to_infinity(group, r); | 
| 160 |  |  | 
| 161 | 0 |     if (BN_is_zero(group->order)) { | 
| 162 | 0 |         ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER); | 
| 163 | 0 |         return 0; | 
| 164 | 0 |     } | 
| 165 | 0 |     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 | 0 |     BN_CTX_start(ctx); | 
| 171 |  | 
 | 
| 172 | 0 |     if (((p = EC_POINT_new(group)) == NULL) | 
| 173 | 0 |         || ((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 | 0 |     if (point == NULL) { | 
| 179 | 0 |         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 | 0 |     } else { | 
| 184 | 0 |         if (!EC_POINT_copy(p, point)) { | 
| 185 | 0 |             ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); | 
| 186 | 0 |             goto err; | 
| 187 | 0 |         } | 
| 188 | 0 |     } | 
| 189 |  |  | 
| 190 | 0 |     EC_POINT_BN_set_flags(p, BN_FLG_CONSTTIME); | 
| 191 | 0 |     EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME); | 
| 192 | 0 |     EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME); | 
| 193 |  | 
 | 
| 194 | 0 |     cardinality = BN_CTX_get(ctx); | 
| 195 | 0 |     lambda = BN_CTX_get(ctx); | 
| 196 | 0 |     k = BN_CTX_get(ctx); | 
| 197 | 0 |     if (k == NULL) { | 
| 198 | 0 |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); | 
| 199 | 0 |         goto err; | 
| 200 | 0 |     } | 
| 201 |  |  | 
| 202 | 0 |     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 | 0 |     cardinality_bits = BN_num_bits(cardinality); | 
| 214 | 0 |     group_top = bn_get_top(cardinality); | 
| 215 | 0 |     if ((bn_wexpand(k, group_top + 2) == NULL) | 
| 216 | 0 |         || (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 | 0 |     if (!BN_copy(k, scalar)) { | 
| 222 | 0 |         ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); | 
| 223 | 0 |         goto err; | 
| 224 | 0 |     } | 
| 225 |  |  | 
| 226 | 0 |     BN_set_flags(k, BN_FLG_CONSTTIME); | 
| 227 |  | 
 | 
| 228 | 0 |     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 | 0 |         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 | 0 |     } | 
| 238 |  |  | 
| 239 | 0 |     if (!BN_add(lambda, k, cardinality)) { | 
| 240 | 0 |         ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); | 
| 241 | 0 |         goto err; | 
| 242 | 0 |     } | 
| 243 | 0 |     BN_set_flags(lambda, BN_FLG_CONSTTIME); | 
| 244 | 0 |     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 | 0 |     kbit = BN_is_bit_set(lambda, cardinality_bits); | 
| 253 | 0 |     BN_consttime_swap(kbit, k, lambda, group_top + 2); | 
| 254 |  | 
 | 
| 255 | 0 |     group_top = bn_get_top(group->field); | 
| 256 | 0 |     if ((bn_wexpand(s->X, group_top) == NULL) | 
| 257 | 0 |         || (bn_wexpand(s->Y, group_top) == NULL) | 
| 258 | 0 |         || (bn_wexpand(s->Z, group_top) == NULL) | 
| 259 | 0 |         || (bn_wexpand(r->X, group_top) == NULL) | 
| 260 | 0 |         || (bn_wexpand(r->Y, group_top) == NULL) | 
| 261 | 0 |         || (bn_wexpand(r->Z, group_top) == NULL) | 
| 262 | 0 |         || (bn_wexpand(p->X, group_top) == NULL) | 
| 263 | 0 |         || (bn_wexpand(p->Y, group_top) == NULL) | 
| 264 | 0 |         || (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 | 0 |     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 | 0 |     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 | 0 |     pbit = 1; | 
| 284 |  | 
 | 
| 285 | 0 | #define EC_POINT_CSWAP(c, a, b, w, t) do {         \ | 
| 286 | 0 |         BN_consttime_swap(c, (a)->X, (b)->X, w);   \ | 
| 287 | 0 |         BN_consttime_swap(c, (a)->Y, (b)->Y, w);   \ | 
| 288 | 0 |         BN_consttime_swap(c, (a)->Z, (b)->Z, w);   \ | 
| 289 | 0 |         t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ | 
| 290 | 0 |         (a)->Z_is_one ^= (t);                      \ | 
| 291 | 0 |         (b)->Z_is_one ^= (t);                      \ | 
| 292 | 0 | } 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 | 0 |     for (i = cardinality_bits - 1; i >= 0; i--) { | 
| 353 | 0 |         kbit = BN_is_bit_set(k, i) ^ pbit; | 
| 354 | 0 |         EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one); | 
| 355 |  |  | 
| 356 |  |         /* Perform a single step of the Montgomery ladder */ | 
| 357 | 0 |         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 | 0 |         pbit ^= kbit; | 
| 366 | 0 |     } | 
| 367 |  |     /* one final cswap to move the right value into r */ | 
| 368 | 0 |     EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one); | 
| 369 | 0 | #undef EC_POINT_CSWAP | 
| 370 |  |  | 
| 371 |  |     /* Finalize ladder (and recover full point coordinates) */ | 
| 372 | 0 |     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 | 0 |     ret = 1; | 
| 378 |  | 
 | 
| 379 | 0 |  err: | 
| 380 | 0 |     EC_POINT_free(p); | 
| 381 | 0 |     EC_POINT_clear_free(s); | 
| 382 | 0 |     BN_CTX_end(ctx); | 
| 383 |  | 
 | 
| 384 | 0 |     return ret; | 
| 385 | 0 | } | 
| 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 | 0 |                 ((size_t) \ | 
| 396 | 0 |                  ((b) >= 2000 ? 6 : \ | 
| 397 | 0 |                   (b) >=  800 ? 5 : \ | 
| 398 | 0 |                   (b) >=  300 ? 4 : \ | 
| 399 | 0 |                   (b) >=   70 ? 3 : \ | 
| 400 | 0 |                   (b) >=   20 ? 2 : \ | 
| 401 | 0 |                   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 | 0 | { | 
| 414 | 0 |     const EC_POINT *generator = NULL; | 
| 415 | 0 |     EC_POINT *tmp = NULL; | 
| 416 | 0 |     size_t totalnum; | 
| 417 | 0 |     size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ | 
| 418 | 0 |     size_t pre_points_per_block = 0; | 
| 419 | 0 |     size_t i, j; | 
| 420 | 0 |     int k; | 
| 421 | 0 |     int r_is_inverted = 0; | 
| 422 | 0 |     int r_is_at_infinity = 1; | 
| 423 | 0 |     size_t *wsize = NULL;       /* individual window sizes */ | 
| 424 | 0 |     signed char **wNAF = NULL;  /* individual wNAFs */ | 
| 425 | 0 |     size_t *wNAF_len = NULL; | 
| 426 | 0 |     size_t max_len = 0; | 
| 427 | 0 |     size_t num_val; | 
| 428 | 0 |     EC_POINT **val = NULL;      /* precomputation */ | 
| 429 | 0 |     EC_POINT **v; | 
| 430 | 0 |     EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or | 
| 431 |  |                                  * 'pre_comp->points' */ | 
| 432 | 0 |     const EC_PRE_COMP *pre_comp = NULL; | 
| 433 | 0 |     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 | 0 |     int ret = 0; | 
| 437 |  | 
 | 
| 438 | 0 |     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 | 0 |         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 | 0 |             return ossl_ec_scalar_mul_ladder(group, r, scalar, NULL, ctx); | 
| 454 | 0 |         } | 
| 455 | 0 |         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 | 0 |             return ossl_ec_scalar_mul_ladder(group, r, scalars[0], points[0], | 
| 464 | 0 |                                              ctx); | 
| 465 | 0 |         } | 
| 466 | 0 |     } | 
| 467 |  |  | 
| 468 | 0 |     if (scalar != NULL) { | 
| 469 | 0 |         generator = EC_GROUP_get0_generator(group); | 
| 470 | 0 |         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 | 0 |         pre_comp = group->pre_comp.ec; | 
| 478 | 0 |         if (pre_comp && pre_comp->numblocks | 
| 479 | 0 |             && (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 | 0 |         } else { | 
| 503 |  |             /* can't use precomputation */ | 
| 504 | 0 |             pre_comp = NULL; | 
| 505 | 0 |             numblocks = 1; | 
| 506 | 0 |             num_scalar = 1;     /* treat 'scalar' like 'num'-th element of | 
| 507 |  |                                  * 'scalars' */ | 
| 508 | 0 |         } | 
| 509 | 0 |     } | 
| 510 |  |  | 
| 511 | 0 |     totalnum = num + numblocks; | 
| 512 |  | 
 | 
| 513 | 0 |     wsize = OPENSSL_malloc(totalnum * sizeof(wsize[0])); | 
| 514 | 0 |     wNAF_len = OPENSSL_malloc(totalnum * sizeof(wNAF_len[0])); | 
| 515 |  |     /* include space for pivot */ | 
| 516 | 0 |     wNAF = OPENSSL_malloc((totalnum + 1) * sizeof(wNAF[0])); | 
| 517 | 0 |     val_sub = OPENSSL_malloc(totalnum * sizeof(val_sub[0])); | 
| 518 |  |  | 
| 519 |  |     /* Ensure wNAF is initialised in case we end up going to err */ | 
| 520 | 0 |     if (wNAF != NULL) | 
| 521 | 0 |         wNAF[0] = NULL;         /* preliminary pivot */ | 
| 522 |  | 
 | 
| 523 | 0 |     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 | 0 |     num_val = 0; | 
| 532 |  | 
 | 
| 533 | 0 |     for (i = 0; i < num + num_scalar; i++) { | 
| 534 | 0 |         size_t bits; | 
| 535 |  | 
 | 
| 536 | 0 |         bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); | 
| 537 | 0 |         wsize[i] = EC_window_bits_for_scalar_size(bits); | 
| 538 | 0 |         num_val += (size_t)1 << (wsize[i] - 1); | 
| 539 | 0 |         wNAF[i + 1] = NULL;     /* make sure we always have a pivot */ | 
| 540 | 0 |         wNAF[i] = | 
| 541 | 0 |             bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], | 
| 542 | 0 |                             &wNAF_len[i]); | 
| 543 | 0 |         if (wNAF[i] == NULL) | 
| 544 | 0 |             goto err; | 
| 545 | 0 |         if (wNAF_len[i] > max_len) | 
| 546 | 0 |             max_len = wNAF_len[i]; | 
| 547 | 0 |     } | 
| 548 |  |  | 
| 549 | 0 |     if (numblocks) { | 
| 550 |  |         /* we go here iff scalar != NULL */ | 
| 551 |  | 
 | 
| 552 | 0 |         if (pre_comp == NULL) { | 
| 553 | 0 |             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 | 0 |         } 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 | 0 |     } | 
| 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 | 0 |     val = OPENSSL_malloc((num_val + 1) * sizeof(val[0])); | 
| 664 | 0 |     if (val == NULL) { | 
| 665 | 0 |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); | 
| 666 | 0 |         goto err; | 
| 667 | 0 |     } | 
| 668 | 0 |     val[num_val] = NULL;        /* pivot element */ | 
| 669 |  |  | 
| 670 |  |     /* allocate points for precomputation */ | 
| 671 | 0 |     v = val; | 
| 672 | 0 |     for (i = 0; i < num + num_scalar; i++) { | 
| 673 | 0 |         val_sub[i] = v; | 
| 674 | 0 |         for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) { | 
| 675 | 0 |             *v = EC_POINT_new(group); | 
| 676 | 0 |             if (*v == NULL) | 
| 677 | 0 |                 goto err; | 
| 678 | 0 |             v++; | 
| 679 | 0 |         } | 
| 680 | 0 |     } | 
| 681 | 0 |     if (!(v == val + num_val)) { | 
| 682 | 0 |         ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); | 
| 683 | 0 |         goto err; | 
| 684 | 0 |     } | 
| 685 |  |  | 
| 686 | 0 |     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 | 0 |     for (i = 0; i < num + num_scalar; i++) { | 
| 697 | 0 |         if (i < num) { | 
| 698 | 0 |             if (!EC_POINT_copy(val_sub[i][0], points[i])) | 
| 699 | 0 |                 goto err; | 
| 700 | 0 |         } else { | 
| 701 | 0 |             if (!EC_POINT_copy(val_sub[i][0], generator)) | 
| 702 | 0 |                 goto err; | 
| 703 | 0 |         } | 
| 704 |  |  | 
| 705 | 0 |         if (wsize[i] > 1) { | 
| 706 | 0 |             if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) | 
| 707 | 0 |                 goto err; | 
| 708 | 0 |             for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) { | 
| 709 | 0 |                 if (!EC_POINT_add | 
| 710 | 0 |                     (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) | 
| 711 | 0 |                     goto err; | 
| 712 | 0 |             } | 
| 713 | 0 |         } | 
| 714 | 0 |     } | 
| 715 |  |  | 
| 716 | 0 |     if (group->meth->points_make_affine == NULL | 
| 717 | 0 |         || !group->meth->points_make_affine(group, num_val, val, ctx)) | 
| 718 | 0 |         goto err; | 
| 719 |  |  | 
| 720 | 0 |     r_is_at_infinity = 1; | 
| 721 |  | 
 | 
| 722 | 0 |     for (k = max_len - 1; k >= 0; k--) { | 
| 723 | 0 |         if (!r_is_at_infinity) { | 
| 724 | 0 |             if (!EC_POINT_dbl(group, r, r, ctx)) | 
| 725 | 0 |                 goto err; | 
| 726 | 0 |         } | 
| 727 |  |  | 
| 728 | 0 |         for (i = 0; i < totalnum; i++) { | 
| 729 | 0 |             if (wNAF_len[i] > (size_t)k) { | 
| 730 | 0 |                 int digit = wNAF[i][k]; | 
| 731 | 0 |                 int is_neg; | 
| 732 |  | 
 | 
| 733 | 0 |                 if (digit) { | 
| 734 | 0 |                     is_neg = digit < 0; | 
| 735 |  | 
 | 
| 736 | 0 |                     if (is_neg) | 
| 737 | 0 |                         digit = -digit; | 
| 738 |  | 
 | 
| 739 | 0 |                     if (is_neg != r_is_inverted) { | 
| 740 | 0 |                         if (!r_is_at_infinity) { | 
| 741 | 0 |                             if (!EC_POINT_invert(group, r, ctx)) | 
| 742 | 0 |                                 goto err; | 
| 743 | 0 |                         } | 
| 744 | 0 |                         r_is_inverted = !r_is_inverted; | 
| 745 | 0 |                     } | 
| 746 |  |  | 
| 747 |  |                     /* digit > 0 */ | 
| 748 |  |  | 
| 749 | 0 |                     if (r_is_at_infinity) { | 
| 750 | 0 |                         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 | 0 |                         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 | 0 |                         r_is_at_infinity = 0; | 
| 767 | 0 |                     } else { | 
| 768 | 0 |                         if (!EC_POINT_add | 
| 769 | 0 |                             (group, r, r, val_sub[i][digit >> 1], ctx)) | 
| 770 | 0 |                             goto err; | 
| 771 | 0 |                     } | 
| 772 | 0 |                 } | 
| 773 | 0 |             } | 
| 774 | 0 |         } | 
| 775 | 0 |     } | 
| 776 |  |  | 
| 777 | 0 |     if (r_is_at_infinity) { | 
| 778 | 0 |         if (!EC_POINT_set_to_infinity(group, r)) | 
| 779 | 0 |             goto err; | 
| 780 | 0 |     } else { | 
| 781 | 0 |         if (r_is_inverted) | 
| 782 | 0 |             if (!EC_POINT_invert(group, r, ctx)) | 
| 783 | 0 |                 goto err; | 
| 784 | 0 |     } | 
| 785 |  |  | 
| 786 | 0 |     ret = 1; | 
| 787 |  | 
 | 
| 788 | 0 |  err: | 
| 789 | 0 |     EC_POINT_free(tmp); | 
| 790 | 0 |     OPENSSL_free(wsize); | 
| 791 | 0 |     OPENSSL_free(wNAF_len); | 
| 792 | 0 |     if (wNAF != NULL) { | 
| 793 | 0 |         signed char **w; | 
| 794 |  | 
 | 
| 795 | 0 |         for (w = wNAF; *w != NULL; w++) | 
| 796 | 0 |             OPENSSL_free(*w); | 
| 797 |  | 
 | 
| 798 | 0 |         OPENSSL_free(wNAF); | 
| 799 | 0 |     } | 
| 800 | 0 |     if (val != NULL) { | 
| 801 | 0 |         for (v = val; *v != NULL; v++) | 
| 802 | 0 |             EC_POINT_clear_free(*v); | 
| 803 |  | 
 | 
| 804 | 0 |         OPENSSL_free(val); | 
| 805 | 0 |     } | 
| 806 | 0 |     OPENSSL_free(val_sub); | 
| 807 | 0 |     return ret; | 
| 808 | 0 | } | 
| 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 | } |