1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2000. */
3 /* ====================================================================
4 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. All advertising materials mentioning features or use of this
19 * software must display the following acknowledgment:
20 * "This product includes software developed by the OpenSSL Project
21 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
22 *
23 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24 * endorse or promote products derived from this software without
25 * prior written permission. For written permission, please contact
26 * licensing@OpenSSL.org.
27 *
28 * 5. Products derived from this software may not be called "OpenSSL"
29 * nor may "OpenSSL" appear in their names without prior written
30 * permission of the OpenSSL Project.
31 *
32 * 6. Redistributions of any form whatsoever must retain the following
33 * acknowledgment:
34 * "This product includes software developed by the OpenSSL Project
35 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48 * OF THE POSSIBILITY OF SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This product includes cryptographic software written by Eric Young
52 * (eay@cryptsoft.com). This product includes software written by Tim
53 * Hudson (tjh@cryptsoft.com). */
54
55 #include <openssl/dsa.h>
56
57 #include <assert.h>
58
59 #include <openssl/bn.h>
60 #include <openssl/bytestring.h>
61 #include <openssl/err.h>
62 #include <openssl/mem.h>
63
64 #include "internal.h"
65 #include "../bytestring/internal.h"
66
67
68 #define OPENSSL_DSA_MAX_MODULUS_BITS 10000
69
70 // This function is in dsa_asn1.c rather than dsa.c because it is reachable from
71 // |EVP_PKEY| parsers. This makes it easier for the static linker to drop most
72 // of the DSA implementation.
dsa_check_key(const DSA * dsa)73 int dsa_check_key(const DSA *dsa) {
74 if (!dsa->p || !dsa->q || !dsa->g) {
75 OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
76 return 0;
77 }
78
79 // Fully checking for invalid DSA groups is expensive, so security and
80 // correctness of the signature scheme depend on how |dsa| was computed. I.e.
81 // we leave "assurance of domain parameter validity" from FIPS 186-4 to the
82 // caller. However, we check bounds on all values to avoid DoS vectors even
83 // when domain parameters are invalid. In particular, signing will infinite
84 // loop if |g| is zero.
85 if (BN_is_negative(dsa->p) || BN_is_negative(dsa->q) || BN_is_zero(dsa->p) ||
86 BN_is_zero(dsa->q) || !BN_is_odd(dsa->p) || !BN_is_odd(dsa->q) ||
87 // |q| must be a prime divisor of |p - 1|, which implies |q < p|.
88 BN_cmp(dsa->q, dsa->p) >= 0 ||
89 // |g| is in the multiplicative group of |p|.
90 BN_is_negative(dsa->g) || BN_is_zero(dsa->g) ||
91 BN_cmp(dsa->g, dsa->p) >= 0) {
92 OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS);
93 return 0;
94 }
95
96 // FIPS 186-4 allows only three different sizes for q.
97 unsigned q_bits = BN_num_bits(dsa->q);
98 if (q_bits != 160 && q_bits != 224 && q_bits != 256) {
99 OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE);
100 return 0;
101 }
102
103 // Bound |dsa->p| to avoid a DoS vector. Note this limit is much larger than
104 // the one in FIPS 186-4, which only allows L = 1024, 2048, and 3072.
105 if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
106 OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE);
107 return 0;
108 }
109
110 if (dsa->pub_key != NULL) {
111 // The public key is also in the multiplicative group of |p|.
112 if (BN_is_negative(dsa->pub_key) || BN_is_zero(dsa->pub_key) ||
113 BN_cmp(dsa->pub_key, dsa->p) >= 0) {
114 OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS);
115 return 0;
116 }
117 }
118
119 if (dsa->priv_key != NULL) {
120 // The private key is a non-zero element of the scalar field, determined by
121 // |q|.
122 if (BN_is_negative(dsa->priv_key) || BN_is_zero(dsa->priv_key) ||
123 BN_cmp(dsa->priv_key, dsa->q) >= 0) {
124 OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS);
125 return 0;
126 }
127 }
128
129 return 1;
130 }
131
parse_integer(CBS * cbs,BIGNUM ** out)132 static int parse_integer(CBS *cbs, BIGNUM **out) {
133 assert(*out == NULL);
134 *out = BN_new();
135 if (*out == NULL) {
136 return 0;
137 }
138 return BN_parse_asn1_unsigned(cbs, *out);
139 }
140
marshal_integer(CBB * cbb,BIGNUM * bn)141 static int marshal_integer(CBB *cbb, BIGNUM *bn) {
142 if (bn == NULL) {
143 // A DSA object may be missing some components.
144 OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER);
145 return 0;
146 }
147 return BN_marshal_asn1(cbb, bn);
148 }
149
DSA_SIG_parse(CBS * cbs)150 DSA_SIG *DSA_SIG_parse(CBS *cbs) {
151 DSA_SIG *ret = DSA_SIG_new();
152 if (ret == NULL) {
153 return NULL;
154 }
155 CBS child;
156 if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
157 !parse_integer(&child, &ret->r) ||
158 !parse_integer(&child, &ret->s) ||
159 CBS_len(&child) != 0) {
160 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
161 DSA_SIG_free(ret);
162 return NULL;
163 }
164 return ret;
165 }
166
DSA_SIG_marshal(CBB * cbb,const DSA_SIG * sig)167 int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) {
168 CBB child;
169 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
170 !marshal_integer(&child, sig->r) ||
171 !marshal_integer(&child, sig->s) ||
172 !CBB_flush(cbb)) {
173 OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
174 return 0;
175 }
176 return 1;
177 }
178
DSA_parse_public_key(CBS * cbs)179 DSA *DSA_parse_public_key(CBS *cbs) {
180 DSA *ret = DSA_new();
181 if (ret == NULL) {
182 return NULL;
183 }
184 CBS child;
185 if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
186 !parse_integer(&child, &ret->pub_key) ||
187 !parse_integer(&child, &ret->p) ||
188 !parse_integer(&child, &ret->q) ||
189 !parse_integer(&child, &ret->g) ||
190 CBS_len(&child) != 0) {
191 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
192 goto err;
193 }
194 if (!dsa_check_key(ret)) {
195 goto err;
196 }
197 return ret;
198
199 err:
200 DSA_free(ret);
201 return NULL;
202 }
203
DSA_marshal_public_key(CBB * cbb,const DSA * dsa)204 int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) {
205 CBB child;
206 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
207 !marshal_integer(&child, dsa->pub_key) ||
208 !marshal_integer(&child, dsa->p) ||
209 !marshal_integer(&child, dsa->q) ||
210 !marshal_integer(&child, dsa->g) ||
211 !CBB_flush(cbb)) {
212 OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
213 return 0;
214 }
215 return 1;
216 }
217
DSA_parse_parameters(CBS * cbs)218 DSA *DSA_parse_parameters(CBS *cbs) {
219 DSA *ret = DSA_new();
220 if (ret == NULL) {
221 return NULL;
222 }
223 CBS child;
224 if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
225 !parse_integer(&child, &ret->p) ||
226 !parse_integer(&child, &ret->q) ||
227 !parse_integer(&child, &ret->g) ||
228 CBS_len(&child) != 0) {
229 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
230 goto err;
231 }
232 if (!dsa_check_key(ret)) {
233 goto err;
234 }
235 return ret;
236
237 err:
238 DSA_free(ret);
239 return NULL;
240 }
241
DSA_marshal_parameters(CBB * cbb,const DSA * dsa)242 int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) {
243 CBB child;
244 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
245 !marshal_integer(&child, dsa->p) ||
246 !marshal_integer(&child, dsa->q) ||
247 !marshal_integer(&child, dsa->g) ||
248 !CBB_flush(cbb)) {
249 OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
250 return 0;
251 }
252 return 1;
253 }
254
DSA_parse_private_key(CBS * cbs)255 DSA *DSA_parse_private_key(CBS *cbs) {
256 DSA *ret = DSA_new();
257 if (ret == NULL) {
258 return NULL;
259 }
260
261 CBS child;
262 uint64_t version;
263 if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
264 !CBS_get_asn1_uint64(&child, &version)) {
265 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
266 goto err;
267 }
268
269 if (version != 0) {
270 OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION);
271 goto err;
272 }
273
274 if (!parse_integer(&child, &ret->p) ||
275 !parse_integer(&child, &ret->q) ||
276 !parse_integer(&child, &ret->g) ||
277 !parse_integer(&child, &ret->pub_key) ||
278 !parse_integer(&child, &ret->priv_key) ||
279 CBS_len(&child) != 0) {
280 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
281 goto err;
282 }
283 if (!dsa_check_key(ret)) {
284 goto err;
285 }
286
287 return ret;
288
289 err:
290 DSA_free(ret);
291 return NULL;
292 }
293
DSA_marshal_private_key(CBB * cbb,const DSA * dsa)294 int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) {
295 CBB child;
296 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
297 !CBB_add_asn1_uint64(&child, 0 /* version */) ||
298 !marshal_integer(&child, dsa->p) ||
299 !marshal_integer(&child, dsa->q) ||
300 !marshal_integer(&child, dsa->g) ||
301 !marshal_integer(&child, dsa->pub_key) ||
302 !marshal_integer(&child, dsa->priv_key) ||
303 !CBB_flush(cbb)) {
304 OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
305 return 0;
306 }
307 return 1;
308 }
309
d2i_DSA_SIG(DSA_SIG ** out_sig,const uint8_t ** inp,long len)310 DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) {
311 if (len < 0) {
312 return NULL;
313 }
314 CBS cbs;
315 CBS_init(&cbs, *inp, (size_t)len);
316 DSA_SIG *ret = DSA_SIG_parse(&cbs);
317 if (ret == NULL) {
318 return NULL;
319 }
320 if (out_sig != NULL) {
321 DSA_SIG_free(*out_sig);
322 *out_sig = ret;
323 }
324 *inp = CBS_data(&cbs);
325 return ret;
326 }
327
i2d_DSA_SIG(const DSA_SIG * in,uint8_t ** outp)328 int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) {
329 CBB cbb;
330 if (!CBB_init(&cbb, 0) ||
331 !DSA_SIG_marshal(&cbb, in)) {
332 CBB_cleanup(&cbb);
333 return -1;
334 }
335 return CBB_finish_i2d(&cbb, outp);
336 }
337
d2i_DSAPublicKey(DSA ** out,const uint8_t ** inp,long len)338 DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) {
339 if (len < 0) {
340 return NULL;
341 }
342 CBS cbs;
343 CBS_init(&cbs, *inp, (size_t)len);
344 DSA *ret = DSA_parse_public_key(&cbs);
345 if (ret == NULL) {
346 return NULL;
347 }
348 if (out != NULL) {
349 DSA_free(*out);
350 *out = ret;
351 }
352 *inp = CBS_data(&cbs);
353 return ret;
354 }
355
i2d_DSAPublicKey(const DSA * in,uint8_t ** outp)356 int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) {
357 CBB cbb;
358 if (!CBB_init(&cbb, 0) ||
359 !DSA_marshal_public_key(&cbb, in)) {
360 CBB_cleanup(&cbb);
361 return -1;
362 }
363 return CBB_finish_i2d(&cbb, outp);
364 }
365
d2i_DSAPrivateKey(DSA ** out,const uint8_t ** inp,long len)366 DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) {
367 if (len < 0) {
368 return NULL;
369 }
370 CBS cbs;
371 CBS_init(&cbs, *inp, (size_t)len);
372 DSA *ret = DSA_parse_private_key(&cbs);
373 if (ret == NULL) {
374 return NULL;
375 }
376 if (out != NULL) {
377 DSA_free(*out);
378 *out = ret;
379 }
380 *inp = CBS_data(&cbs);
381 return ret;
382 }
383
i2d_DSAPrivateKey(const DSA * in,uint8_t ** outp)384 int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) {
385 CBB cbb;
386 if (!CBB_init(&cbb, 0) ||
387 !DSA_marshal_private_key(&cbb, in)) {
388 CBB_cleanup(&cbb);
389 return -1;
390 }
391 return CBB_finish_i2d(&cbb, outp);
392 }
393
d2i_DSAparams(DSA ** out,const uint8_t ** inp,long len)394 DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) {
395 if (len < 0) {
396 return NULL;
397 }
398 CBS cbs;
399 CBS_init(&cbs, *inp, (size_t)len);
400 DSA *ret = DSA_parse_parameters(&cbs);
401 if (ret == NULL) {
402 return NULL;
403 }
404 if (out != NULL) {
405 DSA_free(*out);
406 *out = ret;
407 }
408 *inp = CBS_data(&cbs);
409 return ret;
410 }
411
i2d_DSAparams(const DSA * in,uint8_t ** outp)412 int i2d_DSAparams(const DSA *in, uint8_t **outp) {
413 CBB cbb;
414 if (!CBB_init(&cbb, 0) ||
415 !DSA_marshal_parameters(&cbb, in)) {
416 CBB_cleanup(&cbb);
417 return -1;
418 }
419 return CBB_finish_i2d(&cbb, outp);
420 }
421