• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "../ec/internal.h"
65 
66 
ECDSA_size(const EC_KEY * key)67 size_t ECDSA_size(const EC_KEY *key) {
68   if (key == NULL) {
69     return 0;
70   }
71 
72   size_t group_order_size;
73   if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) {
74     group_order_size = key->ecdsa_meth->group_order_size(key);
75   } else {
76     const EC_GROUP *group = EC_KEY_get0_group(key);
77     if (group == NULL) {
78       return 0;
79     }
80 
81     group_order_size = BN_num_bytes(EC_GROUP_get0_order(group));
82   }
83 
84   return ECDSA_SIG_max_len(group_order_size);
85 }
86 
ECDSA_SIG_new(void)87 ECDSA_SIG *ECDSA_SIG_new(void) {
88   ECDSA_SIG *sig = OPENSSL_malloc(sizeof(ECDSA_SIG));
89   if (sig == NULL) {
90     return NULL;
91   }
92   sig->r = BN_new();
93   sig->s = BN_new();
94   if (sig->r == NULL || sig->s == NULL) {
95     ECDSA_SIG_free(sig);
96     return NULL;
97   }
98   return sig;
99 }
100 
ECDSA_SIG_free(ECDSA_SIG * sig)101 void ECDSA_SIG_free(ECDSA_SIG *sig) {
102   if (sig == NULL) {
103     return;
104   }
105 
106   BN_free(sig->r);
107   BN_free(sig->s);
108   OPENSSL_free(sig);
109 }
110 
ECDSA_SIG_parse(CBS * cbs)111 ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) {
112   ECDSA_SIG *ret = ECDSA_SIG_new();
113   if (ret == NULL) {
114     return NULL;
115   }
116   CBS child;
117   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
118       !BN_cbs2unsigned(&child, ret->r) ||
119       !BN_cbs2unsigned(&child, ret->s) ||
120       CBS_len(&child) != 0) {
121     OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
122     ECDSA_SIG_free(ret);
123     return NULL;
124   }
125   return ret;
126 }
127 
ECDSA_SIG_from_bytes(const uint8_t * in,size_t in_len)128 ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) {
129   CBS cbs;
130   CBS_init(&cbs, in, in_len);
131   ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs);
132   if (ret == NULL || CBS_len(&cbs) != 0) {
133     OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
134     ECDSA_SIG_free(ret);
135     return NULL;
136   }
137   return ret;
138 }
139 
ECDSA_SIG_marshal(CBB * cbb,const ECDSA_SIG * sig)140 int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) {
141   CBB child;
142   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
143       !BN_bn2cbb(&child, sig->r) ||
144       !BN_bn2cbb(&child, sig->s) ||
145       !CBB_flush(cbb)) {
146     OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
147     return 0;
148   }
149   return 1;
150 }
151 
ECDSA_SIG_to_bytes(uint8_t ** out_bytes,size_t * out_len,const ECDSA_SIG * sig)152 int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len,
153                        const ECDSA_SIG *sig) {
154   CBB cbb;
155   CBB_zero(&cbb);
156   if (!CBB_init(&cbb, 0) ||
157       !ECDSA_SIG_marshal(&cbb, sig) ||
158       !CBB_finish(&cbb, out_bytes, out_len)) {
159     OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
160     CBB_cleanup(&cbb);
161     return 0;
162   }
163   return 1;
164 }
165 
166 /* der_len_len returns the number of bytes needed to represent a length of |len|
167  * in DER. */
der_len_len(size_t len)168 static size_t der_len_len(size_t len) {
169   if (len < 0x80) {
170     return 1;
171   }
172   size_t ret = 1;
173   while (len > 0) {
174     ret++;
175     len >>= 8;
176   }
177   return ret;
178 }
179 
ECDSA_SIG_max_len(size_t order_len)180 size_t ECDSA_SIG_max_len(size_t order_len) {
181   /* Compute the maximum length of an |order_len| byte integer. Defensively
182    * assume that the leading 0x00 is included. */
183   size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len;
184   if (integer_len < order_len) {
185     return 0;
186   }
187   /* An ECDSA signature is two INTEGERs. */
188   size_t value_len = 2 * integer_len;
189   if (value_len < integer_len) {
190     return 0;
191   }
192   /* Add the header. */
193   size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len;
194   if (ret < value_len) {
195     return 0;
196   }
197   return ret;
198 }
199 
d2i_ECDSA_SIG(ECDSA_SIG ** out,const uint8_t ** inp,long len)200 ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) {
201   if (len < 0) {
202     return NULL;
203   }
204   CBS cbs;
205   CBS_init(&cbs, *inp, (size_t)len);
206   ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs);
207   if (ret == NULL) {
208     return NULL;
209   }
210   if (out != NULL) {
211     ECDSA_SIG_free(*out);
212     *out = ret;
213   }
214   *inp += (size_t)len - CBS_len(&cbs);
215   return ret;
216 }
217 
i2d_ECDSA_SIG(const ECDSA_SIG * sig,uint8_t ** outp)218 int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) {
219   uint8_t *der;
220   size_t der_len;
221   if (!ECDSA_SIG_to_bytes(&der, &der_len, sig)) {
222     return -1;
223   }
224   if (der_len > INT_MAX) {
225     OPENSSL_PUT_ERROR(ECDSA, ERR_R_OVERFLOW);
226     OPENSSL_free(der);
227     return -1;
228   }
229   if (outp != NULL) {
230     if (*outp == NULL) {
231       *outp = der;
232       der = NULL;
233     } else {
234       memcpy(*outp, der, der_len);
235       *outp += der_len;
236     }
237   }
238   OPENSSL_free(der);
239   return (int)der_len;
240 }
241