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/ec/internal.h" |
66 | #include "../internal.h" |
67 | |
68 | |
69 | int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, |
70 | unsigned int *sig_len, const EC_KEY *eckey) { |
71 | if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { |
72 | return eckey->ecdsa_meth->sign(digest, digest_len, sig, sig_len, |
73 | (EC_KEY*) eckey /* cast away const */); |
74 | } |
75 | |
76 | int ret = 0; |
77 | ECDSA_SIG *s = ECDSA_do_sign(digest, digest_len, eckey); |
78 | if (s == NULL) { |
79 | *sig_len = 0; |
80 | goto err; |
81 | } |
82 | |
83 | CBB cbb; |
84 | CBB_zero(&cbb); |
85 | size_t len; |
86 | if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) || |
87 | !ECDSA_SIG_marshal(&cbb, s) || |
88 | !CBB_finish(&cbb, NULL, &len)) { |
89 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
90 | CBB_cleanup(&cbb); |
91 | *sig_len = 0; |
92 | goto err; |
93 | } |
94 | *sig_len = (unsigned)len; |
95 | ret = 1; |
96 | |
97 | err: |
98 | ECDSA_SIG_free(s); |
99 | return ret; |
100 | } |
101 | |
102 | int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, |
103 | const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) { |
104 | ECDSA_SIG *s; |
105 | int ret = 0; |
106 | uint8_t *der = NULL; |
107 | |
108 | // Decode the ECDSA signature. |
109 | s = ECDSA_SIG_from_bytes(sig, sig_len); |
110 | if (s == NULL) { |
111 | goto err; |
112 | } |
113 | |
114 | // Defend against potential laxness in the DER parser. |
115 | size_t der_len; |
116 | if (!ECDSA_SIG_to_bytes(&der, &der_len, s) || |
117 | der_len != sig_len || OPENSSL_memcmp(sig, der, sig_len) != 0) { |
118 | // This should never happen. crypto/bytestring is strictly DER. |
119 | OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR); |
120 | goto err; |
121 | } |
122 | |
123 | ret = ECDSA_do_verify(digest, digest_len, s, eckey); |
124 | |
125 | err: |
126 | OPENSSL_free(der); |
127 | ECDSA_SIG_free(s); |
128 | return ret; |
129 | } |
130 | |
131 | |
132 | size_t ECDSA_size(const EC_KEY *key) { |
133 | if (key == NULL) { |
134 | return 0; |
135 | } |
136 | |
137 | size_t group_order_size; |
138 | if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) { |
139 | group_order_size = key->ecdsa_meth->group_order_size(key); |
140 | } else { |
141 | const EC_GROUP *group = EC_KEY_get0_group(key); |
142 | if (group == NULL) { |
143 | return 0; |
144 | } |
145 | |
146 | group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); |
147 | } |
148 | |
149 | return ECDSA_SIG_max_len(group_order_size); |
150 | } |
151 | |
152 | ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) { |
153 | ECDSA_SIG *ret = ECDSA_SIG_new(); |
154 | if (ret == NULL) { |
155 | return NULL; |
156 | } |
157 | CBS child; |
158 | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
159 | !BN_parse_asn1_unsigned(&child, ret->r) || |
160 | !BN_parse_asn1_unsigned(&child, ret->s) || |
161 | CBS_len(&child) != 0) { |
162 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
163 | ECDSA_SIG_free(ret); |
164 | return NULL; |
165 | } |
166 | return ret; |
167 | } |
168 | |
169 | ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) { |
170 | CBS cbs; |
171 | CBS_init(&cbs, in, in_len); |
172 | ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); |
173 | if (ret == NULL || CBS_len(&cbs) != 0) { |
174 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); |
175 | ECDSA_SIG_free(ret); |
176 | return NULL; |
177 | } |
178 | return ret; |
179 | } |
180 | |
181 | int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) { |
182 | CBB child; |
183 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
184 | !BN_marshal_asn1(&child, sig->r) || |
185 | !BN_marshal_asn1(&child, sig->s) || |
186 | !CBB_flush(cbb)) { |
187 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
188 | return 0; |
189 | } |
190 | return 1; |
191 | } |
192 | |
193 | int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, |
194 | const ECDSA_SIG *sig) { |
195 | CBB cbb; |
196 | CBB_zero(&cbb); |
197 | if (!CBB_init(&cbb, 0) || |
198 | !ECDSA_SIG_marshal(&cbb, sig) || |
199 | !CBB_finish(&cbb, out_bytes, out_len)) { |
200 | OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); |
201 | CBB_cleanup(&cbb); |
202 | return 0; |
203 | } |
204 | return 1; |
205 | } |
206 | |
207 | // der_len_len returns the number of bytes needed to represent a length of |len| |
208 | // in DER. |
209 | static size_t der_len_len(size_t len) { |
210 | if (len < 0x80) { |
211 | return 1; |
212 | } |
213 | size_t ret = 1; |
214 | while (len > 0) { |
215 | ret++; |
216 | len >>= 8; |
217 | } |
218 | return ret; |
219 | } |
220 | |
221 | size_t ECDSA_SIG_max_len(size_t order_len) { |
222 | // Compute the maximum length of an |order_len| byte integer. Defensively |
223 | // assume that the leading 0x00 is included. |
224 | size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; |
225 | if (integer_len < order_len) { |
226 | return 0; |
227 | } |
228 | // An ECDSA signature is two INTEGERs. |
229 | size_t value_len = 2 * integer_len; |
230 | if (value_len < integer_len) { |
231 | return 0; |
232 | } |
233 | // Add the header. |
234 | size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; |
235 | if (ret < value_len) { |
236 | return 0; |
237 | } |
238 | return ret; |
239 | } |
240 | |
241 | ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { |
242 | if (len < 0) { |
243 | return NULL; |
244 | } |
245 | CBS cbs; |
246 | CBS_init(&cbs, *inp, (size_t)len); |
247 | ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); |
248 | if (ret == NULL) { |
249 | return NULL; |
250 | } |
251 | if (out != NULL) { |
252 | ECDSA_SIG_free(*out); |
253 | *out = ret; |
254 | } |
255 | *inp = CBS_data(&cbs); |
256 | return ret; |
257 | } |
258 | |
259 | int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { |
260 | CBB cbb; |
261 | if (!CBB_init(&cbb, 0) || |
262 | !ECDSA_SIG_marshal(&cbb, sig)) { |
263 | CBB_cleanup(&cbb); |
264 | return -1; |
265 | } |
266 | return CBB_finish_i2d(&cbb, outp); |
267 | } |
268 | |