Rewrite BN_mpi2bn() using CBS and bn_bin2bn_cbs().
authorjsing <jsing@openbsd.org>
Wed, 17 Apr 2024 14:47:17 +0000 (14:47 +0000)
committerjsing <jsing@openbsd.org>
Wed, 17 Apr 2024 14:47:17 +0000 (14:47 +0000)
ok tb@

lib/libcrypto/bn/bn_convert.c

index 0bfb00e..7c5ba85 100644 (file)
@@ -1,4 +1,4 @@
-/* $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.
  *
@@ -720,45 +720,42 @@ BN_bn2mpi(const BIGNUM *a, unsigned char *d)
 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);