/src/boringssl/crypto/ecdsa_extra/ecdsa_asn1.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* ==================================================================== |
2 | | * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. |
3 | | * |
4 | | * Redistribution and use in source and binary forms, with or without |
5 | | * modification, are permitted provided that the following conditions |
6 | | * are met: |
7 | | * |
8 | | * 1. Redistributions of source code must retain the above copyright |
9 | | * notice, this list of conditions and the following disclaimer. |
10 | | * |
11 | | * 2. Redistributions in binary form must reproduce the above copyright |
12 | | * notice, this list of conditions and the following disclaimer in |
13 | | * the documentation and/or other materials provided with the |
14 | | * distribution. |
15 | | * |
16 | | * 3. All advertising materials mentioning features or use of this |
17 | | * software must display the following acknowledgment: |
18 | | * "This product includes software developed by the OpenSSL Project |
19 | | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
20 | | * |
21 | | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
22 | | * endorse or promote products derived from this software without |
23 | | * prior written permission. For written permission, please contact |
24 | | * openssl-core@OpenSSL.org. |
25 | | * |
26 | | * 5. Products derived from this software may not be called "OpenSSL" |
27 | | * nor may "OpenSSL" appear in their names without prior written |
28 | | * permission of the OpenSSL Project. |
29 | | * |
30 | | * 6. Redistributions of any form whatsoever must retain the following |
31 | | * acknowledgment: |
32 | | * "This product includes software developed by the OpenSSL Project |
33 | | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
34 | | * |
35 | | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
36 | | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
37 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
38 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
39 | | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
40 | | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
41 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
42 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
43 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
44 | | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
45 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
46 | | * OF THE POSSIBILITY OF SUCH DAMAGE. |
47 | | * ==================================================================== |
48 | | * |
49 | | * This product includes cryptographic software written by Eric Young |
50 | | * (eay@cryptsoft.com). This product includes software written by Tim |
51 | | * Hudson (tjh@cryptsoft.com). */ |
52 | | |
53 | | #include <openssl/ecdsa.h> |
54 | | |
55 | | #include <limits.h> |
56 | | #include <string.h> |
57 | | |
58 | | #include <openssl/bn.h> |
59 | | #include <openssl/bytestring.h> |
60 | | #include <openssl/err.h> |
61 | | #include <openssl/ec_key.h> |
62 | | #include <openssl/mem.h> |
63 | | |
64 | | #include "../bytestring/internal.h" |
65 | | #include "../fipsmodule/ecdsa/internal.h" |
66 | | #include "../internal.h" |
67 | | |
68 | | |
69 | | static ECDSA_SIG *ecdsa_sig_from_fixed(const EC_KEY *key, const uint8_t *in, |
70 | 0 | size_t len) { |
71 | 0 | const EC_GROUP *group = EC_KEY_get0_group(key); |
72 | 0 | if (group == NULL) { |
73 | 0 | OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); |
74 | 0 | return NULL; |
75 | 0 | } |
76 | 0 | size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group)); |
77 | 0 | if (len != 2 * scalar_len) { |
78 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
79 | 0 | return NULL; |
80 | 0 | } |
81 | 0 | ECDSA_SIG *ret = ECDSA_SIG_new(); |
82 | 0 | if (ret == NULL || |
83 | 0 | !BN_bin2bn(in, scalar_len, ret->r) || |
84 | 0 | !BN_bin2bn(in + scalar_len, scalar_len, ret->s)) { |
85 | 0 | ECDSA_SIG_free(ret); |
86 | 0 | return NULL; |
87 | 0 | } |
88 | 0 | return ret; |
89 | 0 | } |
90 | | |
91 | | static int ecdsa_sig_to_fixed(const EC_KEY *key, uint8_t *out, size_t *out_len, |
92 | 15 | size_t max_out, const ECDSA_SIG *sig) { |
93 | 15 | const EC_GROUP *group = EC_KEY_get0_group(key); |
94 | 15 | if (group == NULL) { |
95 | 0 | OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); |
96 | 0 | return 0; |
97 | 0 | } |
98 | 15 | size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group)); |
99 | 15 | if (max_out < 2 * scalar_len) { |
100 | 0 | OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); |
101 | 0 | return 0; |
102 | 0 | } |
103 | 15 | if (BN_is_negative(sig->r) || |
104 | 15 | !BN_bn2bin_padded(out, scalar_len, sig->r) || |
105 | 15 | BN_is_negative(sig->s) || |
106 | 15 | !BN_bn2bin_padded(out + scalar_len, scalar_len, sig->s)) { |
107 | 2 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
108 | 2 | return 0; |
109 | 2 | } |
110 | 13 | *out_len = 2 * scalar_len; |
111 | 13 | return 1; |
112 | 15 | } |
113 | | |
114 | | int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, |
115 | 0 | unsigned int *out_sig_len, const EC_KEY *eckey) { |
116 | 0 | if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { |
117 | 0 | return eckey->ecdsa_meth->sign(digest, digest_len, sig, out_sig_len, |
118 | 0 | (EC_KEY*) eckey /* cast away const */); |
119 | 0 | } |
120 | | |
121 | 0 | *out_sig_len = 0; |
122 | 0 | uint8_t fixed[ECDSA_MAX_FIXED_LEN]; |
123 | 0 | size_t fixed_len; |
124 | 0 | if (!ecdsa_sign_fixed(digest, digest_len, fixed, &fixed_len, sizeof(fixed), |
125 | 0 | eckey)) { |
126 | 0 | return 0; |
127 | 0 | } |
128 | | |
129 | | // TODO(davidben): We can actually do better and go straight from the DER |
130 | | // format to the fixed-width format without a malloc. |
131 | 0 | ECDSA_SIG *s = ecdsa_sig_from_fixed(eckey, fixed, fixed_len); |
132 | 0 | if (s == NULL) { |
133 | 0 | return 0; |
134 | 0 | } |
135 | | |
136 | 0 | int ret = 0; |
137 | 0 | CBB cbb; |
138 | 0 | CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)); |
139 | 0 | size_t len; |
140 | 0 | if (!ECDSA_SIG_marshal(&cbb, s) || |
141 | 0 | !CBB_finish(&cbb, NULL, &len)) { |
142 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
143 | 0 | goto err; |
144 | 0 | } |
145 | 0 | *out_sig_len = (unsigned)len; |
146 | 0 | ret = 1; |
147 | |
|
148 | 0 | err: |
149 | 0 | ECDSA_SIG_free(s); |
150 | 0 | return ret; |
151 | 0 | } |
152 | | |
153 | | int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, |
154 | 0 | const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) { |
155 | | // Decode the ECDSA signature. |
156 | | // |
157 | | // TODO(davidben): We can actually do better and go straight from the DER |
158 | | // format to the fixed-width format without a malloc. |
159 | 0 | int ret = 0; |
160 | 0 | uint8_t *der = NULL; |
161 | 0 | ECDSA_SIG *s = ECDSA_SIG_from_bytes(sig, sig_len); |
162 | 0 | if (s == NULL) { |
163 | 0 | goto err; |
164 | 0 | } |
165 | | |
166 | | // Defend against potential laxness in the DER parser. |
167 | 0 | size_t der_len; |
168 | 0 | if (!ECDSA_SIG_to_bytes(&der, &der_len, s) || |
169 | 0 | der_len != sig_len || OPENSSL_memcmp(sig, der, sig_len) != 0) { |
170 | | // This should never happen. crypto/bytestring is strictly DER. |
171 | 0 | OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR); |
172 | 0 | goto err; |
173 | 0 | } |
174 | | |
175 | 0 | uint8_t fixed[ECDSA_MAX_FIXED_LEN]; |
176 | 0 | size_t fixed_len; |
177 | 0 | ret = ecdsa_sig_to_fixed(eckey, fixed, &fixed_len, sizeof(fixed), s) && |
178 | 0 | ecdsa_verify_fixed(digest, digest_len, fixed, fixed_len, eckey); |
179 | |
|
180 | 0 | err: |
181 | 0 | OPENSSL_free(der); |
182 | 0 | ECDSA_SIG_free(s); |
183 | 0 | return ret; |
184 | 0 | } |
185 | | |
186 | | |
187 | 0 | size_t ECDSA_size(const EC_KEY *key) { |
188 | 0 | if (key == NULL) { |
189 | 0 | return 0; |
190 | 0 | } |
191 | | |
192 | 0 | size_t group_order_size; |
193 | 0 | if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) { |
194 | 0 | group_order_size = key->ecdsa_meth->group_order_size(key); |
195 | 0 | } else { |
196 | 0 | const EC_GROUP *group = EC_KEY_get0_group(key); |
197 | 0 | if (group == NULL) { |
198 | 0 | return 0; |
199 | 0 | } |
200 | | |
201 | 0 | group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); |
202 | 0 | } |
203 | | |
204 | 0 | return ECDSA_SIG_max_len(group_order_size); |
205 | 0 | } |
206 | | |
207 | 52 | ECDSA_SIG *ECDSA_SIG_new(void) { |
208 | 52 | ECDSA_SIG *sig = OPENSSL_malloc(sizeof(ECDSA_SIG)); |
209 | 52 | if (sig == NULL) { |
210 | 0 | return NULL; |
211 | 0 | } |
212 | 52 | sig->r = BN_new(); |
213 | 52 | sig->s = BN_new(); |
214 | 52 | if (sig->r == NULL || sig->s == NULL) { |
215 | 0 | ECDSA_SIG_free(sig); |
216 | 0 | return NULL; |
217 | 0 | } |
218 | 52 | return sig; |
219 | 52 | } |
220 | | |
221 | 607 | void ECDSA_SIG_free(ECDSA_SIG *sig) { |
222 | 607 | if (sig == NULL) { |
223 | 0 | return; |
224 | 0 | } |
225 | | |
226 | 607 | BN_free(sig->r); |
227 | 607 | BN_free(sig->s); |
228 | 607 | OPENSSL_free(sig); |
229 | 607 | } |
230 | | |
231 | 217 | const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig) { |
232 | 217 | return sig->r; |
233 | 217 | } |
234 | | |
235 | 217 | const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig) { |
236 | 217 | return sig->s; |
237 | 217 | } |
238 | | |
239 | | void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **out_r, |
240 | 0 | const BIGNUM **out_s) { |
241 | 0 | if (out_r != NULL) { |
242 | 0 | *out_r = sig->r; |
243 | 0 | } |
244 | 0 | if (out_s != NULL) { |
245 | 0 | *out_s = sig->s; |
246 | 0 | } |
247 | 0 | } |
248 | | |
249 | 375 | int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { |
250 | 375 | if (r == NULL || s == NULL) { |
251 | 0 | return 0; |
252 | 0 | } |
253 | 375 | BN_free(sig->r); |
254 | 375 | BN_free(sig->s); |
255 | 375 | sig->r = r; |
256 | 375 | sig->s = s; |
257 | 375 | return 1; |
258 | 375 | } |
259 | | |
260 | | int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, |
261 | 15 | const ECDSA_SIG *sig, const EC_KEY *eckey) { |
262 | 15 | uint8_t fixed[ECDSA_MAX_FIXED_LEN]; |
263 | 15 | size_t fixed_len; |
264 | 15 | return ecdsa_sig_to_fixed(eckey, fixed, &fixed_len, sizeof(fixed), sig) && |
265 | 15 | ecdsa_verify_fixed(digest, digest_len, fixed, fixed_len, eckey); |
266 | 15 | } |
267 | | |
268 | | // This function is only exported for testing and is not called in production |
269 | | // code. |
270 | | ECDSA_SIG *ECDSA_sign_with_nonce_and_leak_private_key_for_testing( |
271 | | const uint8_t *digest, size_t digest_len, const EC_KEY *eckey, |
272 | 0 | const uint8_t *nonce, size_t nonce_len) { |
273 | 0 | uint8_t sig[ECDSA_MAX_FIXED_LEN]; |
274 | 0 | size_t sig_len; |
275 | 0 | if (!ecdsa_sign_fixed_with_nonce_for_known_answer_test( |
276 | 0 | digest, digest_len, sig, &sig_len, sizeof(sig), eckey, nonce, |
277 | 0 | nonce_len)) { |
278 | 0 | return NULL; |
279 | 0 | } |
280 | | |
281 | 0 | return ecdsa_sig_from_fixed(eckey, sig, sig_len); |
282 | 0 | } |
283 | | |
284 | | ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, |
285 | | const EC_KEY *eckey) { |
286 | | uint8_t sig[ECDSA_MAX_FIXED_LEN]; |
287 | | size_t sig_len; |
288 | | if (!ecdsa_sign_fixed(digest, digest_len, sig, &sig_len, sizeof(sig), |
289 | | eckey)) { |
290 | | return NULL; |
291 | | } |
292 | | |
293 | | return ecdsa_sig_from_fixed(eckey, sig, sig_len); |
294 | | } |
295 | | |
296 | 0 | ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) { |
297 | 0 | ECDSA_SIG *ret = ECDSA_SIG_new(); |
298 | 0 | if (ret == NULL) { |
299 | 0 | return NULL; |
300 | 0 | } |
301 | 0 | CBS child; |
302 | 0 | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
303 | 0 | !BN_parse_asn1_unsigned(&child, ret->r) || |
304 | 0 | !BN_parse_asn1_unsigned(&child, ret->s) || |
305 | 0 | CBS_len(&child) != 0) { |
306 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
307 | 0 | ECDSA_SIG_free(ret); |
308 | 0 | return NULL; |
309 | 0 | } |
310 | 0 | return ret; |
311 | 0 | } |
312 | | |
313 | 0 | ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) { |
314 | 0 | CBS cbs; |
315 | 0 | CBS_init(&cbs, in, in_len); |
316 | 0 | ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); |
317 | 0 | if (ret == NULL || CBS_len(&cbs) != 0) { |
318 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
319 | 0 | ECDSA_SIG_free(ret); |
320 | 0 | return NULL; |
321 | 0 | } |
322 | 0 | return ret; |
323 | 0 | } |
324 | | |
325 | 0 | int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) { |
326 | 0 | CBB child; |
327 | 0 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
328 | 0 | !BN_marshal_asn1(&child, sig->r) || |
329 | 0 | !BN_marshal_asn1(&child, sig->s) || |
330 | 0 | !CBB_flush(cbb)) { |
331 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
332 | 0 | return 0; |
333 | 0 | } |
334 | 0 | return 1; |
335 | 0 | } |
336 | | |
337 | | int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, |
338 | 0 | const ECDSA_SIG *sig) { |
339 | 0 | CBB cbb; |
340 | 0 | CBB_zero(&cbb); |
341 | 0 | if (!CBB_init(&cbb, 0) || |
342 | 0 | !ECDSA_SIG_marshal(&cbb, sig) || |
343 | 0 | !CBB_finish(&cbb, out_bytes, out_len)) { |
344 | 0 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
345 | 0 | CBB_cleanup(&cbb); |
346 | 0 | return 0; |
347 | 0 | } |
348 | 0 | return 1; |
349 | 0 | } |
350 | | |
351 | | // der_len_len returns the number of bytes needed to represent a length of |len| |
352 | | // in DER. |
353 | 0 | static size_t der_len_len(size_t len) { |
354 | 0 | if (len < 0x80) { |
355 | 0 | return 1; |
356 | 0 | } |
357 | 0 | size_t ret = 1; |
358 | 0 | while (len > 0) { |
359 | 0 | ret++; |
360 | 0 | len >>= 8; |
361 | 0 | } |
362 | 0 | return ret; |
363 | 0 | } |
364 | | |
365 | 0 | size_t ECDSA_SIG_max_len(size_t order_len) { |
366 | | // Compute the maximum length of an |order_len| byte integer. Defensively |
367 | | // assume that the leading 0x00 is included. |
368 | 0 | size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; |
369 | 0 | if (integer_len < order_len) { |
370 | 0 | return 0; |
371 | 0 | } |
372 | | // An ECDSA signature is two INTEGERs. |
373 | 0 | size_t value_len = 2 * integer_len; |
374 | 0 | if (value_len < integer_len) { |
375 | 0 | return 0; |
376 | 0 | } |
377 | | // Add the header. |
378 | 0 | size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; |
379 | 0 | if (ret < value_len) { |
380 | 0 | return 0; |
381 | 0 | } |
382 | 0 | return ret; |
383 | 0 | } |
384 | | |
385 | 0 | ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { |
386 | 0 | if (len < 0) { |
387 | 0 | return NULL; |
388 | 0 | } |
389 | 0 | CBS cbs; |
390 | 0 | CBS_init(&cbs, *inp, (size_t)len); |
391 | 0 | ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); |
392 | 0 | if (ret == NULL) { |
393 | 0 | return NULL; |
394 | 0 | } |
395 | 0 | if (out != NULL) { |
396 | 0 | ECDSA_SIG_free(*out); |
397 | 0 | *out = ret; |
398 | 0 | } |
399 | 0 | *inp = CBS_data(&cbs); |
400 | 0 | return ret; |
401 | 0 | } |
402 | | |
403 | 0 | int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { |
404 | 0 | CBB cbb; |
405 | 0 | if (!CBB_init(&cbb, 0) || |
406 | 0 | !ECDSA_SIG_marshal(&cbb, sig)) { |
407 | 0 | CBB_cleanup(&cbb); |
408 | 0 | return -1; |
409 | 0 | } |
410 | 0 | return CBB_finish_i2d(&cbb, outp); |
411 | 0 | } |