xref: /freebsd/contrib/unbound/sldns/keyraw.c (revision be771a7b7f4580a30d99e41a5bb1b93a385a119d)
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 #ifdef USE_DSA
199 /* Retrieve params as BIGNUM from raw buffer */
200 static int
201 sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
202 	BIGNUM** q, BIGNUM** g, BIGNUM** y)
203 {
204 	uint8_t T;
205 	uint16_t length;
206 	uint16_t offset;
207 
208 	if(len == 0)
209 		return 0;
210 	T = (uint8_t)key[0];
211 	length = (64 + T * 8);
212 	offset = 1;
213 
214 	if (T > 8) {
215 		return 0;
216 	}
217 	if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
218 		return 0;
219 
220 	*q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
221 	offset += SHA_DIGEST_LENGTH;
222 
223 	*p = BN_bin2bn(key+offset, (int)length, NULL);
224 	offset += length;
225 
226 	*g = BN_bin2bn(key+offset, (int)length, NULL);
227 	offset += length;
228 
229 	*y = BN_bin2bn(key+offset, (int)length, NULL);
230 
231 	if(!*q || !*p || !*g || !*y) {
232 		BN_free(*q);
233 		BN_free(*p);
234 		BN_free(*g);
235 		BN_free(*y);
236 		return 0;
237 	}
238 	return 1;
239 }
240 
241 #ifndef HAVE_OSSL_PARAM_BLD_NEW
242 DSA *
243 sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
244 {
245 	DSA *dsa;
246 	BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL;
247 	if(!sldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) {
248 		return NULL;
249 	}
250 	/* create the key and set its properties */
251 	if(!(dsa = DSA_new())) {
252 		return NULL;
253 	}
254 #if OPENSSL_VERSION_NUMBER < 0x10100000 || \
255         (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
256 #ifndef S_SPLINT_S
257 	dsa->p = P;
258 	dsa->q = Q;
259 	dsa->g = G;
260 	dsa->pub_key = Y;
261 #endif /* splint */
262 
263 #else /* OPENSSL_VERSION_NUMBER */
264 	if (!DSA_set0_pqg(dsa, P, Q, G)) {
265 		/* QPG not yet attached, need to free */
266 		BN_free(Q);
267 		BN_free(P);
268 		BN_free(G);
269 
270 		DSA_free(dsa);
271 		BN_free(Y);
272 		return NULL;
273 	}
274 	if (!DSA_set0_key(dsa, Y, NULL)) {
275 		/* QPG attached, cleaned up by DSA_fre() */
276 		DSA_free(dsa);
277 		BN_free(Y);
278 		return NULL;
279 	}
280 #endif
281 
282 	return dsa;
283 }
284 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
285 
286 EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
287 {
288 #ifdef HAVE_OSSL_PARAM_BLD_NEW
289 	EVP_PKEY* evp_key = NULL;
290 	EVP_PKEY_CTX* ctx;
291 	BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL;
292 	OSSL_PARAM_BLD* param_bld;
293 	OSSL_PARAM* params = NULL;
294 	if(!sldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) {
295 		return NULL;
296 	}
297 
298 	param_bld = OSSL_PARAM_BLD_new();
299 	if(!param_bld) {
300 		BN_free(p);
301 		BN_free(q);
302 		BN_free(g);
303 		BN_free(y);
304 		return NULL;
305 	}
306 	if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) ||
307 	   !OSSL_PARAM_BLD_push_BN(param_bld, "g", g) ||
308 	   !OSSL_PARAM_BLD_push_BN(param_bld, "q", q) ||
309 	   !OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) {
310 		OSSL_PARAM_BLD_free(param_bld);
311 		BN_free(p);
312 		BN_free(q);
313 		BN_free(g);
314 		BN_free(y);
315 		return NULL;
316 	}
317 	params = OSSL_PARAM_BLD_to_param(param_bld);
318 	OSSL_PARAM_BLD_free(param_bld);
319 
320 	ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
321 	if(!ctx) {
322 		OSSL_PARAM_free(params);
323 		BN_free(p);
324 		BN_free(q);
325 		BN_free(g);
326 		BN_free(y);
327 		return NULL;
328 	}
329 	if(EVP_PKEY_fromdata_init(ctx) <= 0) {
330 		EVP_PKEY_CTX_free(ctx);
331 		OSSL_PARAM_free(params);
332 		BN_free(p);
333 		BN_free(q);
334 		BN_free(g);
335 		BN_free(y);
336 		return NULL;
337 	}
338 	if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
339 		EVP_PKEY_CTX_free(ctx);
340 		OSSL_PARAM_free(params);
341 		BN_free(p);
342 		BN_free(q);
343 		BN_free(g);
344 		BN_free(y);
345 		return NULL;
346 	}
347 
348 	EVP_PKEY_CTX_free(ctx);
349 	OSSL_PARAM_free(params);
350 	BN_free(p);
351 	BN_free(q);
352 	BN_free(g);
353 	BN_free(y);
354 	return evp_key;
355 #else
356 	DSA* dsa;
357 	EVP_PKEY* evp_key = EVP_PKEY_new();
358 	if(!evp_key) {
359 		return NULL;
360 	}
361 	dsa = sldns_key_buf2dsa_raw(key, len);
362 	if(!dsa) {
363 		EVP_PKEY_free(evp_key);
364 		return NULL;
365 	}
366 	if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
367 		DSA_free(dsa);
368 		EVP_PKEY_free(evp_key);
369 		return NULL;
370 	}
371 	return evp_key;
372 #endif
373 }
374 #endif /* USE_DSA */
375 
376 /* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
377 static int
378 sldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n,
379 	BIGNUM** e)
380 {
381 	uint16_t offset;
382 	uint16_t exp;
383 	uint16_t int16;
384 
385 	if (len == 0)
386 		return 0;
387 	if (key[0] == 0) {
388 		if(len < 3)
389 			return 0;
390 		memmove(&int16, key+1, 2);
391 		exp = ntohs(int16);
392 		offset = 3;
393 	} else {
394 		exp = key[0];
395 		offset = 1;
396 	}
397 
398 	/* key length at least one */
399 	if(len < (size_t)offset + exp + 1)
400 		return 0;
401 
402 	/* Exponent */
403 	*e = BN_new();
404 	if(!*e) return 0;
405 	(void) BN_bin2bn(key+offset, (int)exp, *e);
406 	offset += exp;
407 
408 	/* Modulus */
409 	*n = BN_new();
410 	if(!*n) {
411 		BN_free(*e);
412 		return 0;
413 	}
414 	/* length of the buffer must match the key length! */
415 	(void) BN_bin2bn(key+offset, (int)(len - offset), *n);
416 	return 1;
417 }
418 
419 #ifndef HAVE_OSSL_PARAM_BLD_NEW
420 RSA *
421 sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
422 {
423 	BIGNUM* modulus = NULL;
424 	BIGNUM* exponent = NULL;
425 	RSA *rsa;
426 	if(!sldns_key_rsa_buf_bignum(key, len, &modulus, &exponent))
427 		return NULL;
428 	rsa = RSA_new();
429 	if(!rsa) {
430 		BN_free(exponent);
431 		BN_free(modulus);
432 		return NULL;
433 	}
434 #if OPENSSL_VERSION_NUMBER < 0x10100000 || \
435         (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
436 #ifndef S_SPLINT_S
437 	rsa->n = modulus;
438 	rsa->e = exponent;
439 #endif /* splint */
440 
441 #else /* OPENSSL_VERSION_NUMBER */
442 	if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
443 		BN_free(exponent);
444 		BN_free(modulus);
445 		RSA_free(rsa);
446 		return NULL;
447 	}
448 #endif
449 
450 	return rsa;
451 }
452 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
453 
454 EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
455 {
456 #ifdef HAVE_OSSL_PARAM_BLD_NEW
457 	EVP_PKEY* evp_key = NULL;
458 	EVP_PKEY_CTX* ctx;
459 	BIGNUM *n=NULL, *e=NULL;
460 	OSSL_PARAM_BLD* param_bld;
461 	OSSL_PARAM* params = NULL;
462 
463 	if(!sldns_key_rsa_buf_bignum(key, len, &n, &e)) {
464 		return NULL;
465 	}
466 
467 	param_bld = OSSL_PARAM_BLD_new();
468 	if(!param_bld) {
469 		BN_free(n);
470 		BN_free(e);
471 		return NULL;
472 	}
473 	if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) {
474 		OSSL_PARAM_BLD_free(param_bld);
475 		BN_free(n);
476 		BN_free(e);
477 		return NULL;
478 	}
479 	if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) {
480 		OSSL_PARAM_BLD_free(param_bld);
481 		BN_free(n);
482 		BN_free(e);
483 		return NULL;
484 	}
485 	params = OSSL_PARAM_BLD_to_param(param_bld);
486 	OSSL_PARAM_BLD_free(param_bld);
487 
488 	ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
489 	if(!ctx) {
490 		OSSL_PARAM_free(params);
491 		BN_free(n);
492 		BN_free(e);
493 		return NULL;
494 	}
495 	if(EVP_PKEY_fromdata_init(ctx) <= 0) {
496 		EVP_PKEY_CTX_free(ctx);
497 		OSSL_PARAM_free(params);
498 		BN_free(n);
499 		BN_free(e);
500 		return NULL;
501 	}
502 	if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
503 		EVP_PKEY_CTX_free(ctx);
504 		OSSL_PARAM_free(params);
505 		BN_free(n);
506 		BN_free(e);
507 		return NULL;
508 	}
509 
510 	EVP_PKEY_CTX_free(ctx);
511 	OSSL_PARAM_free(params);
512 	BN_free(n);
513 	BN_free(e);
514 	return evp_key;
515 #else
516 	RSA* rsa;
517 	EVP_PKEY *evp_key = EVP_PKEY_new();
518 	if(!evp_key) {
519 		return NULL;
520 	}
521 	rsa = sldns_key_buf2rsa_raw(key, len);
522 	if(!rsa) {
523 		EVP_PKEY_free(evp_key);
524 		return NULL;
525 	}
526 	if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
527 		RSA_free(rsa);
528 		EVP_PKEY_free(evp_key);
529 		return NULL;
530 	}
531 	return evp_key;
532 #endif
533 }
534 
535 #ifdef USE_GOST
536 EVP_PKEY*
537 sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
538 {
539 	/* prefix header for X509 encoding */
540 	uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
541 		0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
542 		0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
543 		0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
544 	unsigned char encoded[37+64];
545 	const unsigned char* pp;
546 	if(keylen != 64) {
547 		/* key wrong size */
548 		return NULL;
549 	}
550 
551 	/* create evp_key */
552 	memmove(encoded, asn, 37);
553 	memmove(encoded+37, key, 64);
554 	pp = (unsigned char*)&encoded[0];
555 
556 	return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
557 }
558 #endif /* USE_GOST */
559 
560 #ifdef USE_ECDSA
561 EVP_PKEY*
562 sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
563 {
564 #ifdef HAVE_OSSL_PARAM_BLD_NEW
565 	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
566 	EVP_PKEY *evp_key = NULL;
567 	EVP_PKEY_CTX* ctx;
568 	OSSL_PARAM_BLD* param_bld;
569 	OSSL_PARAM* params = NULL;
570 	char* group = NULL;
571 
572 	/* check length, which uncompressed must be 2 bignums */
573 	if(algo == LDNS_ECDSAP256SHA256) {
574 		if(keylen != 2*256/8) return NULL;
575 		group = "prime256v1";
576 	} else if(algo == LDNS_ECDSAP384SHA384) {
577 		if(keylen != 2*384/8) return NULL;
578 		group = "P-384";
579 	} else {
580 		return NULL;
581 	}
582 	if(keylen+1 > sizeof(buf)) { /* sanity check */
583 		return NULL;
584 	}
585 	/* prepend the 0x04 for uncompressed format */
586 	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
587 	memmove(buf+1, key, keylen);
588 
589 	param_bld = OSSL_PARAM_BLD_new();
590 	if(!param_bld) {
591 		return NULL;
592 	}
593 	if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) ||
594 	   !OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) {
595 		OSSL_PARAM_BLD_free(param_bld);
596 		return NULL;
597 	}
598 	params = OSSL_PARAM_BLD_to_param(param_bld);
599 	OSSL_PARAM_BLD_free(param_bld);
600 
601 	ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
602 	if(!ctx) {
603 		OSSL_PARAM_free(params);
604 		return NULL;
605 	}
606 	if(EVP_PKEY_fromdata_init(ctx) <= 0) {
607 		EVP_PKEY_CTX_free(ctx);
608 		OSSL_PARAM_free(params);
609 		return NULL;
610 	}
611 	if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
612 		EVP_PKEY_CTX_free(ctx);
613 		OSSL_PARAM_free(params);
614 		return NULL;
615 	}
616 	EVP_PKEY_CTX_free(ctx);
617 	OSSL_PARAM_free(params);
618 	return evp_key;
619 #else
620 	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
621         const unsigned char* pp = buf;
622         EVP_PKEY *evp_key;
623         EC_KEY *ec;
624 	/* check length, which uncompressed must be 2 bignums */
625         if(algo == LDNS_ECDSAP256SHA256) {
626 		if(keylen != 2*256/8) return NULL;
627                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
628         } else if(algo == LDNS_ECDSAP384SHA384) {
629 		if(keylen != 2*384/8) return NULL;
630                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
631         } else    ec = NULL;
632         if(!ec) return NULL;
633 	if(keylen+1 > sizeof(buf)) { /* sanity check */
634                 EC_KEY_free(ec);
635 		return NULL;
636 	}
637 	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
638 	 * of openssl) for uncompressed data */
639 	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
640 	memmove(buf+1, key, keylen);
641         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
642                 EC_KEY_free(ec);
643                 return NULL;
644         }
645         evp_key = EVP_PKEY_new();
646         if(!evp_key) {
647                 EC_KEY_free(ec);
648                 return NULL;
649         }
650         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
651 		EVP_PKEY_free(evp_key);
652 		EC_KEY_free(ec);
653 		return NULL;
654 	}
655         return evp_key;
656 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
657 }
658 #endif /* USE_ECDSA */
659 
660 #ifdef USE_ED25519
661 EVP_PKEY*
662 sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
663 {
664 	/* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
665 	uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
666 		0x70, 0x03, 0x21, 0x00};
667 	int pre_len = 12;
668 	uint8_t buf[256];
669 	EVP_PKEY *evp_key;
670 	/* pp gets modified by d2i() */
671 	const unsigned char* pp = (unsigned char*)buf;
672 	if(keylen != 32 || keylen + pre_len > sizeof(buf))
673 		return NULL; /* wrong length */
674 	memmove(buf, pre, pre_len);
675 	memmove(buf+pre_len, key, keylen);
676 	evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
677 	return evp_key;
678 }
679 #endif /* USE_ED25519 */
680 
681 #ifdef USE_ED448
682 EVP_PKEY*
683 sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
684 {
685 	/* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
686 	uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
687 		0x71, 0x03, 0x3a, 0x00};
688         int pre_len = 12;
689 	uint8_t buf[256];
690         EVP_PKEY *evp_key;
691 	/* pp gets modified by d2i() */
692         const unsigned char* pp = (unsigned char*)buf;
693 	if(keylen != 57 || keylen + pre_len > sizeof(buf))
694 		return NULL; /* wrong length */
695 	memmove(buf, pre, pre_len);
696 	memmove(buf+pre_len, key, keylen);
697 	evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
698         return evp_key;
699 }
700 #endif /* USE_ED448 */
701 
702 int
703 sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
704 	const EVP_MD* md)
705 {
706 	EVP_MD_CTX* ctx;
707 	ctx = EVP_MD_CTX_create();
708 	if(!ctx)
709 		return 0;
710 	if(!EVP_DigestInit_ex(ctx, md, NULL) ||
711 		!EVP_DigestUpdate(ctx, data, len) ||
712 		!EVP_DigestFinal_ex(ctx, dest, NULL)) {
713 		EVP_MD_CTX_destroy(ctx);
714 		return 0;
715 	}
716 	EVP_MD_CTX_destroy(ctx);
717 	return 1;
718 }
719 #endif /* HAVE_SSL */
720