-/* $OpenBSD: bn_convert.c,v 1.18 2024/04/16 13:14:46 jsing Exp $ */
+/* $OpenBSD: bn_convert.c,v 1.19 2024/04/17 14:45:46 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
LCRYPTO_ALIAS(BN_bn2binpad);
static int
-bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs)
+bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs, int lebin)
{
BIGNUM *bn = NULL;
BN_ULONG w;
w = 0;
while (CBS_len(cbs) > 0) {
- if (!CBS_get_last_u8(cbs, &v))
- goto err;
+ if (lebin) {
+ if (!CBS_get_u8(cbs, &v))
+ goto err;
+ } else {
+ if (!CBS_get_last_u8(cbs, &v))
+ goto err;
+ }
w |= (BN_ULONG)v << b;
b += 8;
CBS_init(&cbs, d, len);
- if (!bn_bin2bn_cbs(&bn, &cbs))
+ if (!bn_bin2bn_cbs(&bn, &cbs, 0))
return NULL;
return bn;
LCRYPTO_ALIAS(BN_bn2lebinpad);
BIGNUM *
-BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
+BN_lebin2bn(const unsigned char *d, int len, BIGNUM *bn)
{
- unsigned int i, m, n;
- BN_ULONG l;
- BIGNUM *bn = NULL;
+ CBS cbs;
- if (ret == NULL)
- ret = bn = BN_new();
- if (ret == NULL)
+ if (len < 0)
return NULL;
+ CBS_init(&cbs, d, len);
- s += len;
- /* Skip trailing zeroes. */
- for (; len > 0 && s[-1] == 0; s--, len--)
- continue;
-
- n = len;
- if (n == 0) {
- ret->top = 0;
- return ret;
- }
-
- i = ((n - 1) / BN_BYTES) + 1;
- m = (n - 1) % BN_BYTES;
- if (!bn_wexpand(ret, (int)i)) {
- BN_free(bn);
+ if (!bn_bin2bn_cbs(&bn, &cbs, 1))
return NULL;
- }
-
- ret->top = i;
- ret->neg = 0;
- l = 0;
- while (n-- > 0) {
- s--;
- 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;
+ return bn;
}
LCRYPTO_ALIAS(BN_lebin2bn);