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