diff options
author | jsing <> | 2023-01-14 15:12:27 +0000 |
---|---|---|
committer | jsing <> | 2023-01-14 15:12:27 +0000 |
commit | d6fac2b07b688bc81647b272f5fa500c41e3e68a (patch) | |
tree | e211a5c0fe5d83d78611b596a5d897cf787f1646 | |
parent | aa7717a6a8a2075dc688a32afc8fd3c1647f6e8e (diff) | |
download | openbsd-d6fac2b07b688bc81647b272f5fa500c41e3e68a.tar.gz openbsd-d6fac2b07b688bc81647b272f5fa500c41e3e68a.tar.bz2 openbsd-d6fac2b07b688bc81647b272f5fa500c41e3e68a.zip |
Greatly simplify bn_expand_internal().
We have a function called recallocarray() - make use of it rather than
handrolling a version of it. Also have bn_expand() call bn_wexpand(),
which avoids some duplication.
ok tb@
-rw-r--r-- | src/lib/libcrypto/bn/bn_lib.c | 129 |
1 files changed, 26 insertions, 103 deletions
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c index e8802300ce..5bfdacb2c6 100644 --- a/src/lib/libcrypto/bn/bn_lib.c +++ b/src/lib/libcrypto/bn/bn_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_lib.c,v 1.71 2023/01/07 16:17:29 jsing Exp $ */ | 1 | /* $OpenBSD: bn_lib.c,v 1.72 2023/01/14 15:12:27 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -259,139 +259,62 @@ bn_correct_top(BIGNUM *a) | |||
259 | a->top--; | 259 | a->top--; |
260 | } | 260 | } |
261 | 261 | ||
262 | /* The caller MUST check that words > b->dmax before calling this */ | 262 | static int |
263 | static BN_ULONG * | 263 | bn_expand_internal(BIGNUM *bn, int words) |
264 | bn_expand_internal(const BIGNUM *b, int words) | ||
265 | { | 264 | { |
266 | BN_ULONG *A, *a = NULL; | 265 | BN_ULONG *d; |
267 | const BN_ULONG *B; | ||
268 | int i; | ||
269 | 266 | ||
267 | if (words < 0) { | ||
268 | BNerror(BN_R_BIGNUM_TOO_LONG); // XXX | ||
269 | return 0; | ||
270 | } | ||
270 | 271 | ||
271 | if (words > (INT_MAX/(4*BN_BITS2))) { | 272 | if (words > INT_MAX / (4 * BN_BITS2)) { |
272 | BNerror(BN_R_BIGNUM_TOO_LONG); | 273 | BNerror(BN_R_BIGNUM_TOO_LONG); |
273 | return NULL; | 274 | return 0; |
274 | } | 275 | } |
275 | if (BN_get_flags(b, BN_FLG_STATIC_DATA)) { | 276 | if (BN_get_flags(bn, BN_FLG_STATIC_DATA)) { |
276 | BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); | 277 | BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); |
277 | return (NULL); | 278 | return 0; |
278 | } | ||
279 | a = A = reallocarray(NULL, words, sizeof(BN_ULONG)); | ||
280 | if (A == NULL) { | ||
281 | BNerror(ERR_R_MALLOC_FAILURE); | ||
282 | return (NULL); | ||
283 | } | ||
284 | #if 1 | ||
285 | B = b->d; | ||
286 | /* Check if the previous number needs to be copied */ | ||
287 | if (B != NULL) { | ||
288 | for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { | ||
289 | /* | ||
290 | * The fact that the loop is unrolled | ||
291 | * 4-wise is a tribute to Intel. It's | ||
292 | * the one that doesn't have enough | ||
293 | * registers to accommodate more data. | ||
294 | * I'd unroll it 8-wise otherwise:-) | ||
295 | * | ||
296 | * <appro@fy.chalmers.se> | ||
297 | */ | ||
298 | BN_ULONG a0, a1, a2, a3; | ||
299 | a0 = B[0]; | ||
300 | a1 = B[1]; | ||
301 | a2 = B[2]; | ||
302 | a3 = B[3]; | ||
303 | A[0] = a0; | ||
304 | A[1] = a1; | ||
305 | A[2] = a2; | ||
306 | A[3] = a3; | ||
307 | } | ||
308 | switch (b->top & 3) { | ||
309 | case 3: | ||
310 | A[2] = B[2]; | ||
311 | case 2: | ||
312 | A[1] = B[1]; | ||
313 | case 1: | ||
314 | A[0] = B[0]; | ||
315 | } | ||
316 | } | 279 | } |
317 | 280 | ||
318 | #else | 281 | d = recallocarray(bn->d, bn->dmax, words, sizeof(BN_ULONG)); |
319 | memset(A, 0, sizeof(BN_ULONG) * words); | 282 | if (d == NULL) { |
320 | memcpy(A, b->d, sizeof(b->d[0]) * b->top); | 283 | BNerror(ERR_R_MALLOC_FAILURE); |
321 | #endif | 284 | return 0; |
322 | |||
323 | return (a); | ||
324 | } | ||
325 | |||
326 | /* This is an internal function that should not be used in applications. | ||
327 | * It ensures that 'b' has enough room for a 'words' word number | ||
328 | * and initialises any unused part of b->d with leading zeros. | ||
329 | * It is mostly used by the various BIGNUM routines. If there is an error, | ||
330 | * NULL is returned. If not, 'b' is returned. */ | ||
331 | |||
332 | static int | ||
333 | bn_expand2(BIGNUM *b, int words) | ||
334 | { | ||
335 | |||
336 | if (words > b->dmax) { | ||
337 | BN_ULONG *a = bn_expand_internal(b, words); | ||
338 | if (a == NULL) | ||
339 | return 0; | ||
340 | if (b->d) | ||
341 | freezero(b->d, b->dmax * sizeof(b->d[0])); | ||
342 | b->d = a; | ||
343 | b->dmax = words; | ||
344 | } | 285 | } |
286 | bn->d = d; | ||
287 | bn->dmax = words; | ||
345 | 288 | ||
346 | /* None of this should be necessary because of what b->top means! */ | ||
347 | #if 0 | ||
348 | /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */ | ||
349 | if (b->top < b->dmax) { | ||
350 | int i; | ||
351 | BN_ULONG *A = &(b->d[b->top]); | ||
352 | for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) { | ||
353 | A[0] = 0; | ||
354 | A[1] = 0; | ||
355 | A[2] = 0; | ||
356 | A[3] = 0; | ||
357 | A[4] = 0; | ||
358 | A[5] = 0; | ||
359 | A[6] = 0; | ||
360 | A[7] = 0; | ||
361 | } | ||
362 | for (i = (b->dmax - b->top)&7; i > 0; i--, A++) | ||
363 | A[0] = 0; | ||
364 | assert(A == &(b->d[b->dmax])); | ||
365 | } | ||
366 | #endif | ||
367 | return 1; | 289 | return 1; |
368 | } | 290 | } |
369 | 291 | ||
370 | int | 292 | int |
371 | bn_expand(BIGNUM *a, int bits) | 293 | bn_expand(BIGNUM *bn, int bits) |
372 | { | 294 | { |
295 | int words; | ||
296 | |||
373 | if (bits < 0) | 297 | if (bits < 0) |
374 | return 0; | 298 | return 0; |
375 | 299 | ||
376 | if (bits > (INT_MAX - BN_BITS2 + 1)) | 300 | if (bits > (INT_MAX - BN_BITS2 + 1)) |
377 | return 0; | 301 | return 0; |
378 | 302 | ||
379 | if (((bits + BN_BITS2 - 1) / BN_BITS2) <= a->dmax) | 303 | words = (bits + BN_BITS2 - 1) / BN_BITS2; |
380 | return 1; | ||
381 | 304 | ||
382 | return bn_expand2(a, (bits + BN_BITS2 - 1) / BN_BITS2); | 305 | return bn_wexpand(bn, words); |
383 | } | 306 | } |
384 | 307 | ||
385 | int | 308 | int |
386 | bn_wexpand(BIGNUM *a, int words) | 309 | bn_wexpand(BIGNUM *bn, int words) |
387 | { | 310 | { |
388 | if (words < 0) | 311 | if (words < 0) |
389 | return 0; | 312 | return 0; |
390 | 313 | ||
391 | if (words <= a->dmax) | 314 | if (words <= bn->dmax) |
392 | return 1; | 315 | return 1; |
393 | 316 | ||
394 | return bn_expand2(a, words); | 317 | return bn_expand_internal(bn, words); |
395 | } | 318 | } |
396 | 319 | ||
397 | BIGNUM * | 320 | BIGNUM * |