summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/bn/bn_convert.c64
1 files changed, 16 insertions, 48 deletions
diff --git a/src/lib/libcrypto/bn/bn_convert.c b/src/lib/libcrypto/bn/bn_convert.c
index 5c3c98b787..0bfb00e958 100644
--- a/src/lib/libcrypto/bn/bn_convert.c
+++ b/src/lib/libcrypto/bn/bn_convert.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_convert.c,v 1.18 2024/04/16 13:14:46 jsing Exp $ */ 1/* $OpenBSD: bn_convert.c,v 1.19 2024/04/17 14:45:46 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -154,7 +154,7 @@ BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
154LCRYPTO_ALIAS(BN_bn2binpad); 154LCRYPTO_ALIAS(BN_bn2binpad);
155 155
156static int 156static int
157bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs) 157bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs, int lebin)
158{ 158{
159 BIGNUM *bn = NULL; 159 BIGNUM *bn = NULL;
160 BN_ULONG w; 160 BN_ULONG w;
@@ -173,8 +173,13 @@ bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs)
173 w = 0; 173 w = 0;
174 174
175 while (CBS_len(cbs) > 0) { 175 while (CBS_len(cbs) > 0) {
176 if (!CBS_get_last_u8(cbs, &v)) 176 if (lebin) {
177 goto err; 177 if (!CBS_get_u8(cbs, &v))
178 goto err;
179 } else {
180 if (!CBS_get_last_u8(cbs, &v))
181 goto err;
182 }
178 183
179 w |= (BN_ULONG)v << b; 184 w |= (BN_ULONG)v << b;
180 b += 8; 185 b += 8;
@@ -212,7 +217,7 @@ BN_bin2bn(const unsigned char *d, int len, BIGNUM *bn)
212 217
213 CBS_init(&cbs, d, len); 218 CBS_init(&cbs, d, len);
214 219
215 if (!bn_bin2bn_cbs(&bn, &cbs)) 220 if (!bn_bin2bn_cbs(&bn, &cbs, 0))
216 return NULL; 221 return NULL;
217 222
218 return bn; 223 return bn;
@@ -230,56 +235,19 @@ BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
230LCRYPTO_ALIAS(BN_bn2lebinpad); 235LCRYPTO_ALIAS(BN_bn2lebinpad);
231 236
232BIGNUM * 237BIGNUM *
233BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) 238BN_lebin2bn(const unsigned char *d, int len, BIGNUM *bn)
234{ 239{
235 unsigned int i, m, n; 240 CBS cbs;
236 BN_ULONG l;
237 BIGNUM *bn = NULL;
238 241
239 if (ret == NULL) 242 if (len < 0)
240 ret = bn = BN_new();
241 if (ret == NULL)
242 return NULL; 243 return NULL;
243 244
245 CBS_init(&cbs, d, len);
244 246
245 s += len; 247 if (!bn_bin2bn_cbs(&bn, &cbs, 1))
246 /* Skip trailing zeroes. */
247 for (; len > 0 && s[-1] == 0; s--, len--)
248 continue;
249
250 n = len;
251 if (n == 0) {
252 ret->top = 0;
253 return ret;
254 }
255
256 i = ((n - 1) / BN_BYTES) + 1;
257 m = (n - 1) % BN_BYTES;
258 if (!bn_wexpand(ret, (int)i)) {
259 BN_free(bn);
260 return NULL; 248 return NULL;
261 }
262
263 ret->top = i;
264 ret->neg = 0;
265 l = 0;
266 while (n-- > 0) {
267 s--;
268 l = (l << 8L) | *s;
269 if (m-- == 0) {
270 ret->d[--i] = l;
271 l = 0;
272 m = BN_BYTES - 1;
273 }
274 }
275 249
276 /* 250 return bn;
277 * need to call this due to clear byte at top if avoiding having the
278 * top bit set (-ve number)
279 */
280 bn_correct_top(ret);
281
282 return ret;
283} 251}
284LCRYPTO_ALIAS(BN_lebin2bn); 252LCRYPTO_ALIAS(BN_lebin2bn);
285 253