diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/bn/bn_convert.c | 102 |
1 files changed, 44 insertions, 58 deletions
diff --git a/src/lib/libcrypto/bn/bn_convert.c b/src/lib/libcrypto/bn/bn_convert.c index d38747e017..6a6354f44e 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.22 2024/06/22 16:33:00 jsing Exp $ */ | 1 | /* $OpenBSD: bn_convert.c,v 1.23 2024/11/08 14:18:44 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 | * |
| @@ -69,87 +69,73 @@ | |||
| 69 | 69 | ||
| 70 | #include "bn_local.h" | 70 | #include "bn_local.h" |
| 71 | #include "bytestring.h" | 71 | #include "bytestring.h" |
| 72 | #include "crypto_internal.h" | ||
| 72 | 73 | ||
| 73 | static int bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs); | 74 | static int bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs); |
| 74 | static int bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs); | 75 | static int bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs); |
| 75 | 76 | ||
| 76 | static const char hex_digits[] = "0123456789ABCDEF"; | 77 | static const char hex_digits[] = "0123456789ABCDEF"; |
| 77 | 78 | ||
| 78 | typedef enum { | ||
| 79 | big, | ||
| 80 | little, | ||
| 81 | } endianness_t; | ||
| 82 | |||
| 83 | /* ignore negative */ | ||
| 84 | static int | 79 | static int |
| 85 | bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness) | 80 | bn_bn2binpad_internal(const BIGNUM *bn, uint8_t *out, int out_len, |
| 81 | int little_endian) | ||
| 86 | { | 82 | { |
| 87 | int n; | 83 | uint8_t mask, v; |
| 88 | size_t i, lasti, j, atop, mask; | 84 | BN_ULONG w; |
| 89 | BN_ULONG l; | 85 | int i, j; |
| 90 | 86 | int b, n; | |
| 91 | /* | ||
| 92 | * In case |a| is fixed-top, BN_num_bytes can return bogus length, | ||
| 93 | * but it's assumed that fixed-top inputs ought to be "nominated" | ||
| 94 | * even for padded output, so it works out... | ||
| 95 | */ | ||
| 96 | n = BN_num_bytes(a); | ||
| 97 | if (tolen == -1) | ||
| 98 | tolen = n; | ||
| 99 | else if (tolen < n) { /* uncommon/unlike case */ | ||
| 100 | BIGNUM temp = *a; | ||
| 101 | 87 | ||
| 102 | bn_correct_top(&temp); | 88 | n = BN_num_bytes(bn); |
| 103 | 89 | ||
| 104 | n = BN_num_bytes(&temp); | 90 | if (out_len == -1) |
| 105 | if (tolen < n) | 91 | out_len = n; |
| 106 | return -1; | 92 | if (out_len < n) |
| 107 | } | 93 | return -1; |
| 108 | 94 | ||
| 109 | /* Swipe through whole available data and don't give away padded zero. */ | 95 | if (bn->dmax == 0) { |
| 110 | atop = a->dmax * BN_BYTES; | 96 | explicit_bzero(out, out_len); |
| 111 | if (atop == 0) { | 97 | return out_len; |
| 112 | explicit_bzero(to, tolen); | ||
| 113 | return tolen; | ||
| 114 | } | 98 | } |
| 115 | 99 | ||
| 116 | lasti = atop - 1; | 100 | mask = 0; |
| 117 | atop = a->top * BN_BYTES; | 101 | b = BN_BITS2; |
| 118 | 102 | j = 0; | |
| 119 | if (endianness == big) | ||
| 120 | to += tolen; /* start from the end of the buffer */ | ||
| 121 | 103 | ||
| 122 | for (i = 0, j = 0; j < (size_t)tolen; j++) { | 104 | for (i = out_len - 1; i >= 0; i--) { |
| 123 | unsigned char val; | 105 | if (b == BN_BITS2) { |
| 124 | 106 | mask = crypto_ct_lt_mask(j, bn->top); | |
| 125 | l = a->d[i / BN_BYTES]; | 107 | w = bn->d[j++ % bn->dmax]; |
| 126 | mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); | 108 | b = 0; |
| 127 | val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); | 109 | } |
| 128 | 110 | out[i] = (w >> b) & mask; | |
| 129 | if (endianness == big) | 111 | b += 8; |
| 130 | *--to = val; | 112 | } |
| 131 | else | ||
| 132 | *to++ = val; | ||
| 133 | 113 | ||
| 134 | i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ | 114 | if (little_endian) { |
| 115 | for (i = 0, j = out_len - 1; i < out_len / 2; i++, j--) { | ||
| 116 | v = out[i]; | ||
| 117 | out[i] = out[j]; | ||
| 118 | out[j] = v; | ||
| 119 | } | ||
| 135 | } | 120 | } |
| 136 | 121 | ||
| 137 | return tolen; | 122 | return out_len; |
| 138 | } | 123 | } |
| 139 | 124 | ||
| 140 | int | 125 | int |
| 141 | BN_bn2bin(const BIGNUM *a, unsigned char *to) | 126 | BN_bn2bin(const BIGNUM *bn, unsigned char *to) |
| 142 | { | 127 | { |
| 143 | return bn2binpad(a, to, -1, big); | 128 | return bn_bn2binpad_internal(bn, to, -1, 0); |
| 144 | } | 129 | } |
| 145 | LCRYPTO_ALIAS(BN_bn2bin); | 130 | LCRYPTO_ALIAS(BN_bn2bin); |
| 146 | 131 | ||
| 147 | int | 132 | int |
| 148 | BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) | 133 | BN_bn2binpad(const BIGNUM *bn, unsigned char *to, int to_len) |
| 149 | { | 134 | { |
| 150 | if (tolen < 0) | 135 | if (to_len < 0) |
| 151 | return -1; | 136 | return -1; |
| 152 | return bn2binpad(a, to, tolen, big); | 137 | |
| 138 | return bn_bn2binpad_internal(bn, to, to_len, 0); | ||
| 153 | } | 139 | } |
| 154 | LCRYPTO_ALIAS(BN_bn2binpad); | 140 | LCRYPTO_ALIAS(BN_bn2binpad); |
| 155 | 141 | ||
| @@ -225,12 +211,12 @@ BN_bin2bn(const unsigned char *d, int len, BIGNUM *bn) | |||
| 225 | LCRYPTO_ALIAS(BN_bin2bn); | 211 | LCRYPTO_ALIAS(BN_bin2bn); |
| 226 | 212 | ||
| 227 | int | 213 | int |
| 228 | BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) | 214 | BN_bn2lebinpad(const BIGNUM *bn, unsigned char *to, int to_len) |
| 229 | { | 215 | { |
| 230 | if (tolen < 0) | 216 | if (to_len < 0) |
| 231 | return -1; | 217 | return -1; |
| 232 | 218 | ||
| 233 | return bn2binpad(a, to, tolen, little); | 219 | return bn_bn2binpad_internal(bn, to, to_len, 1); |
| 234 | } | 220 | } |
| 235 | LCRYPTO_ALIAS(BN_bn2lebinpad); | 221 | LCRYPTO_ALIAS(BN_bn2lebinpad); |
| 236 | 222 | ||
