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