summaryrefslogtreecommitdiffstats
path: root/freebsd/crypto/openssl/crypto/bn/bn_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/crypto/openssl/crypto/bn/bn_lib.c')
-rw-r--r--freebsd/crypto/openssl/crypto/bn/bn_lib.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/freebsd/crypto/openssl/crypto/bn/bn_lib.c b/freebsd/crypto/openssl/crypto/bn/bn_lib.c
index e63f6100..755322ce 100644
--- a/freebsd/crypto/openssl/crypto/bn/bn_lib.c
+++ b/freebsd/crypto/openssl/crypto/bn/bn_lib.c
@@ -265,8 +265,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
const BN_ULONG *B;
int i;
- bn_check_top(b);
-
if (words > (INT_MAX / (4 * BN_BITS2))) {
BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
return NULL;
@@ -400,8 +398,6 @@ BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
BIGNUM *bn_expand2(BIGNUM *b, int words)
{
- bn_check_top(b);
-
if (words > b->dmax) {
BN_ULONG *a = bn_expand_internal(b, words);
if (!a)
@@ -435,7 +431,6 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
assert(A == &(b->d[b->dmax]));
}
#endif
- bn_check_top(b);
return b;
}
@@ -499,12 +494,18 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
#endif
- a->top = b->top;
a->neg = b->neg;
+ a->top = b->top;
+ a->flags |= b->flags & BN_FLG_FIXED_TOP;
bn_check_top(a);
return (a);
}
+#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \
+ | BN_FLG_CONSTTIME \
+ | BN_FLG_FIXED_TOP))
+#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED))
+
void BN_swap(BIGNUM *a, BIGNUM *b)
{
int flags_old_a, flags_old_b;
@@ -532,10 +533,8 @@ void BN_swap(BIGNUM *a, BIGNUM *b)
b->dmax = tmp_dmax;
b->neg = tmp_neg;
- a->flags =
- (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
- b->flags =
- (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
+ a->flags = FLAGS_STRUCT(flags_old_a) | FLAGS_DATA(flags_old_b);
+ b->flags = FLAGS_STRUCT(flags_old_b) | FLAGS_DATA(flags_old_a);
bn_check_top(a);
bn_check_top(b);
}
@@ -547,6 +546,7 @@ void BN_clear(BIGNUM *a)
OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
a->top = 0;
a->neg = 0;
+ a->flags &= ~BN_FLG_FIXED_TOP;
}
BN_ULONG BN_get_word(const BIGNUM *a)
@@ -567,6 +567,7 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
a->neg = 0;
a->d[0] = w;
a->top = (w ? 1 : 0);
+ a->flags &= ~BN_FLG_FIXED_TOP;
bn_check_top(a);
return (1);
}
@@ -615,6 +616,41 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
}
/* ignore negative */
+static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
+{
+ int n;
+ size_t i, inc, lasti, j;
+ BN_ULONG l;
+
+ n = BN_num_bytes(a);
+ if (tolen == -1)
+ tolen = n;
+ else if (tolen < n)
+ return -1;
+
+ if (n == 0) {
+ OPENSSL_cleanse(to, tolen);
+ return tolen;
+ }
+
+ lasti = n - 1;
+ for (i = 0, inc = 1, j = tolen; j > 0;) {
+ l = a->d[i / BN_BYTES];
+ to[--j] = (unsigned char)(l >> (8 * (i % BN_BYTES)) & (0 - inc));
+ inc = (i - lasti) >> (8 * sizeof(i) - 1);
+ i += inc; /* stay on top limb */
+ }
+
+ return tolen;
+}
+
+int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
+{
+ if (tolen < 0)
+ return -1;
+ return bn2binpad(a, to, tolen);
+}
+
int BN_bn2bin(const BIGNUM *a, unsigned char *to)
{
int n, i;
@@ -713,6 +749,7 @@ int BN_set_bit(BIGNUM *a, int n)
for (k = a->top; k < i + 1; k++)
a->d[k] = 0;
a->top = i + 1;
+ a->flags &= ~BN_FLG_FIXED_TOP;
}
a->d[i] |= (((BN_ULONG)1) << j);