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