]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/crypto_openssl.c
ipsec-317.220.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / crypto_openssl.c
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
78 typedef 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
101 static X509 *mem2x509(vchar_t *);
102 #endif
103 static 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 */
116 static 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 */
140 static 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
207 static 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 */
253 int
254 eay_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
282 vchar_t *
283 eay_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 */
316 int
317 eay_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. */
411 static X509 *
412 mem2x509(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 */
447 char *
448 eay_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
477 vchar_t *
478 eay_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 */
519 vchar_t *
520 eay_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
526 vchar_t *
527 eay_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
533 int
534 eay_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
548 int
549 eay_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 */
564 vchar_t *
565 eay_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
571 vchar_t *
572 eay_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
578 int
579 eay_3des_weakkey(key)
580 vchar_t *key;
581 {
582 return 0;
583 }
584
585 int
586 eay_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 */
601 vchar_t *
602 eay_aes_encrypt(data, key, iv)
603 vchar_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
608 vchar_t *
609 eay_aes_decrypt(data, key, iv)
610 vchar_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
615 int
616 eay_aes_keylen(len)
617 int 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
634 int
635 eay_aes_weakkey(key)
636 vchar_t *key;
637 {
638 return 0;
639 }
640
641 /* for ipsec part */
642 int
643 eay_null_hashlen()
644 {
645 return 0;
646 }
647
648 int
649 eay_null_keylen(len)
650 int len;
651 {
652 return 0;
653 }
654
655 /*
656 * HMAC functions
657 */
658 static caddr_t
659 eay_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 */
674 vchar_t *
675 eay_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
688 caddr_t
689 eay_hmacsha2_512_init(key)
690 vchar_t *key;
691 {
692 return eay_hmac_init(key, kCCHmacAlgSHA512);
693 }
694
695 void
696 eay_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
703 vchar_t *
704 eay_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 */
722 vchar_t *
723 eay_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
736 caddr_t
737 eay_hmacsha2_384_init(key)
738 vchar_t *key;
739 {
740 return eay_hmac_init(key, kCCHmacAlgSHA384);
741 }
742
743 void
744 eay_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
751 vchar_t *
752 eay_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 */
770 vchar_t *
771 eay_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
784 caddr_t
785 eay_hmacsha2_256_init(key)
786 vchar_t *key;
787 {
788 return eay_hmac_init(key, kCCHmacAlgSHA256);
789 }
790
791 void
792 eay_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
799 vchar_t *
800 eay_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 */
819 vchar_t *
820 eay_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
833 caddr_t
834 eay_hmacsha1_init(key)
835 vchar_t *key;
836 {
837 return eay_hmac_init(key, kCCHmacAlgSHA1);
838 }
839
840 void
841 eay_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
848 vchar_t *
849 eay_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 */
867 vchar_t *
868 eay_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
881 caddr_t
882 eay_hmacmd5_init(key)
883 vchar_t *key;
884 {
885 return eay_hmac_init(key, kCCHmacAlgMD5);
886 }
887
888 void
889 eay_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
896 vchar_t *
897 eay_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 */
918 caddr_t
919 eay_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
928 void
929 eay_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
938 vchar_t *
939 eay_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
953 vchar_t *
954 eay_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
967 int
968 eay_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
979 typedef SHA512_CTX SHA384_CTX;
980
981 caddr_t
982 eay_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
991 void
992 eay_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
1001 vchar_t *
1002 eay_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
1016 vchar_t *
1017 eay_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
1030 int
1031 eay_sha2_384_hashlen()
1032 {
1033 return SHA384_DIGEST_LENGTH << 3;
1034 }
1035 #endif
1036
1037 #ifdef WITH_SHA2
1038 /*
1039 * SHA2-256 functions
1040 */
1041 caddr_t
1042 eay_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
1051 void
1052 eay_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
1061 vchar_t *
1062 eay_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
1076 vchar_t *
1077 eay_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
1090 int
1091 eay_sha2_256_hashlen()
1092 {
1093 return SHA256_DIGEST_LENGTH << 3;
1094 }
1095 #endif
1096
1097 /*
1098 * SHA functions
1099 */
1100 caddr_t
1101 eay_sha1_init()
1102 {
1103 SHA_CTX *c = racoon_malloc(sizeof(*c));
1104
1105 SHA1_Init(c);
1106
1107 return((caddr_t)c);
1108 }
1109
1110 void
1111 eay_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
1120 vchar_t *
1121 eay_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
1135 vchar_t *
1136 eay_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
1149 int
1150 eay_sha1_hashlen()
1151 {
1152 return SHA_DIGEST_LENGTH << 3;
1153 }
1154
1155 /*
1156 * MD5 functions
1157 */
1158 caddr_t
1159 eay_md5_init()
1160 {
1161 MD5_CTX *c = racoon_malloc(sizeof(*c));
1162
1163 MD5_Init(c);
1164
1165 return((caddr_t)c);
1166 }
1167
1168 void
1169 eay_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
1178 vchar_t *
1179 eay_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
1193 vchar_t *
1194 eay_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
1207 int
1208 eay_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 */
1219 vchar_t *
1220 eay_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
1231 end:
1232 if (r)
1233 BN_free(r);
1234 return(res);
1235 }
1236 #else
1237 vchar_t *
1238 eay_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 */
1256 int
1257 eay_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
1298 end:
1299 if (dh != NULL)
1300 DH_free(dh);
1301 if (p != 0)
1302 BN_free(p);
1303 return(error);
1304 }
1305
1306 int
1307 eay_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
1346 end:
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 */
1369 int
1370 eay_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
1380 int
1381 eay_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
1394 void
1395 eay_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
1406 u_int32_t
1407 eay_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
1420 const char *
1421 eay_version()
1422 {
1423 return SSLeay_version(SSLEAY_VERSION);
1424 }
1425 #endif