OSSL_FN: Wrap BN shift and compare functions around OSSL_FN functions

Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Fri Jun 26 14:23:18 2026
(Merged from https://github.com/openssl/openssl/pull/31460)
This commit is contained in:
Richard Levitte 2026-06-11 16:43:03 +02:00 committed by Tomas Mraz
parent 148767fc9a
commit 5072424737
2 changed files with 129 additions and 79 deletions

View file

@ -183,26 +183,34 @@ static ossl_inline int bn_num_bits_consttime(const BIGNUM *a)
int BN_num_bits(const BIGNUM *a)
{
int i = a->top - 1;
bn_check_top(a);
if (a->flags & BN_FLG_CONSTTIME) {
/*
* We assume that BIGNUMs flagged as CONSTTIME have also been expanded
* so that a->dmax is not leaking secret information.
*
* In other words, it's the caller's responsibility to ensure `a` has
* been preallocated in advance to a public length if we hit this
* branch.
*
*/
return bn_num_bits_consttime(a);
/* TODO(FIXNUM): TO BE REMOVED */
if (a->data == NULL) {
int i = a->top - 1;
if (a->flags & BN_FLG_CONSTTIME) {
/*
* We assume that BIGNUMs flagged as CONSTTIME have also been expanded
* so that a->dmax is not leaking secret information.
*
* In other words, it's the caller's responsibility to ensure `a` has
* been preallocated in advance to a public length if we hit this
* branch.
*
*/
return bn_num_bits_consttime(a);
}
if (ossl_unlikely(BN_is_zero(a)))
return 0;
return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
}
if (ossl_unlikely(BN_is_zero(a)))
return 0;
size_t bits = OSSL_FN_num_bits(a->data);
return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
return bits > INT_MAX ? INT_MAX : (int)bits;
}
static void bn_free_d(BIGNUM *a, bool clear)
@ -736,46 +744,49 @@ int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen)
int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
{
int i;
BN_ULONG t1, t2, *ap, *bp;
ap = a->d;
bp = b->d;
if (BN_get_flags(a, BN_FLG_CONSTTIME)
&& a->top == b->top) {
int res = 0;
for (i = 0; i < b->top; i++) {
res = constant_time_select_int((int)constant_time_lt_bn(ap[i], bp[i]),
-1, res);
res = constant_time_select_int((int)constant_time_lt_bn(bp[i], ap[i]),
1, res);
}
return res;
}
bn_check_top(a);
bn_check_top(b);
i = a->top - b->top;
if (i != 0)
return i;
/* TODO(FIXNUM): TO BE REMOVED */
if (a->data == NULL || b->data == NULL) {
int i;
BN_ULONG t1, t2, *ap, *bp;
for (i = a->top - 1; i >= 0; i--) {
t1 = ap[i];
t2 = bp[i];
if (t1 != t2)
return ((t1 > t2) ? 1 : -1);
ap = a->d;
bp = b->d;
if (BN_get_flags(a, BN_FLG_CONSTTIME)
&& a->top == b->top) {
int res = 0;
for (i = 0; i < b->top; i++) {
res = constant_time_select_int((int)constant_time_lt_bn(ap[i], bp[i]),
-1, res);
res = constant_time_select_int((int)constant_time_lt_bn(bp[i], ap[i]),
1, res);
}
return res;
}
i = a->top - b->top;
if (i != 0)
return i;
for (i = a->top - 1; i >= 0; i--) {
t1 = ap[i];
t2 = bp[i];
if (t1 != t2)
return ((t1 > t2) ? 1 : -1);
}
return 0;
}
return 0;
return OSSL_FN_cmp(a->data, b->data);
}
int BN_cmp(const BIGNUM *a, const BIGNUM *b)
{
int i;
int gt, lt;
BN_ULONG t1, t2;
if ((a == NULL) || (b == NULL)) {
if (a != NULL)
@ -803,17 +814,31 @@ int BN_cmp(const BIGNUM *a, const BIGNUM *b)
lt = 1;
}
if (a->top > b->top)
return gt;
if (a->top < b->top)
return lt;
for (i = a->top - 1; i >= 0; i--) {
t1 = a->d[i];
t2 = b->d[i];
if (t1 > t2)
/* TODO(FIXNUM): TO BE REMOVED */
if (a->data == NULL || b->data == NULL) {
int i;
BN_ULONG t1, t2;
if (a->top > b->top)
return gt;
if (t1 < t2)
if (a->top < b->top)
return lt;
for (i = a->top - 1; i >= 0; i--) {
t1 = a->d[i];
t2 = b->d[i];
if (t1 > t2)
return gt;
if (t1 < t2)
return lt;
}
return 0;
}
switch (OSSL_FN_cmp(a->data, b->data)) {
case 1:
return gt;
case -1:
return lt;
}
return 0;
}

View file

@ -13,33 +13,44 @@
int BN_lshift1(BIGNUM *r, const BIGNUM *a)
{
register BN_ULONG *ap, *rp, t, c;
int i;
bn_check_top(r);
bn_check_top(a);
if (r != a) {
r->neg = a->neg;
if (bn_wexpand(r, a->top + 1) == NULL)
return 0;
bn_set_top(r, a->top);
} else {
if (bn_wexpand(r, a->top + 1) == NULL)
return 0;
/* TODO(FIXNUM): TO BE REMOVED */
if (r->data == NULL || a->data == NULL) {
register BN_ULONG *ap, *rp, t, c;
int i;
if (r != a) {
r->neg = a->neg;
if (bn_wexpand(r, a->top + 1) == NULL)
return 0;
bn_set_top(r, a->top);
} else {
if (bn_wexpand(r, a->top + 1) == NULL)
return 0;
}
ap = a->d;
rp = r->d;
c = 0;
for (i = 0; i < a->top; i++) {
t = *(ap++);
*(rp++) = ((t << 1) | c) & BN_MASK2;
c = t >> (BN_BITS2 - 1);
}
*rp = c;
bn_set_top(r, r->top + (int)c);
bn_check_top(r);
return 1;
}
ap = a->d;
rp = r->d;
c = 0;
for (i = 0; i < a->top; i++) {
t = *(ap++);
*(rp++) = ((t << 1) | c) & BN_MASK2;
c = t >> (BN_BITS2 - 1);
}
*rp = c;
bn_set_top(r, r->top + (int)c);
bn_check_top(r);
return 1;
size_t top = a->top + 1;
OSSL_FN *rf = bn_acquire_ossl_fn(r, (int)top);
int ret = OSSL_FN_lshift1(rf, a->data);
bn_release(r, (int)top);
BN_set_negative(r, ret && a->neg);
return ret;
}
int BN_rshift1(BIGNUM *r, const BIGNUM *a)
@ -86,11 +97,25 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
return 0;
}
ret = bn_lshift_fixed_top(r, a, n);
/* TODO(FIXNUM): TO BE REMOVED */
if (r->data == NULL || a->data == NULL) {
ret = bn_lshift_fixed_top(r, a, n);
bn_correct_top(r);
bn_check_top(r);
return ret;
}
bn_correct_top(r);
bn_check_top(r);
bn_check_top(a);
size_t top = a->top + n / BN_BITS2 + 1;
OSSL_FN *rf = bn_acquire_ossl_fn(r, (int)top);
ret = OSSL_FN_lshift(rf, a->data, n);
bn_release(r, (int)top);
BN_set_negative(r, ret && a->neg);
return ret;
}