1 /* Written by Dr Stephen N Henson ([email protected]) 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 * [email protected].
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 * ([email protected]). This product includes software written by Tim
53 * Hudson ([email protected]). */
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) ||
123 constant_time_declassify_int(BN_is_zero(dsa->priv_key)) ||
124 constant_time_declassify_int(BN_cmp(dsa->priv_key, dsa->q) >= 0)) {
125 OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS);
126 return 0;
127 }
128 }
129
130 return 1;
131 }
132
parse_integer(CBS * cbs,BIGNUM ** out)133 static int parse_integer(CBS *cbs, BIGNUM **out) {
134 assert(*out == NULL);
135 *out = BN_new();
136 if (*out == NULL) {
137 return 0;
138 }
139 return BN_parse_asn1_unsigned(cbs, *out);
140 }
141
marshal_integer(CBB * cbb,BIGNUM * bn)142 static int marshal_integer(CBB *cbb, BIGNUM *bn) {
143 if (bn == NULL) {
144 // A DSA object may be missing some components.
145 OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER);
146 return 0;
147 }
148 return BN_marshal_asn1(cbb, bn);
149 }
150
DSA_SIG_parse(CBS * cbs)151 DSA_SIG *DSA_SIG_parse(CBS *cbs) {
152 DSA_SIG *ret = DSA_SIG_new();
153 if (ret == NULL) {
154 return NULL;
155 }
156 CBS child;
157 if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
158 !parse_integer(&child, &ret->r) ||
159 !parse_integer(&child, &ret->s) ||
160 CBS_len(&child) != 0) {
161 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
162 DSA_SIG_free(ret);
163 return NULL;
164 }
165 return ret;
166 }
167
DSA_SIG_marshal(CBB * cbb,const DSA_SIG * sig)168 int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) {
169 CBB child;
170 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
171 !marshal_integer(&child, sig->r) ||
172 !marshal_integer(&child, sig->s) ||
173 !CBB_flush(cbb)) {
174 OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
175 return 0;
176 }
177 return 1;
178 }
179
DSA_parse_public_key(CBS * cbs)180 DSA *DSA_parse_public_key(CBS *cbs) {
181 DSA *ret = DSA_new();
182 if (ret == NULL) {
183 return NULL;
184 }
185 CBS child;
186 if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
187 !parse_integer(&child, &ret->pub_key) ||
188 !parse_integer(&child, &ret->p) ||
189 !parse_integer(&child, &ret->q) ||
190 !parse_integer(&child, &ret->g) ||
191 CBS_len(&child) != 0) {
192 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
193 goto err;
194 }
195 if (!dsa_check_key(ret)) {
196 goto err;
197 }
198 return ret;
199
200 err:
201 DSA_free(ret);
202 return NULL;
203 }
204
DSA_marshal_public_key(CBB * cbb,const DSA * dsa)205 int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) {
206 CBB child;
207 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
208 !marshal_integer(&child, dsa->pub_key) ||
209 !marshal_integer(&child, dsa->p) ||
210 !marshal_integer(&child, dsa->q) ||
211 !marshal_integer(&child, dsa->g) ||
212 !CBB_flush(cbb)) {
213 OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
214 return 0;
215 }
216 return 1;
217 }
218
DSA_parse_parameters(CBS * cbs)219 DSA *DSA_parse_parameters(CBS *cbs) {
220 DSA *ret = DSA_new();
221 if (ret == NULL) {
222 return NULL;
223 }
224 CBS child;
225 if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
226 !parse_integer(&child, &ret->p) ||
227 !parse_integer(&child, &ret->q) ||
228 !parse_integer(&child, &ret->g) ||
229 CBS_len(&child) != 0) {
230 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
231 goto err;
232 }
233 if (!dsa_check_key(ret)) {
234 goto err;
235 }
236 return ret;
237
238 err:
239 DSA_free(ret);
240 return NULL;
241 }
242
DSA_marshal_parameters(CBB * cbb,const DSA * dsa)243 int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) {
244 CBB child;
245 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
246 !marshal_integer(&child, dsa->p) ||
247 !marshal_integer(&child, dsa->q) ||
248 !marshal_integer(&child, dsa->g) ||
249 !CBB_flush(cbb)) {
250 OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
251 return 0;
252 }
253 return 1;
254 }
255
DSA_parse_private_key(CBS * cbs)256 DSA *DSA_parse_private_key(CBS *cbs) {
257 DSA *ret = DSA_new();
258 if (ret == NULL) {
259 return NULL;
260 }
261
262 CBS child;
263 uint64_t version;
264 if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
265 !CBS_get_asn1_uint64(&child, &version)) {
266 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
267 goto err;
268 }
269
270 if (version != 0) {
271 OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION);
272 goto err;
273 }
274
275 if (!parse_integer(&child, &ret->p) ||
276 !parse_integer(&child, &ret->q) ||
277 !parse_integer(&child, &ret->g) ||
278 !parse_integer(&child, &ret->pub_key) ||
279 !parse_integer(&child, &ret->priv_key) ||
280 CBS_len(&child) != 0) {
281 OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
282 goto err;
283 }
284 if (!dsa_check_key(ret)) {
285 goto err;
286 }
287
288 return ret;
289
290 err:
291 DSA_free(ret);
292 return NULL;
293 }
294
DSA_marshal_private_key(CBB * cbb,const DSA * dsa)295 int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) {
296 CBB child;
297 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
298 !CBB_add_asn1_uint64(&child, 0 /* version */) ||
299 !marshal_integer(&child, dsa->p) ||
300 !marshal_integer(&child, dsa->q) ||
301 !marshal_integer(&child, dsa->g) ||
302 !marshal_integer(&child, dsa->pub_key) ||
303 !marshal_integer(&child, dsa->priv_key) ||
304 !CBB_flush(cbb)) {
305 OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
306 return 0;
307 }
308 return 1;
309 }
310
d2i_DSA_SIG(DSA_SIG ** out_sig,const uint8_t ** inp,long len)311 DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) {
312 if (len < 0) {
313 return NULL;
314 }
315 CBS cbs;
316 CBS_init(&cbs, *inp, (size_t)len);
317 DSA_SIG *ret = DSA_SIG_parse(&cbs);
318 if (ret == NULL) {
319 return NULL;
320 }
321 if (out_sig != NULL) {
322 DSA_SIG_free(*out_sig);
323 *out_sig = ret;
324 }
325 *inp = CBS_data(&cbs);
326 return ret;
327 }
328
i2d_DSA_SIG(const DSA_SIG * in,uint8_t ** outp)329 int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) {
330 CBB cbb;
331 if (!CBB_init(&cbb, 0) ||
332 !DSA_SIG_marshal(&cbb, in)) {
333 CBB_cleanup(&cbb);
334 return -1;
335 }
336 return CBB_finish_i2d(&cbb, outp);
337 }
338
d2i_DSAPublicKey(DSA ** out,const uint8_t ** inp,long len)339 DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) {
340 if (len < 0) {
341 return NULL;
342 }
343 CBS cbs;
344 CBS_init(&cbs, *inp, (size_t)len);
345 DSA *ret = DSA_parse_public_key(&cbs);
346 if (ret == NULL) {
347 return NULL;
348 }
349 if (out != NULL) {
350 DSA_free(*out);
351 *out = ret;
352 }
353 *inp = CBS_data(&cbs);
354 return ret;
355 }
356
i2d_DSAPublicKey(const DSA * in,uint8_t ** outp)357 int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) {
358 CBB cbb;
359 if (!CBB_init(&cbb, 0) ||
360 !DSA_marshal_public_key(&cbb, in)) {
361 CBB_cleanup(&cbb);
362 return -1;
363 }
364 return CBB_finish_i2d(&cbb, outp);
365 }
366
d2i_DSAPrivateKey(DSA ** out,const uint8_t ** inp,long len)367 DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) {
368 if (len < 0) {
369 return NULL;
370 }
371 CBS cbs;
372 CBS_init(&cbs, *inp, (size_t)len);
373 DSA *ret = DSA_parse_private_key(&cbs);
374 if (ret == NULL) {
375 return NULL;
376 }
377 if (out != NULL) {
378 DSA_free(*out);
379 *out = ret;
380 }
381 *inp = CBS_data(&cbs);
382 return ret;
383 }
384
i2d_DSAPrivateKey(const DSA * in,uint8_t ** outp)385 int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) {
386 CBB cbb;
387 if (!CBB_init(&cbb, 0) ||
388 !DSA_marshal_private_key(&cbb, in)) {
389 CBB_cleanup(&cbb);
390 return -1;
391 }
392 return CBB_finish_i2d(&cbb, outp);
393 }
394
d2i_DSAparams(DSA ** out,const uint8_t ** inp,long len)395 DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) {
396 if (len < 0) {
397 return NULL;
398 }
399 CBS cbs;
400 CBS_init(&cbs, *inp, (size_t)len);
401 DSA *ret = DSA_parse_parameters(&cbs);
402 if (ret == NULL) {
403 return NULL;
404 }
405 if (out != NULL) {
406 DSA_free(*out);
407 *out = ret;
408 }
409 *inp = CBS_data(&cbs);
410 return ret;
411 }
412
i2d_DSAparams(const DSA * in,uint8_t ** outp)413 int i2d_DSAparams(const DSA *in, uint8_t **outp) {
414 CBB cbb;
415 if (!CBB_init(&cbb, 0) ||
416 !DSA_marshal_parameters(&cbb, in)) {
417 CBB_cleanup(&cbb);
418 return -1;
419 }
420 return CBB_finish_i2d(&cbb, outp);
421 }
422