Branch data Line data Source code
1 : : /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 : : * project 2006.
3 : : */
4 : : /* ====================================================================
5 : : * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions
9 : : * are met:
10 : : *
11 : : * 1. Redistributions of source code must retain the above copyright
12 : : * notice, this list of conditions and the following disclaimer.
13 : : *
14 : : * 2. Redistributions in binary form must reproduce the above copyright
15 : : * notice, this list of conditions and the following disclaimer in
16 : : * the documentation and/or other materials provided with the
17 : : * distribution.
18 : : *
19 : : * 3. All advertising materials mentioning features or use of this
20 : : * software must display the following acknowledgment:
21 : : * "This product includes software developed by the OpenSSL Project
22 : : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 : : *
24 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 : : * endorse or promote products derived from this software without
26 : : * prior written permission. For written permission, please contact
27 : : * licensing@OpenSSL.org.
28 : : *
29 : : * 5. Products derived from this software may not be called "OpenSSL"
30 : : * nor may "OpenSSL" appear in their names without prior written
31 : : * permission of the OpenSSL Project.
32 : : *
33 : : * 6. Redistributions of any form whatsoever must retain the following
34 : : * acknowledgment:
35 : : * "This product includes software developed by the OpenSSL Project
36 : : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 : : *
38 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
50 : : * ====================================================================
51 : : *
52 : : * This product includes cryptographic software written by Eric Young
53 : : * (eay@cryptsoft.com). This product includes software written by Tim
54 : : * Hudson (tjh@cryptsoft.com).
55 : : *
56 : : */
57 : :
58 : : #include <stdio.h>
59 : : #include "cryptlib.h"
60 : : #include <openssl/asn1t.h>
61 : : #include <openssl/x509.h>
62 : : #include <openssl/evp.h>
63 : : #include <openssl/dh.h>
64 : : #include <openssl/bn.h>
65 : : #ifndef OPENSSL_NO_DSA
66 : : #include <openssl/dsa.h>
67 : : #endif
68 : : #include <openssl/objects.h>
69 : : #include "evp_locl.h"
70 : :
71 : : /* DH pkey context structure */
72 : :
73 : : typedef struct
74 : : {
75 : : /* Parameter gen parameters */
76 : : int prime_len;
77 : : int generator;
78 : : int use_dsa;
79 : : int subprime_len;
80 : : /* message digest used for parameter generation */
81 : : const EVP_MD *md;
82 : : int rfc5114_param;
83 : : /* Keygen callback info */
84 : : int gentmp[2];
85 : : /* KDF (if any) to use for DH */
86 : : char kdf_type;
87 : : /* OID to use for KDF */
88 : : ASN1_OBJECT *kdf_oid;
89 : : /* Message digest to use for key derivation */
90 : : const EVP_MD *kdf_md;
91 : : /* User key material */
92 : : unsigned char *kdf_ukm;
93 : : size_t kdf_ukmlen;
94 : : /* KDF output length */
95 : : size_t kdf_outlen;
96 : : } DH_PKEY_CTX;
97 : :
98 : 3 : static int pkey_dh_init(EVP_PKEY_CTX *ctx)
99 : : {
100 : : DH_PKEY_CTX *dctx;
101 : 3 : dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX));
102 [ + - ]: 3 : if (!dctx)
103 : : return 0;
104 : 3 : dctx->prime_len = 1024;
105 : 3 : dctx->subprime_len = -1;
106 : 3 : dctx->generator = 2;
107 : 3 : dctx->use_dsa = 0;
108 : 3 : dctx->md = NULL;
109 : 3 : dctx->rfc5114_param = 0;
110 : :
111 : 3 : dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
112 : 3 : dctx->kdf_oid = NULL;
113 : 3 : dctx->kdf_md = NULL;
114 : 3 : dctx->kdf_ukm = NULL;
115 : 3 : dctx->kdf_ukmlen = 0;
116 : 3 : dctx->kdf_outlen = 0;
117 : :
118 : 3 : ctx->data = dctx;
119 : 3 : ctx->keygen_info = dctx->gentmp;
120 : 3 : ctx->keygen_info_count = 2;
121 : :
122 : 3 : return 1;
123 : : }
124 : :
125 : 0 : static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
126 : : {
127 : : DH_PKEY_CTX *dctx, *sctx;
128 [ # # ]: 0 : if (!pkey_dh_init(dst))
129 : : return 0;
130 : 0 : sctx = src->data;
131 : 0 : dctx = dst->data;
132 : 0 : dctx->prime_len = sctx->prime_len;
133 : 0 : dctx->subprime_len = sctx->subprime_len;
134 : 0 : dctx->generator = sctx->generator;
135 : 0 : dctx->use_dsa = sctx->use_dsa;
136 : 0 : dctx->md = sctx->md;
137 : 0 : dctx->rfc5114_param = sctx->rfc5114_param;
138 : :
139 : 0 : dctx->kdf_type = sctx->kdf_type;
140 : 0 : dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
141 [ # # ]: 0 : if (!dctx->kdf_oid)
142 : : return 0;
143 : 0 : dctx->kdf_md = sctx->kdf_md;
144 [ # # ]: 0 : if (dctx->kdf_ukm)
145 : : {
146 : 0 : dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
147 : 0 : dctx->kdf_ukmlen = sctx->kdf_ukmlen;
148 : : }
149 : 0 : dctx->kdf_outlen = sctx->kdf_outlen;
150 : 0 : return 1;
151 : : }
152 : :
153 : 3 : static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
154 : : {
155 : 3 : DH_PKEY_CTX *dctx = ctx->data;
156 [ + - ]: 3 : if (dctx)
157 : : {
158 [ - + ]: 3 : if (dctx->kdf_ukm)
159 : 0 : OPENSSL_free(dctx->kdf_ukm);
160 [ + + ]: 3 : if (dctx->kdf_oid)
161 : 2 : ASN1_OBJECT_free(dctx->kdf_oid);
162 : 3 : OPENSSL_free(dctx);
163 : : }
164 : 3 : }
165 : :
166 : 16 : static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
167 : : {
168 : 16 : DH_PKEY_CTX *dctx = ctx->data;
169 [ - - - - : 16 : switch (type)
- + + + +
- + - + -
- + ]
170 : : {
171 : : case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
172 [ # # ]: 0 : if (p1 < 256)
173 : : return -2;
174 : 0 : dctx->prime_len = p1;
175 : 0 : return 1;
176 : :
177 : : case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
178 [ # # ]: 0 : if (dctx->use_dsa == 0)
179 : : return -2;
180 : 0 : dctx->subprime_len = p1;
181 : 0 : return 1;
182 : :
183 : : case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
184 [ # # ]: 0 : if (dctx->use_dsa)
185 : : return -2;
186 : 0 : dctx->generator = p1;
187 : 0 : return 1;
188 : :
189 : : case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
190 : : #ifdef OPENSSL_NO_DSA
191 : : if (p1 != 0)
192 : : return -2;
193 : : #else
194 [ # # ]: 0 : if (p1 < 0 || p1 > 2)
195 : : return -2;
196 : : #endif
197 : 0 : dctx->use_dsa = p1;
198 : 0 : return 1;
199 : :
200 : : case EVP_PKEY_CTRL_DH_RFC5114:
201 [ # # ]: 0 : if (p1 < 1 || p1 > 3)
202 : : return -2;
203 : 0 : dctx->rfc5114_param = p1;
204 : 0 : return 1;
205 : :
206 : : case EVP_PKEY_CTRL_PEER_KEY:
207 : : /* Default behaviour is OK */
208 : : return 1;
209 : :
210 : : case EVP_PKEY_CTRL_DH_KDF_TYPE:
211 [ + + ]: 3 : if (p1 == -2)
212 : 1 : return dctx->kdf_type;
213 [ + - ]: 2 : if (p1 != EVP_PKEY_DH_KDF_NONE &&
214 : : p1 != EVP_PKEY_DH_KDF_X9_42)
215 : : return -2;
216 : 2 : dctx->kdf_type = p1;
217 : 2 : return 1;
218 : :
219 : : case EVP_PKEY_CTRL_DH_KDF_MD:
220 : 2 : dctx->kdf_md = p2;
221 : 2 : return 1;
222 : :
223 : : case EVP_PKEY_CTRL_GET_DH_KDF_MD:
224 : 1 : *(const EVP_MD **)p2 = dctx->kdf_md;
225 : 1 : return 1;
226 : :
227 : : case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
228 [ + - ]: 2 : if (p1 <= 0)
229 : : return -2;
230 : 2 : dctx->kdf_outlen = (size_t)p1;
231 : 2 : return 1;
232 : :
233 : : case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
234 : 0 : *(int *)p2 = dctx->kdf_outlen;
235 : 0 : return 1;
236 : :
237 : : case EVP_PKEY_CTRL_DH_KDF_UKM:
238 [ - + ]: 2 : if (dctx->kdf_ukm)
239 : 0 : OPENSSL_free(dctx->kdf_ukm);
240 : 2 : dctx->kdf_ukm = p2;
241 [ - + ]: 2 : if (p2)
242 : 0 : dctx->kdf_ukmlen = p1;
243 : : else
244 : 2 : dctx->kdf_ukmlen = 0;
245 : : return 1;
246 : :
247 : : case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
248 : 0 : *(unsigned char **)p2 = dctx->kdf_ukm;
249 : 0 : return dctx->kdf_ukmlen;
250 : :
251 : : case EVP_PKEY_CTRL_DH_KDF_OID:
252 [ - + ]: 2 : if (dctx->kdf_oid)
253 : 0 : ASN1_OBJECT_free(dctx->kdf_oid);
254 : 2 : dctx->kdf_oid = p2;
255 : 2 : return 1;
256 : :
257 : : case EVP_PKEY_CTRL_GET_DH_KDF_OID:
258 : 0 : *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
259 : 0 : return 1;
260 : :
261 : : default:
262 : 0 : return -2;
263 : :
264 : : }
265 : : }
266 : :
267 : :
268 : 0 : static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
269 : : const char *type, const char *value)
270 : : {
271 [ # # ]: 0 : if (!strcmp(type, "dh_paramgen_prime_len"))
272 : : {
273 : : int len;
274 : 0 : len = atoi(value);
275 : 0 : return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
276 : : }
277 [ # # ]: 0 : if (!strcmp(type, "dh_rfc5114"))
278 : : {
279 : 0 : DH_PKEY_CTX *dctx = ctx->data;
280 : : int len;
281 : 0 : len = atoi(value);
282 [ # # ]: 0 : if (len < 0 || len > 3)
283 : : return -2;
284 : 0 : dctx->rfc5114_param = len;
285 : 0 : return 1;
286 : : }
287 [ # # ]: 0 : if (!strcmp(type, "dh_paramgen_generator"))
288 : : {
289 : : int len;
290 : 0 : len = atoi(value);
291 : 0 : return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
292 : : }
293 [ # # ]: 0 : if (!strcmp(type, "dh_paramgen_subprime_len"))
294 : : {
295 : : int len;
296 : 0 : len = atoi(value);
297 : 0 : return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
298 : : }
299 [ # # ]: 0 : if (!strcmp(type, "dh_paramgen_type"))
300 : : {
301 : : int typ;
302 : 0 : typ = atoi(value);
303 : 0 : return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
304 : : }
305 : : return -2;
306 : : }
307 : :
308 : : #ifndef OPENSSL_NO_DSA
309 : :
310 : : extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
311 : : const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
312 : : unsigned char *seed_out,
313 : : int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
314 : :
315 : : extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
316 : : const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
317 : : int idx, unsigned char *seed_out,
318 : : int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
319 : :
320 : 0 : static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
321 : : {
322 : : DSA *ret;
323 : 0 : int rv = 0;
324 : 0 : int prime_len = dctx->prime_len;
325 : 0 : int subprime_len = dctx->subprime_len;
326 : 0 : const EVP_MD *md = dctx->md;
327 [ # # ]: 0 : if (dctx->use_dsa > 2)
328 : : return NULL;
329 : 0 : ret = DSA_new();
330 [ # # ]: 0 : if (!ret)
331 : : return NULL;
332 [ # # ]: 0 : if (subprime_len == -1)
333 : : {
334 [ # # ]: 0 : if (prime_len >= 2048)
335 : : subprime_len = 256;
336 : : else
337 : 0 : subprime_len = 160;
338 : : }
339 [ # # ]: 0 : if (md == NULL)
340 : : {
341 [ # # ]: 0 : if (prime_len >= 2048)
342 : 0 : md = EVP_sha256();
343 : : else
344 : 0 : md = EVP_sha1();
345 : : }
346 [ # # ]: 0 : if (dctx->use_dsa == 1)
347 : 0 : rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
348 : : NULL, 0, NULL, NULL, NULL, pcb);
349 [ # # ]: 0 : else if(dctx->use_dsa == 2)
350 : 0 : rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
351 : : NULL, 0, -1, NULL, NULL, NULL, pcb);
352 [ # # ]: 0 : if (rv <= 0)
353 : : {
354 : 0 : DSA_free(ret);
355 : 0 : return NULL;
356 : : }
357 : : return ret;
358 : : }
359 : :
360 : : #endif
361 : :
362 : 0 : static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
363 : : {
364 : 0 : DH *dh = NULL;
365 : 0 : DH_PKEY_CTX *dctx = ctx->data;
366 : : BN_GENCB *pcb, cb;
367 : : int ret;
368 [ # # ]: 0 : if (dctx->rfc5114_param)
369 : : {
370 [ # # # # ]: 0 : switch (dctx->rfc5114_param)
371 : : {
372 : : case 1:
373 : 0 : dh = DH_get_1024_160();
374 : 0 : break;
375 : :
376 : : case 2:
377 : 0 : dh = DH_get_2048_224();
378 : 0 : break;
379 : :
380 : : case 3:
381 : 0 : dh = DH_get_2048_256();
382 : 0 : break;
383 : :
384 : : default:
385 : : return -2;
386 : : }
387 : 0 : EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
388 : 0 : return 1;
389 : : }
390 : :
391 [ # # ]: 0 : if (ctx->pkey_gencb)
392 : : {
393 : 0 : pcb = &cb;
394 : 0 : evp_pkey_set_cb_translate(pcb, ctx);
395 : : }
396 : : else
397 : : pcb = NULL;
398 : : #ifndef OPENSSL_NO_DSA
399 [ # # ]: 0 : if (dctx->use_dsa)
400 : : {
401 : : DSA *dsa_dh;
402 : 0 : dsa_dh = dsa_dh_generate(dctx, pcb);
403 [ # # ]: 0 : if (!dsa_dh)
404 : : return 0;
405 : 0 : dh = DSA_dup_DH(dsa_dh);
406 : 0 : DSA_free(dsa_dh);
407 [ # # ]: 0 : if (!dh)
408 : : return 0;
409 : 0 : EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
410 : 0 : return 1;
411 : : }
412 : : #endif
413 : 0 : dh = DH_new();
414 [ # # ]: 0 : if (!dh)
415 : : return 0;
416 : 0 : ret = DH_generate_parameters_ex(dh,
417 : : dctx->prime_len, dctx->generator, pcb);
418 : :
419 [ # # ]: 0 : if (ret)
420 : 0 : EVP_PKEY_assign_DH(pkey, dh);
421 : : else
422 : 0 : DH_free(dh);
423 : 0 : return ret;
424 : : }
425 : :
426 : 1 : static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
427 : : {
428 : 1 : DH *dh = NULL;
429 [ - + ]: 1 : if (ctx->pkey == NULL)
430 : : {
431 : 0 : DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
432 : 0 : return 0;
433 : : }
434 : 1 : dh = DH_new();
435 [ + - ]: 1 : if (!dh)
436 : : return 0;
437 : 1 : EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
438 : : /* Note: if error return, pkey is freed by parent routine */
439 [ + - ]: 1 : if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
440 : : return 0;
441 : 1 : return DH_generate_key(pkey->pkey.dh);
442 : : }
443 : :
444 : 2 : static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
445 : : {
446 : : int ret;
447 : : DH *dh;
448 : 2 : DH_PKEY_CTX *dctx = ctx->data;
449 : : BIGNUM *dhpub;
450 [ + - ][ - + ]: 2 : if (!ctx->pkey || !ctx->peerkey)
451 : : {
452 : 0 : DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
453 : 0 : return 0;
454 : : }
455 : 2 : dh = ctx->pkey->pkey.dh;
456 : 2 : dhpub = ctx->peerkey->pkey.dh->pub_key;
457 [ - + ]: 2 : if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE)
458 : : {
459 [ # # ]: 0 : if (key == NULL)
460 : : {
461 : 0 : *keylen = DH_size(dh);
462 : 0 : return 1;
463 : : }
464 : 0 : ret = DH_compute_key(key, dhpub, dh);
465 [ # # ]: 0 : if (ret < 0)
466 : : return ret;
467 : 0 : *keylen = ret;
468 : 0 : return 1;
469 : : }
470 [ + - ]: 2 : else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42)
471 : : {
472 : 2 : unsigned char *Z = NULL;
473 : 2 : size_t Zlen = 0;
474 [ + - ][ + - ]: 2 : if (!dctx->kdf_outlen || !dctx->kdf_oid)
475 : : return 0;
476 [ - + ]: 2 : if (key == NULL)
477 : : {
478 : 0 : *keylen = dctx->kdf_outlen;
479 : 0 : return 1;
480 : : }
481 [ + - ]: 2 : if (*keylen != dctx->kdf_outlen)
482 : : return 0;
483 : 2 : ret = 0;
484 : 2 : Zlen = DH_size(dh);
485 : 2 : Z = OPENSSL_malloc(Zlen);
486 [ + - ]: 2 : if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
487 : : goto err;
488 [ + - ]: 2 : if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
489 : 2 : dctx->kdf_ukm, dctx->kdf_ukmlen,
490 : : dctx->kdf_md))
491 : : goto err;
492 : 2 : *keylen = dctx->kdf_outlen;
493 : 2 : ret = 1;
494 : : err:
495 [ + - ]: 2 : if (Z)
496 : : {
497 : 2 : OPENSSL_cleanse(Z, Zlen);
498 : 2 : OPENSSL_free(Z);
499 : : }
500 : 2 : return ret;
501 : : }
502 : : return 1;
503 : : }
504 : :
505 : : const EVP_PKEY_METHOD dh_pkey_meth =
506 : : {
507 : : EVP_PKEY_DH,
508 : : 0,
509 : : pkey_dh_init,
510 : : pkey_dh_copy,
511 : : pkey_dh_cleanup,
512 : :
513 : : 0,
514 : : pkey_dh_paramgen,
515 : :
516 : : 0,
517 : : pkey_dh_keygen,
518 : :
519 : : 0,
520 : : 0,
521 : :
522 : : 0,
523 : : 0,
524 : :
525 : : 0,0,
526 : :
527 : : 0,0,0,0,
528 : :
529 : : 0,0,
530 : :
531 : : 0,0,
532 : :
533 : : 0,
534 : : pkey_dh_derive,
535 : :
536 : : pkey_dh_ctrl,
537 : : pkey_dh_ctrl_str
538 : :
539 : : };
540 : :
541 : : const EVP_PKEY_METHOD dhx_pkey_meth =
542 : : {
543 : : EVP_PKEY_DHX,
544 : : 0,
545 : : pkey_dh_init,
546 : : pkey_dh_copy,
547 : : pkey_dh_cleanup,
548 : :
549 : : 0,
550 : : pkey_dh_paramgen,
551 : :
552 : : 0,
553 : : pkey_dh_keygen,
554 : :
555 : : 0,
556 : : 0,
557 : :
558 : : 0,
559 : : 0,
560 : :
561 : : 0,0,
562 : :
563 : : 0,0,0,0,
564 : :
565 : : 0,0,
566 : :
567 : : 0,0,
568 : :
569 : : 0,
570 : : pkey_dh_derive,
571 : :
572 : : pkey_dh_ctrl,
573 : : pkey_dh_ctrl_str
574 : :
575 : : };
|