976eb622aa085533fd5fd101d41be678706ace68
[openssl.git] / crypto / dsa / dsa_lib.c
1 /*
2  * Copyright 1995-2018 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 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include "internal/refcount.h"
13 #include <openssl/bn.h>
14 #include "dsa_local.h"
15 #include <openssl/asn1.h>
16 #include <openssl/engine.h>
17 #include <openssl/dh.h>
18 #include "crypto/dsa.h"
19
20 #ifndef FIPS_MODE
21
22 int DSA_set_ex_data(DSA *d, int idx, void *arg)
23 {
24     return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
25 }
26
27 void *DSA_get_ex_data(DSA *d, int idx)
28 {
29     return CRYPTO_get_ex_data(&d->ex_data, idx);
30 }
31
32 #ifndef OPENSSL_NO_DH
33 DH *DSA_dup_DH(const DSA *r)
34 {
35     /*
36      * DSA has p, q, g, optional pub_key, optional priv_key. DH has p,
37      * optional length, g, optional pub_key, optional priv_key, optional q.
38      */
39
40     DH *ret = NULL;
41     BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
42
43     if (r == NULL)
44         goto err;
45     ret = DH_new();
46     if (ret == NULL)
47         goto err;
48     if (r->p != NULL || r->g != NULL || r->q != NULL) {
49         if (r->p == NULL || r->g == NULL || r->q == NULL) {
50             /* Shouldn't happen */
51             goto err;
52         }
53         p = BN_dup(r->p);
54         g = BN_dup(r->g);
55         q = BN_dup(r->q);
56         if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g))
57             goto err;
58         p = g = q = NULL;
59     }
60
61     if (r->pub_key != NULL) {
62         pub_key = BN_dup(r->pub_key);
63         if (pub_key == NULL)
64             goto err;
65         if (r->priv_key != NULL) {
66             priv_key = BN_dup(r->priv_key);
67             if (priv_key == NULL)
68                 goto err;
69         }
70         if (!DH_set0_key(ret, pub_key, priv_key))
71             goto err;
72     } else if (r->priv_key != NULL) {
73         /* Shouldn't happen */
74         goto err;
75     }
76
77     return ret;
78
79  err:
80     BN_free(p);
81     BN_free(g);
82     BN_free(q);
83     BN_free(pub_key);
84     BN_free(priv_key);
85     DH_free(ret);
86     return NULL;
87 }
88 #endif
89
90 const BIGNUM *DSA_get0_p(const DSA *d)
91 {
92     return d->p;
93 }
94
95 const BIGNUM *DSA_get0_q(const DSA *d)
96 {
97     return d->q;
98 }
99
100 const BIGNUM *DSA_get0_g(const DSA *d)
101 {
102     return d->g;
103 }
104
105 const BIGNUM *DSA_get0_pub_key(const DSA *d)
106 {
107     return d->pub_key;
108 }
109
110 const BIGNUM *DSA_get0_priv_key(const DSA *d)
111 {
112     return d->priv_key;
113 }
114
115 void DSA_clear_flags(DSA *d, int flags)
116 {
117     d->flags &= ~flags;
118 }
119
120 int DSA_test_flags(const DSA *d, int flags)
121 {
122     return d->flags & flags;
123 }
124
125 void DSA_set_flags(DSA *d, int flags)
126 {
127     d->flags |= flags;
128 }
129
130 ENGINE *DSA_get0_engine(DSA *d)
131 {
132     return d->engine;
133 }
134
135 int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
136 {
137     /*
138      * NB: The caller is specifically setting a method, so it's not up to us
139      * to deal with which ENGINE it comes from.
140      */
141     const DSA_METHOD *mtmp;
142     mtmp = dsa->meth;
143     if (mtmp->finish)
144         mtmp->finish(dsa);
145 #ifndef OPENSSL_NO_ENGINE
146     ENGINE_finish(dsa->engine);
147     dsa->engine = NULL;
148 #endif
149     dsa->meth = meth;
150     if (meth->init)
151         meth->init(dsa);
152     return 1;
153 }
154 #endif /* FIPS_MODE */
155
156
157 const DSA_METHOD *DSA_get_method(DSA *d)
158 {
159     return d->meth;
160 }
161
162 static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine)
163 {
164     DSA *ret = OPENSSL_zalloc(sizeof(*ret));
165
166     if (ret == NULL) {
167         DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
168         return NULL;
169     }
170
171     ret->references = 1;
172     ret->lock = CRYPTO_THREAD_lock_new();
173     if (ret->lock == NULL) {
174         DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
175         OPENSSL_free(ret);
176         return NULL;
177     }
178
179     ret->meth = DSA_get_default_method();
180 #if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
181     ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */
182     if (engine) {
183         if (!ENGINE_init(engine)) {
184             DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
185             goto err;
186         }
187         ret->engine = engine;
188     } else
189         ret->engine = ENGINE_get_default_DSA();
190     if (ret->engine) {
191         ret->meth = ENGINE_get_DSA(ret->engine);
192         if (ret->meth == NULL) {
193             DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
194             goto err;
195         }
196     }
197 #endif
198
199     ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
200
201 #ifndef FIPS_MODE
202     if (!crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
203         goto err;
204 #endif
205
206     if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
207         DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL);
208         goto err;
209     }
210
211     return ret;
212
213  err:
214     DSA_free(ret);
215     return NULL;
216 }
217
218 DSA *DSA_new_method(ENGINE *engine)
219 {
220     return dsa_new_method(NULL, engine);
221 }
222
223 DSA *DSA_new(void)
224 {
225     return DSA_new_method(NULL);
226 }
227
228 void DSA_free(DSA *r)
229 {
230     int i;
231
232     if (r == NULL)
233         return;
234
235     CRYPTO_DOWN_REF(&r->references, &i, r->lock);
236     REF_PRINT_COUNT("DSA", r);
237     if (i > 0)
238         return;
239     REF_ASSERT_ISNT(i < 0);
240
241     if (r->meth != NULL && r->meth->finish != NULL)
242         r->meth->finish(r);
243 #if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
244     ENGINE_finish(r->engine);
245 #endif
246
247 #ifndef FIPS_MODE
248     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
249 #endif
250
251     CRYPTO_THREAD_lock_free(r->lock);
252
253     BN_clear_free(r->p);
254     BN_clear_free(r->q);
255     BN_clear_free(r->g);
256     BN_clear_free(r->pub_key);
257     BN_clear_free(r->priv_key);
258     OPENSSL_free(r);
259 }
260
261 int DSA_up_ref(DSA *r)
262 {
263     int i;
264
265     if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
266         return 0;
267
268     REF_PRINT_COUNT("DSA", r);
269     REF_ASSERT_ISNT(i < 2);
270     return ((i > 1) ? 1 : 0);
271 }
272
273 void DSA_get0_pqg(const DSA *d,
274                   const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
275 {
276     if (p != NULL)
277         *p = d->p;
278     if (q != NULL)
279         *q = d->q;
280     if (g != NULL)
281         *g = d->g;
282 }
283
284 int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
285 {
286     /* If the fields p, q and g in d are NULL, the corresponding input
287      * parameters MUST be non-NULL.
288      */
289     if ((d->p == NULL && p == NULL)
290         || (d->q == NULL && q == NULL)
291         || (d->g == NULL && g == NULL))
292         return 0;
293
294     if (p != NULL) {
295         BN_free(d->p);
296         d->p = p;
297     }
298     if (q != NULL) {
299         BN_free(d->q);
300         d->q = q;
301     }
302     if (g != NULL) {
303         BN_free(d->g);
304         d->g = g;
305     }
306     d->dirty_cnt++;
307
308     return 1;
309 }
310
311 void DSA_get0_key(const DSA *d,
312                   const BIGNUM **pub_key, const BIGNUM **priv_key)
313 {
314     if (pub_key != NULL)
315         *pub_key = d->pub_key;
316     if (priv_key != NULL)
317         *priv_key = d->priv_key;
318 }
319
320 int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
321 {
322     /* If the field pub_key in d is NULL, the corresponding input
323      * parameters MUST be non-NULL.  The priv_key field may
324      * be left NULL.
325      */
326     if (d->pub_key == NULL && pub_key == NULL)
327         return 0;
328
329     if (pub_key != NULL) {
330         BN_free(d->pub_key);
331         d->pub_key = pub_key;
332     }
333     if (priv_key != NULL) {
334         BN_free(d->priv_key);
335         d->priv_key = priv_key;
336     }
337     d->dirty_cnt++;
338
339     return 1;
340 }
341
342 int DSA_security_bits(const DSA *d)
343 {
344     if (d->p && d->q)
345         return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
346     return -1;
347 }
348
349 int DSA_bits(const DSA *dsa)
350 {
351     return BN_num_bits(dsa->p);
352 }