1/*	$NetBSD: crypto_openssl.c,v 1.11.6.1 2006/12/18 10:18:10 vanhu Exp $	*/
2
3/* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#define COMMON_DIGEST_FOR_OPENSSL 1
37
38#include <sys/types.h>
39#include <sys/param.h>
40
41#include <stdlib.h>
42#include <stdio.h>
43#include <limits.h>
44#include <string.h>
45
46#ifdef HAVE_OPENSSL
47/* get openssl/ssleay version number */
48#include <openssl/opensslv.h>
49
50#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090602fL)
51#error OpenSSL version 0.9.6 or later required.
52#endif
53#include <openssl/pem.h>
54#include <openssl/evp.h>
55#include <openssl/x509.h>
56#include <openssl/x509v3.h>
57#include <openssl/x509_vfy.h>
58#include <openssl/bn.h>
59#include <openssl/dh.h>
60#include <openssl/des.h>
61#include <openssl/crypto.h>
62#ifdef HAVE_OPENSSL_ENGINE_H
63#include <openssl/engine.h>
64#endif
65#include <openssl/err.h>
66#else /* HAVE_OPENSSL */
67#include <Security/SecDH.h>
68#include <Security/SecRandom.h>
69#endif /* HAVE_OPENSSL */
70
71#include <CommonCrypto/CommonDigest.h>
72#include <CommonCrypto/CommonHMAC.h>
73#include <CommonCrypto/CommonCryptor.h>
74
75#ifdef HAVE_OPENSSL
76/* 0.9.7 stuff? */
77#if OPENSSL_VERSION_NUMBER < 0x0090700fL
78typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
79#else
80#define USE_NEW_DES_API
81#endif
82
83#define OpenSSL_BUG()	do { plog(ASL_LEVEL_ERR, "OpenSSL function failed\n"); } while(0)
84#endif
85
86#include "crypto_openssl.h"
87#include "var.h"
88#include "misc.h"
89#include "vmbuf.h"
90#include "plog.h"
91#include "debug.h"
92#include "gcmalloc.h"
93
94
95/*
96 * I hate to cast every parameter to des_xx into void *, but it is
97 * necessary for SSLeay/OpenSSL portability.  It sucks.
98 */
99
100#ifdef HAVE_OPENSSL
101static X509 *mem2x509(vchar_t *);
102#endif
103static caddr_t eay_hmac_init (vchar_t *, CCHmacAlgorithm);
104
105
106#ifdef HAVE_OPENSSL
107
108/*
109 * The following are derived from code in crypto/x509/x509_cmp.c
110 * in OpenSSL0.9.7c:
111 * X509_NAME_wildcmp() adds wildcard matching to the original
112 * X509_NAME_cmp(), nocase_cmp() and nocase_spacenorm_cmp() are as is.
113 */
114#include <ctype.h>
115/* Case insensitive string comparision */
116static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
117{
118	int i;
119
120	if (a->length != b->length)
121		return (a->length - b->length);
122
123	for (i=0; i<a->length; i++)
124	{
125		int ca, cb;
126
127		ca = tolower(a->data[i]);
128		cb = tolower(b->data[i]);
129
130		if (ca != cb)
131			return(ca-cb);
132	}
133	return 0;
134}
135
136/* Case insensitive string comparision with space normalization
137 * Space normalization - ignore leading, trailing spaces,
138 *       multiple spaces between characters are replaced by single space
139 */
140static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
141{
142	unsigned char *pa = NULL, *pb = NULL;
143	int la, lb;
144
145	la = a->length;
146	lb = b->length;
147	pa = a->data;
148	pb = b->data;
149
150	/* skip leading spaces */
151	while (la > 0 && isspace(*pa))
152	{
153		la--;
154		pa++;
155	}
156	while (lb > 0 && isspace(*pb))
157	{
158		lb--;
159		pb++;
160	}
161
162	/* skip trailing spaces */
163	while (la > 0 && isspace(pa[la-1]))
164		la--;
165	while (lb > 0 && isspace(pb[lb-1]))
166		lb--;
167
168	/* compare strings with space normalization */
169	while (la > 0 && lb > 0)
170	{
171		int ca, cb;
172
173		/* compare character */
174		ca = tolower(*pa);
175		cb = tolower(*pb);
176		if (ca != cb)
177			return (ca - cb);
178
179		pa++; pb++;
180		la--; lb--;
181
182		if (la <= 0 || lb <= 0)
183			break;
184
185		/* is white space next character ? */
186		if (isspace(*pa) && isspace(*pb))
187		{
188			/* skip remaining white spaces */
189			while (la > 0 && isspace(*pa))
190			{
191				la--;
192				pa++;
193			}
194			while (lb > 0 && isspace(*pb))
195			{
196				lb--;
197				pb++;
198			}
199		}
200	}
201	if (la > 0 || lb > 0)
202		return la - lb;
203
204	return 0;
205}
206
207static int X509_NAME_wildcmp(const X509_NAME *a, const X509_NAME *b)
208{
209    int i,j;
210    X509_NAME_ENTRY *na,*nb;
211
212    if (sk_X509_NAME_ENTRY_num(a->entries)
213	!= sk_X509_NAME_ENTRY_num(b->entries))
214	    return sk_X509_NAME_ENTRY_num(a->entries)
215	      -sk_X509_NAME_ENTRY_num(b->entries);
216    for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
217    {
218	    na=sk_X509_NAME_ENTRY_value(a->entries,i);
219	    nb=sk_X509_NAME_ENTRY_value(b->entries,i);
220	    j=OBJ_cmp(na->object,nb->object);
221	    if (j) return(j);
222	    if ((na->value->length == 1 && na->value->data[0] == '*')
223	     || (nb->value->length == 1 && nb->value->data[0] == '*'))
224		    continue;
225	    j=na->value->type-nb->value->type;
226	    if (j) return(j);
227	    if (na->value->type == V_ASN1_PRINTABLESTRING)
228		    j=nocase_spacenorm_cmp(na->value, nb->value);
229	    else if (na->value->type == V_ASN1_IA5STRING
230		    && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
231		    j=nocase_cmp(na->value, nb->value);
232	    else
233		    {
234		    j=na->value->length-nb->value->length;
235		    if (j) return(j);
236		    j=memcmp(na->value->data,nb->value->data,
237			    na->value->length);
238		    }
239	    if (j) return(j);
240	    j=na->set-nb->set;
241	    if (j) return(j);
242    }
243
244    return(0);
245}
246
247/*
248 * compare two subjectNames.
249 * OUT:        0: equal
250 *	positive:
251 *	      -1: other error.
252 */
253int
254eay_cmp_asn1dn(n1, n2)
255	vchar_t *n1, *n2;
256{
257	X509_NAME *a = NULL, *b = NULL;
258	caddr_t p;
259	int i = -1;
260
261	p = n1->v;
262	if (!d2i_X509_NAME(&a, (void *)&p, n1->l))
263		goto end;
264	p = n2->v;
265	if (!d2i_X509_NAME(&b, (void *)&p, n2->l))
266		goto end;
267
268	i = X509_NAME_wildcmp(a, b);
269
270    end:
271	if (a)
272		X509_NAME_free(a);
273	if (b)
274		X509_NAME_free(b);
275	return i;
276}
277
278/*
279 * Get the common name from a cert
280 */
281#define EAY_MAX_CN_LEN 256
282vchar_t *
283eay_get_x509_common_name(cert)
284	vchar_t *cert;
285{
286	X509 *x509 = NULL;
287	X509_NAME *name;
288	vchar_t *commonName = NULL;
289
290	commonName = vmalloc(EAY_MAX_CN_LEN);
291	if (commonName == NULL) {
292		plog(ASL_LEVEL_ERR, "no memory\n");
293		return NULL;
294	}
295
296	x509 = mem2x509(cert);
297	if (x509 == NULL) {
298		vfree(commonName);
299		return NULL;
300	}
301
302	name = X509_get_subject_name(x509);
303	X509_NAME_get_text_by_NID(name, NID_commonName, commonName->v, EAY_MAX_CN_LEN);
304
305	commonName->l = strlen(commonName->v);
306
307	if (x509)
308		X509_free(x509);
309	return commonName;
310}
311
312/*
313 * get the subjectAltName from X509 certificate.
314 * the name must be terminated by '\0'.
315 */
316int
317eay_get_x509subjectaltname(cert, altname, type, pos, len)
318	vchar_t *cert;
319	char **altname;
320	int *type;
321	int pos;
322	int *len;
323{
324	X509 *x509 = NULL;
325	int i;
326	GENERAL_NAMES 	*gens = NULL;
327	GENERAL_NAME 	*gen;
328	int error = -1;
329
330	*altname = NULL;
331	*type = GENT_OTHERNAME;
332
333	x509 = mem2x509(cert);
334	if (x509 == NULL)
335		goto end;
336
337	gens = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
338	if (gens == NULL)
339		goto end;
340
341	for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
342		if (i + 1 != pos)
343			continue;
344		break;
345	}
346
347	/* there is no data at "pos" */
348	if (i == sk_GENERAL_NAME_num(gens))
349		goto end;
350
351	gen = sk_GENERAL_NAME_value(gens, i);
352
353	/* make sure the data is terminated by '\0'. */
354	if (gen->d.ia5->data[gen->d.ia5->length] != '\0') {
355		plog(ASL_LEVEL_ERR,
356			"data is not terminated by 0.");
357		hexdump(gen->d.ia5->data, gen->d.ia5->length + 1);
358		goto end;
359	}
360
361	/* read DNSName / Email */
362	if (gen->type == GEN_DNS	||
363		gen->type == GEN_EMAIL  ||
364		gen->type == GEN_URI) {
365
366		*len = gen->d.ia5->length + 1;
367		*altname = racoon_malloc(*len);
368		if (!*altname)
369			goto end;
370
371		strlcpy(*altname, (const char *)gen->d.ia5->data, *len);
372		*type = gen->type;
373
374		error = 0;
375	} else if (gen->type == GEN_IPADD) {
376
377		*len = gen->d.ia5->length + 1;
378		*altname = racoon_malloc(*len);
379		if (!*altname)
380			goto end;
381
382		memcpy(*altname, (const char *)gen->d.ia5->data, *len);
383		*type = gen->type;
384
385		error = 0;
386	}
387
388   end:
389	if (error) {
390		if (*altname) {
391			racoon_free(*altname);
392			*altname = NULL;
393		}
394#ifndef EAYDEBUG
395		plog(ASL_LEVEL_ERR, "%s\n", eay_strerror());
396#else
397		printf("%s\n", eay_strerror());
398#endif
399	}
400	if (gens)
401	        /* free the whole stack. */
402		sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
403	if (x509)
404		X509_free(x509);
405
406	return error;
407}
408
409
410/* get X509 structure from buffer. */
411static X509 *
412mem2x509(cert)
413	vchar_t *cert;
414{
415	X509 *x509;
416
417#ifndef EAYDEBUG
418    {
419	u_char *bp;
420
421	bp = (unsigned char *) cert->v;
422
423	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
424    }
425#else
426    {
427	BIO *bio;
428	int len;
429
430	bio = BIO_new(BIO_s_mem());
431	if (bio == NULL)
432		return NULL;
433	len = BIO_write(bio, cert->v, cert->l);
434	if (len == -1)
435		return NULL;
436	x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
437	BIO_free(bio);
438    }
439#endif
440	return x509;
441}
442
443/*
444 * get error string
445 * MUST load ERR_load_crypto_strings() first.
446 */
447char *
448eay_strerror()
449{
450	static char ebuf[512];
451	int len = 0, n;
452	unsigned long l;
453	char buf[200];
454	const char *file, *data;
455	int line, flags;
456	unsigned long es;
457
458	es = CRYPTO_thread_id();
459
460	while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){
461		n = snprintf(ebuf + len, sizeof(ebuf) - len,
462				"%lu:%s:%s:%d:%s ",
463				es, ERR_error_string(l, buf), file, line,
464				(flags & ERR_TXT_STRING) ? data : "");
465		if (n < 0 || n >= sizeof(ebuf) - len)
466			break;
467		len += n;
468		if (sizeof(ebuf) < len)
469			break;
470	}
471
472	return ebuf;
473}
474
475#endif /* HAVE_OPENSSL */
476
477vchar_t *
478eay_CCCrypt(CCOperation  oper,
479			CCAlgorithm  algo,
480			CCOptions    opts,
481			vchar_t     *data,
482			vchar_t     *key,
483			vchar_t     *iv)
484{
485    vchar_t         *res;
486    size_t           res_len = 0;
487    CCCryptorStatus  status;
488
489    /* allocate buffer for result */
490    if ((res = vmalloc(data->l)) == NULL)
491        return NULL;
492
493    status = CCCrypt(oper,
494                     algo,
495                     opts,
496                     key->v, key->l,
497                     iv->v,
498                     data->v, data->l,
499                     res->v, res->l, &res_len);
500    if (status == kCCSuccess) {
501        if (res->l != res_len) {
502            plog(ASL_LEVEL_ERR,
503                 "crypt %d %d length mismatch. expected: %zd. got: %zd.\n",
504                 oper, algo, res->l, res_len);
505        }
506        return res;
507    } else {
508        plog(ASL_LEVEL_ERR,
509             "crypt %d %d error. status %d.\n",
510             oper, algo, (int)status);
511    }
512    vfree(res);
513    return NULL;
514}
515
516/*
517 * DES-CBC
518 */
519vchar_t *
520eay_des_encrypt(data, key, iv)
521	vchar_t *data, *key, *iv;
522{
523    return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv));
524}
525
526vchar_t *
527eay_des_decrypt(data, key, iv)
528	vchar_t *data, *key, *iv;
529{
530    return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv));
531}
532
533int
534eay_des_weakkey(key)
535	vchar_t *key;
536{
537#ifdef HAVE_OPENSSL
538#ifdef USE_NEW_DES_API
539	return DES_is_weak_key((void *)key->v);
540#else
541	return des_is_weak_key((void *)key->v);
542#endif
543#else
544	return 0;
545#endif
546}
547
548int
549eay_des_keylen(len)
550	int len;
551{
552    /* CommonCrypto return lengths in bytes, ipsec-tools
553     * uses lengths in bits, therefore conversion is required.
554     */
555    if (len != 0 && len != (kCCKeySizeDES << 3))
556        return -1;
557
558    return kCCKeySizeDES << 3;
559}
560
561/*
562 * 3DES-CBC
563 */
564vchar_t *
565eay_3des_encrypt(data, key, iv)
566	vchar_t *data, *key, *iv;
567{
568    return(eay_CCCrypt(kCCEncrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv));
569}
570
571vchar_t *
572eay_3des_decrypt(data, key, iv)
573	vchar_t *data, *key, *iv;
574{
575    return(eay_CCCrypt(kCCDecrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv));
576}
577
578int
579eay_3des_weakkey(key)
580	vchar_t *key;
581{
582	return 0;
583}
584
585int
586eay_3des_keylen(len)
587	int len;
588{
589    /* CommonCrypto return lengths in bytes, ipsec-tools
590     * uses lengths in bits, therefore conversion is required.
591     */
592    if (len != 0 && len != (kCCKeySize3DES << 3))
593        return -1;
594
595    return kCCKeySize3DES << 3;
596}
597
598/*
599 * AES(RIJNDAEL)-CBC
600 */
601vchar_t *
602eay_aes_encrypt(data, key, iv)
603vchar_t *data, *key, *iv;
604{
605    return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv));
606}
607
608vchar_t *
609eay_aes_decrypt(data, key, iv)
610vchar_t *data, *key, *iv;
611{
612    return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv));
613}
614
615int
616eay_aes_keylen(len)
617int len;
618{
619    /* CommonCrypto return lengths in bytes, ipsec-tools
620     * uses lengths in bits, therefore conversion is required.
621     */
622    if (len != 0) {
623        if (len != (kCCKeySizeAES128 << 3) &&
624            len != (kCCKeySizeAES192 << 3) &&
625            len != (kCCKeySizeAES256 << 3))
626            return -1;
627    } else {
628        return kCCKeySizeAES128 << 3;
629    }
630    return len;
631}
632
633
634int
635eay_aes_weakkey(key)
636	vchar_t *key;
637{
638	return 0;
639}
640
641/* for ipsec part */
642int
643eay_null_hashlen()
644{
645	return 0;
646}
647
648int
649eay_null_keylen(len)
650	int len;
651{
652	return 0;
653}
654
655/*
656 * HMAC functions
657 */
658static caddr_t
659eay_hmac_init(key, algorithm)
660	vchar_t *key;
661	CCHmacAlgorithm algorithm;
662{
663	CCHmacContext *c = racoon_malloc(sizeof(*c));
664
665	CCHmacInit(c, algorithm, key->v, key->l);
666
667	return (caddr_t)c;
668}
669
670#ifdef WITH_SHA2
671/*
672 * HMAC SHA2-512
673 */
674vchar_t *
675eay_hmacsha2_512_one(key, data)
676	vchar_t *key, *data;
677{
678	vchar_t *res;
679	caddr_t ctx;
680
681	ctx = eay_hmacsha2_512_init(key);
682	eay_hmacsha2_512_update(ctx, data);
683	res = eay_hmacsha2_512_final(ctx);
684
685	return(res);
686}
687
688caddr_t
689eay_hmacsha2_512_init(key)
690	vchar_t *key;
691{
692	return eay_hmac_init(key, kCCHmacAlgSHA512);
693}
694
695void
696eay_hmacsha2_512_update(c, data)
697	caddr_t c;
698	vchar_t *data;
699{
700	CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
701}
702
703vchar_t *
704eay_hmacsha2_512_final(c)
705	caddr_t c;
706{
707	vchar_t *res;
708
709	if ((res = vmalloc(CC_SHA512_DIGEST_LENGTH)) == 0)
710		return NULL;
711
712	CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
713	res->l = CC_SHA512_DIGEST_LENGTH;
714
715	(void)racoon_free(c);
716	return(res);
717}
718
719/*
720 * HMAC SHA2-384
721 */
722vchar_t *
723eay_hmacsha2_384_one(key, data)
724	vchar_t *key, *data;
725{
726	vchar_t *res;
727	caddr_t ctx;
728
729	ctx = eay_hmacsha2_384_init(key);
730	eay_hmacsha2_384_update(ctx, data);
731	res = eay_hmacsha2_384_final(ctx);
732
733	return(res);
734}
735
736caddr_t
737eay_hmacsha2_384_init(key)
738	vchar_t *key;
739{
740	return eay_hmac_init(key, kCCHmacAlgSHA384);
741}
742
743void
744eay_hmacsha2_384_update(c, data)
745	caddr_t c;
746	vchar_t *data;
747{
748	CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
749}
750
751vchar_t *
752eay_hmacsha2_384_final(c)
753	caddr_t c;
754{
755	vchar_t *res;
756
757	if ((res = vmalloc(CC_SHA384_DIGEST_LENGTH)) == 0)
758		return NULL;
759
760	CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
761	res->l = CC_SHA384_DIGEST_LENGTH;
762
763	(void)racoon_free(c);
764	return(res);
765}
766
767/*
768 * HMAC SHA2-256
769 */
770vchar_t *
771eay_hmacsha2_256_one(key, data)
772	vchar_t *key, *data;
773{
774	vchar_t *res;
775	caddr_t ctx;
776
777	ctx = eay_hmacsha2_256_init(key);
778	eay_hmacsha2_256_update(ctx, data);
779	res = eay_hmacsha2_256_final(ctx);
780
781	return(res);
782}
783
784caddr_t
785eay_hmacsha2_256_init(key)
786	vchar_t *key;
787{
788	return eay_hmac_init(key, kCCHmacAlgSHA256);
789}
790
791void
792eay_hmacsha2_256_update(c, data)
793	caddr_t c;
794	vchar_t *data;
795{
796	CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
797}
798
799vchar_t *
800eay_hmacsha2_256_final(c)
801	caddr_t c;
802{
803	vchar_t *res;
804
805	if ((res = vmalloc(CC_SHA256_DIGEST_LENGTH)) == 0)
806		return NULL;
807
808	CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
809	res->l = CC_SHA256_DIGEST_LENGTH;
810
811	(void)racoon_free(c);
812	return(res);
813}
814#endif	/* WITH_SHA2 */
815
816/*
817 * HMAC SHA1
818 */
819vchar_t *
820eay_hmacsha1_one(key, data)
821	vchar_t *key, *data;
822{
823	vchar_t *res;
824	caddr_t ctx;
825
826	ctx = eay_hmacsha1_init(key);
827	eay_hmacsha1_update(ctx, data);
828	res = eay_hmacsha1_final(ctx);
829
830	return(res);
831}
832
833caddr_t
834eay_hmacsha1_init(key)
835	vchar_t *key;
836{
837	return eay_hmac_init(key, kCCHmacAlgSHA1);
838}
839
840void
841eay_hmacsha1_update(c, data)
842	caddr_t c;
843	vchar_t *data;
844{
845	CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
846}
847
848vchar_t *
849eay_hmacsha1_final(c)
850	caddr_t c;
851{
852	vchar_t *res;
853
854	if ((res = vmalloc(CC_SHA1_DIGEST_LENGTH)) == 0)
855		return NULL;
856
857	CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
858	res->l = CC_SHA1_DIGEST_LENGTH;
859
860	(void)racoon_free(c);
861	return(res);
862}
863
864/*
865 * HMAC MD5
866 */
867vchar_t *
868eay_hmacmd5_one(key, data)
869	vchar_t *key, *data;
870{
871	vchar_t *res;
872	caddr_t ctx;
873
874	ctx = eay_hmacmd5_init(key);
875	eay_hmacmd5_update(ctx, data);
876	res = eay_hmacmd5_final(ctx);
877
878	return(res);
879}
880
881caddr_t
882eay_hmacmd5_init(key)
883	vchar_t *key;
884{
885	return eay_hmac_init(key, kCCHmacAlgMD5);
886}
887
888void
889eay_hmacmd5_update(c, data)
890	caddr_t c;
891	vchar_t *data;
892{
893	CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
894}
895
896vchar_t *
897eay_hmacmd5_final(c)
898	caddr_t c;
899{
900	vchar_t *res;
901
902	if ((res = vmalloc(CC_MD5_DIGEST_LENGTH)) == 0)
903		return NULL;
904
905	CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
906	res->l = CC_MD5_DIGEST_LENGTH;
907	(void)racoon_free(c);
908
909	return(res);
910}
911
912
913
914#ifdef WITH_SHA2
915/*
916 * SHA2-512 functions
917 */
918caddr_t
919eay_sha2_512_init()
920{
921	SHA512_CTX *c = racoon_malloc(sizeof(*c));
922
923	SHA512_Init(c);
924
925	return((caddr_t)c);
926}
927
928void
929eay_sha2_512_update(c, data)
930	caddr_t c;
931	vchar_t *data;
932{
933	SHA512_Update(ALIGNED_CAST(SHA512_CTX *)c, (unsigned char *) data->v, data->l);
934
935	return;
936}
937
938vchar_t *
939eay_sha2_512_final(c)
940	caddr_t c;
941{
942	vchar_t *res;
943
944	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
945		return(0);
946
947	SHA512_Final((unsigned char *) res->v, ALIGNED_CAST(SHA512_CTX *)c);
948	(void)racoon_free(c);
949
950	return(res);
951}
952
953vchar_t *
954eay_sha2_512_one(data)
955	vchar_t *data;
956{
957	caddr_t ctx;
958	vchar_t *res;
959
960	ctx = eay_sha2_512_init();
961	eay_sha2_512_update(ctx, data);
962	res = eay_sha2_512_final(ctx);
963
964	return(res);
965}
966
967int
968eay_sha2_512_hashlen()
969{
970	return SHA512_DIGEST_LENGTH << 3;
971}
972#endif
973
974#ifdef WITH_SHA2
975/*
976 * SHA2-384 functions
977 */
978
979typedef SHA512_CTX SHA384_CTX;
980
981caddr_t
982eay_sha2_384_init()
983{
984	SHA384_CTX *c = racoon_malloc(sizeof(*c));
985
986	SHA384_Init(c);
987
988	return((caddr_t)c);
989}
990
991void
992eay_sha2_384_update(c, data)
993	caddr_t c;
994	vchar_t *data;
995{
996	SHA384_Update(ALIGNED_CAST(SHA384_CTX *)c, (unsigned char *) data->v, data->l);
997
998	return;
999}
1000
1001vchar_t *
1002eay_sha2_384_final(c)
1003	caddr_t c;
1004{
1005	vchar_t *res;
1006
1007	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
1008		return(0);
1009
1010	SHA384_Final((unsigned char *) res->v, ALIGNED_CAST(SHA384_CTX *)c);
1011	(void)racoon_free(c);
1012
1013	return(res);
1014}
1015
1016vchar_t *
1017eay_sha2_384_one(data)
1018	vchar_t *data;
1019{
1020	caddr_t ctx;
1021	vchar_t *res;
1022
1023	ctx = eay_sha2_384_init();
1024	eay_sha2_384_update(ctx, data);
1025	res = eay_sha2_384_final(ctx);
1026
1027	return(res);
1028}
1029
1030int
1031eay_sha2_384_hashlen()
1032{
1033	return SHA384_DIGEST_LENGTH << 3;
1034}
1035#endif
1036
1037#ifdef WITH_SHA2
1038/*
1039 * SHA2-256 functions
1040 */
1041caddr_t
1042eay_sha2_256_init()
1043{
1044	SHA256_CTX *c = racoon_malloc(sizeof(*c));
1045
1046	SHA256_Init(c);
1047
1048	return((caddr_t)c);
1049}
1050
1051void
1052eay_sha2_256_update(c, data)
1053	caddr_t c;
1054	vchar_t *data;
1055{
1056	SHA256_Update(ALIGNED_CAST(SHA256_CTX *)c, (unsigned char *) data->v, data->l);
1057
1058	return;
1059}
1060
1061vchar_t *
1062eay_sha2_256_final(c)
1063	caddr_t c;
1064{
1065	vchar_t *res;
1066
1067	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
1068		return(0);
1069
1070	SHA256_Final((unsigned char *) res->v, ALIGNED_CAST(SHA256_CTX *)c);
1071	(void)racoon_free(c);
1072
1073	return(res);
1074}
1075
1076vchar_t *
1077eay_sha2_256_one(data)
1078	vchar_t *data;
1079{
1080	caddr_t ctx;
1081	vchar_t *res;
1082
1083	ctx = eay_sha2_256_init();
1084	eay_sha2_256_update(ctx, data);
1085	res = eay_sha2_256_final(ctx);
1086
1087	return(res);
1088}
1089
1090int
1091eay_sha2_256_hashlen()
1092{
1093	return SHA256_DIGEST_LENGTH << 3;
1094}
1095#endif
1096
1097/*
1098 * SHA functions
1099 */
1100caddr_t
1101eay_sha1_init()
1102{
1103	SHA_CTX *c = racoon_malloc(sizeof(*c));
1104
1105	SHA1_Init(c);
1106
1107	return((caddr_t)c);
1108}
1109
1110void
1111eay_sha1_update(c, data)
1112	caddr_t c;
1113	vchar_t *data;
1114{
1115	SHA1_Update(ALIGNED_CAST(SHA_CTX *)c, data->v, data->l);
1116
1117	return;
1118}
1119
1120vchar_t *
1121eay_sha1_final(c)
1122	caddr_t c;
1123{
1124	vchar_t *res;
1125
1126	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
1127		return(0);
1128
1129	SHA1_Final((unsigned char *) res->v, ALIGNED_CAST(SHA_CTX *)c);
1130	(void)racoon_free(c);
1131
1132	return(res);
1133}
1134
1135vchar_t *
1136eay_sha1_one(data)
1137	vchar_t *data;
1138{
1139	caddr_t ctx;
1140	vchar_t *res;
1141
1142	ctx = eay_sha1_init();
1143	eay_sha1_update(ctx, data);
1144	res = eay_sha1_final(ctx);
1145
1146	return(res);
1147}
1148
1149int
1150eay_sha1_hashlen()
1151{
1152	return SHA_DIGEST_LENGTH << 3;
1153}
1154
1155/*
1156 * MD5 functions
1157 */
1158caddr_t
1159eay_md5_init()
1160{
1161	MD5_CTX *c = racoon_malloc(sizeof(*c));
1162
1163	MD5_Init(c);
1164
1165	return((caddr_t)c);
1166}
1167
1168void
1169eay_md5_update(c, data)
1170	caddr_t c;
1171	vchar_t *data;
1172{
1173	MD5_Update(ALIGNED_CAST(MD5_CTX *)c, data->v, data->l);
1174
1175	return;
1176}
1177
1178vchar_t *
1179eay_md5_final(c)
1180	caddr_t c;
1181{
1182	vchar_t *res;
1183
1184	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
1185		return(0);
1186
1187	MD5_Final((unsigned char *) res->v, ALIGNED_CAST(MD5_CTX *)c);
1188	(void)racoon_free(c);
1189
1190	return(res);
1191}
1192
1193vchar_t *
1194eay_md5_one(data)
1195	vchar_t *data;
1196{
1197	caddr_t ctx;
1198	vchar_t *res;
1199
1200	ctx = eay_md5_init();
1201	eay_md5_update(ctx, data);
1202	res = eay_md5_final(ctx);
1203
1204	return(res);
1205}
1206
1207int
1208eay_md5_hashlen()
1209{
1210	return MD5_DIGEST_LENGTH << 3;
1211}
1212
1213
1214#ifdef HAVE_OPENSSL
1215/*
1216 * eay_set_random
1217 *   size: number of bytes.
1218 */
1219vchar_t *
1220eay_set_random(size)
1221	u_int32_t size;
1222{
1223	BIGNUM *r = NULL;
1224	vchar_t *res = 0;
1225
1226	if ((r = BN_new()) == NULL)
1227		goto end;
1228	BN_rand(r, size * 8, 0, 0);
1229	eay_bn2v(&res, r);
1230
1231end:
1232	if (r)
1233		BN_free(r);
1234	return(res);
1235}
1236#else
1237vchar_t *
1238eay_set_random(u_int32_t size)
1239{
1240	vchar_t *res = vmalloc(size);
1241
1242	if (res == NULL)
1243		return NULL;
1244
1245	if (SecRandomCopyBytes(kSecRandomDefault, size, (uint8_t*)res->v)) {
1246		vfree(res);
1247		return NULL;
1248	}
1249
1250	return res;
1251}
1252#endif
1253
1254#ifdef HAVE_OPENSSL
1255/* DH */
1256int
1257eay_dh_generate(prime, g, publen, pub, priv)
1258	vchar_t *prime, **pub, **priv;
1259	u_int publen;
1260	u_int32_t g;
1261{
1262	BIGNUM *p = NULL;
1263	DH *dh = NULL;
1264	int error = -1;
1265
1266	/* initialize */
1267	/* pre-process to generate number */
1268	if (eay_v2bn(&p, prime) < 0)
1269		goto end;
1270
1271	if ((dh = DH_new()) == NULL)
1272		goto end;
1273	dh->p = p;
1274	p = NULL;	/* p is now part of dh structure */
1275	dh->g = NULL;
1276	if ((dh->g = BN_new()) == NULL)
1277		goto end;
1278	if (!BN_set_word(dh->g, g))
1279		goto end;
1280
1281	if (publen != 0)
1282		dh->length = publen;
1283
1284	/* generate public and private number */
1285	if (!DH_generate_key(dh))
1286		goto end;
1287
1288	/* copy results to buffers */
1289	if (eay_bn2v(pub, dh->pub_key) < 0)
1290		goto end;
1291	if (eay_bn2v(priv, dh->priv_key) < 0) {
1292		vfree(*pub);
1293		goto end;
1294	}
1295
1296	error = 0;
1297
1298end:
1299	if (dh != NULL)
1300		DH_free(dh);
1301	if (p != 0)
1302		BN_free(p);
1303	return(error);
1304}
1305
1306int
1307eay_dh_compute(prime, g, pub, priv, pub2, key)
1308	vchar_t *prime, *pub, *priv, *pub2, **key;
1309	u_int32_t g;
1310{
1311	BIGNUM *dh_pub = NULL;
1312	DH *dh = NULL;
1313	int l;
1314	unsigned char *v = NULL;
1315	int error = -1;
1316
1317	/* make public number to compute */
1318	if (eay_v2bn(&dh_pub, pub2) < 0)
1319		goto end;
1320
1321	/* make DH structure */
1322	if ((dh = DH_new()) == NULL)
1323		goto end;
1324	if (eay_v2bn(&dh->p, prime) < 0)
1325		goto end;
1326	if (eay_v2bn(&dh->pub_key, pub) < 0)
1327		goto end;
1328	if (eay_v2bn(&dh->priv_key, priv) < 0)
1329		goto end;
1330	dh->length = pub2->l * 8;
1331
1332	dh->g = NULL;
1333	if ((dh->g = BN_new()) == NULL)
1334		goto end;
1335	if (!BN_set_word(dh->g, g))
1336		goto end;
1337
1338	if ((v = racoon_calloc(prime->l, sizeof(u_char))) == NULL)
1339		goto end;
1340	if ((l = DH_compute_key(v, dh_pub, dh)) == -1)
1341		goto end;
1342	memcpy((*key)->v + (prime->l - l), v, l);
1343
1344	error = 0;
1345
1346end:
1347	if (dh_pub != NULL)
1348		BN_free(dh_pub);
1349	if (dh != NULL)
1350		DH_free(dh);
1351	if (v != NULL)
1352		racoon_free(v);
1353	return(error);
1354}
1355
1356/*
1357 * convert vchar_t <-> BIGNUM.
1358 *
1359 * vchar_t: unit is u_char, network endian, most significant byte first.
1360 * BIGNUM: unit is BN_ULONG, each of BN_ULONG is in host endian,
1361 *	least significant BN_ULONG must come first.
1362 *
1363 * hex value of "0x3ffe050104" is represented as follows:
1364 *	vchar_t: 3f fe 05 01 04
1365 *	BIGNUM (BN_ULONG = u_int8_t): 04 01 05 fe 3f
1366 *	BIGNUM (BN_ULONG = u_int16_t): 0x0104 0xfe05 0x003f
1367 *	BIGNUM (BN_ULONG = u_int32_t_t): 0xfe050104 0x0000003f
1368 */
1369int
1370eay_v2bn(bn, var)
1371	BIGNUM **bn;
1372	vchar_t *var;
1373{
1374	if ((*bn = BN_bin2bn((unsigned char *) var->v, var->l, NULL)) == NULL)
1375		return -1;
1376
1377	return 0;
1378}
1379
1380int
1381eay_bn2v(var, bn)
1382	vchar_t **var;
1383	BIGNUM *bn;
1384{
1385	*var = vmalloc(bn->top * BN_BYTES);
1386	if (*var == NULL)
1387		return(-1);
1388
1389	(*var)->l = BN_bn2bin(bn, (unsigned char *) (*var)->v);
1390
1391	return 0;
1392}
1393
1394void
1395eay_init()
1396{
1397	OpenSSL_add_all_algorithms();
1398	ERR_load_crypto_strings();
1399#ifdef HAVE_OPENSSL_ENGINE_H
1400	ENGINE_load_builtin_engines();
1401	ENGINE_register_all_complete();
1402#endif
1403}
1404#endif /* HAVE_OPENSSL */
1405
1406u_int32_t
1407eay_random()
1408{
1409	u_int32_t result;
1410	vchar_t *vrand;
1411
1412	vrand = eay_set_random(sizeof(result));
1413	memcpy(&result, vrand->v, sizeof(result));
1414	vfree(vrand);
1415
1416	return result;
1417}
1418
1419#ifdef HAVE_OPENSSL
1420const char *
1421eay_version()
1422{
1423	return SSLeay_version(SSLEAY_VERSION);
1424}
1425#endif
1426