blob: 9275a530811637270e2ea12a75a4cdfba7c4a48c [file] [log] [blame]
Rich Salzd2e9e322016-05-17 14:51:26 -04001/*
Pauli677963e2017-08-18 13:52:46 +10002 * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +00003 *
Rich Salzd2e9e322016-05-17 14:51:26 -04004 * Licensed under the OpenSSL license (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
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +00008 */
9
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000010#include <stdio.h>
Richard Levitteb39fc562015-05-14 16:56:48 +020011#include "internal/cryptlib.h"
Paulicd420b02017-08-22 07:17:35 +100012#include "internal/refcount.h"
Bodo Möllerec577821999-04-23 22:13:45 +000013#include <openssl/bn.h>
Matt Caswell12583962016-03-30 15:21:39 +010014#include "dsa_locl.h"
Bodo Möllerec577821999-04-23 22:13:45 +000015#include <openssl/asn1.h>
Rich Salz3c272082016-03-18 14:30:20 -040016#include <openssl/engine.h>
17#include <openssl/dh.h>
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000018
Ulf Möller6b691a51999-04-19 21:31:43 +000019DSA *DSA_new(void)
Matt Caswell0f113f32015-01-22 03:40:55 +000020{
21 return DSA_new_method(NULL);
22}
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +000023
Geoff Thorpecb784862001-09-25 20:23:40 +000024int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
Matt Caswell0f113f32015-01-22 03:40:55 +000025{
26 /*
27 * NB: The caller is specifically setting a method, so it's not up to us
28 * to deal with which ENGINE it comes from.
29 */
30 const DSA_METHOD *mtmp;
31 mtmp = dsa->meth;
32 if (mtmp->finish)
33 mtmp->finish(dsa);
Richard Levitte0b13e9f2003-01-30 17:39:26 +000034#ifndef OPENSSL_NO_ENGINE
Rich Salz7c96dbc2016-02-25 12:09:06 -050035 ENGINE_finish(dsa->engine);
36 dsa->engine = NULL;
Richard Levitte0b13e9f2003-01-30 17:39:26 +000037#endif
Matt Caswell0f113f32015-01-22 03:40:55 +000038 dsa->meth = meth;
39 if (meth->init)
40 meth->init(dsa);
41 return 1;
42}
Richard Levitte5270e702000-10-26 21:07:28 +000043
Matt Caswell6e9fa572016-03-30 17:18:55 +010044const DSA_METHOD *DSA_get_method(DSA *d)
45{
46 return d->meth;
47}
48
Richard Levitte5270e702000-10-26 21:07:28 +000049DSA *DSA_new_method(ENGINE *engine)
Matt Caswell0f113f32015-01-22 03:40:55 +000050{
FdaSilvaYY2bbf0ba2016-03-08 20:11:48 +010051 DSA *ret = OPENSSL_zalloc(sizeof(*ret));
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000052
Matt Caswell0f113f32015-01-22 03:40:55 +000053 if (ret == NULL) {
54 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
Alessandro Ghedinid188a532016-03-04 15:43:46 +000055 return NULL;
Matt Caswell0f113f32015-01-22 03:40:55 +000056 }
FdaSilvaYY2bbf0ba2016-03-08 20:11:48 +010057
58 ret->references = 1;
59 ret->lock = CRYPTO_THREAD_lock_new();
60 if (ret->lock == NULL) {
FdaSilvaYYb2b361f2016-04-30 16:23:33 +020061 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
FdaSilvaYY2bbf0ba2016-03-08 20:11:48 +010062 OPENSSL_free(ret);
63 return NULL;
64 }
65
Matt Caswell0f113f32015-01-22 03:40:55 +000066 ret->meth = DSA_get_default_method();
Richard Levitte0b13e9f2003-01-30 17:39:26 +000067#ifndef OPENSSL_NO_ENGINE
FdaSilvaYY2bbf0ba2016-03-08 20:11:48 +010068 ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */
Matt Caswell0f113f32015-01-22 03:40:55 +000069 if (engine) {
70 if (!ENGINE_init(engine)) {
71 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
FdaSilvaYY2bbf0ba2016-03-08 20:11:48 +010072 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +000073 }
74 ret->engine = engine;
75 } else
76 ret->engine = ENGINE_get_default_DSA();
77 if (ret->engine) {
78 ret->meth = ENGINE_get_DSA(ret->engine);
Rich Salz7c96dbc2016-02-25 12:09:06 -050079 if (ret->meth == NULL) {
Matt Caswell0f113f32015-01-22 03:40:55 +000080 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
FdaSilvaYY2bbf0ba2016-03-08 20:11:48 +010081 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +000082 }
83 }
Richard Levitte0b13e9f2003-01-30 17:39:26 +000084#endif
Dr. Stephen Henson0c9de422001-06-23 23:07:34 +000085
Matt Caswell0f113f32015-01-22 03:40:55 +000086 ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
Alessandro Ghedinid188a532016-03-04 15:43:46 +000087
FdaSilvaYY2bbf0ba2016-03-08 20:11:48 +010088 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
89 goto err;
Alessandro Ghedinid188a532016-03-04 15:43:46 +000090
91 if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
FdaSilvaYY2bbf0ba2016-03-08 20:11:48 +010092 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL);
93err:
Alessandro Ghedinid188a532016-03-04 15:43:46 +000094 DSA_free(ret);
Matt Caswell0f113f32015-01-22 03:40:55 +000095 ret = NULL;
96 }
97
Alessandro Ghedinid188a532016-03-04 15:43:46 +000098 return ret;
Matt Caswell0f113f32015-01-22 03:40:55 +000099}
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000100
Ulf Möller6b691a51999-04-19 21:31:43 +0000101void DSA_free(DSA *r)
Matt Caswell0f113f32015-01-22 03:40:55 +0000102{
103 int i;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000104
Matt Caswell0f113f32015-01-22 03:40:55 +0000105 if (r == NULL)
106 return;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000107
Kurt Roeckx2f545ae2016-08-27 16:01:08 +0200108 CRYPTO_DOWN_REF(&r->references, &i, r->lock);
Rich Salzf3f1cf82016-01-30 12:04:25 -0500109 REF_PRINT_COUNT("DSA", r);
Matt Caswell0f113f32015-01-22 03:40:55 +0000110 if (i > 0)
111 return;
Rich Salzf3f1cf82016-01-30 12:04:25 -0500112 REF_ASSERT_ISNT(i < 0);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000113
Matt Caswell0f113f32015-01-22 03:40:55 +0000114 if (r->meth->finish)
115 r->meth->finish(r);
Richard Levitte0b13e9f2003-01-30 17:39:26 +0000116#ifndef OPENSSL_NO_ENGINE
FdaSilvaYY17fa4e82016-02-28 16:01:41 +0100117 ENGINE_finish(r->engine);
Richard Levitte0b13e9f2003-01-30 17:39:26 +0000118#endif
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000119
Matt Caswell0f113f32015-01-22 03:40:55 +0000120 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
Geoff Thorped50f1bd2000-11-29 19:59:45 +0000121
Alessandro Ghedinid188a532016-03-04 15:43:46 +0000122 CRYPTO_THREAD_lock_free(r->lock);
123
Rich Salz23a1d5e2015-04-30 21:37:06 -0400124 BN_clear_free(r->p);
125 BN_clear_free(r->q);
126 BN_clear_free(r->g);
127 BN_clear_free(r->pub_key);
128 BN_clear_free(r->priv_key);
Matt Caswell0f113f32015-01-22 03:40:55 +0000129 OPENSSL_free(r);
130}
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000131
Bodo Möller6ac4e8b2001-09-03 13:40:07 +0000132int DSA_up_ref(DSA *r)
Matt Caswell0f113f32015-01-22 03:40:55 +0000133{
Alessandro Ghedinid188a532016-03-04 15:43:46 +0000134 int i;
135
Kurt Roeckx2f545ae2016-08-27 16:01:08 +0200136 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
Alessandro Ghedinid188a532016-03-04 15:43:46 +0000137 return 0;
Rich Salzf3f1cf82016-01-30 12:04:25 -0500138
139 REF_PRINT_COUNT("DSA", r);
140 REF_ASSERT_ISNT(i < 2);
Matt Caswell0f113f32015-01-22 03:40:55 +0000141 return ((i > 1) ? 1 : 0);
142}
Geoff Thorpe5cbc2e82001-08-25 17:24:21 +0000143
Richard Levittea4aba802000-11-07 13:54:39 +0000144int DSA_size(const DSA *r)
Matt Caswell0f113f32015-01-22 03:40:55 +0000145{
146 int ret, i;
147 ASN1_INTEGER bs;
148 unsigned char buf[4]; /* 4 bytes looks really small. However,
149 * i2d_ASN1_INTEGER() will not look beyond
150 * the first byte, as long as the second
151 * parameter is NULL. */
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000152
Matt Caswell0f113f32015-01-22 03:40:55 +0000153 i = BN_num_bits(r->q);
154 bs.length = (i + 7) / 8;
155 bs.data = buf;
156 bs.type = V_ASN1_INTEGER;
157 /* If the top bit is set the asn1 encoding is 1 larger. */
158 buf[0] = 0xff;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000159
Matt Caswell0f113f32015-01-22 03:40:55 +0000160 i = i2d_ASN1_INTEGER(&bs, NULL);
161 i += i; /* r and s */
162 ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
KaoruToda26a7d932017-10-17 23:04:09 +0900163 return ret;
Matt Caswell0f113f32015-01-22 03:40:55 +0000164}
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000165
Dr. Stephen Hensondd9d2332000-01-23 23:41:49 +0000166int DSA_set_ex_data(DSA *d, int idx, void *arg)
Matt Caswell0f113f32015-01-22 03:40:55 +0000167{
KaoruToda26a7d932017-10-17 23:04:09 +0900168 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
Matt Caswell0f113f32015-01-22 03:40:55 +0000169}
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000170
Dr. Stephen Hensondd9d2332000-01-23 23:41:49 +0000171void *DSA_get_ex_data(DSA *d, int idx)
Matt Caswell0f113f32015-01-22 03:40:55 +0000172{
KaoruToda26a7d932017-10-17 23:04:09 +0900173 return CRYPTO_get_ex_data(&d->ex_data, idx);
Matt Caswell0f113f32015-01-22 03:40:55 +0000174}
Dr. Stephen Hensonc0711f71999-08-22 17:57:38 +0000175
Dr. Stephen Henson2514fa72014-01-18 14:51:40 +0000176int DSA_security_bits(const DSA *d)
Matt Caswell0f113f32015-01-22 03:40:55 +0000177{
Dr. Stephen Henson72245f32015-12-30 13:34:53 +0000178 if (d->p && d->q)
179 return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
180 return -1;
Matt Caswell0f113f32015-01-22 03:40:55 +0000181}
Dr. Stephen Henson2514fa72014-01-18 14:51:40 +0000182
Richard Levittecf1b7d92001-02-19 16:06:34 +0000183#ifndef OPENSSL_NO_DH
Richard Levittea4aba802000-11-07 13:54:39 +0000184DH *DSA_dup_DH(const DSA *r)
Matt Caswell0f113f32015-01-22 03:40:55 +0000185{
186 /*
187 * DSA has p, q, g, optional pub_key, optional priv_key. DH has p,
188 * optional length, g, optional pub_key, optional priv_key, optional q.
189 */
Bodo Möller48c843c1999-08-05 11:50:18 +0000190
Matt Caswell0f113f32015-01-22 03:40:55 +0000191 DH *ret = NULL;
Matt Caswell0aeddcf2016-04-06 17:49:48 +0100192 BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
Bodo Möller48c843c1999-08-05 11:50:18 +0000193
Matt Caswell0f113f32015-01-22 03:40:55 +0000194 if (r == NULL)
195 goto err;
196 ret = DH_new();
197 if (ret == NULL)
198 goto err;
Matt Caswell0aeddcf2016-04-06 17:49:48 +0100199 if (r->p != NULL || r->g != NULL || r->q != NULL) {
200 if (r->p == NULL || r->g == NULL || r->q == NULL) {
201 /* Shouldn't happen */
Matt Caswell0f113f32015-01-22 03:40:55 +0000202 goto err;
Matt Caswell0aeddcf2016-04-06 17:49:48 +0100203 }
204 p = BN_dup(r->p);
205 g = BN_dup(r->g);
206 q = BN_dup(r->q);
207 if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g))
Matt Caswell0f113f32015-01-22 03:40:55 +0000208 goto err;
Matt Caswell998f2cb2016-04-07 14:08:52 +0100209 p = g = q = NULL;
Matt Caswell0f113f32015-01-22 03:40:55 +0000210 }
Matt Caswell0aeddcf2016-04-06 17:49:48 +0100211
212 if (r->pub_key != NULL) {
213 pub_key = BN_dup(r->pub_key);
214 if (pub_key == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000215 goto err;
Matt Caswell0aeddcf2016-04-06 17:49:48 +0100216 if (r->priv_key != NULL) {
217 priv_key = BN_dup(r->priv_key);
218 if (priv_key == NULL)
219 goto err;
220 }
221 if (!DH_set0_key(ret, pub_key, priv_key))
Matt Caswell0f113f32015-01-22 03:40:55 +0000222 goto err;
Matt Caswell0aeddcf2016-04-06 17:49:48 +0100223 } else if (r->priv_key != NULL) {
224 /* Shouldn't happen */
225 goto err;
226 }
Bodo Möller48c843c1999-08-05 11:50:18 +0000227
Matt Caswell0f113f32015-01-22 03:40:55 +0000228 return ret;
Bodo Möller48c843c1999-08-05 11:50:18 +0000229
230 err:
Matt Caswell0aeddcf2016-04-06 17:49:48 +0100231 BN_free(p);
232 BN_free(g);
233 BN_free(q);
234 BN_free(pub_key);
235 BN_free(priv_key);
Rich Salzd6407082015-03-24 10:17:37 -0400236 DH_free(ret);
Matt Caswell0f113f32015-01-22 03:40:55 +0000237 return NULL;
238}
Bodo Möller48c843c1999-08-05 11:50:18 +0000239#endif
Matt Caswell12583962016-03-30 15:21:39 +0100240
Richard Levittefd809cf2016-06-14 15:48:16 +0200241void DSA_get0_pqg(const DSA *d,
242 const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
Matt Caswell12583962016-03-30 15:21:39 +0100243{
Matt Caswell6e9fa572016-03-30 17:18:55 +0100244 if (p != NULL)
245 *p = d->p;
246 if (q != NULL)
247 *q = d->q;
248 if (g != NULL)
249 *g = d->g;
Matt Caswell12583962016-03-30 15:21:39 +0100250}
251
252int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
253{
Richard Levittefd809cf2016-06-14 15:48:16 +0200254 /* If the fields p, q and g in d are NULL, the corresponding input
Richard Levitte1da12e32016-04-25 20:28:54 +0200255 * parameters MUST be non-NULL.
Richard Levitte1da12e32016-04-25 20:28:54 +0200256 */
Matt Caswellb84e1222016-06-16 10:07:32 +0100257 if ((d->p == NULL && p == NULL)
258 || (d->q == NULL && q == NULL)
259 || (d->g == NULL && g == NULL))
Matt Caswell12583962016-03-30 15:21:39 +0100260 return 0;
Richard Levitte1da12e32016-04-25 20:28:54 +0200261
262 if (p != NULL) {
263 BN_free(d->p);
264 d->p = p;
265 }
266 if (q != NULL) {
267 BN_free(d->q);
268 d->q = q;
269 }
270 if (g != NULL) {
271 BN_free(d->g);
272 d->g = g;
273 }
Matt Caswell12583962016-03-30 15:21:39 +0100274
275 return 1;
276}
277
Richard Levittefd809cf2016-06-14 15:48:16 +0200278void DSA_get0_key(const DSA *d,
279 const BIGNUM **pub_key, const BIGNUM **priv_key)
Matt Caswell12583962016-03-30 15:21:39 +0100280{
Matt Caswell6e9fa572016-03-30 17:18:55 +0100281 if (pub_key != NULL)
282 *pub_key = d->pub_key;
283 if (priv_key != NULL)
284 *priv_key = d->priv_key;
Matt Caswell12583962016-03-30 15:21:39 +0100285}
286
Matt Caswell6e9fa572016-03-30 17:18:55 +0100287int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
Matt Caswell12583962016-03-30 15:21:39 +0100288{
Richard Levittefd809cf2016-06-14 15:48:16 +0200289 /* If the field pub_key in d is NULL, the corresponding input
Richard Levitte1da12e32016-04-25 20:28:54 +0200290 * parameters MUST be non-NULL. The priv_key field may
291 * be left NULL.
Richard Levitte1da12e32016-04-25 20:28:54 +0200292 */
Richard Levittefd809cf2016-06-14 15:48:16 +0200293 if (d->pub_key == NULL && pub_key == NULL)
Matt Caswell12583962016-03-30 15:21:39 +0100294 return 0;
295
Richard Levitte1da12e32016-04-25 20:28:54 +0200296 if (pub_key != NULL) {
297 BN_free(d->pub_key);
298 d->pub_key = pub_key;
299 }
300 if (priv_key != NULL) {
301 BN_free(d->priv_key);
302 d->priv_key = priv_key;
303 }
Matt Caswell12583962016-03-30 15:21:39 +0100304
305 return 1;
306}
307
Dr. Matthias St. Pierree6f35b52018-05-27 08:57:55 +0200308const BIGNUM *DSA_get0_p(const DSA *d)
309{
310 return d->p;
311}
312
313const BIGNUM *DSA_get0_q(const DSA *d)
314{
315 return d->q;
316}
317
318const BIGNUM *DSA_get0_g(const DSA *d)
319{
320 return d->g;
321}
322
323const BIGNUM *DSA_get0_pub_key(const DSA *d)
324{
325 return d->pub_key;
326}
327
328const BIGNUM *DSA_get0_priv_key(const DSA *d)
329{
330 return d->priv_key;
331}
332
Matt Caswell12583962016-03-30 15:21:39 +0100333void DSA_clear_flags(DSA *d, int flags)
334{
335 d->flags &= ~flags;
336}
337
338int DSA_test_flags(const DSA *d, int flags)
339{
340 return d->flags & flags;
341}
342
343void DSA_set_flags(DSA *d, int flags)
344{
345 d->flags |= flags;
346}
347
348ENGINE *DSA_get0_engine(DSA *d)
349{
350 return d->engine;
351}
Dr. Stephen Henson5d8d9a82016-08-01 18:37:03 +0100352
353int DSA_bits(const DSA *dsa)
354{
355 return BN_num_bits(dsa->p);
356}