diff options
Diffstat (limited to 'freebsd/crypto/openssl/crypto/bn/bn_lib.c')
-rw-r--r-- | freebsd/crypto/openssl/crypto/bn/bn_lib.c | 57 |
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); |