summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2023-04-19 10:51:22 +0000
committerjsing <>2023-04-19 10:51:22 +0000
commit0954bbaddbf74f6f184f313822c63bf1b56695bd (patch)
treeb572e3eea1eb6a5996c544ab694d76a6c2c83085 /src/lib
parent0aeb12748acb6b4c8e28de80f588e344c1dab0fe (diff)
downloadopenbsd-0954bbaddbf74f6f184f313822c63bf1b56695bd.tar.gz
openbsd-0954bbaddbf74f6f184f313822c63bf1b56695bd.tar.bz2
openbsd-0954bbaddbf74f6f184f313822c63bf1b56695bd.zip
unifdef BN_RECURSION
This removes a bunch of incomplete and scary code, which potentially leaks secrets and is not constant time. A performance gain is achieved on arm64 for sizes that we care about, while a minimal decrease in performance is noted for larger sizes on some other platforms. While we will potentially reimplement Karatsuba (or Toom-Cook) at a later date, it will be easier and safer to do it from a clean slate. ok tb@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/bn/bn.h8
-rw-r--r--src/lib/libcrypto/bn/bn_lib.c50
-rw-r--r--src/lib/libcrypto/bn/bn_local.h10
-rw-r--r--src/lib/libcrypto/bn/bn_mul.c423
-rw-r--r--src/lib/libcrypto/bn/bn_sqr.c108
5 files changed, 5 insertions, 594 deletions
diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h
index bb85ea442c..53b109bd8a 100644
--- a/src/lib/libcrypto/bn/bn.h
+++ b/src/lib/libcrypto/bn/bn.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn.h,v 1.61 2023/04/16 09:13:46 tb Exp $ */ 1/* $OpenBSD: bn.h,v 1.62 2023/04/19 10:51:22 jsing Exp $ */
2/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -138,12 +138,6 @@
138extern "C" { 138extern "C" {
139#endif 139#endif
140 140
141#ifndef OPENSSL_SMALL_FOOTPRINT
142#define BN_MUL_COMBA
143#define BN_SQR_COMBA
144#define BN_RECURSION
145#endif
146
147/* This next option uses the C libraries (2 word)/(1 word) function. 141/* This next option uses the C libraries (2 word)/(1 word) function.
148 * If it is not defined, I use my C version (which is slower). 142 * If it is not defined, I use my C version (which is slower).
149 * The reason for this flag is that when the particular C compiler 143 * The reason for this flag is that when the particular C compiler
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c
index f25caa04af..89664fbb97 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.81 2023/04/14 11:04:24 jsing Exp $ */ 1/* $OpenBSD: bn_lib.c,v 1.82 2023/04/19 10:51:22 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 *
@@ -735,54 +735,6 @@ BN_set_negative(BIGNUM *bn, int neg)
735 bn->neg = ~BN_is_zero(bn) & bn_ct_ne_zero(neg); 735 bn->neg = ~BN_is_zero(bn) & bn_ct_ne_zero(neg);
736} 736}
737 737
738int
739bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
740{
741 int i;
742 BN_ULONG aa, bb;
743
744 aa = a[n - 1];
745 bb = b[n - 1];
746 if (aa != bb)
747 return ((aa > bb) ? 1 : -1);
748 for (i = n - 2; i >= 0; i--) {
749 aa = a[i];
750 bb = b[i];
751 if (aa != bb)
752 return ((aa > bb) ? 1 : -1);
753 }
754 return (0);
755}
756
757/* Here follows a specialised variants of bn_cmp_words(). It has the
758 property of performing the operation on arrays of different sizes.
759 The sizes of those arrays is expressed through cl, which is the
760 common length ( basicall, min(len(a),len(b)) ), and dl, which is the
761 delta between the two lengths, calculated as len(a)-len(b).
762 All lengths are the number of BN_ULONGs... */
763
764int
765bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
766{
767 int n, i;
768
769 n = cl - 1;
770
771 if (dl < 0) {
772 for (i = dl; i < 0; i++) {
773 if (b[n - i] != 0)
774 return -1; /* a < b */
775 }
776 }
777 if (dl > 0) {
778 for (i = dl; i > 0; i--) {
779 if (a[n + i] != 0)
780 return 1; /* a > b */
781 }
782 }
783 return bn_cmp_words(a, b, cl);
784}
785
786/* 738/*
787 * Constant-time conditional swap of a and b. 739 * Constant-time conditional swap of a and b.
788 * a and b are swapped if condition is not 0. 740 * a and b are swapped if condition is not 0.
diff --git a/src/lib/libcrypto/bn/bn_local.h b/src/lib/libcrypto/bn/bn_local.h
index 4912ae96f3..5e85dfc3de 100644
--- a/src/lib/libcrypto/bn/bn_local.h
+++ b/src/lib/libcrypto/bn/bn_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_local.h,v 1.18 2023/03/27 08:37:33 tb Exp $ */ 1/* $OpenBSD: bn_local.h,v 1.19 2023/04/19 10:51:22 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 *
@@ -256,14 +256,6 @@ void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
256void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a); 256void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
257void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a); 257void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
258 258
259int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n);
260int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
261 int cl, int dl);
262void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
263 int dna, int dnb, BN_ULONG *t);
264void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
265 int n, int tna, int tnb, BN_ULONG *t);
266void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t);
267int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, 259int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
268 const BN_ULONG *np, const BN_ULONG *n0, int num); 260 const BN_ULONG *np, const BN_ULONG *n0, int num);
269 261
diff --git a/src/lib/libcrypto/bn/bn_mul.c b/src/lib/libcrypto/bn/bn_mul.c
index fe3f29617f..118e8cddc5 100644
--- a/src/lib/libcrypto/bn/bn_mul.c
+++ b/src/lib/libcrypto/bn/bn_mul.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_mul.c,v 1.36 2023/03/30 14:28:56 tb Exp $ */ 1/* $OpenBSD: bn_mul.c,v 1.37 2023/04/19 10:51:22 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 *
@@ -313,323 +313,8 @@ bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
313 } 313 }
314} 314}
315 315
316#ifdef BN_RECURSION
317/* Karatsuba recursive multiplication algorithm
318 * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
319
320/* r is 2*n2 words in size,
321 * a and b are both n2 words in size.
322 * n2 must be a power of 2.
323 * We multiply and return the result.
324 * t must be 2*n2 words in size
325 * We calculate
326 * a[0]*b[0]
327 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
328 * a[1]*b[1]
329 */
330/* dnX may not be positive, but n2/2+dnX has to be */
331void
332bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, int dna,
333 int dnb, BN_ULONG *t)
334{
335 int n = n2 / 2, c1, c2;
336 int tna = n + dna, tnb = n + dnb;
337 unsigned int neg, zero;
338 BN_ULONG ln, lo, *p;
339
340# ifdef BN_MUL_COMBA
341# if 0
342 if (n2 == 4) {
343 bn_mul_comba4(r, a, b);
344 return;
345 }
346# endif
347 /* Only call bn_mul_comba 8 if n2 == 8 and the
348 * two arrays are complete [steve]
349 */
350 if (n2 == 8 && dna == 0 && dnb == 0) {
351 bn_mul_comba8(r, a, b);
352 return;
353 }
354# endif /* BN_MUL_COMBA */
355 /* Else do normal multiply */
356 if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
357 bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
358 if ((dna + dnb) < 0)
359 memset(&r[2*n2 + dna + dnb], 0,
360 sizeof(BN_ULONG) * -(dna + dnb));
361 return;
362 }
363 /* r=(a[0]-a[1])*(b[1]-b[0]) */
364 c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
365 c2 = bn_cmp_part_words(&(b[n]), b,tnb, tnb - n);
366 zero = neg = 0;
367 switch (c1 * 3 + c2) {
368 case -4:
369 bn_sub(t, n, &a[n], tna, a, n); /* - */
370 bn_sub(&t[n], n, b, n, &b[n], tnb); /* - */
371 break;
372 case -3:
373 zero = 1;
374 break;
375 case -2:
376 bn_sub(t, n, &a[n], tna, a, n); /* - */
377 bn_sub(&t[n], n, &b[n], tnb, b, n); /* + */
378 neg = 1;
379 break;
380 case -1:
381 case 0:
382 case 1:
383 zero = 1;
384 break;
385 case 2:
386 bn_sub(t, n, a, n, &a[n], tna); /* + */
387 bn_sub(&t[n], n, b, n, &b[n], tnb); /* - */
388 neg = 1;
389 break;
390 case 3:
391 zero = 1;
392 break;
393 case 4:
394 bn_sub(t, n, a, n, &a[n], tna);
395 bn_sub(&t[n], n, &b[n], tnb, b, n);
396 break;
397 }
398
399# ifdef BN_MUL_COMBA
400 if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
401 extra args to do this well */
402 {
403 if (!zero)
404 bn_mul_comba4(&(t[n2]), t, &(t[n]));
405 else
406 memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG));
407
408 bn_mul_comba4(r, a, b);
409 bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
410 } else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
411 take extra args to do this
412 well */
413 {
414 if (!zero)
415 bn_mul_comba8(&(t[n2]), t, &(t[n]));
416 else
417 memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG));
418
419 bn_mul_comba8(r, a, b);
420 bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
421 } else
422# endif /* BN_MUL_COMBA */
423 {
424 p = &(t[n2 * 2]);
425 if (!zero)
426 bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
427 else
428 memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
429 bn_mul_recursive(r, a, b, n, 0, 0, p);
430 bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
431 }
432
433 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
434 * r[10] holds (a[0]*b[0])
435 * r[32] holds (b[1]*b[1])
436 */
437
438 c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
439
440 if (neg) /* if t[32] is negative */
441 {
442 c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
443 } else {
444 /* Might have a carry */
445 c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
446 }
447
448 /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
449 * r[10] holds (a[0]*b[0])
450 * r[32] holds (b[1]*b[1])
451 * c1 holds the carry bits
452 */
453 c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
454 if (c1) {
455 p = &(r[n + n2]);
456 lo= *p;
457 ln = (lo + c1) & BN_MASK2;
458 *p = ln;
459
460 /* The overflow will stop before we over write
461 * words we should not overwrite */
462 if (ln < (BN_ULONG)c1) {
463 do {
464 p++;
465 lo= *p;
466 ln = (lo + 1) & BN_MASK2;
467 *p = ln;
468 } while (ln == 0);
469 }
470 }
471}
472
473/* n+tn is the word length
474 * t needs to be n*4 is size, as does r */
475/* tnX may not be negative but less than n */
476void
477bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, int tna,
478 int tnb, BN_ULONG *t)
479{
480 int i, j, n2 = n * 2;
481 int c1, c2, neg;
482 BN_ULONG ln, lo, *p;
483
484 if (n < 8) {
485 bn_mul_normal(r, a, n + tna, b, n + tnb);
486 return;
487 }
488
489 /* r=(a[0]-a[1])*(b[1]-b[0]) */
490 c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
491 c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
492 neg = 0;
493 switch (c1 * 3 + c2) {
494 case -4:
495 bn_sub(t, n, &a[n], tna, a, n); /* - */
496 bn_sub(&t[n], n, b, n, &b[n], tnb); /* - */
497 break;
498 case -3:
499 /* break; */
500 case -2:
501 bn_sub(t, n, &a[n], tna, a, n); /* - */
502 bn_sub(&t[n], n, &b[n], tnb, b, n); /* + */
503 neg = 1;
504 break;
505 case -1:
506 case 0:
507 case 1:
508 /* break; */
509 case 2:
510 bn_sub(t, n, a, n, &a[n], tna); /* + */
511 bn_sub(&t[n], n, b, n, &b[n], tnb); /* - */
512 neg = 1;
513 break;
514 case 3:
515 /* break; */
516 case 4:
517 bn_sub(t, n, a, n, &a[n], tna);
518 bn_sub(&t[n], n, &b[n], tnb, b, n);
519 break;
520 }
521 /* The zero case isn't yet implemented here. The speedup
522 would probably be negligible. */
523# if 0
524 if (n == 4) {
525 bn_mul_comba4(&(t[n2]), t, &(t[n]));
526 bn_mul_comba4(r, a, b);
527 bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
528 memset(&(r[n2 + tn * 2]), 0, sizeof(BN_ULONG) * (n2 - tn * 2));
529 } else
530# endif
531 if (n == 8) {
532 bn_mul_comba8(&(t[n2]), t, &(t[n]));
533 bn_mul_comba8(r, a, b);
534 bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
535 memset(&(r[n2 + tna + tnb]), 0,
536 sizeof(BN_ULONG) * (n2 - tna - tnb));
537 } else {
538 p = &(t[n2*2]);
539 bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
540 bn_mul_recursive(r, a, b, n, 0, 0, p);
541 i = n / 2;
542 /* If there is only a bottom half to the number,
543 * just do it */
544 if (tna > tnb)
545 j = tna - i;
546 else
547 j = tnb - i;
548 if (j == 0) {
549 bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
550 i, tna - i, tnb - i, p);
551 memset(&(r[n2 + i * 2]), 0,
552 sizeof(BN_ULONG) * (n2 - i * 2));
553 }
554 else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
555 {
556 bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
557 i, tna - i, tnb - i, p);
558 memset(&(r[n2 + tna + tnb]), 0,
559 sizeof(BN_ULONG) * (n2 - tna - tnb));
560 }
561 else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
562 {
563 memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2);
564 if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL &&
565 tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
566 bn_mul_normal(&(r[n2]), &(a[n]), tna,
567 &(b[n]), tnb);
568 } else {
569 for (;;) {
570 i /= 2;
571 /* these simplified conditions work
572 * exclusively because difference
573 * between tna and tnb is 1 or 0 */
574 if (i < tna || i < tnb) {
575 bn_mul_part_recursive(&(r[n2]),
576 &(a[n]), &(b[n]), i,
577 tna - i, tnb - i, p);
578 break;
579 } else if (i == tna || i == tnb) {
580 bn_mul_recursive(&(r[n2]),
581 &(a[n]), &(b[n]), i,
582 tna - i, tnb - i, p);
583 break;
584 }
585 }
586 }
587 }
588 }
589
590 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
591 * r[10] holds (a[0]*b[0])
592 * r[32] holds (b[1]*b[1])
593 */
594
595 c1 = (int)(bn_add_words(t, r,&(r[n2]), n2));
596
597 if (neg) /* if t[32] is negative */
598 {
599 c1 -= (int)(bn_sub_words(&(t[n2]), t,&(t[n2]), n2));
600 } else {
601 /* Might have a carry */
602 c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
603 }
604
605 /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
606 * r[10] holds (a[0]*b[0])
607 * r[32] holds (b[1]*b[1])
608 * c1 holds the carry bits
609 */
610 c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
611 if (c1) {
612 p = &(r[n + n2]);
613 lo= *p;
614 ln = (lo + c1)&BN_MASK2;
615 *p = ln;
616
617 /* The overflow will stop before we over write
618 * words we should not overwrite */
619 if (ln < (BN_ULONG)c1) {
620 do {
621 p++;
622 lo= *p;
623 ln = (lo + 1) & BN_MASK2;
624 *p = ln;
625 } while (ln == 0);
626 }
627 }
628}
629#endif /* BN_RECURSION */
630 316
631#ifndef HAVE_BN_MUL 317#ifndef HAVE_BN_MUL
632#ifndef BN_RECURSION
633int 318int
634bn_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, int rn, BN_CTX *ctx) 319bn_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, int rn, BN_CTX *ctx)
635{ 320{
@@ -638,112 +323,6 @@ bn_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, int rn, BN_CTX *ctx)
638 return 1; 323 return 1;
639} 324}
640 325
641#else /* BN_RECURSION */
642int
643bn_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, int rn, BN_CTX *ctx)
644{
645 BIGNUM *t = NULL;
646 int al, bl, i, k;
647 int j = 0;
648 int ret = 0;
649
650 BN_CTX_start(ctx);
651
652 al = a->top;
653 bl = b->top;
654
655 i = al - bl;
656
657 if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
658 if (i >= -1 && i <= 1) {
659 /* Find out the power of two lower or equal
660 to the longest of the two numbers */
661 if (i >= 0) {
662 j = BN_num_bits_word((BN_ULONG)al);
663 }
664 if (i == -1) {
665 j = BN_num_bits_word((BN_ULONG)bl);
666 }
667 j = 1 << (j - 1);
668 assert(j <= al || j <= bl);
669 k = j + j;
670 if ((t = BN_CTX_get(ctx)) == NULL)
671 goto err;
672 if (al > j || bl > j) {
673 if (!bn_wexpand(t, k * 4))
674 goto err;
675 if (!bn_wexpand(r, k * 4))
676 goto err;
677 bn_mul_part_recursive(r->d, a->d, b->d,
678 j, al - j, bl - j, t->d);
679 }
680 else /* al <= j || bl <= j */
681 {
682 if (!bn_wexpand(t, k * 2))
683 goto err;
684 if (!bn_wexpand(r, k * 2))
685 goto err;
686 bn_mul_recursive(r->d, a->d, b->d,
687 j, al - j, bl - j, t->d);
688 }
689 r->top = rn;
690 goto end;
691 }
692#if 0
693 if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {
694 BIGNUM *tmp_bn = (BIGNUM *)b;
695 if (!bn_wexpand(tmp_bn, al))
696 goto err;
697 tmp_bn->d[bl] = 0;
698 bl++;
699 i--;
700 } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
701 BIGNUM *tmp_bn = (BIGNUM *)a;
702 if (!bn_wexpand(tmp_bn, bl))
703 goto err;
704 tmp_bn->d[al] = 0;
705 al++;
706 i++;
707 }
708 if (i == 0) {
709 /* symmetric and > 4 */
710 /* 16 or larger */
711 j = BN_num_bits_word((BN_ULONG)al);
712 j = 1 << (j - 1);
713 k = j + j;
714 if ((t = BN_CTX_get(ctx)) == NULL)
715 goto err;
716 if (al == j) /* exact multiple */
717 {
718 if (!bn_wexpand(t, k * 2))
719 goto err;
720 if (!bn_wexpand(r, k * 2))
721 goto err;
722 bn_mul_recursive(r->d, a->d, b->d, al, t->d);
723 } else {
724 if (!bn_wexpand(t, k * 4))
725 goto err;
726 if (!bn_wexpand(r, k * 4))
727 goto err;
728 bn_mul_part_recursive(r->d, a->d, b->d,
729 al - j, j, t->d);
730 }
731 r->top = top;
732 goto end;
733 }
734#endif
735 }
736
737 bn_mul_normal(r->d, a->d, al, b->d, bl);
738
739 end:
740 ret = 1;
741 err:
742 BN_CTX_end(ctx);
743
744 return ret;
745}
746#endif /* BN_RECURSION */
747#endif /* HAVE_BN_MUL */ 326#endif /* HAVE_BN_MUL */
748 327
749int 328int
diff --git a/src/lib/libcrypto/bn/bn_sqr.c b/src/lib/libcrypto/bn/bn_sqr.c
index d5da775200..d414800feb 100644
--- a/src/lib/libcrypto/bn/bn_sqr.c
+++ b/src/lib/libcrypto/bn/bn_sqr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_sqr.c,v 1.29 2023/03/30 14:28:56 tb Exp $ */ 1/* $OpenBSD: bn_sqr.c,v 1.30 2023/04/19 10:51:22 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 *
@@ -228,90 +228,6 @@ bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
228 bn_add_words(r, r, tmp, max); 228 bn_add_words(r, r, tmp, max);
229} 229}
230 230
231#ifdef BN_RECURSION
232/* r is 2*n words in size,
233 * a and b are both n words in size. (There's not actually a 'b' here ...)
234 * n must be a power of 2.
235 * We multiply and return the result.
236 * t must be 2*n words in size
237 * We calculate
238 * a[0]*b[0]
239 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
240 * a[1]*b[1]
241 */
242void
243bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
244{
245 int n = n2 / 2;
246 int zero, c1;
247 BN_ULONG ln, lo, *p;
248
249 if (n2 == 4) {
250 bn_sqr_comba4(r, a);
251 return;
252 } else if (n2 == 8) {
253 bn_sqr_comba8(r, a);
254 return;
255 }
256 if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) {
257 bn_sqr_normal(r, a, n2, t);
258 return;
259 }
260 /* r=(a[0]-a[1])*(a[1]-a[0]) */
261 c1 = bn_cmp_words(a, &(a[n]), n);
262 zero = 0;
263 if (c1 > 0)
264 bn_sub_words(t, a, &(a[n]), n);
265 else if (c1 < 0)
266 bn_sub_words(t, &(a[n]), a, n);
267 else
268 zero = 1;
269
270 /* The result will always be negative unless it is zero */
271 p = &(t[n2*2]);
272
273 if (!zero)
274 bn_sqr_recursive(&(t[n2]), t, n, p);
275 else
276 memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
277 bn_sqr_recursive(r, a, n, p);
278 bn_sqr_recursive(&(r[n2]), &(a[n]), n, p);
279
280 /* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
281 * r[10] holds (a[0]*b[0])
282 * r[32] holds (b[1]*b[1])
283 */
284
285 c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
286
287 /* t[32] is negative */
288 c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
289
290 /* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
291 * r[10] holds (a[0]*a[0])
292 * r[32] holds (a[1]*a[1])
293 * c1 holds the carry bits
294 */
295 c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
296 if (c1) {
297 p = &(r[n + n2]);
298 lo= *p;
299 ln = (lo + c1) & BN_MASK2;
300 *p = ln;
301
302 /* The overflow will stop before we over write
303 * words we should not overwrite */
304 if (ln < (BN_ULONG)c1) {
305 do {
306 p++;
307 lo= *p;
308 ln = (lo + 1) & BN_MASK2;
309 *p = ln;
310 } while (ln == 0);
311 }
312 }
313}
314#endif
315 231
316/* 232/*
317 * bn_sqr() computes a * a, storing the result in r. The caller must ensure that 233 * bn_sqr() computes a * a, storing the result in r. The caller must ensure that
@@ -330,31 +246,9 @@ bn_sqr(BIGNUM *r, const BIGNUM *a, int rn, BN_CTX *ctx)
330 if ((tmp = BN_CTX_get(ctx)) == NULL) 246 if ((tmp = BN_CTX_get(ctx)) == NULL)
331 goto err; 247 goto err;
332 248
333#if defined(BN_RECURSION)
334 if (a->top < BN_SQR_RECURSIVE_SIZE_NORMAL) {
335 BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
336 bn_sqr_normal(r->d, a->d, a->top, t);
337 } else {
338 int j, k;
339
340 j = BN_num_bits_word((BN_ULONG)a->top);
341 j = 1 << (j - 1);
342 k = j + j;
343 if (a->top == j) {
344 if (!bn_wexpand(tmp, k * 2))
345 goto err;
346 bn_sqr_recursive(r->d, a->d, a->top, tmp->d);
347 } else {
348 if (!bn_wexpand(tmp, rn))
349 goto err;
350 bn_sqr_normal(r->d, a->d, a->top, tmp->d);
351 }
352 }
353#else
354 if (!bn_wexpand(tmp, rn)) 249 if (!bn_wexpand(tmp, rn))
355 goto err; 250 goto err;
356 bn_sqr_normal(r->d, a->d, a->top, tmp->d); 251 bn_sqr_normal(r->d, a->d, a->top, tmp->d);
357#endif
358 252
359 ret = 1; 253 ret = 1;
360 254