Add simple ASN.1 utils for DSA signature DER.
[openssl.git] / crypto / asn1_dsa.c
1 /*
2  * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /*
11  * A simple ASN.1 DER encoder/decoder for DSA-Sig-Value and ECDSA-Sig-Value.
12  *
13  * DSA-Sig-Value ::= SEQUENCE {
14  *  r  INTEGER,
15  *  s  INTEGER
16  * }
17  *
18  * ECDSA-Sig-Value ::= SEQUENCE {
19  *  r  INTEGER,
20  *  s  INTEGER
21  * }
22  */
23
24 #include <openssl/crypto.h>
25 #include <openssl/bn.h>
26 #include "internal/asn1_dsa.h"
27
28 #define ID_SEQUENCE 0x30
29 #define ID_INTEGER 0x02
30
31 /*
32  * Outputs the encoding of the length octets for a DER value with a content
33  * length of cont_len bytes to *ppout and, if successful, increments *ppout
34  * past the data just written.
35  *
36  * The maximum supported content length is 65535 (0xffff) bytes.
37  * The maximum returned length in bytes of the encoded output is 3.
38  *
39  * If ppout is NULL then the output size is calculated and returned but no
40  * output is produced.
41  * If ppout is not NULL then *ppout must not be NULL.
42  *
43  * An attempt to produce more than len bytes results in an error.
44  * Returns the number of bytes of output produced (or that would be produced)
45  * or 0 if an error occurs.
46  */
47 size_t encode_der_length(size_t cont_len, unsigned char **ppout, size_t len)
48 {
49     size_t encoded_len;
50
51     if (cont_len <= 0x7f) {
52         encoded_len = 1;
53     } else if (cont_len <= 0xff) {
54         encoded_len = 2;
55     } else if (cont_len <= 0xffff) {
56         encoded_len = 3;
57     } else {
58         /* Too large for supported length encodings */
59         return 0;
60     }
61     if (encoded_len > len)
62         return 0;
63     if (ppout != NULL) {
64         unsigned char *out = *ppout;
65         switch (encoded_len) {
66         case 2:
67             *out++ = 0x81;
68             break;
69         case 3:
70             *out++ = 0x82;
71             *out++ = (unsigned char)(cont_len >> 8);
72             break;
73         }
74         *out++ = (unsigned char)cont_len;
75         *ppout = out;
76     }
77     return encoded_len;
78 }
79
80 /*
81  * Outputs the DER encoding of a positive ASN.1 INTEGER to *ppout and, if
82  * successful, increments *ppout past the data just written.
83  *
84  * If n is negative then an error results.
85  * If ppout is NULL then the output size is calculated and returned but no
86  * output is produced.
87  * If ppout is not NULL then *ppout must not be NULL.
88  *
89  * An attempt to produce more than len bytes results in an error.
90  * Returns the number of bytes of output produced (or that would be produced)
91  * or 0 if an error occurs.
92  */
93 size_t encode_der_integer(const BIGNUM *n, unsigned char **ppout, size_t len)
94 {
95     unsigned char *out = NULL;
96     unsigned char **pp = NULL;
97     size_t produced;
98     size_t c;
99     size_t cont_len;
100
101     if (len < 1 || BN_is_negative(n))
102         return 0;
103
104     /*
105      * Calculate the ASN.1 INTEGER DER content length for n.
106      * This is the number of whole bytes required to represent n (i.e. rounded
107      * down), plus one.
108      * If n is zero then the content is a single zero byte (length = 1).
109      * If the number of bits of n is a multiple of 8 then an extra zero padding
110      * byte is included to ensure that the value is still treated as positive
111      * in the INTEGER two's complement representation.
112      */
113     cont_len = BN_num_bits(n) / 8 + 1;
114
115     if (ppout != NULL) {
116         out = *ppout;
117         pp = &out;
118         *out++ = ID_INTEGER;
119     }
120     produced = 1;
121     if ((c = encode_der_length(cont_len, pp, len - produced)) == 0)
122         return 0;
123     produced += c;
124     if (cont_len > len - produced)
125         return 0;
126     if (pp != NULL) {
127         if (BN_bn2binpad(n, out, (int)cont_len) != (int)cont_len)
128             return 0;
129         out += cont_len;
130         *ppout = out;
131     }
132     produced += cont_len;
133     return produced;
134 }
135
136 /*
137  * Outputs the DER encoding of a DSA-Sig-Value or ECDSA-Sig-Value to *ppout
138  * and increments *ppout past the data just written.
139  *
140  * If ppout is NULL then the output size is calculated and returned but no
141  * output is produced.
142  * If ppout is not NULL then *ppout must not be NULL.
143  *
144  * An attempt to produce more than len bytes results in an error.
145  * Returns the number of bytes of output produced (or that would be produced)
146  * or 0 if an error occurs.
147  */
148 size_t encode_der_dsa_sig(const BIGNUM *r, const BIGNUM *s,
149                           unsigned char **ppout, size_t len)
150 {
151     unsigned char *out = NULL;
152     unsigned char **pp = NULL;
153     size_t produced;
154     size_t c;
155     size_t r_der_len;
156     size_t s_der_len;
157     size_t cont_len;
158
159     if (len < 1
160             || (r_der_len = encode_der_integer(r, NULL, SIZE_MAX)) == 0
161             || (s_der_len = encode_der_integer(s, NULL, SIZE_MAX)) == 0)
162         return 0;
163
164     cont_len = r_der_len + s_der_len;
165
166     if (ppout != NULL) {
167         out = *ppout;
168         pp = &out;
169         *out++ = ID_SEQUENCE;
170     }
171     produced = 1;
172     if ((c = encode_der_length(cont_len, pp, len - produced)) == 0)
173         return 0;
174     produced += c;
175     if ((c = encode_der_integer(r, pp, len - produced)) == 0)
176         return 0;
177     produced += c;
178     if ((c = encode_der_integer(s, pp, len - produced)) == 0)
179         return 0;
180     produced += c;
181     if (pp != NULL)
182         *ppout = out;
183     return produced;
184 }
185
186 /*
187  * Decodes the DER length octets at *ppin, stores the decoded length to
188  * *pcont_len and, if successful, increments *ppin past the data that was
189  * consumed.
190  *
191  * pcont_len, ppin and *ppin must not be NULL.
192  *
193  * An attempt to consume more than len bytes results in an error.
194  * Returns the number of bytes of input consumed or 0 if an error occurs.
195  */
196 size_t decode_der_length(size_t *pcont_len, const unsigned char **ppin,
197                          size_t len)
198 {
199     const unsigned char *in = *ppin;
200     size_t consumed;
201     size_t n;
202
203     if (len < 1)
204         return 0;
205     n = *in++;
206     consumed = 1;
207     if (n > 0x7f) {
208         if (n == 0x81 && len - consumed >= 1) {
209             n = *in++;
210             if (n <= 0x7f)
211                 return 0; /* Not DER. */
212             ++consumed;
213         } else if (n == 0x82 && len - consumed >= 2) {
214             n = *in++ << 8;
215             n |= *in++;
216             if (n <= 0xff)
217                 return 0; /* Not DER. */
218             consumed += 2;
219         } else {
220             return 0; /* Too large, invalid, or not DER. */
221         }
222     }
223     *pcont_len = n;
224     *ppin = in;
225     return consumed;
226 }
227
228 /*
229  * Decodes a single ASN.1 INTEGER value from *ppin, which must be DER encoded,
230  * updates n with the decoded value, and, if successful, increments *ppin past
231  * the data that was consumed.
232  *
233  * The BIGNUM, n, must have already been allocated by calling BN_new().
234  * ppin and *ppin must not be NULL.
235  *
236  * An attempt to consume more than len bytes results in an error.
237  * Returns the number of bytes of input consumed or 0 if an error occurs.
238  *
239  * If the buffer is supposed to only contain a single INTEGER value with no
240  * trailing garbage then it is up to the caller to verify that all bytes
241  * were consumed.
242  */
243 size_t decode_der_integer(BIGNUM *n, const unsigned char **ppin, size_t len)
244 {
245     const unsigned char *in = *ppin;
246     size_t consumed;
247     size_t c;
248     size_t cont_len;
249
250     if (len < 1 || n == NULL || *in++ != ID_INTEGER)
251         return 0;
252     consumed = 1;
253     if ((c = decode_der_length(&cont_len, &in, len - consumed)) == 0)
254         return 0;
255     consumed += c;
256     /* Check for a positive INTEGER with valid content encoding and decode. */
257     if (cont_len > len - consumed || cont_len < 1 || (in[0] & 0x80) != 0
258             || (cont_len >= 2 && in[0] == 0 && (in[1] & 0x80) == 0)
259             || BN_bin2bn(in, (int)cont_len, n) == NULL)
260         return 0;
261     in += cont_len;
262     consumed += cont_len;
263     *ppin = in;
264     return consumed;
265 }
266
267 static size_t decode_dsa_sig_content(BIGNUM *r, BIGNUM *s,
268                                      const unsigned char **ppin, size_t len)
269 {
270     const unsigned char *in = *ppin;
271     size_t consumed = 0;
272     size_t c;
273
274     if ((c = decode_der_integer(r, &in, len - consumed)) == 0)
275         return 0;
276     consumed += c;
277     if ((c = decode_der_integer(s, &in, len - consumed)) == 0)
278         return 0;
279     consumed += c;
280     *ppin = in;
281     return consumed;
282 }
283
284 /*
285  * Decodes a single DSA-Sig-Value or ECDSA-Sig-Value from *ppin, which must be
286  * DER encoded, updates r and s with the decoded values, and increments *ppin
287  * past the data that was consumed.
288  *
289  * The BIGNUMs, r and s, must have already been allocated by calls to BN_new().
290  * ppin and *ppin must not be NULL.
291  *
292  * An attempt to consume more than len bytes results in an error.
293  * Returns the number of bytes of input consumed or 0 if an error occurs.
294  *
295  * If the buffer is supposed to only contain a single [EC]DSA-Sig-Value with no
296  * trailing garbage then it is up to the caller to verify that all bytes
297  * were consumed.
298  */
299 size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin,
300                           size_t len)
301 {
302     const unsigned char *in = *ppin;
303     size_t consumed;
304     size_t c;
305     size_t cont_len;
306
307     if (len < 1 || *in++ != ID_SEQUENCE)
308         return 0;
309     consumed = 1;
310     if ((c = decode_der_length(&cont_len, &in, len - consumed)) == 0)
311         return 0;
312     consumed += c;
313     if (cont_len > len - consumed
314             || (c = decode_dsa_sig_content(r, s, &in, cont_len)) == 0
315             || c != cont_len)
316         return 0;
317     consumed += c;
318     *ppin = in;
319     return consumed;
320 }
321