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