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