Coverage Report

Created: 2022-08-24 06:31

/src/libressl/crypto/dsa/dsa_lib.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: dsa_lib.c,v 1.35 2022/06/27 12:28:46 tb Exp $ */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
60
61
#include <stdio.h>
62
63
#include <openssl/opensslconf.h>
64
65
#include <openssl/asn1.h>
66
#include <openssl/bn.h>
67
#include <openssl/dsa.h>
68
#include <openssl/err.h>
69
70
#ifndef OPENSSL_NO_DH
71
#include <openssl/dh.h>
72
#endif
73
#ifndef OPENSSL_NO_ENGINE
74
#include <openssl/engine.h>
75
#endif
76
77
#include "dh_local.h"
78
#include "dsa_locl.h"
79
80
static const DSA_METHOD *default_DSA_method = NULL;
81
82
void
83
DSA_set_default_method(const DSA_METHOD *meth)
84
0
{
85
0
  default_DSA_method = meth;
86
0
}
87
88
const DSA_METHOD *
89
DSA_get_default_method(void)
90
34.7k
{
91
34.7k
  if (!default_DSA_method)
92
1
    default_DSA_method = DSA_OpenSSL();
93
34.7k
  return default_DSA_method;
94
34.7k
}
95
96
DSA *
97
DSA_new(void)
98
34.7k
{
99
34.7k
  return DSA_new_method(NULL);
100
34.7k
}
101
102
int
103
DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
104
0
{
105
  /*
106
   * NB: The caller is specifically setting a method, so it's not up to us
107
   * to deal with which ENGINE it comes from.
108
   */
109
0
        const DSA_METHOD *mtmp;
110
0
        mtmp = dsa->meth;
111
0
        if (mtmp->finish)
112
0
    mtmp->finish(dsa);
113
0
#ifndef OPENSSL_NO_ENGINE
114
0
  ENGINE_finish(dsa->engine);
115
0
  dsa->engine = NULL;
116
0
#endif
117
0
        dsa->meth = meth;
118
0
        if (meth->init)
119
0
    meth->init(dsa);
120
0
        return 1;
121
0
}
122
123
DSA *
124
DSA_new_method(ENGINE *engine)
125
34.7k
{
126
34.7k
  DSA *ret;
127
128
34.7k
  ret = malloc(sizeof(DSA));
129
34.7k
  if (ret == NULL) {
130
0
    DSAerror(ERR_R_MALLOC_FAILURE);
131
0
    return NULL;
132
0
  }
133
34.7k
  ret->meth = DSA_get_default_method();
134
34.7k
#ifndef OPENSSL_NO_ENGINE
135
34.7k
  if (engine) {
136
0
    if (!ENGINE_init(engine)) {
137
0
      DSAerror(ERR_R_ENGINE_LIB);
138
0
      free(ret);
139
0
      return NULL;
140
0
    }
141
0
    ret->engine = engine;
142
0
  } else
143
34.7k
    ret->engine = ENGINE_get_default_DSA();
144
34.7k
  if (ret->engine) {
145
0
    ret->meth = ENGINE_get_DSA(ret->engine);
146
0
    if (ret->meth == NULL) {
147
0
      DSAerror(ERR_R_ENGINE_LIB);
148
0
      ENGINE_finish(ret->engine);
149
0
      free(ret);
150
0
      return NULL;
151
0
    }
152
0
  }
153
34.7k
#endif
154
155
34.7k
  ret->pad = 0;
156
34.7k
  ret->version = 0;
157
34.7k
  ret->p = NULL;
158
34.7k
  ret->q = NULL;
159
34.7k
  ret->g = NULL;
160
161
34.7k
  ret->pub_key = NULL;
162
34.7k
  ret->priv_key = NULL;
163
164
34.7k
  ret->kinv = NULL;
165
34.7k
  ret->r = NULL;
166
34.7k
  ret->method_mont_p = NULL;
167
168
34.7k
  ret->references = 1;
169
34.7k
  ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
170
34.7k
  CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
171
34.7k
  if (ret->meth->init != NULL && !ret->meth->init(ret)) {
172
0
#ifndef OPENSSL_NO_ENGINE
173
0
    ENGINE_finish(ret->engine);
174
0
#endif
175
0
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
176
0
    free(ret);
177
0
    ret = NULL;
178
0
  }
179
180
34.7k
  return ret;
181
34.7k
}
182
183
void
184
DSA_free(DSA *r)
185
35.4k
{
186
35.4k
  int i;
187
188
35.4k
  if (r == NULL)
189
628
    return;
190
191
34.8k
  i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DSA);
192
34.8k
  if (i > 0)
193
119
    return;
194
195
34.7k
  if (r->meth->finish)
196
34.7k
    r->meth->finish(r);
197
34.7k
#ifndef OPENSSL_NO_ENGINE
198
34.7k
  ENGINE_finish(r->engine);
199
34.7k
#endif
200
201
34.7k
  CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
202
203
34.7k
  BN_clear_free(r->p);
204
34.7k
  BN_clear_free(r->q);
205
34.7k
  BN_clear_free(r->g);
206
34.7k
  BN_clear_free(r->pub_key);
207
34.7k
  BN_clear_free(r->priv_key);
208
34.7k
  BN_clear_free(r->kinv);
209
34.7k
  BN_clear_free(r->r);
210
34.7k
  free(r);
211
34.7k
}
212
213
int
214
DSA_up_ref(DSA *r)
215
119
{
216
119
  int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA);
217
119
  return i > 1 ? 1 : 0;
218
119
}
219
220
int
221
DSA_size(const DSA *r)
222
0
{
223
0
  int ret, i;
224
0
  ASN1_INTEGER bs;
225
0
  unsigned char buf[4]; /* 4 bytes looks really small.
226
           However, i2d_ASN1_INTEGER() will not look
227
           beyond the first byte, as long as the second
228
           parameter is NULL. */
229
230
0
  i = BN_num_bits(r->q);
231
0
  bs.length = (i + 7) / 8;
232
0
  bs.data = buf;
233
0
  bs.type = V_ASN1_INTEGER;
234
  /* If the top bit is set the asn1 encoding is 1 larger. */
235
0
  buf[0] = 0xff;
236
237
0
  i = i2d_ASN1_INTEGER(&bs, NULL);
238
0
  i += i; /* r and s */
239
0
  ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
240
0
  return ret;
241
0
}
242
243
int
244
DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
245
    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
246
0
{
247
0
  return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp,
248
0
      new_func, dup_func, free_func);
249
0
}
250
251
int
252
DSA_set_ex_data(DSA *d, int idx, void *arg)
253
0
{
254
0
  return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
255
0
}
256
257
void *
258
DSA_get_ex_data(DSA *d, int idx)
259
0
{
260
0
  return CRYPTO_get_ex_data(&d->ex_data, idx);
261
0
}
262
263
int
264
DSA_security_bits(const DSA *d)
265
0
{
266
0
  if (d->p == NULL || d->q == NULL)
267
0
    return -1;
268
269
0
  return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
270
0
}
271
272
#ifndef OPENSSL_NO_DH
273
DH *
274
DSA_dup_DH(const DSA *r)
275
0
{
276
  /*
277
   * DSA has p, q, g, optional pub_key, optional priv_key.
278
   * DH has p, optional length, g, optional pub_key, optional priv_key,
279
   * optional q.
280
   */ 
281
0
  DH *ret = NULL;
282
283
0
  if (r == NULL)
284
0
    goto err;
285
0
  ret = DH_new();
286
0
  if (ret == NULL)
287
0
    goto err;
288
0
  if (r->p != NULL) 
289
0
    if ((ret->p = BN_dup(r->p)) == NULL)
290
0
      goto err;
291
0
  if (r->q != NULL) {
292
0
    ret->length = BN_num_bits(r->q);
293
0
    if ((ret->q = BN_dup(r->q)) == NULL)
294
0
      goto err;
295
0
  }
296
0
  if (r->g != NULL)
297
0
    if ((ret->g = BN_dup(r->g)) == NULL)
298
0
      goto err;
299
0
  if (r->pub_key != NULL)
300
0
    if ((ret->pub_key = BN_dup(r->pub_key)) == NULL)
301
0
      goto err;
302
0
  if (r->priv_key != NULL)
303
0
    if ((ret->priv_key = BN_dup(r->priv_key)) == NULL)
304
0
      goto err;
305
306
0
  return ret;
307
308
0
err:
309
0
  DH_free(ret);
310
0
  return NULL;
311
0
}
312
#endif
313
314
void
315
DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
316
0
{
317
0
  if (p != NULL)
318
0
    *p = d->p;
319
0
  if (q != NULL)
320
0
    *q = d->q;
321
0
  if (g != NULL)
322
0
    *g = d->g;
323
0
}
324
325
int
326
DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
327
0
{
328
0
  if ((d->p == NULL && p == NULL) || (d->q == NULL && q == NULL) ||
329
0
      (d->g == NULL && g == NULL))
330
0
    return 0;
331
332
0
  if (p != NULL) {
333
0
    BN_free(d->p);
334
0
    d->p = p;
335
0
  }
336
0
  if (q != NULL) {
337
0
    BN_free(d->q);
338
0
    d->q = q;
339
0
  }
340
0
  if (g != NULL) {
341
0
    BN_free(d->g);
342
0
    d->g = g;
343
0
  }
344
345
0
  return 1;
346
0
}
347
348
void
349
DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
350
0
{
351
0
  if (pub_key != NULL)
352
0
    *pub_key = d->pub_key;
353
0
  if (priv_key != NULL)
354
0
    *priv_key = d->priv_key;
355
0
}
356
357
int
358
DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
359
0
{
360
0
  if (d->pub_key == NULL && pub_key == NULL)
361
0
    return 0;
362
363
0
  if (pub_key != NULL) {
364
0
    BN_free(d->pub_key);
365
0
    d->pub_key = pub_key;
366
0
  }
367
0
  if (priv_key != NULL) {
368
0
    BN_free(d->priv_key);
369
0
    d->priv_key = priv_key;
370
0
  }
371
372
0
  return 1;
373
0
}
374
375
const BIGNUM *
376
DSA_get0_p(const DSA *d)
377
0
{
378
0
  return d->p;
379
0
}
380
381
const BIGNUM *
382
DSA_get0_q(const DSA *d)
383
0
{
384
0
  return d->q;
385
0
}
386
387
const BIGNUM *
388
DSA_get0_g(const DSA *d)
389
0
{
390
0
  return d->g;
391
0
}
392
393
const BIGNUM *
394
DSA_get0_pub_key(const DSA *d)
395
0
{
396
0
  return d->pub_key;
397
0
}
398
399
const BIGNUM *
400
DSA_get0_priv_key(const DSA *d)
401
0
{
402
0
  return d->priv_key;
403
0
}
404
405
void
406
DSA_clear_flags(DSA *d, int flags)
407
0
{
408
0
  d->flags &= ~flags;
409
0
}
410
411
int
412
DSA_test_flags(const DSA *d, int flags)
413
0
{
414
0
  return d->flags & flags;
415
0
}
416
417
void
418
DSA_set_flags(DSA *d, int flags)
419
0
{
420
0
  d->flags |= flags;
421
0
}
422
423
ENGINE *
424
DSA_get0_engine(DSA *d)
425
0
{
426
0
  return d->engine;
427
0
}
428
429
int
430
DSA_bits(const DSA *dsa)
431
0
{
432
0
  return BN_num_bits(dsa->p);
433
0
}