/src/openssl30/crypto/ffc/ffc_params.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2019-2023 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 <string.h> /* memset */ |
11 | | #include <openssl/core_names.h> |
12 | | #include "internal/ffc.h" |
13 | | #include "internal/param_build_set.h" |
14 | | #include "internal/nelem.h" |
15 | | |
16 | | #ifndef FIPS_MODULE |
17 | | # include <openssl/asn1.h> /* ossl_ffc_params_print */ |
18 | | #endif |
19 | | |
20 | | void ossl_ffc_params_init(FFC_PARAMS *params) |
21 | 1.29M | { |
22 | 1.29M | memset(params, 0, sizeof(*params)); |
23 | 1.29M | params->pcounter = -1; |
24 | 1.29M | params->gindex = FFC_UNVERIFIABLE_GINDEX; |
25 | 1.29M | params->flags = FFC_PARAM_FLAG_VALIDATE_PQG; |
26 | 1.29M | } |
27 | | |
28 | | void ossl_ffc_params_cleanup(FFC_PARAMS *params) |
29 | 648k | { |
30 | 648k | BN_free(params->p); |
31 | 648k | BN_free(params->q); |
32 | 648k | BN_free(params->g); |
33 | 648k | BN_free(params->j); |
34 | 648k | OPENSSL_free(params->seed); |
35 | 648k | ossl_ffc_params_init(params); |
36 | 648k | } |
37 | | |
38 | | void ossl_ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) |
39 | 84.6k | { |
40 | 84.6k | if (p != NULL && p != d->p) { |
41 | 84.6k | BN_free(d->p); |
42 | 84.6k | d->p = p; |
43 | 84.6k | } |
44 | 84.6k | if (q != NULL && q != d->q) { |
45 | 79.1k | BN_free(d->q); |
46 | 79.1k | d->q = q; |
47 | 79.1k | } |
48 | 84.6k | if (g != NULL && g != d->g) { |
49 | 84.6k | BN_free(d->g); |
50 | 84.6k | d->g = g; |
51 | 84.6k | } |
52 | 84.6k | } |
53 | | |
54 | | void ossl_ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, |
55 | | const BIGNUM **q, const BIGNUM **g) |
56 | 46.7k | { |
57 | 46.7k | if (p != NULL) |
58 | 46.7k | *p = d->p; |
59 | 46.7k | if (q != NULL) |
60 | 38.5k | *q = d->q; |
61 | 46.7k | if (g != NULL) |
62 | 38.5k | *g = d->g; |
63 | 46.7k | } |
64 | | |
65 | | |
66 | | /* j is the 'cofactor' that is optionally output for ASN1. */ |
67 | | void ossl_ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j) |
68 | 82.9k | { |
69 | 82.9k | BN_free(d->j); |
70 | 82.9k | d->j = NULL; |
71 | 82.9k | if (j != NULL) |
72 | 9.19k | d->j = j; |
73 | 82.9k | } |
74 | | |
75 | | int ossl_ffc_params_set_seed(FFC_PARAMS *params, |
76 | | const unsigned char *seed, size_t seedlen) |
77 | 1.92k | { |
78 | 1.92k | if (params == NULL) |
79 | 0 | return 0; |
80 | | |
81 | 1.92k | if (params->seed != NULL) { |
82 | 0 | if (params->seed == seed) |
83 | 0 | return 1; |
84 | 0 | OPENSSL_free(params->seed); |
85 | 0 | } |
86 | | |
87 | 1.92k | if (seed != NULL && seedlen > 0) { |
88 | 24 | params->seed = OPENSSL_memdup(seed, seedlen); |
89 | 24 | if (params->seed == NULL) |
90 | 0 | return 0; |
91 | 24 | params->seedlen = seedlen; |
92 | 1.90k | } else { |
93 | 1.90k | params->seed = NULL; |
94 | 1.90k | params->seedlen = 0; |
95 | 1.90k | } |
96 | 1.92k | return 1; |
97 | 1.92k | } |
98 | | |
99 | | void ossl_ffc_params_set_gindex(FFC_PARAMS *params, int index) |
100 | 0 | { |
101 | 0 | params->gindex = index; |
102 | 0 | } |
103 | | |
104 | | void ossl_ffc_params_set_pcounter(FFC_PARAMS *params, int index) |
105 | 0 | { |
106 | 0 | params->pcounter = index; |
107 | 0 | } |
108 | | |
109 | | void ossl_ffc_params_set_h(FFC_PARAMS *params, int index) |
110 | 0 | { |
111 | 0 | params->h = index; |
112 | 0 | } |
113 | | |
114 | | void ossl_ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags) |
115 | 0 | { |
116 | 0 | params->flags = flags; |
117 | 0 | } |
118 | | |
119 | | void ossl_ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, |
120 | | int enable) |
121 | 80.1k | { |
122 | 80.1k | if (enable) |
123 | 50.8k | params->flags |= flags; |
124 | 29.2k | else |
125 | 29.2k | params->flags &= ~flags; |
126 | 80.1k | } |
127 | | |
128 | | int ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props) |
129 | 0 | { |
130 | 0 | params->mdname = alg; |
131 | 0 | params->mdprops = props; |
132 | 0 | return 1; |
133 | 0 | } |
134 | | |
135 | | int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, |
136 | | const unsigned char *seed, |
137 | | size_t seedlen, int counter) |
138 | 233 | { |
139 | 233 | if (!ossl_ffc_params_set_seed(params, seed, seedlen)) |
140 | 0 | return 0; |
141 | 233 | params->pcounter = counter; |
142 | 233 | return 1; |
143 | 233 | } |
144 | | |
145 | | void ossl_ffc_params_get_validate_params(const FFC_PARAMS *params, |
146 | | unsigned char **seed, size_t *seedlen, |
147 | | int *pcounter) |
148 | 274 | { |
149 | 274 | if (seed != NULL) |
150 | 274 | *seed = params->seed; |
151 | 274 | if (seedlen != NULL) |
152 | 274 | *seedlen = params->seedlen; |
153 | 274 | if (pcounter != NULL) |
154 | 274 | *pcounter = params->pcounter; |
155 | 274 | } |
156 | | |
157 | | static int ffc_bn_cpy(BIGNUM **dst, const BIGNUM *src) |
158 | 37.6k | { |
159 | 37.6k | BIGNUM *a; |
160 | | |
161 | | /* |
162 | | * If source is read only just copy the pointer, so |
163 | | * we don't have to reallocate it. |
164 | | */ |
165 | 37.6k | if (src == NULL) |
166 | 13.5k | a = NULL; |
167 | 24.1k | else if (BN_get_flags(src, BN_FLG_STATIC_DATA) |
168 | 24.1k | && !BN_get_flags(src, BN_FLG_MALLOCED)) |
169 | 3.10k | a = (BIGNUM *)src; |
170 | 20.9k | else if ((a = BN_dup(src)) == NULL) |
171 | 0 | return 0; |
172 | 37.6k | BN_clear_free(*dst); |
173 | 37.6k | *dst = a; |
174 | 37.6k | return 1; |
175 | 37.6k | } |
176 | | |
177 | | int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) |
178 | 9.42k | { |
179 | 9.42k | if (!ffc_bn_cpy(&dst->p, src->p) |
180 | 9.42k | || !ffc_bn_cpy(&dst->g, src->g) |
181 | 9.42k | || !ffc_bn_cpy(&dst->q, src->q) |
182 | 9.42k | || !ffc_bn_cpy(&dst->j, src->j)) |
183 | 0 | return 0; |
184 | | |
185 | 9.42k | dst->mdname = src->mdname; |
186 | 9.42k | dst->mdprops = src->mdprops; |
187 | 9.42k | OPENSSL_free(dst->seed); |
188 | 9.42k | dst->seedlen = src->seedlen; |
189 | 9.42k | if (src->seed != NULL) { |
190 | 64 | dst->seed = OPENSSL_memdup(src->seed, src->seedlen); |
191 | 64 | if (dst->seed == NULL) |
192 | 0 | return 0; |
193 | 9.35k | } else { |
194 | 9.35k | dst->seed = NULL; |
195 | 9.35k | } |
196 | 9.42k | dst->nid = src->nid; |
197 | 9.42k | dst->pcounter = src->pcounter; |
198 | 9.42k | dst->h = src->h; |
199 | 9.42k | dst->gindex = src->gindex; |
200 | 9.42k | dst->flags = src->flags; |
201 | 9.42k | dst->keylength = src->keylength; |
202 | 9.42k | return 1; |
203 | 9.42k | } |
204 | | |
205 | | int ossl_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) |
206 | 55.4k | { |
207 | 55.4k | return BN_cmp(a->p, b->p) == 0 |
208 | 55.4k | && BN_cmp(a->g, b->g) == 0 |
209 | 55.4k | && (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */ |
210 | 55.4k | } |
211 | | |
212 | | int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, |
213 | | OSSL_PARAM params[]) |
214 | 60.2k | { |
215 | 60.2k | int test_flags; |
216 | | |
217 | 60.2k | if (ffc == NULL) |
218 | 0 | return 0; |
219 | | |
220 | 60.2k | if (ffc->p != NULL |
221 | 60.2k | && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_P, ffc->p)) |
222 | 0 | return 0; |
223 | 60.2k | if (ffc->q != NULL |
224 | 60.2k | && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_Q, ffc->q)) |
225 | 0 | return 0; |
226 | 60.2k | if (ffc->g != NULL |
227 | 60.2k | && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_G, ffc->g)) |
228 | 0 | return 0; |
229 | 60.2k | if (ffc->j != NULL |
230 | 60.2k | && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_COFACTOR, |
231 | 3.08k | ffc->j)) |
232 | 0 | return 0; |
233 | 60.2k | if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_GINDEX, |
234 | 60.2k | ffc->gindex)) |
235 | 0 | return 0; |
236 | 60.2k | if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_PCOUNTER, |
237 | 60.2k | ffc->pcounter)) |
238 | 0 | return 0; |
239 | 60.2k | if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_H, ffc->h)) |
240 | 0 | return 0; |
241 | 60.2k | if (ffc->seed != NULL |
242 | 60.2k | && !ossl_param_build_set_octet_string(bld, params, |
243 | 0 | OSSL_PKEY_PARAM_FFC_SEED, |
244 | 0 | ffc->seed, ffc->seedlen)) |
245 | 0 | return 0; |
246 | 60.2k | if (ffc->nid != NID_undef) { |
247 | 1.73k | const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); |
248 | 1.73k | const char *name = ossl_ffc_named_group_get_name(group); |
249 | | |
250 | 1.73k | if (name == NULL |
251 | 1.73k | || !ossl_param_build_set_utf8_string(bld, params, |
252 | 1.73k | OSSL_PKEY_PARAM_GROUP_NAME, |
253 | 1.73k | name)) |
254 | 0 | return 0; |
255 | 1.73k | } |
256 | 60.2k | test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0); |
257 | 60.2k | if (!ossl_param_build_set_int(bld, params, |
258 | 60.2k | OSSL_PKEY_PARAM_FFC_VALIDATE_PQ, test_flags)) |
259 | 0 | return 0; |
260 | 60.2k | test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_G) != 0); |
261 | 60.2k | if (!ossl_param_build_set_int(bld, params, |
262 | 60.2k | OSSL_PKEY_PARAM_FFC_VALIDATE_G, test_flags)) |
263 | 0 | return 0; |
264 | 60.2k | test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_LEGACY) != 0); |
265 | 60.2k | if (!ossl_param_build_set_int(bld, params, |
266 | 60.2k | OSSL_PKEY_PARAM_FFC_VALIDATE_LEGACY, |
267 | 60.2k | test_flags)) |
268 | 0 | return 0; |
269 | | |
270 | 60.2k | if (ffc->mdname != NULL |
271 | 60.2k | && !ossl_param_build_set_utf8_string(bld, params, |
272 | 0 | OSSL_PKEY_PARAM_FFC_DIGEST, |
273 | 0 | ffc->mdname)) |
274 | 0 | return 0; |
275 | 60.2k | if (ffc->mdprops != NULL |
276 | 60.2k | && !ossl_param_build_set_utf8_string(bld, params, |
277 | 0 | OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, |
278 | 0 | ffc->mdprops)) |
279 | 0 | return 0; |
280 | 60.2k | return 1; |
281 | 60.2k | } |
282 | | |
283 | | #ifndef FIPS_MODULE |
284 | | int ossl_ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent) |
285 | 355 | { |
286 | 355 | if (!ASN1_bn_print(bp, "prime P:", ffc->p, NULL, indent)) |
287 | 0 | goto err; |
288 | 355 | if (!ASN1_bn_print(bp, "generator G:", ffc->g, NULL, indent)) |
289 | 0 | goto err; |
290 | 355 | if (ffc->q != NULL |
291 | 355 | && !ASN1_bn_print(bp, "subgroup order Q:", ffc->q, NULL, indent)) |
292 | 0 | goto err; |
293 | 355 | if (ffc->j != NULL |
294 | 355 | && !ASN1_bn_print(bp, "subgroup factor:", ffc->j, NULL, indent)) |
295 | 0 | goto err; |
296 | 355 | if (ffc->seed != NULL) { |
297 | 0 | size_t i; |
298 | |
|
299 | 0 | if (!BIO_indent(bp, indent, 128) |
300 | 0 | || BIO_puts(bp, "seed:") <= 0) |
301 | 0 | goto err; |
302 | 0 | for (i = 0; i < ffc->seedlen; i++) { |
303 | 0 | if ((i % 15) == 0) { |
304 | 0 | if (BIO_puts(bp, "\n") <= 0 |
305 | 0 | || !BIO_indent(bp, indent + 4, 128)) |
306 | 0 | goto err; |
307 | 0 | } |
308 | 0 | if (BIO_printf(bp, "%02x%s", ffc->seed[i], |
309 | 0 | ((i + 1) == ffc->seedlen) ? "" : ":") <= 0) |
310 | 0 | goto err; |
311 | 0 | } |
312 | 0 | if (BIO_write(bp, "\n", 1) <= 0) |
313 | 0 | return 0; |
314 | 0 | } |
315 | 355 | if (ffc->pcounter != -1) { |
316 | 0 | if (!BIO_indent(bp, indent, 128) |
317 | 0 | || BIO_printf(bp, "counter: %d\n", ffc->pcounter) <= 0) |
318 | 0 | goto err; |
319 | 0 | } |
320 | 355 | return 1; |
321 | 0 | err: |
322 | 0 | return 0; |
323 | 355 | } |
324 | | #endif /* FIPS_MODULE */ |