]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/bind9/lib/dns/opensslecdsa_link.c
Fix remote denial of service vulnerability when parsing malformed
[FreeBSD/releng/9.3.git] / contrib / bind9 / lib / dns / opensslecdsa_link.c
1 /*
2  * Copyright (C) 2012-2014  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <config.h>
18
19 #ifdef HAVE_OPENSSL_ECDSA
20
21 #if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384)
22 #error "ECDSA without EVP for SHA2?"
23 #endif
24
25 #include <isc/entropy.h>
26 #include <isc/mem.h>
27 #include <isc/sha2.h>
28 #include <isc/string.h>
29 #include <isc/util.h>
30
31 #include <dns/keyvalues.h>
32 #include <dst/result.h>
33
34 #include "dst_internal.h"
35 #include "dst_openssl.h"
36 #include "dst_parse.h"
37
38 #include <openssl/err.h>
39 #include <openssl/objects.h>
40 #include <openssl/ecdsa.h>
41 #include <openssl/bn.h>
42
43 #ifndef NID_X9_62_prime256v1
44 #error "P-256 group is not known (NID_X9_62_prime256v1)"
45 #endif
46 #ifndef NID_secp384r1
47 #error "P-384 group is not known (NID_secp384r1)"
48 #endif
49
50 #define DST_RET(a) {ret = a; goto err;}
51
52 static isc_result_t opensslecdsa_todns(const dst_key_t *key,
53                                        isc_buffer_t *data);
54
55 static isc_result_t
56 opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
57         EVP_MD_CTX *evp_md_ctx;
58         const EVP_MD *type = NULL;
59
60         UNUSED(key);
61         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
62                 dctx->key->key_alg == DST_ALG_ECDSA384);
63
64         evp_md_ctx = EVP_MD_CTX_create();
65         if (evp_md_ctx == NULL)
66                 return (ISC_R_NOMEMORY);
67         if (dctx->key->key_alg == DST_ALG_ECDSA256)
68                 type = EVP_sha256();
69         else
70                 type = EVP_sha384();
71
72         if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
73                 EVP_MD_CTX_destroy(evp_md_ctx);
74                 return (dst__openssl_toresult3(dctx->category,
75                                                "EVP_DigestInit_ex",
76                                                ISC_R_FAILURE));
77         }
78
79         dctx->ctxdata.evp_md_ctx = evp_md_ctx;
80
81         return (ISC_R_SUCCESS);
82 }
83
84 static void
85 opensslecdsa_destroyctx(dst_context_t *dctx) {
86         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
87
88         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
89                 dctx->key->key_alg == DST_ALG_ECDSA384);
90
91         if (evp_md_ctx != NULL) {
92                 EVP_MD_CTX_destroy(evp_md_ctx);
93                 dctx->ctxdata.evp_md_ctx = NULL;
94         }
95 }
96
97 static isc_result_t
98 opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
99         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
100
101         REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
102                 dctx->key->key_alg == DST_ALG_ECDSA384);
103
104         if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
105                 return (dst__openssl_toresult3(dctx->category,
106                                                "EVP_DigestUpdate",
107                                                ISC_R_FAILURE));
108
109         return (ISC_R_SUCCESS);
110 }
111
112 static int
113 BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
114         int bytes = size - BN_num_bytes(bn);
115
116         while (bytes-- > 0)
117                 *buf++ = 0;
118         BN_bn2bin(bn, buf);
119         return (size);
120 }
121
122 static isc_result_t
123 opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
124         isc_result_t ret;
125         dst_key_t *key = dctx->key;
126         isc_region_t r;
127         ECDSA_SIG *ecdsasig;
128         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
129         EVP_PKEY *pkey = key->keydata.pkey;
130         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
131         unsigned int dgstlen, siglen;
132         unsigned char digest[EVP_MAX_MD_SIZE];
133
134         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
135                 key->key_alg == DST_ALG_ECDSA384);
136
137         if (eckey == NULL)
138                 return (ISC_R_FAILURE);
139
140         if (key->key_alg == DST_ALG_ECDSA256)
141                 siglen = DNS_SIG_ECDSA256SIZE;
142         else
143                 siglen = DNS_SIG_ECDSA384SIZE;
144
145         isc_buffer_availableregion(sig, &r);
146         if (r.length < siglen)
147                 DST_RET(ISC_R_NOSPACE);
148
149         if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen))
150                 DST_RET(dst__openssl_toresult3(dctx->category,
151                                                "EVP_DigestFinal",
152                                                ISC_R_FAILURE));
153
154         ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey);
155         if (ecdsasig == NULL)
156                 DST_RET(dst__openssl_toresult3(dctx->category,
157                                                "ECDSA_do_sign",
158                                                DST_R_SIGNFAILURE));
159         BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2);
160         isc_region_consume(&r, siglen / 2);
161         BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2);
162         isc_region_consume(&r, siglen / 2);
163         ECDSA_SIG_free(ecdsasig);
164         isc_buffer_add(sig, siglen);
165         ret = ISC_R_SUCCESS;
166
167  err:
168         if (eckey != NULL)
169                 EC_KEY_free(eckey);
170         return (ret);
171 }
172
173 static isc_result_t
174 opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
175         isc_result_t ret;
176         dst_key_t *key = dctx->key;
177         int status;
178         unsigned char *cp = sig->base;
179         ECDSA_SIG *ecdsasig = NULL;
180         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
181         EVP_PKEY *pkey = key->keydata.pkey;
182         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
183         unsigned int dgstlen, siglen;
184         unsigned char digest[EVP_MAX_MD_SIZE];
185
186         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
187                 key->key_alg == DST_ALG_ECDSA384);
188
189         if (eckey == NULL)
190                 return (ISC_R_FAILURE);
191
192         if (key->key_alg == DST_ALG_ECDSA256)
193                 siglen = DNS_SIG_ECDSA256SIZE;
194         else
195                 siglen = DNS_SIG_ECDSA384SIZE;
196
197         if (sig->length != siglen)
198                 return (DST_R_VERIFYFAILURE);
199
200         if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
201                 DST_RET (dst__openssl_toresult3(dctx->category,
202                                                 "EVP_DigestFinal_ex",
203                                                 ISC_R_FAILURE));
204
205         ecdsasig = ECDSA_SIG_new();
206         if (ecdsasig == NULL)
207                 DST_RET (ISC_R_NOMEMORY);
208         if (ecdsasig->r != NULL)
209                 BN_free(ecdsasig->r);
210         ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
211         cp += siglen / 2;
212         if (ecdsasig->s != NULL)
213                 BN_free(ecdsasig->s);
214         ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
215         /* cp += siglen / 2; */
216
217         status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
218         switch (status) {
219         case 1:
220                 ret = ISC_R_SUCCESS;
221                 break;
222         case 0:
223                 ret = dst__openssl_toresult(DST_R_VERIFYFAILURE);
224                 break;
225         default:
226                 ret = dst__openssl_toresult3(dctx->category,
227                                              "ECDSA_do_verify",
228                                              DST_R_VERIFYFAILURE);
229                 break;
230         }
231
232  err:
233         if (ecdsasig != NULL)
234                 ECDSA_SIG_free(ecdsasig);
235         if (eckey != NULL)
236                 EC_KEY_free(eckey);
237         return (ret);
238 }
239
240 static isc_boolean_t
241 opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
242         isc_boolean_t ret;
243         int status;
244         EVP_PKEY *pkey1 = key1->keydata.pkey;
245         EVP_PKEY *pkey2 = key2->keydata.pkey;
246         EC_KEY *eckey1 = NULL;
247         EC_KEY *eckey2 = NULL;
248         const BIGNUM *priv1, *priv2;
249
250         if (pkey1 == NULL && pkey2 == NULL)
251                 return (ISC_TRUE);
252         else if (pkey1 == NULL || pkey2 == NULL)
253                 return (ISC_FALSE);
254
255         eckey1 = EVP_PKEY_get1_EC_KEY(pkey1);
256         eckey2 = EVP_PKEY_get1_EC_KEY(pkey2);
257         if (eckey1 == NULL && eckey2 == NULL) {
258                 DST_RET (ISC_TRUE);
259         } else if (eckey1 == NULL || eckey2 == NULL)
260                 DST_RET (ISC_FALSE);
261
262         status = EVP_PKEY_cmp(pkey1, pkey2);
263         if (status != 1)
264                 DST_RET (ISC_FALSE);
265
266         priv1 = EC_KEY_get0_private_key(eckey1);
267         priv2 = EC_KEY_get0_private_key(eckey2);
268         if (priv1 != NULL || priv2 != NULL) {
269                 if (priv1 == NULL || priv2 == NULL)
270                         DST_RET (ISC_FALSE);
271                 if (BN_cmp(priv1, priv2) != 0)
272                         DST_RET (ISC_FALSE);
273         }
274         ret = ISC_TRUE;
275
276  err:
277         if (eckey1 != NULL)
278                 EC_KEY_free(eckey1);
279         if (eckey2 != NULL)
280                 EC_KEY_free(eckey2);
281         return (ret);
282 }
283
284 static isc_result_t
285 opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
286         isc_result_t ret;
287         EVP_PKEY *pkey;
288         EC_KEY *eckey = NULL;
289         int group_nid;
290
291         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
292                 key->key_alg == DST_ALG_ECDSA384);
293         UNUSED(unused);
294         UNUSED(callback);
295
296         if (key->key_alg == DST_ALG_ECDSA256)
297                 group_nid = NID_X9_62_prime256v1;
298         else
299                 group_nid = NID_secp384r1;
300
301         eckey = EC_KEY_new_by_curve_name(group_nid);
302         if (eckey == NULL)
303                 return (dst__openssl_toresult2("EC_KEY_new_by_curve_name",
304                                                DST_R_OPENSSLFAILURE));
305
306         if (EC_KEY_generate_key(eckey) != 1)
307                 DST_RET (dst__openssl_toresult2("EC_KEY_generate_key",
308                                                 DST_R_OPENSSLFAILURE));
309
310         pkey = EVP_PKEY_new();
311         if (pkey == NULL)
312                 DST_RET (ISC_R_NOMEMORY);
313         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
314                 EVP_PKEY_free(pkey);
315                 DST_RET (ISC_R_FAILURE);
316         }
317         key->keydata.pkey = pkey;
318         ret = ISC_R_SUCCESS;
319
320  err:
321         if (eckey != NULL)
322                 EC_KEY_free(eckey);
323         return (ret);
324 }
325
326 static isc_boolean_t
327 opensslecdsa_isprivate(const dst_key_t *key) {
328         isc_boolean_t ret;
329         EVP_PKEY *pkey = key->keydata.pkey;
330         EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
331
332         ret = ISC_TF(eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL);
333         if (eckey != NULL)
334                 EC_KEY_free(eckey);
335         return (ret);
336 }
337
338 static void
339 opensslecdsa_destroy(dst_key_t *key) {
340         EVP_PKEY *pkey = key->keydata.pkey;
341
342         EVP_PKEY_free(pkey);
343         key->keydata.pkey = NULL;
344 }
345
346 static isc_result_t
347 opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) {
348         isc_result_t ret;
349         EVP_PKEY *pkey;
350         EC_KEY *eckey = NULL;
351         isc_region_t r;
352         int len;
353         unsigned char *cp;
354         unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
355
356         REQUIRE(key->keydata.pkey != NULL);
357
358         pkey = key->keydata.pkey;
359         eckey = EVP_PKEY_get1_EC_KEY(pkey);
360         if (eckey == NULL)
361                 return (dst__openssl_toresult(ISC_R_FAILURE));
362         len = i2o_ECPublicKey(eckey, NULL);
363         /* skip form */
364         len--;
365
366         isc_buffer_availableregion(data, &r);
367         if (r.length < (unsigned int) len)
368                 DST_RET (ISC_R_NOSPACE);
369         cp = buf;
370         if (!i2o_ECPublicKey(eckey, &cp))
371                 DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
372         memmove(r.base, buf + 1, len);
373         isc_buffer_add(data, len);
374         ret = ISC_R_SUCCESS;
375
376  err:
377         if (eckey != NULL)
378                 EC_KEY_free(eckey);
379         return (ret);
380 }
381
382 static isc_result_t
383 opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
384         isc_result_t ret;
385         EVP_PKEY *pkey;
386         EC_KEY *eckey = NULL;
387         isc_region_t r;
388         int group_nid;
389         unsigned int len;
390         const unsigned char *cp;
391         unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
392
393         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
394                 key->key_alg == DST_ALG_ECDSA384);
395
396         if (key->key_alg == DST_ALG_ECDSA256) {
397                 len = DNS_KEY_ECDSA256SIZE;
398                 group_nid = NID_X9_62_prime256v1;
399         } else {
400                 len = DNS_KEY_ECDSA384SIZE;
401                 group_nid = NID_secp384r1;
402         }
403
404         isc_buffer_remainingregion(data, &r);
405         if (r.length == 0)
406                 return (ISC_R_SUCCESS);
407         if (r.length < len)
408                 return (DST_R_INVALIDPUBLICKEY);
409
410         eckey = EC_KEY_new_by_curve_name(group_nid);
411         if (eckey == NULL)
412                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
413
414         buf[0] = POINT_CONVERSION_UNCOMPRESSED;
415         memmove(buf + 1, r.base, len);
416         cp = buf;
417         if (o2i_ECPublicKey(&eckey,
418                             (const unsigned char **) &cp,
419                             (long) len + 1) == NULL)
420                 DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
421         if (EC_KEY_check_key(eckey) != 1)
422                 DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
423
424         pkey = EVP_PKEY_new();
425         if (pkey == NULL)
426                 DST_RET (ISC_R_NOMEMORY);
427         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
428                 EVP_PKEY_free(pkey);
429                 DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
430         }
431
432         isc_buffer_forward(data, len);
433         key->keydata.pkey = pkey;
434         ret = ISC_R_SUCCESS;
435
436  err:
437         if (eckey != NULL)
438                 EC_KEY_free(eckey);
439         return (ret);
440 }
441
442 static isc_result_t
443 opensslecdsa_tofile(const dst_key_t *key, const char *directory) {
444         isc_result_t ret;
445         EVP_PKEY *pkey;
446         EC_KEY *eckey = NULL;
447         const BIGNUM *privkey;
448         dst_private_t priv;
449         unsigned char *buf = NULL;
450
451         if (key->keydata.pkey == NULL)
452                 return (DST_R_NULLKEY);
453
454         if (key->external) {
455                 priv.nelements = 0;
456                 return (dst__privstruct_writefile(key, &priv, directory));
457         }
458
459         pkey = key->keydata.pkey;
460         eckey = EVP_PKEY_get1_EC_KEY(pkey);
461         if (eckey == NULL)
462                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
463         privkey = EC_KEY_get0_private_key(eckey);
464         if (privkey == NULL)
465                 DST_RET (ISC_R_FAILURE);
466
467         buf = isc_mem_get(key->mctx, BN_num_bytes(privkey));
468         if (buf == NULL)
469                 DST_RET (ISC_R_NOMEMORY);
470
471         priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY;
472         priv.elements[0].length = BN_num_bytes(privkey);
473         BN_bn2bin(privkey, buf);
474         priv.elements[0].data = buf;
475         priv.nelements = ECDSA_NTAGS;
476         ret = dst__privstruct_writefile(key, &priv, directory);
477
478  err:
479         if (eckey != NULL)
480                 EC_KEY_free(eckey);
481         if (buf != NULL)
482                 isc_mem_put(key->mctx, buf, BN_num_bytes(privkey));
483         return (ret);
484 }
485
486 static isc_result_t
487 ecdsa_check(EC_KEY *eckey, dst_key_t *pub)
488 {
489         isc_result_t ret = ISC_R_FAILURE;
490         EVP_PKEY *pkey;
491         EC_KEY *pubeckey = NULL;
492         const EC_POINT *pubkey;
493
494         if (pub == NULL)
495                 return (ISC_R_SUCCESS);
496         pkey = pub->keydata.pkey;
497         if (pkey == NULL)
498                 return (ISC_R_SUCCESS);
499         pubeckey = EVP_PKEY_get1_EC_KEY(pkey);
500         if (pubeckey == NULL)
501                 return (ISC_R_SUCCESS);
502         pubkey = EC_KEY_get0_public_key(pubeckey);
503         if (pubkey == NULL)
504                 DST_RET (ISC_R_SUCCESS);
505         if (EC_KEY_set_public_key(eckey, pubkey) != 1)
506                 DST_RET (ISC_R_SUCCESS);
507         if (EC_KEY_check_key(eckey) == 1)
508                 DST_RET (ISC_R_SUCCESS);
509
510  err:
511         if (pubeckey != NULL)
512                 EC_KEY_free(pubeckey);
513         return (ret);
514 }
515
516 static isc_result_t
517 opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
518         dst_private_t priv;
519         isc_result_t ret;
520         EVP_PKEY *pkey, *pubpkey;
521         EC_KEY *eckey = NULL, *pubeckey = NULL;
522         const EC_POINT *pubkey;
523         BIGNUM *privkey;
524         int group_nid;
525         isc_mem_t *mctx = key->mctx;
526
527         REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
528                 key->key_alg == DST_ALG_ECDSA384);
529
530         if (key->key_alg == DST_ALG_ECDSA256)
531                 group_nid = NID_X9_62_prime256v1;
532         else
533                 group_nid = NID_secp384r1;
534
535         eckey = EC_KEY_new_by_curve_name(group_nid);
536         if (eckey == NULL)
537                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
538
539         /* read private key file */
540         ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
541         if (ret != ISC_R_SUCCESS)
542                 goto err;
543
544         if (key->external) {
545                 /*
546                  * Copy the public key to this new key.
547                  */
548                 if (pub == NULL)
549                         DST_RET(DST_R_INVALIDPRIVATEKEY);
550                 pubpkey = pub->keydata.pkey;
551                 pubeckey = EVP_PKEY_get1_EC_KEY(pubpkey);
552                 if (pubeckey == NULL)
553                         DST_RET(DST_R_INVALIDPRIVATEKEY);
554                 pubkey = EC_KEY_get0_public_key(pubeckey);
555                 if (pubkey == NULL)
556                         DST_RET(DST_R_INVALIDPRIVATEKEY);
557                 if (EC_KEY_set_public_key(eckey, pubkey) != 1)
558                         DST_RET(DST_R_INVALIDPRIVATEKEY);
559                 if (EC_KEY_check_key(eckey) != 1)
560                         DST_RET(DST_R_INVALIDPRIVATEKEY);
561         } else {
562                 privkey = BN_bin2bn(priv.elements[0].data,
563                                     priv.elements[0].length, NULL);
564                 if (privkey == NULL)
565                         DST_RET(ISC_R_NOMEMORY);
566                 if (!EC_KEY_set_private_key(eckey, privkey))
567                         DST_RET(ISC_R_NOMEMORY);
568                 if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS)
569                         DST_RET(DST_R_INVALIDPRIVATEKEY);
570                 dst__privstruct_free(&priv, mctx);
571                 memset(&priv, 0, sizeof(priv));
572         }
573
574         pkey = EVP_PKEY_new();
575         if (pkey == NULL)
576                 DST_RET (ISC_R_NOMEMORY);
577         if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
578                 EVP_PKEY_free(pkey);
579                 DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
580         }
581         key->keydata.pkey = pkey;
582         ret = ISC_R_SUCCESS;
583
584  err:
585         if (eckey != NULL)
586                 EC_KEY_free(eckey);
587         if (pubeckey != NULL)
588                 EC_KEY_free(pubeckey);
589         dst__privstruct_free(&priv, mctx);
590         memset(&priv, 0, sizeof(priv));
591         return (ret);
592 }
593
594 static dst_func_t opensslecdsa_functions = {
595         opensslecdsa_createctx,
596         opensslecdsa_destroyctx,
597         opensslecdsa_adddata,
598         opensslecdsa_sign,
599         opensslecdsa_verify,
600         NULL, /*%< verify2 */
601         NULL, /*%< computesecret */
602         opensslecdsa_compare,
603         NULL, /*%< paramcompare */
604         opensslecdsa_generate,
605         opensslecdsa_isprivate,
606         opensslecdsa_destroy,
607         opensslecdsa_todns,
608         opensslecdsa_fromdns,
609         opensslecdsa_tofile,
610         opensslecdsa_parse,
611         NULL, /*%< cleanup */
612         NULL, /*%< fromlabel */
613         NULL, /*%< dump */
614         NULL, /*%< restore */
615 };
616
617 isc_result_t
618 dst__opensslecdsa_init(dst_func_t **funcp) {
619         REQUIRE(funcp != NULL);
620         if (*funcp == NULL)
621                 *funcp = &opensslecdsa_functions;
622         return (ISC_R_SUCCESS);
623 }
624
625 #else /* HAVE_OPENSSL_ECDSA */
626
627 #include <isc/util.h>
628
629 EMPTY_TRANSLATION_UNIT
630
631 #endif /* HAVE_OPENSSL_ECDSA */
632 /*! \file */