diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/bn/bn_convert.c | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/src/lib/libcrypto/bn/bn_convert.c b/src/lib/libcrypto/bn/bn_convert.c index 60075e53ed..2b12670ea5 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.16 2024/04/16 13:04:05 jsing Exp $ */ | 1 | /* $OpenBSD: bn_convert.c,v 1.17 2024/04/16 13:11:37 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 | * |
@@ -153,46 +153,69 @@ BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) | |||
153 | } | 153 | } |
154 | LCRYPTO_ALIAS(BN_bn2binpad); | 154 | LCRYPTO_ALIAS(BN_bn2binpad); |
155 | 155 | ||
156 | BIGNUM * | 156 | static int |
157 | BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) | 157 | bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs) |
158 | { | 158 | { |
159 | unsigned int i, m; | ||
160 | unsigned int n; | ||
161 | BN_ULONG l; | ||
162 | BIGNUM *bn = NULL; | 159 | BIGNUM *bn = NULL; |
160 | BN_ULONG w; | ||
161 | uint8_t v; | ||
162 | int b, i; | ||
163 | 163 | ||
164 | if (len < 0) | 164 | if ((bn = *bnp) == NULL) |
165 | return (NULL); | 165 | bn = BN_new(); |
166 | if (ret == NULL) | 166 | if (bn == NULL) |
167 | ret = bn = BN_new(); | 167 | goto err; |
168 | if (ret == NULL) | 168 | if (!bn_expand_bytes(bn, CBS_len(cbs))) |
169 | return (NULL); | 169 | goto err; |
170 | l = 0; | 170 | |
171 | n = len; | 171 | b = BN_BITS2; |
172 | if (n == 0) { | 172 | i = 0; |
173 | ret->top = 0; | 173 | w = 0; |
174 | return (ret); | 174 | |
175 | while (CBS_len(cbs) > 0) { | ||
176 | if (!CBS_get_last_u8(cbs, &v)) | ||
177 | goto err; | ||
178 | |||
179 | w |= (BN_ULONG)v << (BN_BITS2 - b); | ||
180 | b -= 8; | ||
181 | |||
182 | if (b == 0 || CBS_len(cbs) == 0) { | ||
183 | b = BN_BITS2; | ||
184 | bn->d[i++] = w; | ||
185 | w = 0; | ||
186 | } | ||
175 | } | 187 | } |
176 | i = ((n - 1) / BN_BYTES) + 1; | 188 | |
177 | m = ((n - 1) % (BN_BYTES)); | 189 | bn->neg = 0; |
178 | if (!bn_wexpand(ret, (int)i)) { | 190 | bn->top = i; |
191 | |||
192 | bn_correct_top(bn); | ||
193 | |||
194 | *bnp = bn; | ||
195 | |||
196 | return 1; | ||
197 | |||
198 | err: | ||
199 | if (*bnp == NULL) | ||
179 | BN_free(bn); | 200 | BN_free(bn); |
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | BIGNUM * | ||
206 | BN_bin2bn(const unsigned char *d, int len, BIGNUM *bn) | ||
207 | { | ||
208 | CBS cbs; | ||
209 | |||
210 | if (len < 0) | ||
180 | return NULL; | 211 | return NULL; |
181 | } | 212 | |
182 | ret->top = i; | 213 | CBS_init(&cbs, d, len); |
183 | ret->neg = 0; | 214 | |
184 | while (n--) { | 215 | if (!bn_bin2bn_cbs(&bn, &cbs)) |
185 | l = (l << 8L) | *(s++); | 216 | return NULL; |
186 | if (m-- == 0) { | 217 | |
187 | ret->d[--i] = l; | 218 | return bn; |
188 | l = 0; | ||
189 | m = BN_BYTES - 1; | ||
190 | } | ||
191 | } | ||
192 | /* need to call this due to clear byte at top if avoiding | ||
193 | * having the top bit set (-ve number) */ | ||
194 | bn_correct_top(ret); | ||
195 | return (ret); | ||
196 | } | 219 | } |
197 | LCRYPTO_ALIAS(BN_bin2bn); | 220 | LCRYPTO_ALIAS(BN_bin2bn); |
198 | 221 | ||