• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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