xref: /freebsd/contrib/unbound/sldns/keyraw.c (revision c1d255d3)
1 /*
2  * keyraw.c - raw key operations and conversions
3  *
4  * (c) NLnet Labs, 2004-2008
5  *
6  * See the file LICENSE for the license
7  */
8 /**
9  * \file
10  * Implementation of raw DNSKEY functions (work on wire rdata).
11  */
12 
13 #include "config.h"
14 #include "sldns/keyraw.h"
15 #include "sldns/rrdef.h"
16 
17 #ifdef HAVE_SSL
18 #include <openssl/ssl.h>
19 #include <openssl/evp.h>
20 #include <openssl/rand.h>
21 #include <openssl/err.h>
22 #include <openssl/md5.h>
23 #ifdef HAVE_OPENSSL_ENGINE_H
24 #  include <openssl/engine.h>
25 #endif
26 #ifdef HAVE_OPENSSL_BN_H
27 #include <openssl/bn.h>
28 #endif
29 #ifdef HAVE_OPENSSL_PARAM_BUILD_H
30 #  include <openssl/param_build.h>
31 #else
32 #  ifdef HAVE_OPENSSL_RSA_H
33 #  include <openssl/rsa.h>
34 #  endif
35 #  ifdef HAVE_OPENSSL_DSA_H
36 #  include <openssl/dsa.h>
37 #  endif
38 #endif
39 #endif /* HAVE_SSL */
40 
41 size_t
42 sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
43 	const size_t len, int alg)
44 {
45 	/* for DSA keys */
46 	uint8_t t;
47 
48 	/* for RSA keys */
49 	uint16_t exp;
50 	uint16_t int16;
51 
52 	switch ((sldns_algorithm)alg) {
53 	case LDNS_DSA:
54 	case LDNS_DSA_NSEC3:
55 		if (len > 0) {
56 			t = keydata[0];
57 			return (64 + t*8)*8;
58 		} else {
59 			return 0;
60 		}
61 		break;
62 	case LDNS_RSAMD5:
63 	case LDNS_RSASHA1:
64 	case LDNS_RSASHA1_NSEC3:
65 #ifdef USE_SHA2
66 	case LDNS_RSASHA256:
67 	case LDNS_RSASHA512:
68 #endif
69 		if (len > 0) {
70 			if (keydata[0] == 0) {
71 				/* big exponent */
72 				if (len > 3) {
73 					memmove(&int16, keydata + 1, 2);
74 					exp = ntohs(int16);
75 					return (len - exp - 3)*8;
76 				} else {
77 					return 0;
78 				}
79 			} else {
80 				exp = keydata[0];
81 				return (len-exp-1)*8;
82 			}
83 		} else {
84 			return 0;
85 		}
86 		break;
87 #ifdef USE_GOST
88 	case LDNS_ECC_GOST:
89 		return 512;
90 #endif
91 #ifdef USE_ECDSA
92         case LDNS_ECDSAP256SHA256:
93                 return 256;
94         case LDNS_ECDSAP384SHA384:
95                 return 384;
96 #endif
97 #ifdef USE_ED25519
98 	case LDNS_ED25519:
99 		return 256;
100 #endif
101 #ifdef USE_ED448
102 	case LDNS_ED448:
103 		return 456;
104 #endif
105 	default:
106 		return 0;
107 	}
108 }
109 
110 uint16_t sldns_calc_keytag_raw(uint8_t* key, size_t keysize)
111 {
112 	if(keysize < 4) {
113 		return 0;
114 	}
115 	/* look at the algorithm field, copied from 2535bis */
116 	if (key[3] == LDNS_RSAMD5) {
117 		uint16_t ac16 = 0;
118 		if (keysize > 4) {
119 			memmove(&ac16, key + keysize - 3, 2);
120 		}
121 		ac16 = ntohs(ac16);
122 		return (uint16_t) ac16;
123 	} else {
124 		size_t i;
125 		uint32_t ac32 = 0;
126 		for (i = 0; i < keysize; ++i) {
127 			ac32 += (i & 1) ? key[i] : key[i] << 8;
128 		}
129 		ac32 += (ac32 >> 16) & 0xFFFF;
130 		return (uint16_t) (ac32 & 0xFFFF);
131 	}
132 }
133 
134 #ifdef HAVE_SSL
135 #ifdef USE_GOST
136 /** store GOST engine reference loaded into OpenSSL library */
137 ENGINE* sldns_gost_engine = NULL;
138 
139 int
140 sldns_key_EVP_load_gost_id(void)
141 {
142 	static int gost_id = 0;
143 	const EVP_PKEY_ASN1_METHOD* meth;
144 	ENGINE* e;
145 
146 	if(gost_id) return gost_id;
147 
148 	/* see if configuration loaded gost implementation from other engine*/
149 	meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
150 	if(meth) {
151 		EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
152 		return gost_id;
153 	}
154 
155 	/* see if engine can be loaded already */
156 	e = ENGINE_by_id("gost");
157 	if(!e) {
158 		/* load it ourself, in case statically linked */
159 		ENGINE_load_builtin_engines();
160 		ENGINE_load_dynamic();
161 		e = ENGINE_by_id("gost");
162 	}
163 	if(!e) {
164 		/* no gost engine in openssl */
165 		return 0;
166 	}
167 	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
168 		ENGINE_finish(e);
169 		ENGINE_free(e);
170 		return 0;
171 	}
172 
173 	meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
174 	if(!meth) {
175 		/* algo not found */
176 		ENGINE_finish(e);
177 		ENGINE_free(e);
178 		return 0;
179 	}
180         /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
181          * on some platforms this frees up the meth and unloads gost stuff */
182         sldns_gost_engine = e;
183 
184 	EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
185 	return gost_id;
186 }
187 
188 void sldns_key_EVP_unload_gost(void)
189 {
190         if(sldns_gost_engine) {
191                 ENGINE_finish(sldns_gost_engine);
192                 ENGINE_free(sldns_gost_engine);
193                 sldns_gost_engine = NULL;
194         }
195 }
196 #endif /* USE_GOST */
197 
198 /* Retrieve params as BIGNUM from raw buffer */
199 static int
200 sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
201 	BIGNUM** q, BIGNUM** g, BIGNUM** y)
202 {
203 	uint8_t T;
204 	uint16_t length;
205 	uint16_t offset;
206 
207 	if(len == 0)
208 		return 0;
209 	T = (uint8_t)key[0];
210 	length = (64 + T * 8);
211 	offset = 1;
212 
213 	if (T > 8) {
214 		return 0;
215 	}
216 	if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
217 		return 0;
218 
219 	*q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
220 	offset += SHA_DIGEST_LENGTH;
221 
222 	*p = BN_bin2bn(key+offset, (int)length, NULL);
223 	offset += length;
224 
225 	*g = BN_bin2bn(key+offset, (int)length, NULL);
226 	offset += length;
227 
228 	*y = BN_bin2bn(key+offset, (int)length, NULL);
229 
230 	if(!*q || !*p || !*g || !*y) {
231 		BN_free(*q);
232 		BN_free(*p);
233 		BN_free(*g);
234 		BN_free(*y);
235 		return 0;
236 	}
237 	return 1;
238 }
239 
240 #ifndef HAVE_OSSL_PARAM_BLD_NEW
241 DSA *
242 sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
243 {
244 	DSA *dsa;
245 	BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL;
246 	if(!sldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) {
247 		return NULL;
248 	}
249 	/* create the key and set its properties */
250 	if(!(dsa = DSA_new())) {
251 		return NULL;
252 	}
253 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
254 #ifndef S_SPLINT_S
255 	dsa->p = P;
256 	dsa->q = Q;
257 	dsa->g = G;
258 	dsa->pub_key = Y;
259 #endif /* splint */
260 
261 #else /* OPENSSL_VERSION_NUMBER */
262 	if (!DSA_set0_pqg(dsa, P, Q, G)) {
263 		/* QPG not yet attached, need to free */
264 		BN_free(Q);
265 		BN_free(P);
266 		BN_free(G);
267 
268 		DSA_free(dsa);
269 		BN_free(Y);
270 		return NULL;
271 	}
272 	if (!DSA_set0_key(dsa, Y, NULL)) {
273 		/* QPG attached, cleaned up by DSA_fre() */
274 		DSA_free(dsa);
275 		BN_free(Y);
276 		return NULL;
277 	}
278 #endif
279 
280 	return dsa;
281 }
282 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
283 
284 EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
285 {
286 #ifdef HAVE_OSSL_PARAM_BLD_NEW
287 	EVP_PKEY* evp_key = NULL;
288 	EVP_PKEY_CTX* ctx;
289 	BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL;
290 	OSSL_PARAM_BLD* param_bld;
291 	OSSL_PARAM* params = NULL;
292 	if(!sldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) {
293 		return NULL;
294 	}
295 
296 	param_bld = OSSL_PARAM_BLD_new();
297 	if(!param_bld) {
298 		BN_free(p);
299 		BN_free(q);
300 		BN_free(g);
301 		BN_free(y);
302 		return NULL;
303 	}
304 	if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) ||
305 	   !OSSL_PARAM_BLD_push_BN(param_bld, "g", g) ||
306 	   !OSSL_PARAM_BLD_push_BN(param_bld, "q", q) ||
307 	   !OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) {
308 		OSSL_PARAM_BLD_free(param_bld);
309 		BN_free(p);
310 		BN_free(q);
311 		BN_free(g);
312 		BN_free(y);
313 		return NULL;
314 	}
315 	params = OSSL_PARAM_BLD_to_param(param_bld);
316 	OSSL_PARAM_BLD_free(param_bld);
317 
318 	ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
319 	if(!ctx) {
320 		OSSL_PARAM_free(params);
321 		BN_free(p);
322 		BN_free(q);
323 		BN_free(g);
324 		BN_free(y);
325 		return NULL;
326 	}
327 	if(EVP_PKEY_fromdata_init(ctx) <= 0) {
328 		EVP_PKEY_CTX_free(ctx);
329 		OSSL_PARAM_free(params);
330 		BN_free(p);
331 		BN_free(q);
332 		BN_free(g);
333 		BN_free(y);
334 		return NULL;
335 	}
336 	if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
337 		EVP_PKEY_CTX_free(ctx);
338 		OSSL_PARAM_free(params);
339 		BN_free(p);
340 		BN_free(q);
341 		BN_free(g);
342 		BN_free(y);
343 		return NULL;
344 	}
345 
346 	EVP_PKEY_CTX_free(ctx);
347 	OSSL_PARAM_free(params);
348 	BN_free(p);
349 	BN_free(q);
350 	BN_free(g);
351 	BN_free(y);
352 	return evp_key;
353 #else
354 	DSA* dsa;
355 	EVP_PKEY* evp_key = EVP_PKEY_new();
356 	if(!evp_key) {
357 		return NULL;
358 	}
359 	dsa = sldns_key_buf2dsa_raw(key, len);
360 	if(!dsa) {
361 		EVP_PKEY_free(evp_key);
362 		return NULL;
363 	}
364 	if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
365 		DSA_free(dsa);
366 		EVP_PKEY_free(evp_key);
367 		return NULL;
368 	}
369 	return evp_key;
370 #endif
371 }
372 
373 /* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
374 static int
375 sldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n,
376 	BIGNUM** e)
377 {
378 	uint16_t offset;
379 	uint16_t exp;
380 	uint16_t int16;
381 
382 	if (len == 0)
383 		return 0;
384 	if (key[0] == 0) {
385 		if(len < 3)
386 			return 0;
387 		memmove(&int16, key+1, 2);
388 		exp = ntohs(int16);
389 		offset = 3;
390 	} else {
391 		exp = key[0];
392 		offset = 1;
393 	}
394 
395 	/* key length at least one */
396 	if(len < (size_t)offset + exp + 1)
397 		return 0;
398 
399 	/* Exponent */
400 	*e = BN_new();
401 	if(!*e) return 0;
402 	(void) BN_bin2bn(key+offset, (int)exp, *e);
403 	offset += exp;
404 
405 	/* Modulus */
406 	*n = BN_new();
407 	if(!*n) {
408 		BN_free(*e);
409 		return 0;
410 	}
411 	/* length of the buffer must match the key length! */
412 	(void) BN_bin2bn(key+offset, (int)(len - offset), *n);
413 	return 1;
414 }
415 
416 #ifndef HAVE_OSSL_PARAM_BLD_NEW
417 RSA *
418 sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
419 {
420 	BIGNUM* modulus = NULL;
421 	BIGNUM* exponent = NULL;
422 	RSA *rsa;
423 	if(!sldns_key_rsa_buf_bignum(key, len, &modulus, &exponent))
424 		return NULL;
425 	rsa = RSA_new();
426 	if(!rsa) {
427 		BN_free(exponent);
428 		BN_free(modulus);
429 		return NULL;
430 	}
431 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
432 #ifndef S_SPLINT_S
433 	rsa->n = modulus;
434 	rsa->e = exponent;
435 #endif /* splint */
436 
437 #else /* OPENSSL_VERSION_NUMBER */
438 	if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
439 		BN_free(exponent);
440 		BN_free(modulus);
441 		RSA_free(rsa);
442 		return NULL;
443 	}
444 #endif
445 
446 	return rsa;
447 }
448 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
449 
450 EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
451 {
452 #ifdef HAVE_OSSL_PARAM_BLD_NEW
453 	EVP_PKEY* evp_key = NULL;
454 	EVP_PKEY_CTX* ctx;
455 	BIGNUM *n=NULL, *e=NULL;
456 	OSSL_PARAM_BLD* param_bld;
457 	OSSL_PARAM* params = NULL;
458 
459 	if(!sldns_key_rsa_buf_bignum(key, len, &n, &e)) {
460 		return NULL;
461 	}
462 
463 	param_bld = OSSL_PARAM_BLD_new();
464 	if(!param_bld) {
465 		BN_free(n);
466 		BN_free(e);
467 		return NULL;
468 	}
469 	if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) {
470 		OSSL_PARAM_BLD_free(param_bld);
471 		BN_free(n);
472 		BN_free(e);
473 		return NULL;
474 	}
475 	if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) {
476 		OSSL_PARAM_BLD_free(param_bld);
477 		BN_free(n);
478 		BN_free(e);
479 		return NULL;
480 	}
481 	params = OSSL_PARAM_BLD_to_param(param_bld);
482 	OSSL_PARAM_BLD_free(param_bld);
483 
484 	ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
485 	if(!ctx) {
486 		OSSL_PARAM_free(params);
487 		BN_free(n);
488 		BN_free(e);
489 		return NULL;
490 	}
491 	if(EVP_PKEY_fromdata_init(ctx) <= 0) {
492 		EVP_PKEY_CTX_free(ctx);
493 		OSSL_PARAM_free(params);
494 		BN_free(n);
495 		BN_free(e);
496 		return NULL;
497 	}
498 	if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
499 		EVP_PKEY_CTX_free(ctx);
500 		OSSL_PARAM_free(params);
501 		BN_free(n);
502 		BN_free(e);
503 		return NULL;
504 	}
505 
506 	EVP_PKEY_CTX_free(ctx);
507 	OSSL_PARAM_free(params);
508 	BN_free(n);
509 	BN_free(e);
510 	return evp_key;
511 #else
512 	RSA* rsa;
513 	EVP_PKEY *evp_key = EVP_PKEY_new();
514 	if(!evp_key) {
515 		return NULL;
516 	}
517 	rsa = sldns_key_buf2rsa_raw(key, len);
518 	if(!rsa) {
519 		EVP_PKEY_free(evp_key);
520 		return NULL;
521 	}
522 	if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
523 		RSA_free(rsa);
524 		EVP_PKEY_free(evp_key);
525 		return NULL;
526 	}
527 	return evp_key;
528 #endif
529 }
530 
531 #ifdef USE_GOST
532 EVP_PKEY*
533 sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
534 {
535 	/* prefix header for X509 encoding */
536 	uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
537 		0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
538 		0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
539 		0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
540 	unsigned char encoded[37+64];
541 	const unsigned char* pp;
542 	if(keylen != 64) {
543 		/* key wrong size */
544 		return NULL;
545 	}
546 
547 	/* create evp_key */
548 	memmove(encoded, asn, 37);
549 	memmove(encoded+37, key, 64);
550 	pp = (unsigned char*)&encoded[0];
551 
552 	return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
553 }
554 #endif /* USE_GOST */
555 
556 #ifdef USE_ECDSA
557 EVP_PKEY*
558 sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
559 {
560 #ifdef HAVE_OSSL_PARAM_BLD_NEW
561 	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
562 	EVP_PKEY *evp_key = NULL;
563 	EVP_PKEY_CTX* ctx;
564 	OSSL_PARAM_BLD* param_bld;
565 	OSSL_PARAM* params = NULL;
566 	char* group = NULL;
567 
568 	/* check length, which uncompressed must be 2 bignums */
569 	if(algo == LDNS_ECDSAP256SHA256) {
570 		if(keylen != 2*256/8) return NULL;
571 		group = "prime256v1";
572 	} else if(algo == LDNS_ECDSAP384SHA384) {
573 		if(keylen != 2*384/8) return NULL;
574 		group = "P-384";
575 	} else {
576 		return NULL;
577 	}
578 	if(keylen+1 > sizeof(buf)) { /* sanity check */
579 		return NULL;
580 	}
581 	/* prepend the 0x04 for uncompressed format */
582 	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
583 	memmove(buf+1, key, keylen);
584 
585 	param_bld = OSSL_PARAM_BLD_new();
586 	if(!param_bld) {
587 		return NULL;
588 	}
589 	if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) ||
590 	   !OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) {
591 		OSSL_PARAM_BLD_free(param_bld);
592 		return NULL;
593 	}
594 	params = OSSL_PARAM_BLD_to_param(param_bld);
595 	OSSL_PARAM_BLD_free(param_bld);
596 
597 	ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
598 	if(!ctx) {
599 		OSSL_PARAM_free(params);
600 		return NULL;
601 	}
602 	if(EVP_PKEY_fromdata_init(ctx) <= 0) {
603 		EVP_PKEY_CTX_free(ctx);
604 		OSSL_PARAM_free(params);
605 		return NULL;
606 	}
607 	if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
608 		EVP_PKEY_CTX_free(ctx);
609 		OSSL_PARAM_free(params);
610 		return NULL;
611 	}
612 	EVP_PKEY_CTX_free(ctx);
613 	OSSL_PARAM_free(params);
614 	return evp_key;
615 #else
616 	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
617         const unsigned char* pp = buf;
618         EVP_PKEY *evp_key;
619         EC_KEY *ec;
620 	/* check length, which uncompressed must be 2 bignums */
621         if(algo == LDNS_ECDSAP256SHA256) {
622 		if(keylen != 2*256/8) return NULL;
623                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
624         } else if(algo == LDNS_ECDSAP384SHA384) {
625 		if(keylen != 2*384/8) return NULL;
626                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
627         } else    ec = NULL;
628         if(!ec) return NULL;
629 	if(keylen+1 > sizeof(buf)) { /* sanity check */
630                 EC_KEY_free(ec);
631 		return NULL;
632 	}
633 	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
634 	 * of openssl) for uncompressed data */
635 	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
636 	memmove(buf+1, key, keylen);
637         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
638                 EC_KEY_free(ec);
639                 return NULL;
640         }
641         evp_key = EVP_PKEY_new();
642         if(!evp_key) {
643                 EC_KEY_free(ec);
644                 return NULL;
645         }
646         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
647 		EVP_PKEY_free(evp_key);
648 		EC_KEY_free(ec);
649 		return NULL;
650 	}
651         return evp_key;
652 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
653 }
654 #endif /* USE_ECDSA */
655 
656 #ifdef USE_ED25519
657 EVP_PKEY*
658 sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
659 {
660 	/* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
661 	uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
662 		0x70, 0x03, 0x21, 0x00};
663 	int pre_len = 12;
664 	uint8_t buf[256];
665 	EVP_PKEY *evp_key;
666 	/* pp gets modified by d2i() */
667 	const unsigned char* pp = (unsigned char*)buf;
668 	if(keylen != 32 || keylen + pre_len > sizeof(buf))
669 		return NULL; /* wrong length */
670 	memmove(buf, pre, pre_len);
671 	memmove(buf+pre_len, key, keylen);
672 	evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
673 	return evp_key;
674 }
675 #endif /* USE_ED25519 */
676 
677 #ifdef USE_ED448
678 EVP_PKEY*
679 sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
680 {
681 	/* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
682 	uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
683 		0x71, 0x03, 0x3a, 0x00};
684         int pre_len = 12;
685 	uint8_t buf[256];
686         EVP_PKEY *evp_key;
687 	/* pp gets modified by d2i() */
688         const unsigned char* pp = (unsigned char*)buf;
689 	if(keylen != 57 || keylen + pre_len > sizeof(buf))
690 		return NULL; /* wrong length */
691 	memmove(buf, pre, pre_len);
692 	memmove(buf+pre_len, key, keylen);
693 	evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
694         return evp_key;
695 }
696 #endif /* USE_ED448 */
697 
698 int
699 sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
700 	const EVP_MD* md)
701 {
702 	EVP_MD_CTX* ctx;
703 	ctx = EVP_MD_CTX_create();
704 	if(!ctx)
705 		return 0;
706 	if(!EVP_DigestInit_ex(ctx, md, NULL) ||
707 		!EVP_DigestUpdate(ctx, data, len) ||
708 		!EVP_DigestFinal_ex(ctx, dest, NULL)) {
709 		EVP_MD_CTX_destroy(ctx);
710 		return 0;
711 	}
712 	EVP_MD_CTX_destroy(ctx);
713 	return 1;
714 }
715 #endif /* HAVE_SSL */
716