/src/boringssl/crypto/ecdsa/ecdsa_asn1.cc
Line | Count | Source |
1 | | // Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <openssl/ecdsa.h> |
16 | | |
17 | | #include <limits.h> |
18 | | #include <string.h> |
19 | | |
20 | | #include <openssl/bn.h> |
21 | | #include <openssl/bytestring.h> |
22 | | #include <openssl/ec_key.h> |
23 | | #include <openssl/err.h> |
24 | | #include <openssl/mem.h> |
25 | | |
26 | | #include "../bytestring/internal.h" |
27 | | #include "../fipsmodule/ecdsa/internal.h" |
28 | | #include "../internal.h" |
29 | | #include "../mem_internal.h" |
30 | | |
31 | | |
32 | | using namespace bssl; |
33 | | |
34 | | static ECDSA_SIG *ecdsa_sig_from_fixed(const EC_KEY *key, const uint8_t *in, |
35 | 562 | size_t len) { |
36 | 562 | const EC_GROUP *group = EC_KEY_get0_group(key); |
37 | 562 | if (group == nullptr) { |
38 | 0 | OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); |
39 | 0 | return nullptr; |
40 | 0 | } |
41 | 562 | size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group)); |
42 | 562 | if (len != 2 * scalar_len) { |
43 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
44 | 0 | return nullptr; |
45 | 0 | } |
46 | 562 | ECDSA_SIG *ret = ECDSA_SIG_new(); |
47 | 562 | if (ret == nullptr || !BN_bin2bn(in, scalar_len, ret->r) || |
48 | 562 | !BN_bin2bn(in + scalar_len, scalar_len, ret->s)) { |
49 | 0 | ECDSA_SIG_free(ret); |
50 | 0 | return nullptr; |
51 | 0 | } |
52 | 562 | return ret; |
53 | 562 | } |
54 | | |
55 | | static int ecdsa_sig_to_fixed(const EC_KEY *key, uint8_t *out, size_t *out_len, |
56 | 14.7k | size_t max_out, const ECDSA_SIG *sig) { |
57 | 14.7k | const EC_GROUP *group = EC_KEY_get0_group(key); |
58 | 14.7k | if (group == nullptr) { |
59 | 0 | OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); |
60 | 0 | return 0; |
61 | 0 | } |
62 | 14.7k | size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group)); |
63 | 14.7k | if (max_out < 2 * scalar_len) { |
64 | 0 | OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); |
65 | 0 | return 0; |
66 | 0 | } |
67 | 14.7k | if (BN_is_negative(sig->r) || !BN_bn2bin_padded(out, scalar_len, sig->r) || |
68 | 14.6k | BN_is_negative(sig->s) || |
69 | 14.6k | !BN_bn2bin_padded(out + scalar_len, scalar_len, sig->s)) { |
70 | 3.15k | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
71 | 3.15k | return 0; |
72 | 3.15k | } |
73 | 11.6k | *out_len = 2 * scalar_len; |
74 | 11.6k | return 1; |
75 | 14.7k | } |
76 | | |
77 | | int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, |
78 | 0 | unsigned int *out_sig_len, const EC_KEY *eckey) { |
79 | 0 | const ECKey *eckey_impl = FromOpaque(eckey); |
80 | 0 | if (eckey_impl->ecdsa_meth && eckey_impl->ecdsa_meth->sign) { |
81 | 0 | return eckey_impl->ecdsa_meth->sign(digest, digest_len, sig, out_sig_len, |
82 | 0 | (EC_KEY *)eckey /* cast away const */); |
83 | 0 | } |
84 | | |
85 | 0 | *out_sig_len = 0; |
86 | 0 | uint8_t fixed[ECDSA_MAX_FIXED_LEN]; |
87 | 0 | size_t fixed_len; |
88 | 0 | if (!ecdsa_sign_fixed(digest, digest_len, fixed, &fixed_len, sizeof(fixed), |
89 | 0 | eckey)) { |
90 | 0 | return 0; |
91 | 0 | } |
92 | | |
93 | | // TODO(davidben): We can actually do better and go straight from the DER |
94 | | // format to the fixed-width format without a malloc. |
95 | 0 | UniquePtr<ECDSA_SIG> s(ecdsa_sig_from_fixed(eckey, fixed, fixed_len)); |
96 | 0 | if (s == nullptr) { |
97 | 0 | return 0; |
98 | 0 | } |
99 | | |
100 | 0 | CBB cbb; |
101 | 0 | CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)); |
102 | 0 | size_t len; |
103 | 0 | if (!ECDSA_SIG_marshal(&cbb, s.get()) || !CBB_finish(&cbb, nullptr, &len)) { |
104 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
105 | 0 | return 0; |
106 | 0 | } |
107 | 0 | *out_sig_len = static_cast<unsigned>(len); |
108 | 0 | return 1; |
109 | 0 | } |
110 | | |
111 | | int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, |
112 | 17.6k | const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) { |
113 | | // Decode the ECDSA signature. |
114 | | // |
115 | | // TODO(davidben): We can actually do better and go straight from the DER |
116 | | // format to the fixed-width format without a malloc. |
117 | 17.6k | int ret = 0; |
118 | 17.6k | uint8_t *der = nullptr; |
119 | 17.6k | UniquePtr<ECDSA_SIG> s(ECDSA_SIG_from_bytes(sig, sig_len)); |
120 | 17.6k | if (s == nullptr) { |
121 | 3.08k | goto err; |
122 | 3.08k | } |
123 | | |
124 | | // Defend against potential laxness in the DER parser. |
125 | 14.5k | size_t der_len; |
126 | 14.5k | if (!ECDSA_SIG_to_bytes(&der, &der_len, s.get()) || der_len != sig_len || |
127 | 14.5k | OPENSSL_memcmp(sig, der, sig_len) != 0) { |
128 | | // This should never happen. crypto/bytestring is strictly DER. |
129 | 0 | OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR); |
130 | 0 | goto err; |
131 | 0 | } |
132 | | |
133 | 14.5k | uint8_t fixed[ECDSA_MAX_FIXED_LEN]; |
134 | 14.5k | size_t fixed_len; |
135 | 14.5k | ret = ecdsa_sig_to_fixed(eckey, fixed, &fixed_len, sizeof(fixed), s.get()) && |
136 | 11.4k | ecdsa_verify_fixed(digest, digest_len, fixed, fixed_len, eckey); |
137 | | |
138 | 17.6k | err: |
139 | 17.6k | OPENSSL_free(der); |
140 | 17.6k | return ret; |
141 | 14.5k | } |
142 | | |
143 | | |
144 | 0 | size_t ECDSA_size(const EC_KEY *key) { |
145 | 0 | if (key == nullptr) { |
146 | 0 | return 0; |
147 | 0 | } |
148 | | |
149 | 0 | const EC_GROUP *group = EC_KEY_get0_group(key); |
150 | 0 | if (group == nullptr) { |
151 | 0 | return 0; |
152 | 0 | } |
153 | | |
154 | 0 | size_t group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); |
155 | 0 | return ECDSA_SIG_max_len(group_order_size); |
156 | 0 | } |
157 | | |
158 | 19.6k | ECDSA_SIG *ECDSA_SIG_new() { |
159 | 19.6k | ECDSA_SIG *sig = New<ECDSA_SIG>(); |
160 | 19.6k | if (sig == nullptr) { |
161 | 0 | return nullptr; |
162 | 0 | } |
163 | 19.6k | sig->r = BN_new(); |
164 | 19.6k | sig->s = BN_new(); |
165 | 19.6k | if (sig->r == nullptr || sig->s == nullptr) { |
166 | 0 | ECDSA_SIG_free(sig); |
167 | 0 | return nullptr; |
168 | 0 | } |
169 | 19.6k | return sig; |
170 | 19.6k | } |
171 | | |
172 | 23.5k | void ECDSA_SIG_free(ECDSA_SIG *sig) { |
173 | 23.5k | if (sig == nullptr) { |
174 | 3.88k | return; |
175 | 3.88k | } |
176 | | |
177 | 19.6k | BN_free(sig->r); |
178 | 19.6k | BN_free(sig->s); |
179 | 19.6k | Delete(sig); |
180 | 19.6k | } |
181 | | |
182 | 0 | const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig) { return sig->r; } |
183 | | |
184 | 0 | const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig) { return sig->s; } |
185 | | |
186 | | void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **out_r, |
187 | 0 | const BIGNUM **out_s) { |
188 | 0 | if (out_r != nullptr) { |
189 | 0 | *out_r = sig->r; |
190 | 0 | } |
191 | 0 | if (out_s != nullptr) { |
192 | 0 | *out_s = sig->s; |
193 | 0 | } |
194 | 0 | } |
195 | | |
196 | 0 | int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { |
197 | 0 | if (r == nullptr || s == nullptr) { |
198 | 0 | return 0; |
199 | 0 | } |
200 | 0 | BN_free(sig->r); |
201 | 0 | BN_free(sig->s); |
202 | 0 | sig->r = r; |
203 | 0 | sig->s = s; |
204 | 0 | return 1; |
205 | 0 | } |
206 | | |
207 | | int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, |
208 | 196 | const ECDSA_SIG *sig, const EC_KEY *eckey) { |
209 | 196 | uint8_t fixed[ECDSA_MAX_FIXED_LEN]; |
210 | 196 | size_t fixed_len; |
211 | 196 | return ecdsa_sig_to_fixed(eckey, fixed, &fixed_len, sizeof(fixed), sig) && |
212 | 196 | ecdsa_verify_fixed(digest, digest_len, fixed, fixed_len, eckey); |
213 | 196 | } |
214 | | |
215 | | // This function is only exported for testing and is not called in production |
216 | | // code. |
217 | | ECDSA_SIG *ECDSA_sign_with_nonce_and_leak_private_key_for_testing( |
218 | | const uint8_t *digest, size_t digest_len, const EC_KEY *eckey, |
219 | 0 | const uint8_t *nonce, size_t nonce_len) { |
220 | 0 | uint8_t sig[ECDSA_MAX_FIXED_LEN]; |
221 | 0 | size_t sig_len; |
222 | 0 | if (!ecdsa_sign_fixed_with_nonce_for_known_answer_test( |
223 | 0 | digest, digest_len, sig, &sig_len, sizeof(sig), eckey, nonce, |
224 | 0 | nonce_len)) { |
225 | 0 | return nullptr; |
226 | 0 | } |
227 | | |
228 | 0 | return ecdsa_sig_from_fixed(eckey, sig, sig_len); |
229 | 0 | } |
230 | | |
231 | | ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, |
232 | 562 | const EC_KEY *eckey) { |
233 | 562 | uint8_t sig[ECDSA_MAX_FIXED_LEN]; |
234 | 562 | size_t sig_len; |
235 | 562 | if (!ecdsa_sign_fixed(digest, digest_len, sig, &sig_len, sizeof(sig), |
236 | 562 | eckey)) { |
237 | 0 | return nullptr; |
238 | 0 | } |
239 | | |
240 | 562 | return ecdsa_sig_from_fixed(eckey, sig, sig_len); |
241 | 562 | } |
242 | | |
243 | 18.8k | ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) { |
244 | 18.8k | ECDSA_SIG *ret = ECDSA_SIG_new(); |
245 | 18.8k | if (ret == nullptr) { |
246 | 0 | return nullptr; |
247 | 0 | } |
248 | 18.8k | CBS child; |
249 | 18.8k | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
250 | 16.1k | !BN_parse_asn1_unsigned(&child, ret->r) || |
251 | 15.8k | !BN_parse_asn1_unsigned(&child, ret->s) || CBS_len(&child) != 0) { |
252 | 3.88k | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
253 | 3.88k | ECDSA_SIG_free(ret); |
254 | 3.88k | return nullptr; |
255 | 3.88k | } |
256 | 14.9k | return ret; |
257 | 18.8k | } |
258 | | |
259 | 18.8k | ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) { |
260 | 18.8k | CBS cbs; |
261 | 18.8k | CBS_init(&cbs, in, in_len); |
262 | 18.8k | ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); |
263 | 18.8k | if (ret == nullptr || CBS_len(&cbs) != 0) { |
264 | 3.90k | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
265 | 3.90k | ECDSA_SIG_free(ret); |
266 | 3.90k | return nullptr; |
267 | 3.90k | } |
268 | 14.9k | return ret; |
269 | 18.8k | } |
270 | | |
271 | 14.9k | int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) { |
272 | 14.9k | CBB child; |
273 | 14.9k | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
274 | 14.9k | !BN_marshal_asn1(&child, sig->r) || !BN_marshal_asn1(&child, sig->s) || |
275 | 14.9k | !CBB_flush(cbb)) { |
276 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
277 | 0 | return 0; |
278 | 0 | } |
279 | 14.9k | return 1; |
280 | 14.9k | } |
281 | | |
282 | | int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, |
283 | 14.9k | const ECDSA_SIG *sig) { |
284 | 14.9k | CBB cbb; |
285 | 14.9k | CBB_zero(&cbb); |
286 | 14.9k | if (!CBB_init(&cbb, 0) || !ECDSA_SIG_marshal(&cbb, sig) || |
287 | 14.9k | !CBB_finish(&cbb, out_bytes, out_len)) { |
288 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
289 | 0 | CBB_cleanup(&cbb); |
290 | 0 | return 0; |
291 | 0 | } |
292 | 14.9k | return 1; |
293 | 14.9k | } |
294 | | |
295 | | // der_len_len returns the number of bytes needed to represent a length of `len` |
296 | | // in DER. |
297 | 0 | static size_t der_len_len(size_t len) { |
298 | 0 | if (len < 0x80) { |
299 | 0 | return 1; |
300 | 0 | } |
301 | 0 | size_t ret = 1; |
302 | 0 | while (len > 0) { |
303 | 0 | ret++; |
304 | 0 | len >>= 8; |
305 | 0 | } |
306 | 0 | return ret; |
307 | 0 | } |
308 | | |
309 | 0 | size_t ECDSA_SIG_max_len(size_t order_len) { |
310 | | // Compute the maximum length of an `order_len` byte integer. Defensively |
311 | | // assume that the leading 0x00 is included. |
312 | 0 | size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; |
313 | 0 | if (integer_len < order_len) { |
314 | 0 | return 0; |
315 | 0 | } |
316 | | // An ECDSA signature is two INTEGERs. |
317 | 0 | size_t value_len = 2 * integer_len; |
318 | 0 | if (value_len < integer_len) { |
319 | 0 | return 0; |
320 | 0 | } |
321 | | // Add the header. |
322 | 0 | size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; |
323 | 0 | if (ret < value_len) { |
324 | 0 | return 0; |
325 | 0 | } |
326 | 0 | return ret; |
327 | 0 | } |
328 | | |
329 | 0 | ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { |
330 | 0 | return D2IFromCBS(out, inp, len, ECDSA_SIG_parse); |
331 | 0 | } |
332 | | |
333 | 0 | int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { |
334 | 0 | return I2DFromCBB( |
335 | 0 | /*initial_capacity=*/64, outp, |
336 | 0 | [&](CBB *cbb) -> bool { return ECDSA_SIG_marshal(cbb, sig); }); |
337 | 0 | } |