Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/nettle/int/dsa-validate.c
Line
Count
Source (jump to first uncovered line)
1
/* dsa-keygen.c
2
 *
3
 * Generation of DSA keypairs
4
 */
5
6
/* nettle, low-level cryptographics library
7
 *
8
 * Copyright (C) 2013 Red Hat
9
 *  
10
 * The nettle library is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU Lesser General Public License as published by
12
 * the Free Software Foundation; either version 2.1 of the License, or (at your
13
 * option) any later version.
14
 * 
15
 * The nettle library is distributed in the hope that it will be useful, but
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
18
 * License for more details.
19
 * 
20
 * You should have received a copy of the GNU Lesser General Public License
21
 * along with the nettle library.  If not, see <https://www.gnu.org/licenses/>.
22
 */
23
24
#if HAVE_CONFIG_H
25
# include "config.h"
26
#endif
27
28
#include <stdlib.h>
29
#include <string.h>
30
31
#include <nettle/dsa.h>
32
#include <dsa-fips.h>
33
34
#include <nettle/bignum.h>
35
36
/* This validates the given p, q, g params using the provided
37
 * dss_params_validation_seeds.
38
 * 
39
 * The hash function used is SHA384.
40
 * 
41
 * pub: The output public key
42
 * key: The output private key
43
 * cert: A certificate that can be used to verify the generated parameters
44
 * index: 1 for digital signatures (DSA), 2 for key establishment (DH)
45
 * 
46
 */
47
int
48
dsa_validate_dss_pqg(struct dsa_params *pub,
49
         struct dss_params_validation_seeds *cert, unsigned index)
50
0
{
51
0
  int ret;
52
0
  uint8_t domain_seed[MAX_PVP_SEED_SIZE * 3];
53
0
  unsigned domain_seed_size = 0;
54
55
0
  ret = _dsa_validate_dss_pq(pub, cert);
56
0
  if (ret == 0)
57
0
    return 0;
58
59
0
  domain_seed_size =
60
0
      cert->seed_length + cert->qseed_length + cert->pseed_length;
61
0
  memcpy(domain_seed, cert->seed, cert->seed_length);
62
0
  memcpy(&domain_seed[cert->seed_length], cert->pseed,
63
0
         cert->pseed_length);
64
0
  memcpy(&domain_seed[cert->seed_length + cert->pseed_length],
65
0
         cert->qseed, cert->qseed_length);
66
67
0
  ret = _dsa_validate_dss_g(pub, domain_seed_size, domain_seed, index);
68
0
  if (ret == 0)
69
0
    return 0;
70
71
0
  return 1;
72
0
}
73
74
int
75
_dsa_validate_dss_g(struct dsa_params *pub,
76
        unsigned domain_seed_size, const uint8_t * domain_seed,
77
        unsigned index)
78
0
{
79
0
  int ret;
80
0
  unsigned p_bits, q_bits;
81
0
  struct dsa_params pub2;
82
0
  mpz_t r;
83
84
0
  p_bits = mpz_sizeinbase(pub->p, 2);
85
0
  q_bits = mpz_sizeinbase(pub->q, 2);
86
87
0
  ret = _dsa_check_qp_sizes(q_bits, p_bits, 0);
88
0
  if (ret == 0) {
89
0
    return 0;
90
0
  }
91
92
0
  mpz_init(r);
93
0
  dsa_params_init(&pub2);
94
95
0
  mpz_set(pub2.p, pub->p);
96
0
  mpz_set(pub2.q, pub->q);
97
98
  /* verify g */
99
0
  if (index > 255) {
100
0
    goto fail;
101
0
  }
102
103
  /* 2<= g <= p-1 */
104
0
  mpz_set(r, pub->p);
105
0
  mpz_sub_ui(r, r, 1);
106
0
  if (mpz_cmp_ui(pub->g, 2) < 0 || mpz_cmp(pub->g, r) >= 0) {
107
0
    goto fail;
108
0
  }
109
110
  /* g^q == 1 mod p */
111
0
  mpz_powm(r, pub->g, pub->q, pub->p);
112
0
  if (mpz_cmp_ui(r, 1) != 0) {
113
0
    goto fail;
114
0
  }
115
116
  /* repeat g generation */
117
0
  ret = _dsa_generate_dss_g(&pub2,
118
0
          domain_seed_size, domain_seed,
119
0
          NULL, NULL, index);
120
0
  if (ret == 0) {
121
0
    goto fail;
122
0
  }
123
124
0
  if (mpz_cmp(pub->g, pub2.g) != 0) {
125
0
    goto fail;
126
0
  }
127
128
  /* everything looks ok */
129
0
  ret = 1;
130
0
  goto finish;
131
132
0
 fail:
133
0
  ret = 0;
134
135
0
 finish:
136
0
  dsa_params_clear(&pub2);
137
0
  mpz_clear(r);
138
139
0
  return ret;
140
0
}
141
142
int
143
_dsa_validate_dss_pq(struct dsa_params *pub,
144
         struct dss_params_validation_seeds *cert)
145
0
{
146
0
  int ret;
147
0
  unsigned p_bits, q_bits;
148
0
  struct dsa_params pub2;
149
0
  struct dss_params_validation_seeds cert2;
150
0
  mpz_t r, s;
151
152
0
  p_bits = mpz_sizeinbase(pub->p, 2);
153
0
  q_bits = mpz_sizeinbase(pub->q, 2);
154
155
0
  ret = _dsa_check_qp_sizes(q_bits, p_bits, 0);
156
0
  if (ret == 0) {
157
0
    return 0;
158
0
  }
159
160
0
  mpz_init(r);
161
0
  mpz_init(s);
162
0
  dsa_params_init(&pub2);
163
164
0
  nettle_mpz_set_str_256_u(s, cert->seed_length, cert->seed);
165
166
  /* firstseed < 2^(N-1) */
167
0
  mpz_set_ui(r, 1);
168
0
  mpz_mul_2exp(r, r, q_bits - 1);
169
170
0
  if (mpz_cmp(s, r) < 0) {
171
0
    goto fail;
172
0
  }
173
174
  /* 2^N <= q */
175
0
  mpz_set_ui(r, 1);
176
0
  mpz_mul_2exp(r, r, q_bits);
177
178
0
  if (mpz_cmp(r, pub->q) <= 0) {
179
0
    goto fail;
180
0
  }
181
182
  /* 2^L <= p */
183
0
  mpz_set_ui(r, 1);
184
0
  mpz_mul_2exp(r, r, p_bits);
185
186
0
  if (mpz_cmp(r, pub->p) <= 0) {
187
0
    goto fail;
188
0
  }
189
190
  /* p-1 mod q != 0 */
191
0
  mpz_set(r, pub->p);
192
0
  mpz_sub_ui(r, r, 1);
193
194
0
  mpz_mod(r, r, pub->q);
195
0
  if (mpz_cmp_ui(r, 0) != 0) {
196
0
    goto fail;
197
0
  }
198
199
  /* replay the construction */
200
0
  ret = _dsa_generate_dss_pq(&pub2, &cert2, cert->seed_length, cert->seed,
201
0
           NULL, NULL, p_bits, q_bits);
202
0
  if (ret == 0) {
203
0
    goto fail;
204
0
  }
205
206
0
  if ((cert->pseed_length > 0 && cert->pseed_length != cert2.pseed_length)
207
0
      || (cert->qseed_length > 0
208
0
    && cert->qseed_length != cert2.qseed_length)
209
0
      || (cert->pgen_counter > 0
210
0
    && cert->pgen_counter != cert2.pgen_counter)
211
0
      || (cert->qgen_counter > 0
212
0
    && cert->qgen_counter != cert2.qgen_counter)
213
0
      || (cert->qseed_length > 0
214
0
    && memcmp(cert->qseed, cert2.qseed, cert2.qseed_length) != 0)
215
0
      || (cert->pseed_length > 0
216
0
    && memcmp(cert->pseed, cert2.pseed, cert2.pseed_length) != 0)) {
217
0
    goto fail;
218
0
  }
219
220
0
  if (mpz_cmp(pub->q, pub2.q) != 0) {
221
0
    goto fail;
222
0
  }
223
224
0
  if (mpz_cmp(pub->p, pub2.p) != 0) {
225
0
    goto fail;
226
0
  }
227
228
0
  if (mpz_sizeinbase(s, 2) < q_bits - 1) {
229
0
    goto fail;
230
0
  }
231
232
0
  ret = 1;
233
0
  goto finish;
234
235
0
 fail:
236
0
  ret = 0;
237
238
0
 finish:
239
0
  dsa_params_clear(&pub2);
240
0
  mpz_clear(r);
241
0
  mpz_clear(s);
242
243
0
  return ret;
244
0
}