-/* $OpenBSD: bn_convert.c,v 1.19 2024/04/17 14:45:46 jsing Exp $ */
+/* $OpenBSD: bn_convert.c,v 1.20 2024/04/17 14:47:17 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
LCRYPTO_ALIAS(BN_bn2mpi);
BIGNUM *
-BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain)
+BN_mpi2bn(const unsigned char *d, int n, BIGNUM *bn_in)
{
- BIGNUM *a = ain;
- long len;
+ BIGNUM *bn = bn_in;
+ uint32_t mpi_len;
+ uint8_t v;
int neg = 0;
+ CBS cbs;
+
+ if (n < 0)
+ return NULL;
+
+ CBS_init(&cbs, d, n);
- if (n < 4) {
+ if (!CBS_get_u32(&cbs, &mpi_len)) {
BNerror(BN_R_INVALID_LENGTH);
- return (NULL);
+ return NULL;
+
}
- len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) |
- (int)d[3];
- if ((len + 4) != n) {
+ if (CBS_len(&cbs) != mpi_len) {
BNerror(BN_R_ENCODING_ERROR);
- return (NULL);
+ return NULL;
+ }
+ if (CBS_len(&cbs) > 0) {
+ if (!CBS_peek_u8(&cbs, &v))
+ return NULL;
+ neg = (v >> 7) & 1;
}
- if (a == NULL)
- a = BN_new();
- if (a == NULL)
- return (NULL);
+ if (!bn_bin2bn_cbs(&bn, &cbs, 0))
+ return NULL;
- if (len == 0) {
- a->neg = 0;
- a->top = 0;
- return (a);
- }
- d += 4;
- if ((*d) & 0x80)
- neg = 1;
- if (BN_bin2bn(d, (int)len, a) == NULL) {
- if (ain == NULL)
- BN_free(a);
- return (NULL);
- }
- BN_set_negative(a, neg);
- if (neg) {
- BN_clear_bit(a, BN_num_bits(a) - 1);
- }
- return (a);
+ if (neg)
+ BN_clear_bit(bn, BN_num_bits(bn) - 1);
+
+ BN_set_negative(bn, neg);
+
+ return bn;
}
LCRYPTO_ALIAS(BN_mpi2bn);