summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2024-11-23 12:56:31 +0000
committertb <>2024-11-23 12:56:31 +0000
commitf69cab5db16bb210dd0d4ae2f7e6e80ea8b29503 (patch)
tree5f349b025c06f8f850b0169de37a2b219f5ab02f
parent66beef8bfe83b33a0c5aaad6a85d57cca57cd62f (diff)
downloadopenbsd-f69cab5db16bb210dd0d4ae2f7e6e80ea8b29503.tar.gz
openbsd-f69cab5db16bb210dd0d4ae2f7e6e80ea8b29503.tar.bz2
openbsd-f69cab5db16bb210dd0d4ae2f7e6e80ea8b29503.zip
Further refactoring of the wNAF code
The big change is that the "rows" are no longer slices of val[] but that they actually own the points they contain. The price for this is an extra allocation for val[] and to piece it together from the two rows. That's ugly, but less ugly than before. Add a helper for freeing a row of points. It can deal with a NULL row so, we can remove a couple of complications. The second change is that the logic for preparing the rows is pulled back into ec_wNAF_mul[]. This way the m * G + n * P logic is in the one function that needs to know about it, the rest just deals with a pair of a point and a scalar. This starts resembling actual code... ok jsing
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c120
1 files changed, 65 insertions, 55 deletions
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
index c33a033805..4944c34a1e 100644
--- a/src/lib/libcrypto/ec/ec_mult.c
+++ b/src/lib/libcrypto/ec/ec_mult.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_mult.c,v 1.50 2024/11/23 07:37:21 tb Exp $ */ 1/* $OpenBSD: ec_mult.c,v 1.51 2024/11/23 12:56:31 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. 3 * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -61,7 +61,9 @@
61 * and contributed to the OpenSSL project. 61 * and contributed to the OpenSSL project.
62 */ 62 */
63 63
64#include <stdint.h>
64#include <stdlib.h> 65#include <stdlib.h>
66#include <string.h>
65 67
66#include <openssl/bn.h> 68#include <openssl/bn.h>
67#include <openssl/ec.h> 69#include <openssl/ec.h>
@@ -160,15 +162,32 @@ ec_compute_wNAF(const BIGNUM *bn, signed char **out_wNAF, size_t *out_wNAF_len,
160 return ret; 162 return ret;
161} 163}
162 164
165static void
166free_row(EC_POINT **row, size_t row_len)
167{
168 size_t i;
169
170 if (row == NULL)
171 return;
172
173 for (i = 0; i < row_len; i++)
174 EC_POINT_free(row[i]);
175 free(row);
176}
177
163static int 178static int
164ec_compute_odd_multiples(const EC_GROUP *group, const EC_POINT *point, 179ec_compute_odd_multiples(const EC_GROUP *group, const EC_POINT *point,
165 EC_POINT **row, size_t len, BN_CTX *ctx) 180 EC_POINT ***out_row, size_t row_len, BN_CTX *ctx)
166{ 181{
182 EC_POINT **row = NULL;
167 EC_POINT *doubled = NULL; 183 EC_POINT *doubled = NULL;
168 size_t i; 184 size_t i;
169 int ret = 0; 185 int ret = 0;
170 186
171 if (len < 1) 187 if (row_len < 1)
188 goto err;
189
190 if ((row = calloc(row_len, sizeof(*row))) == NULL)
172 goto err; 191 goto err;
173 192
174 if ((row[0] = EC_POINT_dup(point, group)) == NULL) 193 if ((row[0] = EC_POINT_dup(point, group)) == NULL)
@@ -178,84 +197,66 @@ ec_compute_odd_multiples(const EC_GROUP *group, const EC_POINT *point,
178 goto err; 197 goto err;
179 if (!EC_POINT_dbl(group, doubled, point, ctx)) 198 if (!EC_POINT_dbl(group, doubled, point, ctx))
180 goto err; 199 goto err;
181 for (i = 1; i < len; i++) { 200 for (i = 1; i < row_len; i++) {
182 if ((row[i] = EC_POINT_new(group)) == NULL) 201 if ((row[i] = EC_POINT_new(group)) == NULL)
183 goto err; 202 goto err;
184 if (!EC_POINT_add(group, row[i], row[i - 1], doubled, ctx)) 203 if (!EC_POINT_add(group, row[i], row[i - 1], doubled, ctx))
185 goto err; 204 goto err;
186 } 205 }
187 206
207 *out_row = row;
208 row = NULL;
209
188 ret = 1; 210 ret = 1;
189 211
190 err: 212 err:
191 EC_POINT_free(doubled); 213 EC_POINT_free(doubled);
214 free_row(row, row_len);
192 215
193 return ret; 216 return ret;
194} 217}
195 218
196/* 219/*
197 * This computes the wNAF representation of m and n and uses the window size to 220 * Compute the wNAF representation of m and a list of odd multiples of point.
198 * precompute the two rows of odd multiples of point and generator. On success,
199 * out_val owns the out_val_len points in the two rows.
200 *
201 * XXX - the only reason we need a single array is to be able to pass it to
202 * EC_POINTs_make_affine(). Consider writing a suitable variant that doesn't
203 * require such grotesque gymnastics.
204 */ 221 */
205 222
206static int 223static int
207ec_wNAF_precompute(const EC_GROUP *group, const BIGNUM *m, const EC_POINT *point, 224ec_compute_row(const EC_GROUP *group, const BIGNUM *m, const EC_POINT *point,
208 const BIGNUM *n, signed char *wNAF[2], size_t wNAF_len[2], EC_POINT **row[2], 225 signed char **wNAF, size_t *wNAF_len, EC_POINT ***out_row, size_t *out_row_len,
209 EC_POINT ***out_val, size_t *out_val_len, BN_CTX *ctx) 226 BN_CTX *ctx)
227{
228 if (!ec_compute_wNAF(m, wNAF, wNAF_len, out_row_len))
229 return 0;
230 if (!ec_compute_odd_multiples(group, point, out_row, *out_row_len, ctx))
231 return 0;
232 return 1;
233}
234
235static int
236ec_normalize_rows(const EC_GROUP *group, EC_POINT **row0, size_t len0,
237 EC_POINT **row1, size_t len1, BN_CTX *ctx)
210{ 238{
211 EC_POINT **val = NULL; 239 EC_POINT **val = NULL;
212 size_t val_len = 0; 240 size_t len = 0;
213 const EC_POINT *generator;
214 size_t len[2] = { 0 };
215 size_t i;
216 int ret = 0; 241 int ret = 0;
217 242
218 *out_val = NULL; 243 if (len1 > SIZE_MAX - len0)
219 *out_val_len = 0;
220
221 if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
222 ECerror(EC_R_UNDEFINED_GENERATOR);
223 goto err;
224 }
225
226 if (!ec_compute_wNAF(m, &wNAF[0], &wNAF_len[0], &len[0]))
227 goto err;
228 if (!ec_compute_wNAF(n, &wNAF[1], &wNAF_len[1], &len[1]))
229 goto err; 244 goto err;
245 len = len0 + len1;
230 246
231 if ((val = calloc(len[0] + len[1], sizeof(*val))) == NULL) { 247 if ((val = calloc(len, sizeof(*val))) == NULL) {
232 ECerror(ERR_R_MALLOC_FAILURE); 248 ECerror(ERR_R_MALLOC_FAILURE);
233 goto err; 249 goto err;
234 } 250 }
235 val_len = len[0] + len[1]; 251 memcpy(&val[0], row0, sizeof(*val) * len0);
236 252 memcpy(&val[len0], row1, sizeof(*val) * len1);
237 row[0] = &val[0];
238 row[1] = &val[len[0]];
239 253
240 if (!ec_compute_odd_multiples(group, generator, row[0], len[0], ctx)) 254 if (!EC_POINTs_make_affine(group, len, val, ctx))
241 goto err; 255 goto err;
242 if (!ec_compute_odd_multiples(group, point, row[1], len[1], ctx))
243 goto err;
244
245 if (!EC_POINTs_make_affine(group, val_len, val, ctx))
246 goto err;
247
248 *out_val = val;
249 val = NULL;
250
251 *out_val_len = val_len;
252 val_len = 0;
253 256
254 ret = 1; 257 ret = 1;
255 258
256 err: 259 err:
257 for (i = 0; i < val_len; i++)
258 EC_POINT_free(val[i]);
259 free(val); 260 free(val);
260 261
261 return ret; 262 return ret;
@@ -269,11 +270,11 @@ int
269ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, 270ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m,
270 const EC_POINT *point, const BIGNUM *n, BN_CTX *ctx) 271 const EC_POINT *point, const BIGNUM *n, BN_CTX *ctx)
271{ 272{
273 const EC_POINT *generator;
272 signed char *wNAF[2] = { 0 }; 274 signed char *wNAF[2] = { 0 };
273 size_t wNAF_len[2] = { 0 }; 275 size_t wNAF_len[2] = { 0 };
274 EC_POINT **row[2] = { 0 }; 276 EC_POINT **row[2] = { 0 };
275 EC_POINT **val = NULL; 277 size_t row_len[2] = { 0 };
276 size_t val_len = 0;
277 size_t i; 278 size_t i;
278 int k; 279 int k;
279 int r_is_inverted = 0; 280 int r_is_inverted = 0;
@@ -289,8 +290,18 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m,
289 goto err; 290 goto err;
290 } 291 }
291 292
292 if (!ec_wNAF_precompute(group, m, point, n, wNAF, wNAF_len, row, 293 if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
293 &val, &val_len, ctx)) 294 ECerror(EC_R_UNDEFINED_GENERATOR);
295 goto err;
296 }
297
298 if (!ec_compute_row(group, m, generator, &wNAF[0], &wNAF_len[0],
299 &row[0], &row_len[0], ctx))
300 goto err;
301 if (!ec_compute_row(group, n, point, &wNAF[1], &wNAF_len[1],
302 &row[1], &row_len[1], ctx))
303 goto err;
304 if (!ec_normalize_rows(group, row[0], row_len[0], row[1], row_len[1], ctx))
294 goto err; 305 goto err;
295 306
296 max_len = wNAF_len[0]; 307 max_len = wNAF_len[0];
@@ -348,9 +359,8 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m,
348 err: 359 err:
349 free(wNAF[0]); 360 free(wNAF[0]);
350 free(wNAF[1]); 361 free(wNAF[1]);
351 for (i = 0; i < val_len; i++) 362 free_row(row[0], row_len[0]);
352 EC_POINT_free(val[i]); 363 free_row(row[1], row_len[1]);
353 free(val);
354 364
355 return ret; 365 return ret;
356} 366}