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 | ||
