Coverage Report

Created: 2025-03-09 06:52

/src/libressl/crypto/dsa/dsa_lib.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: dsa_lib.c,v 1.48 2024/03/27 01:49:31 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
74
#include "dh_local.h"
75
#include "dsa_local.h"
76
77
static const DSA_METHOD *default_DSA_method = NULL;
78
79
void
80
DSA_set_default_method(const DSA_METHOD *meth)
81
0
{
82
0
  default_DSA_method = meth;
83
0
}
84
LCRYPTO_ALIAS(DSA_set_default_method);
85
86
const DSA_METHOD *
87
DSA_get_default_method(void)
88
23.4k
{
89
23.4k
  if (!default_DSA_method)
90
4
    default_DSA_method = DSA_OpenSSL();
91
23.4k
  return default_DSA_method;
92
23.4k
}
93
LCRYPTO_ALIAS(DSA_get_default_method);
94
95
DSA *
96
DSA_new(void)
97
23.4k
{
98
23.4k
  return DSA_new_method(NULL);
99
23.4k
}
100
LCRYPTO_ALIAS(DSA_new);
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
  dsa->meth = meth;
114
0
  if (meth->init)
115
0
    meth->init(dsa);
116
0
  return 1;
117
0
}
118
LCRYPTO_ALIAS(DSA_set_method);
119
120
DSA *
121
DSA_new_method(ENGINE *engine)
122
23.4k
{
123
23.4k
  DSA *dsa;
124
125
23.4k
  if ((dsa = calloc(1, sizeof(DSA))) == NULL) {
126
0
    DSAerror(ERR_R_MALLOC_FAILURE);
127
0
    goto err;
128
0
  }
129
130
23.4k
  dsa->meth = DSA_get_default_method();
131
23.4k
  dsa->flags = dsa->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
132
23.4k
  dsa->references = 1;
133
134
23.4k
  if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, dsa, &dsa->ex_data))
135
0
    goto err;
136
23.4k
  if (dsa->meth->init != NULL && !dsa->meth->init(dsa))
137
0
    goto err;
138
139
23.4k
  return dsa;
140
141
0
 err:
142
0
  DSA_free(dsa);
143
144
0
  return NULL;
145
23.4k
}
146
LCRYPTO_ALIAS(DSA_new_method);
147
148
void
149
DSA_free(DSA *dsa)
150
25.5k
{
151
25.5k
  if (dsa == NULL)
152
2.04k
    return;
153
154
23.4k
  if (CRYPTO_add(&dsa->references, -1, CRYPTO_LOCK_DSA) > 0)
155
40
    return;
156
157
23.4k
  if (dsa->meth != NULL && dsa->meth->finish != NULL)
158
23.4k
    dsa->meth->finish(dsa);
159
160
23.4k
  CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, dsa, &dsa->ex_data);
161
162
23.4k
  BN_free(dsa->p);
163
23.4k
  BN_free(dsa->q);
164
23.4k
  BN_free(dsa->g);
165
23.4k
  BN_free(dsa->pub_key);
166
23.4k
  BN_free(dsa->priv_key);
167
23.4k
  BN_free(dsa->kinv);
168
23.4k
  BN_free(dsa->r);
169
23.4k
  free(dsa);
170
23.4k
}
171
LCRYPTO_ALIAS(DSA_free);
172
173
int
174
DSA_up_ref(DSA *dsa)
175
40
{
176
40
  return CRYPTO_add(&dsa->references, 1, CRYPTO_LOCK_DSA) > 1;
177
40
}
178
LCRYPTO_ALIAS(DSA_up_ref);
179
180
int
181
DSA_size(const DSA *dsa)
182
95
{
183
95
  DSA_SIG signature;
184
95
  int ret = 0;
185
186
95
  signature.r = dsa->q;
187
95
  signature.s = dsa->q;
188
189
95
  if ((ret = i2d_DSA_SIG(&signature, NULL)) < 0)
190
0
    ret = 0;
191
192
95
  return ret;
193
95
}
194
LCRYPTO_ALIAS(DSA_size);
195
196
int
197
DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
198
    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
199
0
{
200
0
  return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp,
201
0
      new_func, dup_func, free_func);
202
0
}
203
LCRYPTO_ALIAS(DSA_get_ex_new_index);
204
205
int
206
DSA_set_ex_data(DSA *dsa, int idx, void *arg)
207
0
{
208
0
  return CRYPTO_set_ex_data(&dsa->ex_data, idx, arg);
209
0
}
210
LCRYPTO_ALIAS(DSA_set_ex_data);
211
212
void *
213
DSA_get_ex_data(DSA *dsa, int idx)
214
0
{
215
0
  return CRYPTO_get_ex_data(&dsa->ex_data, idx);
216
0
}
217
LCRYPTO_ALIAS(DSA_get_ex_data);
218
219
int
220
DSA_security_bits(const DSA *dsa)
221
4
{
222
4
  if (dsa->p == NULL || dsa->q == NULL)
223
0
    return -1;
224
225
4
  return BN_security_bits(BN_num_bits(dsa->p), BN_num_bits(dsa->q));
226
4
}
227
LCRYPTO_ALIAS(DSA_security_bits);
228
229
#ifndef OPENSSL_NO_DH
230
DH *
231
DSA_dup_DH(const DSA *dsa)
232
0
{
233
  /*
234
   * DSA has p, q, g, optional pub_key, optional priv_key.
235
   * DH has p, optional length, g, optional pub_key, optional priv_key,
236
   * optional q.
237
   */
238
0
  DH *dh = NULL;
239
240
0
  if (dsa == NULL)
241
0
    goto err;
242
243
0
  if ((dh = DH_new()) == NULL)
244
0
    goto err;
245
246
0
  if (dsa->p != NULL) {
247
0
    if ((dh->p = BN_dup(dsa->p)) == NULL)
248
0
      goto err;
249
0
  }
250
0
  if (dsa->q != NULL) {
251
0
    dh->length = BN_num_bits(dsa->q);
252
0
    if ((dh->q = BN_dup(dsa->q)) == NULL)
253
0
      goto err;
254
0
  }
255
0
  if (dsa->g != NULL) {
256
0
    if ((dh->g = BN_dup(dsa->g)) == NULL)
257
0
      goto err;
258
0
  }
259
0
  if (dsa->pub_key != NULL) {
260
0
    if ((dh->pub_key = BN_dup(dsa->pub_key)) == NULL)
261
0
      goto err;
262
0
  }
263
0
  if (dsa->priv_key != NULL) {
264
0
    if ((dh->priv_key = BN_dup(dsa->priv_key)) == NULL)
265
0
      goto err;
266
0
  }
267
268
0
  return dh;
269
270
0
 err:
271
0
  DH_free(dh);
272
0
  return NULL;
273
0
}
274
LCRYPTO_ALIAS(DSA_dup_DH);
275
#endif
276
277
void
278
DSA_get0_pqg(const DSA *dsa, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
279
0
{
280
0
  if (p != NULL)
281
0
    *p = dsa->p;
282
0
  if (q != NULL)
283
0
    *q = dsa->q;
284
0
  if (g != NULL)
285
0
    *g = dsa->g;
286
0
}
287
LCRYPTO_ALIAS(DSA_get0_pqg);
288
289
int
290
DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g)
291
311
{
292
311
  if ((dsa->p == NULL && p == NULL) || (dsa->q == NULL && q == NULL) ||
293
311
      (dsa->g == NULL && g == NULL))
294
0
    return 0;
295
296
311
  if (p != NULL) {
297
311
    BN_free(dsa->p);
298
311
    dsa->p = p;
299
311
  }
300
311
  if (q != NULL) {
301
311
    BN_free(dsa->q);
302
311
    dsa->q = q;
303
311
  }
304
311
  if (g != NULL) {
305
311
    BN_free(dsa->g);
306
311
    dsa->g = g;
307
311
  }
308
309
311
  return 1;
310
311
}
311
LCRYPTO_ALIAS(DSA_set0_pqg);
312
313
void
314
DSA_get0_key(const DSA *dsa, const BIGNUM **pub_key, const BIGNUM **priv_key)
315
0
{
316
0
  if (pub_key != NULL)
317
0
    *pub_key = dsa->pub_key;
318
0
  if (priv_key != NULL)
319
0
    *priv_key = dsa->priv_key;
320
0
}
321
LCRYPTO_ALIAS(DSA_get0_key);
322
323
int
324
DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key)
325
337
{
326
337
  if (dsa->pub_key == NULL && pub_key == NULL)
327
26
    return 0;
328
329
311
  if (pub_key != NULL) {
330
311
    BN_free(dsa->pub_key);
331
311
    dsa->pub_key = pub_key;
332
311
  }
333
311
  if (priv_key != NULL) {
334
95
    BN_free(dsa->priv_key);
335
95
    dsa->priv_key = priv_key;
336
95
  }
337
338
311
  return 1;
339
337
}
340
LCRYPTO_ALIAS(DSA_set0_key);
341
342
const BIGNUM *
343
DSA_get0_p(const DSA *dsa)
344
623
{
345
623
  return dsa->p;
346
623
}
347
LCRYPTO_ALIAS(DSA_get0_p);
348
349
const BIGNUM *
350
DSA_get0_q(const DSA *dsa)
351
623
{
352
623
  return dsa->q;
353
623
}
354
LCRYPTO_ALIAS(DSA_get0_q);
355
356
const BIGNUM *
357
DSA_get0_g(const DSA *dsa)
358
623
{
359
623
  return dsa->g;
360
623
}
361
LCRYPTO_ALIAS(DSA_get0_g);
362
363
const BIGNUM *
364
DSA_get0_pub_key(const DSA *dsa)
365
0
{
366
0
  return dsa->pub_key;
367
0
}
368
LCRYPTO_ALIAS(DSA_get0_pub_key);
369
370
const BIGNUM *
371
DSA_get0_priv_key(const DSA *dsa)
372
0
{
373
0
  return dsa->priv_key;
374
0
}
375
LCRYPTO_ALIAS(DSA_get0_priv_key);
376
377
void
378
DSA_clear_flags(DSA *dsa, int flags)
379
0
{
380
0
  dsa->flags &= ~flags;
381
0
}
382
LCRYPTO_ALIAS(DSA_clear_flags);
383
384
int
385
DSA_test_flags(const DSA *dsa, int flags)
386
0
{
387
0
  return dsa->flags & flags;
388
0
}
389
LCRYPTO_ALIAS(DSA_test_flags);
390
391
void
392
DSA_set_flags(DSA *dsa, int flags)
393
0
{
394
0
  dsa->flags |= flags;
395
0
}
396
LCRYPTO_ALIAS(DSA_set_flags);
397
398
ENGINE *
399
DSA_get0_engine(DSA *dsa)
400
0
{
401
0
  return NULL;
402
0
}
403
LCRYPTO_ALIAS(DSA_get0_engine);
404
405
int
406
DSA_bits(const DSA *dsa)
407
0
{
408
0
  return BN_num_bits(dsa->p);
409
0
}
410
LCRYPTO_ALIAS(DSA_bits);
411
412
int
413
dsa_check_key(const DSA *dsa)
414
426
{
415
426
  int p_bits, q_bits;
416
417
426
  if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
418
0
    DSAerror(DSA_R_MISSING_PARAMETERS);
419
0
    return 0;
420
0
  }
421
422
  /* Checking that p and q are primes is expensive. Check they are odd. */
423
426
  if (!BN_is_odd(dsa->p) || !BN_is_odd(dsa->q)) {
424
183
    DSAerror(DSA_R_INVALID_PARAMETERS);
425
183
    return 0;
426
183
  }
427
428
  /* FIPS 186-4: 1 < g < p. */
429
243
  if (BN_cmp(dsa->g, BN_value_one()) <= 0 ||
430
243
      BN_cmp(dsa->g, dsa->p) >= 0) {
431
68
    DSAerror(DSA_R_INVALID_PARAMETERS);
432
68
    return 0;
433
68
  }
434
435
  /* We know p and g are positive. The next two checks imply q > 0. */
436
175
  if (BN_is_negative(dsa->q)) {
437
8
    DSAerror(DSA_R_BAD_Q_VALUE);
438
8
    return 0;
439
8
  }
440
441
  /* FIPS 186-4 only allows three sizes for q. */
442
167
  q_bits = BN_num_bits(dsa->q);
443
167
  if (q_bits != 160 && q_bits != 224 && q_bits != 256) {
444
82
    DSAerror(DSA_R_BAD_Q_VALUE);
445
82
    return 0;
446
82
  }
447
448
  /*
449
   * XXX - FIPS 186-4 only allows 1024, 2048, and 3072 bits for p.
450
   * Cap the size to reduce DoS risks. Poor defaults make keys with
451
   * incorrect p sizes >= 512 bits common, so only enforce a weak
452
   * lower bound.
453
   */
454
85
  p_bits = BN_num_bits(dsa->p);
455
85
  if (p_bits > OPENSSL_DSA_MAX_MODULUS_BITS) {
456
1
    DSAerror(DSA_R_MODULUS_TOO_LARGE);
457
1
    return 0;
458
1
  }
459
84
  if (p_bits < 512) {
460
3
    DSAerror(DSA_R_INVALID_PARAMETERS);
461
3
    return 0;
462
3
  }
463
464
  /* The public key must be in the multiplicative group (mod p). */
465
81
  if (dsa->pub_key != NULL) {
466
41
    if (BN_cmp(dsa->pub_key, BN_value_one()) <= 0 ||
467
41
        BN_cmp(dsa->pub_key, dsa->p) >= 0) {
468
25
      DSAerror(DSA_R_INVALID_PARAMETERS);
469
25
      return 0;
470
25
    }
471
41
  }
472
473
  /* The private key must be nonzero and in GF(q). */
474
56
  if (dsa->priv_key != NULL) {
475
43
    if (BN_cmp(dsa->priv_key, BN_value_one()) < 0 ||
476
43
        BN_cmp(dsa->priv_key, dsa->q) >= 0) {
477
2
      DSAerror(DSA_R_INVALID_PARAMETERS);
478
2
      return 0;
479
2
    }
480
43
  }
481
482
54
  return 1;
483
56
}