diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2024-04-16 13:11:38 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2024-04-16 13:11:38 +0000 |
commit | 249b74135d408ef54b7c1797699b779867f653eb (patch) | |
tree | 9d198276887f0c16a5e1a27cc2dc46732bca8ace /lib | |
parent | 6a02cf6846fbac3d44e5f6054cbba29dc26fb5eb (diff) |
Rewrite BN_bin2bn() using CBS.
ok tb@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libcrypto/bn/bn_convert.c | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/lib/libcrypto/bn/bn_convert.c b/lib/libcrypto/bn/bn_convert.c index 60075e53ed9..2b12670ea56 100644 --- a/lib/libcrypto/bn/bn_convert.c +++ b/lib/libcrypto/bn/bn_convert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_convert.c,v 1.16 2024/04/16 13:04:05 jsing Exp $ */ +/* $OpenBSD: bn_convert.c,v 1.17 2024/04/16 13:11:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -153,46 +153,69 @@ BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) } LCRYPTO_ALIAS(BN_bn2binpad); -BIGNUM * -BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +static int +bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs) { - unsigned int i, m; - unsigned int n; - BN_ULONG l; BIGNUM *bn = NULL; + BN_ULONG w; + uint8_t v; + int b, i; - if (len < 0) - return (NULL); - if (ret == NULL) - ret = bn = BN_new(); - if (ret == NULL) - return (NULL); - l = 0; - n = len; - if (n == 0) { - ret->top = 0; - return (ret); + if ((bn = *bnp) == NULL) + bn = BN_new(); + if (bn == NULL) + goto err; + if (!bn_expand_bytes(bn, CBS_len(cbs))) + goto err; + + b = BN_BITS2; + i = 0; + w = 0; + + while (CBS_len(cbs) > 0) { + if (!CBS_get_last_u8(cbs, &v)) + goto err; + + w |= (BN_ULONG)v << (BN_BITS2 - b); + b -= 8; + + if (b == 0 || CBS_len(cbs) == 0) { + b = BN_BITS2; + bn->d[i++] = w; + w = 0; + } } - i = ((n - 1) / BN_BYTES) + 1; - m = ((n - 1) % (BN_BYTES)); - if (!bn_wexpand(ret, (int)i)) { + + bn->neg = 0; + bn->top = i; + + bn_correct_top(bn); + + *bnp = bn; + + return 1; + + err: + if (*bnp == NULL) BN_free(bn); + + return 0; +} + +BIGNUM * +BN_bin2bn(const unsigned char *d, int len, BIGNUM *bn) +{ + CBS cbs; + + if (len < 0) return NULL; - } - ret->top = i; - ret->neg = 0; - while (n--) { - l = (l << 8L) | *(s++); - if (m-- == 0) { - ret->d[--i] = l; - l = 0; - m = BN_BYTES - 1; - } - } - /* need to call this due to clear byte at top if avoiding - * having the top bit set (-ve number) */ - bn_correct_top(ret); - return (ret); + + CBS_init(&cbs, d, len); + + if (!bn_bin2bn_cbs(&bn, &cbs)) + return NULL; + + return bn; } LCRYPTO_ALIAS(BN_bin2bn); |