2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
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
11 * A simple ASN.1 DER encoder/decoder for DSA-Sig-Value and ECDSA-Sig-Value.
13 * DSA-Sig-Value ::= SEQUENCE {
18 * ECDSA-Sig-Value ::= SEQUENCE {
24 #include <openssl/crypto.h>
25 #include <openssl/bn.h>
26 #include "internal/asn1_dsa.h"
27 #include "internal/packet.h"
29 #define ID_SEQUENCE 0x30
30 #define ID_INTEGER 0x02
33 * Outputs the encoding of the length octets for a DER value with a content
34 * length of cont_len bytes to *ppout and, if successful, increments *ppout
35 * past the data just written.
37 * The maximum supported content length is 65535 (0xffff) bytes.
38 * The maximum returned length in bytes of the encoded output is 3.
40 * If ppout is NULL then the output size is calculated and returned but no
42 * If ppout is not NULL then *ppout must not be NULL.
44 * An attempt to produce more than len bytes results in an error.
45 * Returns the number of bytes of output produced (or that would be produced)
46 * or 0 if an error occurs.
48 size_t encode_der_length(size_t cont_len, unsigned char **ppout, size_t len)
52 if (cont_len <= 0x7f) {
54 } else if (cont_len <= 0xff) {
56 } else if (cont_len <= 0xffff) {
59 /* Too large for supported length encodings */
62 if (encoded_len > len)
65 unsigned char *out = *ppout;
66 switch (encoded_len) {
72 *out++ = (unsigned char)(cont_len >> 8);
75 *out++ = (unsigned char)cont_len;
82 * Outputs the DER encoding of a positive ASN.1 INTEGER to *ppout and, if
83 * successful, increments *ppout past the data just written.
85 * If n is negative then an error results.
86 * If ppout is NULL then the output size is calculated and returned but no
88 * If ppout is not NULL then *ppout must not be NULL.
90 * An attempt to produce more than len bytes results in an error.
91 * Returns the number of bytes of output produced (or that would be produced)
92 * or 0 if an error occurs.
94 size_t encode_der_integer(const BIGNUM *n, unsigned char **ppout, size_t len)
96 unsigned char *out = NULL;
97 unsigned char **pp = NULL;
102 if (len < 1 || BN_is_negative(n))
106 * Calculate the ASN.1 INTEGER DER content length for n.
107 * This is the number of whole bytes required to represent n (i.e. rounded
109 * If n is zero then the content is a single zero byte (length = 1).
110 * If the number of bits of n is a multiple of 8 then an extra zero padding
111 * byte is included to ensure that the value is still treated as positive
112 * in the INTEGER two's complement representation.
114 cont_len = BN_num_bits(n) / 8 + 1;
122 if ((c = encode_der_length(cont_len, pp, len - produced)) == 0)
125 if (cont_len > len - produced)
128 if (BN_bn2binpad(n, out, (int)cont_len) != (int)cont_len)
133 produced += cont_len;
138 * Outputs the DER encoding of a DSA-Sig-Value or ECDSA-Sig-Value to *ppout
139 * and increments *ppout past the data just written.
141 * If ppout is NULL then the output size is calculated and returned but no
142 * output is produced.
143 * If ppout is not NULL then *ppout must not be NULL.
145 * An attempt to produce more than len bytes results in an error.
146 * Returns the number of bytes of output produced (or that would be produced)
147 * or 0 if an error occurs.
149 size_t encode_der_dsa_sig(const BIGNUM *r, const BIGNUM *s,
150 unsigned char **ppout, size_t len)
152 unsigned char *out = NULL;
153 unsigned char **pp = NULL;
161 || (r_der_len = encode_der_integer(r, NULL, SIZE_MAX)) == 0
162 || (s_der_len = encode_der_integer(s, NULL, SIZE_MAX)) == 0)
165 cont_len = r_der_len + s_der_len;
170 *out++ = ID_SEQUENCE;
173 if ((c = encode_der_length(cont_len, pp, len - produced)) == 0)
176 if ((c = encode_der_integer(r, pp, len - produced)) == 0)
179 if ((c = encode_der_integer(s, pp, len - produced)) == 0)
188 * Decodes the DER length octets in pkt and initialises subpkt with the
189 * following bytes of that length.
191 * Returns 1 on success or 0 on failure.
193 int decode_der_length(PACKET *pkt, PACKET *subpkt)
197 if (!PACKET_get_1(pkt, &byte))
201 return PACKET_get_sub_packet(pkt, subpkt, (size_t)byte);
203 return PACKET_get_length_prefixed_1(pkt, subpkt);
205 return PACKET_get_length_prefixed_2(pkt, subpkt);
207 /* Too large, invalid, or not DER. */
212 * Decodes a single ASN.1 INTEGER value from pkt, which must be DER encoded,
213 * and updates n with the decoded value.
215 * The BIGNUM, n, must have already been allocated by calling BN_new().
216 * pkt must not be NULL.
218 * An attempt to consume more than len bytes results in an error.
219 * Returns 1 on success or 0 on error.
221 * If the PACKET is supposed to only contain a single INTEGER value with no
222 * trailing garbage then it is up to the caller to verify that all bytes
225 int decode_der_integer(PACKET *pkt, BIGNUM *n)
227 PACKET contpkt, tmppkt;
228 unsigned int tag, tmp;
230 /* Check we have an integer and get the content bytes */
231 if (!PACKET_get_1(pkt, &tag)
233 || !decode_der_length(pkt, &contpkt))
236 /* Peek ahead at the first bytes to check for proper encoding */
238 /* The INTEGER must be positive */
239 if (!PACKET_get_1(&tmppkt, &tmp)
240 || (tmp & 0x80) != 0)
242 /* If there a zero padding byte the next byte must have the msb set */
243 if (PACKET_remaining(&tmppkt) > 0 && tmp == 0) {
244 if (!PACKET_get_1(&tmppkt, &tmp)
245 || (tmp & 0x80) == 0)
249 if (BN_bin2bn(PACKET_data(&contpkt),
250 (int)PACKET_remaining(&contpkt), n) == NULL)
257 * Decodes a single DSA-Sig-Value or ECDSA-Sig-Value from *ppin, which must be
258 * DER encoded, updates r and s with the decoded values, and increments *ppin
259 * past the data that was consumed.
261 * The BIGNUMs, r and s, must have already been allocated by calls to BN_new().
262 * ppin and *ppin must not be NULL.
264 * An attempt to consume more than len bytes results in an error.
265 * Returns the number of bytes of input consumed or 0 if an error occurs.
267 * If the buffer is supposed to only contain a single [EC]DSA-Sig-Value with no
268 * trailing garbage then it is up to the caller to verify that all bytes
271 size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin,
278 if (!PACKET_buf_init(&pkt, *ppin, len)
279 || !PACKET_get_1(&pkt, &tag)
280 || tag != ID_SEQUENCE
281 || !decode_der_length(&pkt, &contpkt)
282 || !decode_der_integer(&contpkt, r)
283 || !decode_der_integer(&contpkt, s)
284 || PACKET_remaining(&contpkt) != 0)
287 consumed = PACKET_data(&pkt) - *ppin;