crypto.c revision 72448
1/* 2 * Copyright (c) 1997 - 2001 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 "krb5_locl.h" 35RCSID("$Id: crypto.c,v 1.29 2000/01/25 23:06:55 assar Exp $"); 36/* RCSID("$FreeBSD: head/crypto/heimdal/lib/krb5/crypto.c 72448 2001-02-13 16:52:56Z assar $"); */ 37 38#undef CRYPTO_DEBUG 39#ifdef CRYPTO_DEBUG 40static void krb5_crypto_debug(krb5_context, int, size_t, krb5_keyblock*); 41#endif 42 43 44struct key_data { 45 krb5_keyblock *key; 46 krb5_data *schedule; 47}; 48 49struct key_usage { 50 unsigned usage; 51 struct key_data key; 52}; 53 54struct krb5_crypto_data { 55 struct encryption_type *et; 56 struct key_data key; 57 int num_key_usage; 58 struct key_usage *key_usage; 59}; 60 61#define CRYPTO_ETYPE(C) ((C)->et->type) 62 63/* bits for `flags' below */ 64#define F_KEYED 1 /* checksum is keyed */ 65#define F_CPROOF 2 /* checksum is collision proof */ 66#define F_DERIVED 4 /* uses derived keys */ 67#define F_VARIANT 8 /* uses `variant' keys (6.4.3) */ 68#define F_PSEUDO 16 /* not a real protocol type */ 69#define F_SPECIAL 32 /* backwards */ 70 71struct salt_type { 72 krb5_salttype type; 73 const char *name; 74 krb5_error_code (*string_to_key)(krb5_context, krb5_enctype, krb5_data, 75 krb5_salt, krb5_keyblock*); 76}; 77 78struct key_type { 79 krb5_keytype type; /* XXX */ 80 const char *name; 81 size_t bits; 82 size_t size; 83 size_t schedule_size; 84#if 0 85 krb5_enctype best_etype; 86#endif 87 void (*random_key)(krb5_context, krb5_keyblock*); 88 void (*schedule)(krb5_context, struct key_data *); 89 struct salt_type *string_to_key; 90}; 91 92struct checksum_type { 93 krb5_cksumtype type; 94 const char *name; 95 size_t blocksize; 96 size_t checksumsize; 97 unsigned flags; 98 void (*checksum)(krb5_context context, 99 struct key_data *key, 100 const void *buf, size_t len, 101 unsigned usage, 102 Checksum *csum); 103 krb5_error_code (*verify)(krb5_context context, 104 struct key_data *key, 105 const void *buf, size_t len, 106 unsigned usage, 107 Checksum *csum); 108}; 109 110struct encryption_type { 111 krb5_enctype type; 112 const char *name; 113 size_t blocksize; 114 size_t confoundersize; 115 struct key_type *keytype; 116 struct checksum_type *cksumtype; 117 struct checksum_type *keyed_checksum; 118 unsigned flags; 119 krb5_error_code (*encrypt)(struct key_data *key, 120 void *data, size_t len, 121 krb5_boolean encrypt, 122 int usage, 123 void *ivec); 124}; 125 126#define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA) 127#define INTEGRITY_USAGE(U) (((U) << 8) | 0x55) 128#define CHECKSUM_USAGE(U) (((U) << 8) | 0x99) 129 130static struct checksum_type *_find_checksum(krb5_cksumtype type); 131static struct encryption_type *_find_enctype(krb5_enctype type); 132static struct key_type *_find_keytype(krb5_keytype type); 133static krb5_error_code _get_derived_key(krb5_context, krb5_crypto, 134 unsigned, struct key_data**); 135static struct key_data *_new_derived_key(krb5_crypto crypto, unsigned usage); 136 137/************************************************************ 138 * * 139 ************************************************************/ 140 141static void 142DES_random_key(krb5_context context, 143 krb5_keyblock *key) 144{ 145 des_cblock *k = key->keyvalue.data; 146 do { 147 krb5_generate_random_block(k, sizeof(des_cblock)); 148 des_set_odd_parity(k); 149 } while(des_is_weak_key(k)); 150} 151 152static void 153DES_schedule(krb5_context context, 154 struct key_data *key) 155{ 156 des_set_key(key->key->keyvalue.data, key->schedule->data); 157} 158 159static krb5_error_code 160DES_string_to_key(krb5_context context, 161 krb5_enctype enctype, 162 krb5_data password, 163 krb5_salt salt, 164 krb5_keyblock *key) 165{ 166 char *s; 167 size_t len; 168 des_cblock tmp; 169 170 len = password.length + salt.saltvalue.length + 1; 171 s = malloc(len); 172 if(s == NULL) 173 return ENOMEM; 174 memcpy(s, password.data, password.length); 175 memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); 176 s[len - 1] = '\0'; 177 des_string_to_key(s, &tmp); 178 key->keytype = enctype; 179 krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp)); 180 memset(&tmp, 0, sizeof(tmp)); 181 memset(s, 0, len); 182 free(s); 183 return 0; 184} 185 186/* This defines the Andrew string_to_key function. It accepts a password 187 * string as input and converts its via a one-way encryption algorithm to a DES 188 * encryption key. It is compatible with the original Andrew authentication 189 * service password database. 190 */ 191 192/* 193 * Short passwords, i.e 8 characters or less. 194 */ 195static void 196DES_AFS3_CMU_string_to_key (krb5_data pw, 197 krb5_data cell, 198 des_cblock *key) 199{ 200 char password[8+1]; /* crypt is limited to 8 chars anyway */ 201 int i; 202 203 for(i = 0; i < 8; i++) { 204 char c = ((i < pw.length) ? ((char*)pw.data)[i] : 0) ^ 205 ((i < cell.length) ? 206 tolower(((unsigned char*)cell.data)[i]) : 0); 207 password[i] = c ? c : 'X'; 208 } 209 password[8] = '\0'; 210 211 memcpy(key, crypt(password, "#~") + 2, sizeof(des_cblock)); 212 213 /* parity is inserted into the LSB so left shift each byte up one 214 bit. This allows ascii characters with a zero MSB to retain as 215 much significance as possible. */ 216 for (i = 0; i < sizeof(des_cblock); i++) 217 ((unsigned char*)key)[i] <<= 1; 218 des_set_odd_parity (key); 219} 220 221/* 222 * Long passwords, i.e 9 characters or more. 223 */ 224static void 225DES_AFS3_Transarc_string_to_key (krb5_data pw, 226 krb5_data cell, 227 des_cblock *key) 228{ 229 des_key_schedule schedule; 230 des_cblock temp_key; 231 des_cblock ivec; 232 char password[512]; 233 size_t passlen; 234 235 memcpy(password, pw.data, min(pw.length, sizeof(password))); 236 if(pw.length < sizeof(password)) { 237 int len = min(cell.length, sizeof(password) - pw.length); 238 int i; 239 240 memcpy(password + pw.length, cell.data, len); 241 for (i = pw.length; i < pw.length + len; ++i) 242 password[i] = tolower((unsigned char)password[i]); 243 } 244 passlen = min(sizeof(password), pw.length + cell.length); 245 memcpy(&ivec, "kerberos", 8); 246 memcpy(&temp_key, "kerberos", 8); 247 des_set_odd_parity (&temp_key); 248 des_set_key (&temp_key, schedule); 249 des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec); 250 251 memcpy(&temp_key, &ivec, 8); 252 des_set_odd_parity (&temp_key); 253 des_set_key (&temp_key, schedule); 254 des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec); 255 memset(&schedule, 0, sizeof(schedule)); 256 memset(&temp_key, 0, sizeof(temp_key)); 257 memset(&ivec, 0, sizeof(ivec)); 258 memset(password, 0, sizeof(password)); 259 260 des_set_odd_parity (key); 261} 262 263static krb5_error_code 264DES_AFS3_string_to_key(krb5_context context, 265 krb5_enctype enctype, 266 krb5_data password, 267 krb5_salt salt, 268 krb5_keyblock *key) 269{ 270 des_cblock tmp; 271 if(password.length > 8) 272 DES_AFS3_Transarc_string_to_key(password, salt.saltvalue, &tmp); 273 else 274 DES_AFS3_CMU_string_to_key(password, salt.saltvalue, &tmp); 275 key->keytype = enctype; 276 krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp)); 277 memset(&key, 0, sizeof(key)); 278 return 0; 279} 280 281static void 282DES3_random_key(krb5_context context, 283 krb5_keyblock *key) 284{ 285 des_cblock *k = key->keyvalue.data; 286 do { 287 krb5_generate_random_block(k, 3 * sizeof(des_cblock)); 288 des_set_odd_parity(&k[0]); 289 des_set_odd_parity(&k[1]); 290 des_set_odd_parity(&k[2]); 291 } while(des_is_weak_key(&k[0]) || 292 des_is_weak_key(&k[1]) || 293 des_is_weak_key(&k[2])); 294} 295 296static void 297DES3_schedule(krb5_context context, 298 struct key_data *key) 299{ 300 des_cblock *k = key->key->keyvalue.data; 301 des_key_schedule *s = key->schedule->data; 302 des_set_key(&k[0], s[0]); 303 des_set_key(&k[1], s[1]); 304 des_set_key(&k[2], s[2]); 305} 306 307/* 308 * A = A xor B. A & B are 8 bytes. 309 */ 310 311static void 312xor (des_cblock *key, const unsigned char *b) 313{ 314 unsigned char *a = (unsigned char*)key; 315 a[0] ^= b[0]; 316 a[1] ^= b[1]; 317 a[2] ^= b[2]; 318 a[3] ^= b[3]; 319 a[4] ^= b[4]; 320 a[5] ^= b[5]; 321 a[6] ^= b[6]; 322 a[7] ^= b[7]; 323} 324 325static krb5_error_code 326DES3_string_to_key(krb5_context context, 327 krb5_enctype enctype, 328 krb5_data password, 329 krb5_salt salt, 330 krb5_keyblock *key) 331{ 332 char *str; 333 size_t len; 334 unsigned char tmp[24]; 335 des_cblock keys[3]; 336 337 len = password.length + salt.saltvalue.length; 338 str = malloc(len); 339 if(len != 0 && str == NULL) 340 return ENOMEM; 341 memcpy(str, password.data, password.length); 342 memcpy(str + password.length, salt.saltvalue.data, salt.saltvalue.length); 343 { 344 des_cblock ivec; 345 des_key_schedule s[3]; 346 int i; 347 348 _krb5_n_fold(str, len, tmp, 24); 349 350 for(i = 0; i < 3; i++){ 351 memcpy(keys + i, tmp + i * 8, sizeof(keys[i])); 352 des_set_odd_parity(keys + i); 353 if(des_is_weak_key(keys + i)) 354 xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0"); 355 des_set_key(keys + i, s[i]); 356 } 357 memset(&ivec, 0, sizeof(ivec)); 358 des_ede3_cbc_encrypt((des_cblock *)tmp, 359 (des_cblock *)tmp, sizeof(tmp), 360 s[0], s[1], s[2], &ivec, DES_ENCRYPT); 361 memset(s, 0, sizeof(s)); 362 memset(&ivec, 0, sizeof(ivec)); 363 for(i = 0; i < 3; i++){ 364 memcpy(keys + i, tmp + i * 8, sizeof(keys[i])); 365 des_set_odd_parity(keys + i); 366 if(des_is_weak_key(keys + i)) 367 xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0"); 368 } 369 memset(tmp, 0, sizeof(tmp)); 370 } 371 key->keytype = enctype; 372 krb5_data_copy(&key->keyvalue, keys, sizeof(keys)); 373 memset(keys, 0, sizeof(keys)); 374 memset(str, 0, len); 375 free(str); 376 return 0; 377} 378 379static krb5_error_code 380DES3_string_to_key_derived(krb5_context context, 381 krb5_enctype enctype, 382 krb5_data password, 383 krb5_salt salt, 384 krb5_keyblock *key) 385{ 386 krb5_error_code ret; 387 size_t len = password.length + salt.saltvalue.length; 388 char *s; 389 390 s = malloc(len); 391 if(len != 0 && s == NULL) 392 return ENOMEM; 393 memcpy(s, password.data, password.length); 394 memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); 395 ret = krb5_string_to_key_derived(context, 396 s, 397 len, 398 enctype, 399 key); 400 memset(s, 0, len); 401 free(s); 402 return ret; 403} 404 405/* 406 * ARCFOUR 407 */ 408 409static void 410ARCFOUR_random_key(krb5_context context, krb5_keyblock *key) 411{ 412 krb5_generate_random_block (key->keyvalue.data, 413 key->keyvalue.length); 414} 415 416static void 417ARCFOUR_schedule(krb5_context context, struct key_data *kd) 418{ 419 RC4_set_key (kd->schedule->data, 420 kd->key->keyvalue.length, kd->key->keyvalue.data); 421} 422 423static krb5_error_code 424ARCFOUR_string_to_key(krb5_context context, 425 krb5_enctype enctype, 426 krb5_data password, 427 krb5_salt salt, 428 krb5_keyblock *key) 429{ 430 char *s, *p; 431 size_t len; 432 int i; 433 MD4_CTX m; 434 435 len = 2 * password.length; 436 s = malloc (len); 437 if (len != 0 && s == NULL) 438 return ENOMEM; 439 for (p = s, i = 0; i < password.length; ++i) { 440 *p++ = ((char *)password.data)[i]; 441 *p++ = 0; 442 } 443 MD4_Init (&m); 444 MD4_Update (&m, s, len); 445 key->keytype = enctype; 446 krb5_data_alloc (&key->keyvalue, 16); 447 MD4_Final (key->keyvalue.data, &m); 448 memset (s, 0, len); 449 free (s); 450 return 0; 451} 452 453extern struct salt_type des_salt[], 454 des3_salt[], des3_salt_derived[], arcfour_salt[]; 455 456struct key_type keytype_null = { 457 KEYTYPE_NULL, 458 "null", 459 0, 460 0, 461 0, 462 NULL, 463 NULL, 464 NULL 465}; 466 467struct key_type keytype_des = { 468 KEYTYPE_DES, 469 "des", 470 56, 471 sizeof(des_cblock), 472 sizeof(des_key_schedule), 473 DES_random_key, 474 DES_schedule, 475 des_salt 476}; 477 478struct key_type keytype_des3 = { 479 KEYTYPE_DES3, 480 "des3", 481 168, 482 3 * sizeof(des_cblock), 483 3 * sizeof(des_key_schedule), 484 DES3_random_key, 485 DES3_schedule, 486 des3_salt 487}; 488 489struct key_type keytype_des3_derived = { 490 KEYTYPE_DES3, 491 "des3", 492 168, 493 3 * sizeof(des_cblock), 494 3 * sizeof(des_key_schedule), 495 DES3_random_key, 496 DES3_schedule, 497 des3_salt_derived 498}; 499 500struct key_type keytype_arcfour = { 501 KEYTYPE_ARCFOUR, 502 "arcfour", 503 128, 504 16, 505 sizeof(RC4_KEY), 506 ARCFOUR_random_key, 507 ARCFOUR_schedule, 508 arcfour_salt 509}; 510 511struct key_type *keytypes[] = { 512 &keytype_null, 513 &keytype_des, 514 &keytype_des3_derived, 515 &keytype_des3, 516 &keytype_arcfour 517}; 518 519static int num_keytypes = sizeof(keytypes) / sizeof(keytypes[0]); 520 521static struct key_type * 522_find_keytype(krb5_keytype type) 523{ 524 int i; 525 for(i = 0; i < num_keytypes; i++) 526 if(keytypes[i]->type == type) 527 return keytypes[i]; 528 return NULL; 529} 530 531 532struct salt_type des_salt[] = { 533 { 534 KRB5_PW_SALT, 535 "pw-salt", 536 DES_string_to_key 537 }, 538 { 539 KRB5_AFS3_SALT, 540 "afs3-salt", 541 DES_AFS3_string_to_key 542 }, 543 { 0 } 544}; 545 546struct salt_type des3_salt[] = { 547 { 548 KRB5_PW_SALT, 549 "pw-salt", 550 DES3_string_to_key 551 }, 552 { 0 } 553}; 554 555struct salt_type des3_salt_derived[] = { 556 { 557 KRB5_PW_SALT, 558 "pw-salt", 559 DES3_string_to_key_derived 560 }, 561 { 0 } 562}; 563 564struct salt_type arcfour_salt[] = { 565 { 566 KRB5_PW_SALT, 567 "pw-salt", 568 ARCFOUR_string_to_key 569 }, 570 { 0 } 571}; 572 573krb5_error_code 574krb5_salttype_to_string (krb5_context context, 575 krb5_enctype etype, 576 krb5_salttype stype, 577 char **string) 578{ 579 struct encryption_type *e; 580 struct salt_type *st; 581 582 e = _find_enctype (etype); 583 if (e == NULL) 584 return KRB5_PROG_ETYPE_NOSUPP; 585 for (st = e->keytype->string_to_key; st && st->type; st++) { 586 if (st->type == stype) { 587 *string = strdup (st->name); 588 if (*string == NULL) 589 return ENOMEM; 590 return 0; 591 } 592 } 593 return HEIM_ERR_SALTTYPE_NOSUPP; 594} 595 596krb5_error_code 597krb5_string_to_salttype (krb5_context context, 598 krb5_enctype etype, 599 const char *string, 600 krb5_salttype *salttype) 601{ 602 struct encryption_type *e; 603 struct salt_type *st; 604 605 e = _find_enctype (etype); 606 if (e == NULL) 607 return KRB5_PROG_ETYPE_NOSUPP; 608 for (st = e->keytype->string_to_key; st && st->type; st++) { 609 if (strcasecmp (st->name, string) == 0) { 610 *salttype = st->type; 611 return 0; 612 } 613 } 614 return HEIM_ERR_SALTTYPE_NOSUPP; 615} 616 617krb5_error_code 618krb5_get_pw_salt(krb5_context context, 619 krb5_const_principal principal, 620 krb5_salt *salt) 621{ 622 size_t len; 623 int i; 624 krb5_error_code ret; 625 char *p; 626 627 salt->salttype = KRB5_PW_SALT; 628 len = strlen(principal->realm); 629 for (i = 0; i < principal->name.name_string.len; ++i) 630 len += strlen(principal->name.name_string.val[i]); 631 ret = krb5_data_alloc (&salt->saltvalue, len); 632 if (ret) 633 return ret; 634 p = salt->saltvalue.data; 635 memcpy (p, principal->realm, strlen(principal->realm)); 636 p += strlen(principal->realm); 637 for (i = 0; i < principal->name.name_string.len; ++i) { 638 memcpy (p, 639 principal->name.name_string.val[i], 640 strlen(principal->name.name_string.val[i])); 641 p += strlen(principal->name.name_string.val[i]); 642 } 643 return 0; 644} 645 646krb5_error_code 647krb5_free_salt(krb5_context context, 648 krb5_salt salt) 649{ 650 krb5_data_free(&salt.saltvalue); 651 return 0; 652} 653 654krb5_error_code 655krb5_string_to_key_data (krb5_context context, 656 krb5_enctype enctype, 657 krb5_data password, 658 krb5_principal principal, 659 krb5_keyblock *key) 660{ 661 krb5_error_code ret; 662 krb5_salt salt; 663 664 ret = krb5_get_pw_salt(context, principal, &salt); 665 if(ret) 666 return ret; 667 ret = krb5_string_to_key_data_salt(context, enctype, password, salt, key); 668 krb5_free_salt(context, salt); 669 return ret; 670} 671 672krb5_error_code 673krb5_string_to_key (krb5_context context, 674 krb5_enctype enctype, 675 const char *password, 676 krb5_principal principal, 677 krb5_keyblock *key) 678{ 679 krb5_data pw; 680 pw.data = (void*)password; 681 pw.length = strlen(password); 682 return krb5_string_to_key_data(context, enctype, pw, principal, key); 683} 684 685/* 686 * Do a string -> key for encryption type `enctype' operation on 687 * `password' (with salt `salt'), returning the resulting key in `key' 688 */ 689 690krb5_error_code 691krb5_string_to_key_data_salt (krb5_context context, 692 krb5_enctype enctype, 693 krb5_data password, 694 krb5_salt salt, 695 krb5_keyblock *key) 696{ 697 struct encryption_type *et =_find_enctype(enctype); 698 struct salt_type *st; 699 if(et == NULL) 700 return KRB5_PROG_ETYPE_NOSUPP; 701 for(st = et->keytype->string_to_key; st && st->type; st++) 702 if(st->type == salt.salttype) 703 return (*st->string_to_key)(context, enctype, password, salt, key); 704 return HEIM_ERR_SALTTYPE_NOSUPP; 705} 706 707/* 708 * Do a string -> key for encryption type `enctype' operation on the 709 * string `password' (with salt `salt'), returning the resulting key 710 * in `key' 711 */ 712 713krb5_error_code 714krb5_string_to_key_salt (krb5_context context, 715 krb5_enctype enctype, 716 const char *password, 717 krb5_salt salt, 718 krb5_keyblock *key) 719{ 720 krb5_data pw; 721 pw.data = (void*)password; 722 pw.length = strlen(password); 723 return krb5_string_to_key_data_salt(context, enctype, pw, salt, key); 724} 725 726krb5_error_code 727krb5_keytype_to_string(krb5_context context, 728 krb5_keytype keytype, 729 char **string) 730{ 731 struct key_type *kt = _find_keytype(keytype); 732 if(kt == NULL) 733 return KRB5_PROG_KEYTYPE_NOSUPP; 734 *string = strdup(kt->name); 735 if(*string == NULL) 736 return ENOMEM; 737 return 0; 738} 739 740krb5_error_code 741krb5_string_to_keytype(krb5_context context, 742 const char *string, 743 krb5_keytype *keytype) 744{ 745 int i; 746 for(i = 0; i < num_keytypes; i++) 747 if(strcasecmp(keytypes[i]->name, string) == 0){ 748 *keytype = keytypes[i]->type; 749 return 0; 750 } 751 return KRB5_PROG_KEYTYPE_NOSUPP; 752} 753 754krb5_error_code 755krb5_generate_random_keyblock(krb5_context context, 756 krb5_enctype type, 757 krb5_keyblock *key) 758{ 759 krb5_error_code ret; 760 struct encryption_type *et = _find_enctype(type); 761 if(et == NULL) 762 return KRB5_PROG_ETYPE_NOSUPP; 763 ret = krb5_data_alloc(&key->keyvalue, et->keytype->size); 764 if(ret) 765 return ret; 766 key->keytype = type; 767 if(et->keytype->random_key) 768 (*et->keytype->random_key)(context, key); 769 else 770 krb5_generate_random_block(key->keyvalue.data, 771 key->keyvalue.length); 772 return 0; 773} 774 775static krb5_error_code 776_key_schedule(krb5_context context, 777 struct key_data *key) 778{ 779 krb5_error_code ret; 780 struct encryption_type *et = _find_enctype(key->key->keytype); 781 struct key_type *kt = et->keytype; 782 783 if(kt->schedule == NULL) 784 return 0; 785 if (key->schedule != NULL) 786 return 0; 787 ALLOC(key->schedule, 1); 788 if(key->schedule == NULL) 789 return ENOMEM; 790 ret = krb5_data_alloc(key->schedule, kt->schedule_size); 791 if(ret) { 792 free(key->schedule); 793 key->schedule = NULL; 794 return ret; 795 } 796 (*kt->schedule)(context, key); 797 return 0; 798} 799 800/************************************************************ 801 * * 802 ************************************************************/ 803 804static void 805NONE_checksum(krb5_context context, 806 struct key_data *key, 807 const void *data, 808 size_t len, 809 unsigned usage, 810 Checksum *C) 811{ 812} 813 814static void 815CRC32_checksum(krb5_context context, 816 struct key_data *key, 817 const void *data, 818 size_t len, 819 unsigned usage, 820 Checksum *C) 821{ 822 u_int32_t crc; 823 unsigned char *r = C->checksum.data; 824 _krb5_crc_init_table (); 825 crc = _krb5_crc_update (data, len, 0); 826 r[0] = crc & 0xff; 827 r[1] = (crc >> 8) & 0xff; 828 r[2] = (crc >> 16) & 0xff; 829 r[3] = (crc >> 24) & 0xff; 830} 831 832static void 833RSA_MD4_checksum(krb5_context context, 834 struct key_data *key, 835 const void *data, 836 size_t len, 837 unsigned usage, 838 Checksum *C) 839{ 840 MD4_CTX m; 841 842 MD4_Init (&m); 843 MD4_Update (&m, data, len); 844 MD4_Final (C->checksum.data, &m); 845} 846 847static void 848RSA_MD4_DES_checksum(krb5_context context, 849 struct key_data *key, 850 const void *data, 851 size_t len, 852 unsigned usage, 853 Checksum *cksum) 854{ 855 MD4_CTX md4; 856 des_cblock ivec; 857 unsigned char *p = cksum->checksum.data; 858 859 krb5_generate_random_block(p, 8); 860 MD4_Init (&md4); 861 MD4_Update (&md4, p, 8); 862 MD4_Update (&md4, data, len); 863 MD4_Final (p + 8, &md4); 864 memset (&ivec, 0, sizeof(ivec)); 865 des_cbc_encrypt((des_cblock*)p, 866 (des_cblock*)p, 867 24, 868 key->schedule->data, 869 &ivec, 870 DES_ENCRYPT); 871} 872 873static krb5_error_code 874RSA_MD4_DES_verify(krb5_context context, 875 struct key_data *key, 876 const void *data, 877 size_t len, 878 unsigned usage, 879 Checksum *C) 880{ 881 MD4_CTX md4; 882 unsigned char tmp[24]; 883 unsigned char res[16]; 884 des_cblock ivec; 885 krb5_error_code ret = 0; 886 887 memset(&ivec, 0, sizeof(ivec)); 888 des_cbc_encrypt(C->checksum.data, 889 (void*)tmp, 890 C->checksum.length, 891 key->schedule->data, 892 &ivec, 893 DES_DECRYPT); 894 MD4_Init (&md4); 895 MD4_Update (&md4, tmp, 8); /* confounder */ 896 MD4_Update (&md4, data, len); 897 MD4_Final (res, &md4); 898 if(memcmp(res, tmp + 8, sizeof(res)) != 0) 899 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 900 memset(tmp, 0, sizeof(tmp)); 901 memset(res, 0, sizeof(res)); 902 return ret; 903} 904 905static void 906RSA_MD5_checksum(krb5_context context, 907 struct key_data *key, 908 const void *data, 909 size_t len, 910 unsigned usage, 911 Checksum *C) 912{ 913 MD5_CTX m; 914 915 MD5_Init (&m); 916 MD5_Update(&m, data, len); 917 MD5_Final (C->checksum.data, &m); 918} 919 920static void 921RSA_MD5_DES_checksum(krb5_context context, 922 struct key_data *key, 923 const void *data, 924 size_t len, 925 unsigned usage, 926 Checksum *C) 927{ 928 MD5_CTX md5; 929 des_cblock ivec; 930 unsigned char *p = C->checksum.data; 931 932 krb5_generate_random_block(p, 8); 933 MD5_Init (&md5); 934 MD5_Update (&md5, p, 8); 935 MD5_Update (&md5, data, len); 936 MD5_Final (p + 8, &md5); 937 memset (&ivec, 0, sizeof(ivec)); 938 des_cbc_encrypt((des_cblock*)p, 939 (des_cblock*)p, 940 24, 941 key->schedule->data, 942 &ivec, 943 DES_ENCRYPT); 944} 945 946static krb5_error_code 947RSA_MD5_DES_verify(krb5_context context, 948 struct key_data *key, 949 const void *data, 950 size_t len, 951 unsigned usage, 952 Checksum *C) 953{ 954 MD5_CTX md5; 955 unsigned char tmp[24]; 956 unsigned char res[16]; 957 des_cblock ivec; 958 des_key_schedule *sched = key->schedule->data; 959 krb5_error_code ret = 0; 960 961 memset(&ivec, 0, sizeof(ivec)); 962 des_cbc_encrypt(C->checksum.data, 963 (void*)tmp, 964 C->checksum.length, 965 sched[0], 966 &ivec, 967 DES_DECRYPT); 968 MD5_Init (&md5); 969 MD5_Update (&md5, tmp, 8); /* confounder */ 970 MD5_Update (&md5, data, len); 971 MD5_Final (res, &md5); 972 if(memcmp(res, tmp + 8, sizeof(res)) != 0) 973 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 974 memset(tmp, 0, sizeof(tmp)); 975 memset(res, 0, sizeof(res)); 976 return ret; 977} 978 979static void 980RSA_MD5_DES3_checksum(krb5_context context, 981 struct key_data *key, 982 const void *data, 983 size_t len, 984 unsigned usage, 985 Checksum *C) 986{ 987 MD5_CTX md5; 988 des_cblock ivec; 989 unsigned char *p = C->checksum.data; 990 des_key_schedule *sched = key->schedule->data; 991 992 krb5_generate_random_block(p, 8); 993 MD5_Init (&md5); 994 MD5_Update (&md5, p, 8); 995 MD5_Update (&md5, data, len); 996 MD5_Final (p + 8, &md5); 997 memset (&ivec, 0, sizeof(ivec)); 998 des_ede3_cbc_encrypt((des_cblock*)p, 999 (des_cblock*)p, 1000 24, 1001 sched[0], sched[1], sched[2], 1002 &ivec, 1003 DES_ENCRYPT); 1004} 1005 1006static krb5_error_code 1007RSA_MD5_DES3_verify(krb5_context context, 1008 struct key_data *key, 1009 const void *data, 1010 size_t len, 1011 unsigned usage, 1012 Checksum *C) 1013{ 1014 MD5_CTX md5; 1015 unsigned char tmp[24]; 1016 unsigned char res[16]; 1017 des_cblock ivec; 1018 des_key_schedule *sched = key->schedule->data; 1019 krb5_error_code ret = 0; 1020 1021 memset(&ivec, 0, sizeof(ivec)); 1022 des_ede3_cbc_encrypt(C->checksum.data, 1023 (void*)tmp, 1024 C->checksum.length, 1025 sched[0], sched[1], sched[2], 1026 &ivec, 1027 DES_DECRYPT); 1028 MD5_Init (&md5); 1029 MD5_Update (&md5, tmp, 8); /* confounder */ 1030 MD5_Update (&md5, data, len); 1031 MD5_Final (res, &md5); 1032 if(memcmp(res, tmp + 8, sizeof(res)) != 0) 1033 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 1034 memset(tmp, 0, sizeof(tmp)); 1035 memset(res, 0, sizeof(res)); 1036 return ret; 1037} 1038 1039static void 1040SHA1_checksum(krb5_context context, 1041 struct key_data *key, 1042 const void *data, 1043 size_t len, 1044 unsigned usage, 1045 Checksum *C) 1046{ 1047 SHA_CTX m; 1048 1049 SHA1_Init(&m); 1050 SHA1_Update(&m, data, len); 1051 SHA1_Final(C->checksum.data, &m); 1052} 1053 1054/* HMAC according to RFC2104 */ 1055static void 1056hmac(krb5_context context, 1057 struct checksum_type *cm, 1058 const void *data, 1059 size_t len, 1060 unsigned usage, 1061 struct key_data *keyblock, 1062 Checksum *result) 1063{ 1064 unsigned char *ipad, *opad; 1065 unsigned char *key; 1066 size_t key_len; 1067 int i; 1068 1069 if(keyblock->key->keyvalue.length > cm->blocksize){ 1070 (*cm->checksum)(context, 1071 keyblock, 1072 keyblock->key->keyvalue.data, 1073 keyblock->key->keyvalue.length, 1074 usage, 1075 result); 1076 key = result->checksum.data; 1077 key_len = result->checksum.length; 1078 } else { 1079 key = keyblock->key->keyvalue.data; 1080 key_len = keyblock->key->keyvalue.length; 1081 } 1082 ipad = malloc(cm->blocksize + len); 1083 opad = malloc(cm->blocksize + cm->checksumsize); 1084 memset(ipad, 0x36, cm->blocksize); 1085 memset(opad, 0x5c, cm->blocksize); 1086 for(i = 0; i < key_len; i++){ 1087 ipad[i] ^= key[i]; 1088 opad[i] ^= key[i]; 1089 } 1090 memcpy(ipad + cm->blocksize, data, len); 1091 (*cm->checksum)(context, keyblock, ipad, cm->blocksize + len, 1092 usage, result); 1093 memcpy(opad + cm->blocksize, result->checksum.data, 1094 result->checksum.length); 1095 (*cm->checksum)(context, keyblock, opad, 1096 cm->blocksize + cm->checksumsize, usage, result); 1097 memset(ipad, 0, cm->blocksize + len); 1098 free(ipad); 1099 memset(opad, 0, cm->blocksize + cm->checksumsize); 1100 free(opad); 1101} 1102 1103static void 1104HMAC_SHA1_DES3_checksum(krb5_context context, 1105 struct key_data *key, 1106 const void *data, 1107 size_t len, 1108 unsigned usage, 1109 Checksum *result) 1110{ 1111 struct checksum_type *c = _find_checksum(CKSUMTYPE_SHA1); 1112 1113 hmac(context, c, data, len, usage, key, result); 1114} 1115 1116/* 1117 * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt 1118 */ 1119 1120static void 1121HMAC_MD5_checksum(krb5_context context, 1122 struct key_data *key, 1123 const void *data, 1124 size_t len, 1125 unsigned usage, 1126 Checksum *result) 1127{ 1128 MD5_CTX md5; 1129 struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); 1130 const char signature[] = "signaturekey"; 1131 Checksum ksign_c; 1132 struct key_data ksign; 1133 krb5_keyblock kb; 1134 unsigned char t[4]; 1135 unsigned char tmp[16]; 1136 unsigned char ksign_c_data[16]; 1137 1138 ksign_c.checksum.length = sizeof(ksign_c_data); 1139 ksign_c.checksum.data = ksign_c_data; 1140 hmac(context, c, signature, sizeof(signature), 0, key, &ksign_c); 1141 ksign.key = &kb; 1142 kb.keyvalue = ksign_c.checksum; 1143 MD5_Init (&md5); 1144 t[0] = (usage >> 0) & 0xFF; 1145 t[1] = (usage >> 8) & 0xFF; 1146 t[2] = (usage >> 16) & 0xFF; 1147 t[3] = (usage >> 24) & 0xFF; 1148 MD5_Update (&md5, t, 4); 1149 MD5_Update (&md5, data, len); 1150 MD5_Final (tmp, &md5); 1151 hmac(context, c, tmp, sizeof(tmp), 0, &ksign, result); 1152} 1153 1154/* 1155 * same as previous but being used while encrypting. 1156 */ 1157 1158static void 1159HMAC_MD5_checksum_enc(krb5_context context, 1160 struct key_data *key, 1161 const void *data, 1162 size_t len, 1163 unsigned usage, 1164 Checksum *result) 1165{ 1166 struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); 1167 Checksum ksign_c; 1168 struct key_data ksign; 1169 krb5_keyblock kb; 1170 unsigned char t[4]; 1171 unsigned char ksign_c_data[16]; 1172 1173 t[0] = (usage >> 0) & 0xFF; 1174 t[1] = (usage >> 8) & 0xFF; 1175 t[2] = (usage >> 16) & 0xFF; 1176 t[3] = (usage >> 24) & 0xFF; 1177 1178 ksign_c.checksum.length = sizeof(ksign_c_data); 1179 ksign_c.checksum.data = ksign_c_data; 1180 hmac(context, c, t, sizeof(t), 0, key, &ksign_c); 1181 ksign.key = &kb; 1182 kb.keyvalue = ksign_c.checksum; 1183 hmac(context, c, data, len, 0, &ksign, result); 1184} 1185 1186struct checksum_type checksum_none = { 1187 CKSUMTYPE_NONE, 1188 "none", 1189 1, 1190 0, 1191 0, 1192 NONE_checksum, 1193 NULL 1194}; 1195struct checksum_type checksum_crc32 = { 1196 CKSUMTYPE_CRC32, 1197 "crc32", 1198 1, 1199 4, 1200 0, 1201 CRC32_checksum, 1202 NULL 1203}; 1204struct checksum_type checksum_rsa_md4 = { 1205 CKSUMTYPE_RSA_MD4, 1206 "rsa-md4", 1207 64, 1208 16, 1209 F_CPROOF, 1210 RSA_MD4_checksum, 1211 NULL 1212}; 1213struct checksum_type checksum_rsa_md4_des = { 1214 CKSUMTYPE_RSA_MD4_DES, 1215 "rsa-md4-des", 1216 64, 1217 24, 1218 F_KEYED | F_CPROOF | F_VARIANT, 1219 RSA_MD4_DES_checksum, 1220 RSA_MD4_DES_verify 1221}; 1222#if 0 1223struct checksum_type checksum_des_mac = { 1224 CKSUMTYPE_DES_MAC, 1225 "des-mac", 1226 0, 1227 0, 1228 0, 1229 DES_MAC_checksum 1230}; 1231struct checksum_type checksum_des_mac_k = { 1232 CKSUMTYPE_DES_MAC_K, 1233 "des-mac-k", 1234 0, 1235 0, 1236 0, 1237 DES_MAC_K_checksum 1238}; 1239struct checksum_type checksum_rsa_md4_des_k = { 1240 CKSUMTYPE_RSA_MD4_DES_K, 1241 "rsa-md4-des-k", 1242 0, 1243 0, 1244 0, 1245 RSA_MD4_DES_K_checksum, 1246 RSA_MD4_DES_K_verify 1247}; 1248#endif 1249struct checksum_type checksum_rsa_md5 = { 1250 CKSUMTYPE_RSA_MD5, 1251 "rsa-md5", 1252 64, 1253 16, 1254 F_CPROOF, 1255 RSA_MD5_checksum, 1256 NULL 1257}; 1258struct checksum_type checksum_rsa_md5_des = { 1259 CKSUMTYPE_RSA_MD5_DES, 1260 "rsa-md5-des", 1261 64, 1262 24, 1263 F_KEYED | F_CPROOF | F_VARIANT, 1264 RSA_MD5_DES_checksum, 1265 RSA_MD5_DES_verify 1266}; 1267struct checksum_type checksum_rsa_md5_des3 = { 1268 CKSUMTYPE_RSA_MD5_DES3, 1269 "rsa-md5-des3", 1270 64, 1271 24, 1272 F_KEYED | F_CPROOF | F_VARIANT, 1273 RSA_MD5_DES3_checksum, 1274 RSA_MD5_DES3_verify 1275}; 1276struct checksum_type checksum_sha1 = { 1277 CKSUMTYPE_SHA1, 1278 "sha1", 1279 64, 1280 20, 1281 F_CPROOF, 1282 SHA1_checksum, 1283 NULL 1284}; 1285struct checksum_type checksum_hmac_sha1_des3 = { 1286 CKSUMTYPE_HMAC_SHA1_DES3, 1287 "hmac-sha1-des3", 1288 64, 1289 20, 1290 F_KEYED | F_CPROOF | F_DERIVED, 1291 HMAC_SHA1_DES3_checksum, 1292 NULL 1293}; 1294 1295struct checksum_type checksum_hmac_md5 = { 1296 CKSUMTYPE_HMAC_MD5, 1297 "hmac-md5", 1298 64, 1299 16, 1300 F_KEYED | F_CPROOF, 1301 HMAC_MD5_checksum, 1302 NULL 1303}; 1304 1305struct checksum_type checksum_hmac_md5_enc = { 1306 CKSUMTYPE_HMAC_MD5_ENC, 1307 "hmac-md5-enc", 1308 64, 1309 16, 1310 F_KEYED | F_CPROOF | F_PSEUDO, 1311 HMAC_MD5_checksum_enc, 1312 NULL 1313}; 1314 1315struct checksum_type *checksum_types[] = { 1316 &checksum_none, 1317 &checksum_crc32, 1318 &checksum_rsa_md4, 1319 &checksum_rsa_md4_des, 1320#if 0 1321 &checksum_des_mac, 1322 &checksum_des_mac_k, 1323 &checksum_rsa_md4_des_k, 1324#endif 1325 &checksum_rsa_md5, 1326 &checksum_rsa_md5_des, 1327 &checksum_rsa_md5_des3, 1328 &checksum_sha1, 1329 &checksum_hmac_sha1_des3, 1330 &checksum_hmac_md5, 1331 &checksum_hmac_md5_enc 1332}; 1333 1334static int num_checksums = sizeof(checksum_types) / sizeof(checksum_types[0]); 1335 1336static struct checksum_type * 1337_find_checksum(krb5_cksumtype type) 1338{ 1339 int i; 1340 for(i = 0; i < num_checksums; i++) 1341 if(checksum_types[i]->type == type) 1342 return checksum_types[i]; 1343 return NULL; 1344} 1345 1346static krb5_error_code 1347get_checksum_key(krb5_context context, 1348 krb5_crypto crypto, 1349 unsigned usage, /* not krb5_key_usage */ 1350 struct checksum_type *ct, 1351 struct key_data **key) 1352{ 1353 krb5_error_code ret = 0; 1354 1355 if(ct->flags & F_DERIVED) 1356 ret = _get_derived_key(context, crypto, usage, key); 1357 else if(ct->flags & F_VARIANT) { 1358 int i; 1359 1360 *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */); 1361 if(*key == NULL) 1362 return ENOMEM; 1363 ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key); 1364 if(ret) 1365 return ret; 1366 for(i = 0; i < (*key)->key->keyvalue.length; i++) 1367 ((unsigned char*)(*key)->key->keyvalue.data)[i] ^= 0xF0; 1368 } else { 1369 *key = &crypto->key; 1370 } 1371 if(ret == 0) 1372 ret = _key_schedule(context, *key); 1373 return ret; 1374} 1375 1376static krb5_error_code 1377do_checksum (krb5_context context, 1378 struct checksum_type *ct, 1379 krb5_crypto crypto, 1380 unsigned usage, 1381 void *data, 1382 size_t len, 1383 Checksum *result) 1384{ 1385 krb5_error_code ret; 1386 struct key_data *dkey; 1387 int keyed_checksum; 1388 1389 keyed_checksum = (ct->flags & F_KEYED) != 0; 1390 if(keyed_checksum && crypto == NULL) 1391 return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ 1392 if(keyed_checksum) { 1393 ret = get_checksum_key(context, crypto, usage, ct, &dkey); 1394 if (ret) 1395 return ret; 1396 } else 1397 dkey = NULL; 1398 result->cksumtype = ct->type; 1399 krb5_data_alloc(&result->checksum, ct->checksumsize); 1400 (*ct->checksum)(context, dkey, data, len, usage, result); 1401 return 0; 1402} 1403 1404static krb5_error_code 1405create_checksum(krb5_context context, 1406 krb5_crypto crypto, 1407 unsigned usage, /* not krb5_key_usage */ 1408 krb5_cksumtype type, /* if crypto == NULL */ 1409 void *data, 1410 size_t len, 1411 Checksum *result) 1412{ 1413 struct checksum_type *ct; 1414 1415 if(crypto) { 1416 ct = crypto->et->keyed_checksum; 1417 if(ct == NULL) 1418 ct = crypto->et->cksumtype; 1419 } else 1420 ct = _find_checksum(type); 1421 if(ct == NULL) 1422 return KRB5_PROG_SUMTYPE_NOSUPP; 1423 return do_checksum (context, ct, crypto, usage, data, len, result); 1424} 1425 1426krb5_error_code 1427krb5_create_checksum(krb5_context context, 1428 krb5_crypto crypto, 1429 unsigned usage_or_type, 1430 void *data, 1431 size_t len, 1432 Checksum *result) 1433{ 1434 return create_checksum(context, crypto, 1435 CHECKSUM_USAGE(usage_or_type), 1436 usage_or_type, data, len, result); 1437} 1438 1439static krb5_error_code 1440verify_checksum(krb5_context context, 1441 krb5_crypto crypto, 1442 unsigned usage, /* not krb5_key_usage */ 1443 void *data, 1444 size_t len, 1445 Checksum *cksum) 1446{ 1447 krb5_error_code ret; 1448 struct key_data *dkey; 1449 int keyed_checksum; 1450 Checksum c; 1451 struct checksum_type *ct; 1452 1453 ct = _find_checksum(cksum->cksumtype); 1454 if(ct == NULL) 1455 return KRB5_PROG_SUMTYPE_NOSUPP; 1456 if(ct->checksumsize != cksum->checksum.length) 1457 return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */ 1458 keyed_checksum = (ct->flags & F_KEYED) != 0; 1459 if(keyed_checksum && crypto == NULL) 1460 return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ 1461 if(keyed_checksum) 1462 ret = get_checksum_key(context, crypto, usage, ct, &dkey); 1463 else 1464 dkey = NULL; 1465 if(ct->verify) 1466 return (*ct->verify)(context, dkey, data, len, usage, cksum); 1467 1468 ret = krb5_data_alloc (&c.checksum, ct->checksumsize); 1469 if (ret) 1470 return ret; 1471 1472 (*ct->checksum)(context, dkey, data, len, usage, &c); 1473 1474 if(c.checksum.length != cksum->checksum.length || 1475 memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) 1476 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 1477 else 1478 ret = 0; 1479 krb5_data_free (&c.checksum); 1480 return ret; 1481} 1482 1483krb5_error_code 1484krb5_verify_checksum(krb5_context context, 1485 krb5_crypto crypto, 1486 krb5_key_usage usage, 1487 void *data, 1488 size_t len, 1489 Checksum *cksum) 1490{ 1491 return verify_checksum(context, crypto, 1492 CHECKSUM_USAGE(usage), data, len, cksum); 1493} 1494 1495krb5_error_code 1496krb5_checksumsize(krb5_context context, 1497 krb5_cksumtype type, 1498 size_t *size) 1499{ 1500 struct checksum_type *ct = _find_checksum(type); 1501 if(ct == NULL) 1502 return KRB5_PROG_SUMTYPE_NOSUPP; 1503 *size = ct->checksumsize; 1504 return 0; 1505} 1506 1507krb5_boolean 1508krb5_checksum_is_keyed(krb5_context context, 1509 krb5_cksumtype type) 1510{ 1511 struct checksum_type *ct = _find_checksum(type); 1512 if(ct == NULL) 1513 return KRB5_PROG_SUMTYPE_NOSUPP; 1514 return ct->flags & F_KEYED; 1515} 1516 1517krb5_boolean 1518krb5_checksum_is_collision_proof(krb5_context context, 1519 krb5_cksumtype type) 1520{ 1521 struct checksum_type *ct = _find_checksum(type); 1522 if(ct == NULL) 1523 return KRB5_PROG_SUMTYPE_NOSUPP; 1524 return ct->flags & F_CPROOF; 1525} 1526 1527/************************************************************ 1528 * * 1529 ************************************************************/ 1530 1531static krb5_error_code 1532NULL_encrypt(struct key_data *key, 1533 void *data, 1534 size_t len, 1535 krb5_boolean encrypt, 1536 int usage, 1537 void *ivec) 1538{ 1539 return 0; 1540} 1541 1542static krb5_error_code 1543DES_CBC_encrypt_null_ivec(struct key_data *key, 1544 void *data, 1545 size_t len, 1546 krb5_boolean encrypt, 1547 int usage, 1548 void *ignore_ivec) 1549{ 1550 des_cblock ivec; 1551 des_key_schedule *s = key->schedule->data; 1552 memset(&ivec, 0, sizeof(ivec)); 1553 des_cbc_encrypt(data, data, len, *s, &ivec, encrypt); 1554 return 0; 1555} 1556 1557static krb5_error_code 1558DES_CBC_encrypt_key_ivec(struct key_data *key, 1559 void *data, 1560 size_t len, 1561 krb5_boolean encrypt, 1562 int usage, 1563 void *ignore_ivec) 1564{ 1565 des_cblock ivec; 1566 des_key_schedule *s = key->schedule->data; 1567 memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec)); 1568 des_cbc_encrypt(data, data, len, *s, &ivec, encrypt); 1569 return 0; 1570} 1571 1572static krb5_error_code 1573DES3_CBC_encrypt(struct key_data *key, 1574 void *data, 1575 size_t len, 1576 krb5_boolean encrypt, 1577 int usage, 1578 void *ignore_ivec) 1579{ 1580 des_cblock ivec; 1581 des_key_schedule *s = key->schedule->data; 1582 memset(&ivec, 0, sizeof(ivec)); 1583 des_ede3_cbc_encrypt(data, data, len, s[0], s[1], s[2], &ivec, encrypt); 1584 return 0; 1585} 1586 1587static krb5_error_code 1588DES3_CBC_encrypt_ivec(struct key_data *key, 1589 void *data, 1590 size_t len, 1591 krb5_boolean encrypt, 1592 int usage, 1593 void *ivec) 1594{ 1595 des_key_schedule *s = key->schedule->data; 1596 1597 des_ede3_cbc_encrypt(data, data, len, s[0], s[1], s[2], ivec, encrypt); 1598 return 0; 1599} 1600 1601static krb5_error_code 1602DES_CFB64_encrypt_null_ivec(struct key_data *key, 1603 void *data, 1604 size_t len, 1605 krb5_boolean encrypt, 1606 int usage, 1607 void *ignore_ivec) 1608{ 1609 des_cblock ivec; 1610 int num = 0; 1611 des_key_schedule *s = key->schedule->data; 1612 memset(&ivec, 0, sizeof(ivec)); 1613 1614 des_cfb64_encrypt(data, data, len, *s, &ivec, &num, encrypt); 1615 return 0; 1616} 1617 1618static krb5_error_code 1619DES_PCBC_encrypt_key_ivec(struct key_data *key, 1620 void *data, 1621 size_t len, 1622 krb5_boolean encrypt, 1623 int usage, 1624 void *ignore_ivec) 1625{ 1626 des_cblock ivec; 1627 des_key_schedule *s = key->schedule->data; 1628 memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec)); 1629 1630 des_pcbc_encrypt(data, data, len, *s, &ivec, encrypt); 1631 return 0; 1632} 1633 1634/* 1635 * section 6 of draft-brezak-win2k-krb-rc4-hmac-03 1636 * 1637 * warning: not for small children 1638 */ 1639 1640static krb5_error_code 1641ARCFOUR_subencrypt(struct key_data *key, 1642 void *data, 1643 size_t len, 1644 int usage, 1645 void *ivec) 1646{ 1647 struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); 1648 Checksum k1_c, k2_c, k3_c, cksum; 1649 struct key_data ke; 1650 krb5_keyblock kb; 1651 unsigned char t[4]; 1652 RC4_KEY rc4_key; 1653 char *cdata = (char *)data; 1654 unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16]; 1655 1656 t[0] = (usage >> 0) & 0xFF; 1657 t[1] = (usage >> 8) & 0xFF; 1658 t[2] = (usage >> 16) & 0xFF; 1659 t[3] = (usage >> 24) & 0xFF; 1660 1661 k1_c.checksum.length = sizeof(k1_c_data); 1662 k1_c.checksum.data = k1_c_data; 1663 1664 hmac(NULL, c, t, sizeof(t), 0, key, &k1_c); 1665 1666 memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data)); 1667 1668 k2_c.checksum.length = sizeof(k2_c_data); 1669 k2_c.checksum.data = k2_c_data; 1670 1671 ke.key = &kb; 1672 kb.keyvalue = k2_c.checksum; 1673 1674 cksum.checksum.length = 16; 1675 cksum.checksum.data = data; 1676 1677 hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum); 1678 1679 ke.key = &kb; 1680 kb.keyvalue = k1_c.checksum; 1681 1682 k3_c.checksum.length = sizeof(k3_c_data); 1683 k3_c.checksum.data = k3_c_data; 1684 1685 hmac(NULL, c, data, 16, 0, &ke, &k3_c); 1686 1687 RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data); 1688 RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16); 1689 memset (k1_c_data, 0, sizeof(k1_c_data)); 1690 memset (k2_c_data, 0, sizeof(k2_c_data)); 1691 memset (k3_c_data, 0, sizeof(k3_c_data)); 1692 return 0; 1693} 1694 1695static krb5_error_code 1696ARCFOUR_subdecrypt(struct key_data *key, 1697 void *data, 1698 size_t len, 1699 int usage, 1700 void *ivec) 1701{ 1702 struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); 1703 Checksum k1_c, k2_c, k3_c, cksum; 1704 struct key_data ke; 1705 krb5_keyblock kb; 1706 unsigned char t[4]; 1707 RC4_KEY rc4_key; 1708 char *cdata = (char *)data; 1709 unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16]; 1710 unsigned char cksum_data[16]; 1711 1712 t[0] = (usage >> 0) & 0xFF; 1713 t[1] = (usage >> 8) & 0xFF; 1714 t[2] = (usage >> 16) & 0xFF; 1715 t[3] = (usage >> 24) & 0xFF; 1716 1717 k1_c.checksum.length = sizeof(k1_c_data); 1718 k1_c.checksum.data = k1_c_data; 1719 1720 hmac(NULL, c, t, sizeof(t), 0, key, &k1_c); 1721 1722 memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data)); 1723 1724 k2_c.checksum.length = sizeof(k2_c_data); 1725 k2_c.checksum.data = k2_c_data; 1726 1727 ke.key = &kb; 1728 kb.keyvalue = k1_c.checksum; 1729 1730 k3_c.checksum.length = sizeof(k3_c_data); 1731 k3_c.checksum.data = k3_c_data; 1732 1733 hmac(NULL, c, cdata, 16, 0, &ke, &k3_c); 1734 1735 RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data); 1736 RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16); 1737 1738 ke.key = &kb; 1739 kb.keyvalue = k2_c.checksum; 1740 1741 cksum.checksum.length = 16; 1742 cksum.checksum.data = cksum_data; 1743 1744 hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum); 1745 1746 memset (k1_c_data, 0, sizeof(k1_c_data)); 1747 memset (k2_c_data, 0, sizeof(k2_c_data)); 1748 memset (k3_c_data, 0, sizeof(k3_c_data)); 1749 1750 if (memcmp (cksum.checksum.data, data, 16) != 0) 1751 return KRB5KRB_AP_ERR_BAD_INTEGRITY; 1752 else 1753 return 0; 1754} 1755 1756/* 1757 * convert the usage numbers used in 1758 * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in 1759 * draft-brezak-win2k-krb-rc4-hmac-03.txt 1760 */ 1761 1762static int 1763usage2arcfour (int usage) 1764{ 1765 switch (usage) { 1766 case KRB5_KU_PA_ENC_TIMESTAMP : 1767 return 1; 1768 case KRB5_KU_TICKET : 1769 return 8; 1770 case KRB5_KU_AS_REP_ENC_PART : 1771 return 8; 1772 case KRB5_KU_TGS_REQ_AUTH_DAT_SESSION : 1773 case KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY : 1774 case KRB5_KU_TGS_REQ_AUTH_CKSUM : 1775 case KRB5_KU_TGS_REQ_AUTH : 1776 return 7; 1777 case KRB5_KU_TGS_REP_ENC_PART_SESSION : 1778 case KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : 1779 return 8; 1780 case KRB5_KU_AP_REQ_AUTH_CKSUM : 1781 case KRB5_KU_AP_REQ_AUTH : 1782 case KRB5_KU_AP_REQ_ENC_PART : 1783 return 11; 1784 case KRB5_KU_KRB_PRIV : 1785 return 0; 1786 case KRB5_KU_KRB_CRED : 1787 case KRB5_KU_KRB_SAFE_CKSUM : 1788 case KRB5_KU_OTHER_ENCRYPTED : 1789 case KRB5_KU_OTHER_CKSUM : 1790 case KRB5_KU_KRB_ERROR : 1791 case KRB5_KU_AD_KDC_ISSUED : 1792 case KRB5_KU_MANDATORY_TICKET_EXTENSION : 1793 case KRB5_KU_AUTH_DATA_TICKET_EXTENSION : 1794 case KRB5_KU_USAGE_SEAL : 1795 case KRB5_KU_USAGE_SIGN : 1796 case KRB5_KU_USAGE_SEQ : 1797 default : 1798 abort (); 1799 } 1800} 1801 1802static krb5_error_code 1803ARCFOUR_encrypt(struct key_data *key, 1804 void *data, 1805 size_t len, 1806 krb5_boolean encrypt, 1807 int usage, 1808 void *ivec) 1809{ 1810 usage = usage2arcfour (usage); 1811 1812 if (encrypt) 1813 return ARCFOUR_subencrypt (key, data, len, usage, ivec); 1814 else 1815 return ARCFOUR_subdecrypt (key, data, len, usage, ivec); 1816} 1817 1818 1819/* 1820 * these should currently be in reverse preference order. 1821 * (only relevant for !F_PSEUDO) */ 1822 1823static struct encryption_type etypes[] = { 1824 { 1825 ETYPE_NULL, 1826 "null", 1827 1, 1828 0, 1829 &keytype_null, 1830 &checksum_none, 1831 NULL, 1832 0, 1833 NULL_encrypt, 1834 }, 1835 { 1836 ETYPE_DES_CBC_CRC, 1837 "des-cbc-crc", 1838 8, 1839 8, 1840 &keytype_des, 1841 &checksum_crc32, 1842 NULL, 1843 0, 1844 DES_CBC_encrypt_key_ivec, 1845 }, 1846 { 1847 ETYPE_DES_CBC_MD4, 1848 "des-cbc-md4", 1849 8, 1850 8, 1851 &keytype_des, 1852 &checksum_rsa_md4, 1853 &checksum_rsa_md4_des, 1854 0, 1855 DES_CBC_encrypt_null_ivec, 1856 }, 1857 { 1858 ETYPE_DES_CBC_MD5, 1859 "des-cbc-md5", 1860 8, 1861 8, 1862 &keytype_des, 1863 &checksum_rsa_md5, 1864 &checksum_rsa_md5_des, 1865 0, 1866 DES_CBC_encrypt_null_ivec, 1867 }, 1868 { 1869 ETYPE_ARCFOUR_HMAC_MD5, 1870 "arcfour-hmac-md5", 1871 1, 1872 8, 1873 &keytype_arcfour, 1874 &checksum_hmac_md5_enc, 1875 &checksum_hmac_md5_enc, 1876 F_SPECIAL, 1877 ARCFOUR_encrypt 1878 }, 1879 { 1880 ETYPE_DES3_CBC_MD5, 1881 "des3-cbc-md5", 1882 8, 1883 8, 1884 &keytype_des3, 1885 &checksum_rsa_md5, 1886 &checksum_rsa_md5_des3, 1887 0, 1888 DES3_CBC_encrypt, 1889 }, 1890 { 1891 ETYPE_DES3_CBC_SHA1, 1892 "des3-cbc-sha1", 1893 8, 1894 8, 1895 &keytype_des3_derived, 1896 &checksum_sha1, 1897 &checksum_hmac_sha1_des3, 1898 F_DERIVED, 1899 DES3_CBC_encrypt, 1900 }, 1901 { 1902 ETYPE_OLD_DES3_CBC_SHA1, 1903 "old-des3-cbc-sha1", 1904 8, 1905 8, 1906 &keytype_des3, 1907 &checksum_sha1, 1908 &checksum_hmac_sha1_des3, 1909 0, 1910 DES3_CBC_encrypt, 1911 }, 1912 { 1913 ETYPE_DES_CBC_NONE, 1914 "des-cbc-none", 1915 8, 1916 0, 1917 &keytype_des, 1918 &checksum_none, 1919 NULL, 1920 F_PSEUDO, 1921 DES_CBC_encrypt_null_ivec, 1922 }, 1923 { 1924 ETYPE_DES_CFB64_NONE, 1925 "des-cfb64-none", 1926 1, 1927 0, 1928 &keytype_des, 1929 &checksum_none, 1930 NULL, 1931 F_PSEUDO, 1932 DES_CFB64_encrypt_null_ivec, 1933 }, 1934 { 1935 ETYPE_DES_PCBC_NONE, 1936 "des-pcbc-none", 1937 8, 1938 0, 1939 &keytype_des, 1940 &checksum_none, 1941 NULL, 1942 F_PSEUDO, 1943 DES_PCBC_encrypt_key_ivec, 1944 }, 1945 { 1946 ETYPE_DES3_CBC_NONE, 1947 "des3-cbc-none", 1948 8, 1949 0, 1950 &keytype_des3_derived, 1951 &checksum_none, 1952 NULL, 1953 F_PSEUDO, 1954 DES3_CBC_encrypt, 1955 }, 1956 { 1957 ETYPE_DES3_CBC_NONE_IVEC, 1958 "des3-cbc-none-ivec", 1959 8, 1960 0, 1961 &keytype_des3_derived, 1962 &checksum_none, 1963 NULL, 1964 F_PSEUDO, 1965 DES3_CBC_encrypt_ivec, 1966 } 1967}; 1968 1969static unsigned num_etypes = sizeof(etypes) / sizeof(etypes[0]); 1970 1971 1972static struct encryption_type * 1973_find_enctype(krb5_enctype type) 1974{ 1975 int i; 1976 for(i = 0; i < num_etypes; i++) 1977 if(etypes[i].type == type) 1978 return &etypes[i]; 1979 return NULL; 1980} 1981 1982 1983krb5_error_code 1984krb5_enctype_to_string(krb5_context context, 1985 krb5_enctype etype, 1986 char **string) 1987{ 1988 struct encryption_type *e; 1989 e = _find_enctype(etype); 1990 if(e == NULL) 1991 return KRB5_PROG_ETYPE_NOSUPP; 1992 *string = strdup(e->name); 1993 if(*string == NULL) 1994 return ENOMEM; 1995 return 0; 1996} 1997 1998krb5_error_code 1999krb5_string_to_enctype(krb5_context context, 2000 const char *string, 2001 krb5_enctype *etype) 2002{ 2003 int i; 2004 for(i = 0; i < num_etypes; i++) 2005 if(strcasecmp(etypes[i].name, string) == 0){ 2006 *etype = etypes[i].type; 2007 return 0; 2008 } 2009 return KRB5_PROG_ETYPE_NOSUPP; 2010} 2011 2012krb5_error_code 2013krb5_enctype_to_keytype(krb5_context context, 2014 krb5_enctype etype, 2015 krb5_keytype *keytype) 2016{ 2017 struct encryption_type *e = _find_enctype(etype); 2018 if(e == NULL) 2019 return KRB5_PROG_ETYPE_NOSUPP; 2020 *keytype = e->keytype->type; /* XXX */ 2021 return 0; 2022} 2023 2024#if 0 2025krb5_error_code 2026krb5_keytype_to_enctype(krb5_context context, 2027 krb5_keytype keytype, 2028 krb5_enctype *etype) 2029{ 2030 struct key_type *kt = _find_keytype(keytype); 2031 krb5_warnx(context, "krb5_keytype_to_enctype(%u)", keytype); 2032 if(kt == NULL) 2033 return KRB5_PROG_KEYTYPE_NOSUPP; 2034 *etype = kt->best_etype; 2035 return 0; 2036} 2037#endif 2038 2039krb5_error_code 2040krb5_keytype_to_enctypes (krb5_context context, 2041 krb5_keytype keytype, 2042 unsigned *len, 2043 int **val) 2044{ 2045 int i; 2046 unsigned n = 0; 2047 int *ret; 2048 2049 for (i = num_etypes - 1; i >= 0; --i) { 2050 if (etypes[i].keytype->type == keytype 2051 && !(etypes[i].flags & F_PSEUDO)) 2052 ++n; 2053 } 2054 ret = malloc(n * sizeof(int)); 2055 if (ret == NULL && n != 0) 2056 return ENOMEM; 2057 n = 0; 2058 for (i = num_etypes - 1; i >= 0; --i) { 2059 if (etypes[i].keytype->type == keytype 2060 && !(etypes[i].flags & F_PSEUDO)) 2061 ret[n++] = etypes[i].type; 2062 } 2063 *len = n; 2064 *val = ret; 2065 return 0; 2066} 2067 2068/* 2069 * First take the configured list of etypes for `keytype' if available, 2070 * else, do `krb5_keytype_to_enctypes'. 2071 */ 2072 2073krb5_error_code 2074krb5_keytype_to_enctypes_default (krb5_context context, 2075 krb5_keytype keytype, 2076 unsigned *len, 2077 int **val) 2078{ 2079 int i, n; 2080 int *ret; 2081 2082 if (keytype != KEYTYPE_DES || context->etypes_des == NULL) 2083 return krb5_keytype_to_enctypes (context, keytype, len, val); 2084 2085 for (n = 0; context->etypes_des[n]; ++n) 2086 ; 2087 ret = malloc (n * sizeof(*ret)); 2088 if (ret == NULL && n != 0) 2089 return ENOMEM; 2090 for (i = 0; i < n; ++i) 2091 ret[i] = context->etypes_des[i]; 2092 *len = n; 2093 *val = ret; 2094 return 0; 2095} 2096 2097krb5_error_code 2098krb5_enctype_valid(krb5_context context, 2099 krb5_enctype etype) 2100{ 2101 return _find_enctype(etype) != NULL; 2102} 2103 2104/* if two enctypes have compatible keys */ 2105krb5_boolean 2106krb5_enctypes_compatible_keys(krb5_context context, 2107 krb5_enctype etype1, 2108 krb5_enctype etype2) 2109{ 2110 struct encryption_type *e1 = _find_enctype(etype1); 2111 struct encryption_type *e2 = _find_enctype(etype2); 2112 return e1 != NULL && e2 != NULL && e1->keytype == e2->keytype; 2113} 2114 2115static krb5_boolean 2116derived_crypto(krb5_context context, 2117 krb5_crypto crypto) 2118{ 2119 return (crypto->et->flags & F_DERIVED) != 0; 2120} 2121 2122static krb5_boolean 2123special_crypto(krb5_context context, 2124 krb5_crypto crypto) 2125{ 2126 return (crypto->et->flags & F_SPECIAL) != 0; 2127} 2128 2129#define CHECKSUMSIZE(C) ((C)->checksumsize) 2130#define CHECKSUMTYPE(C) ((C)->type) 2131 2132static krb5_error_code 2133encrypt_internal_derived(krb5_context context, 2134 krb5_crypto crypto, 2135 unsigned usage, 2136 void *data, 2137 size_t len, 2138 krb5_data *result, 2139 void *ivec) 2140{ 2141 size_t sz, block_sz, checksum_sz; 2142 Checksum cksum; 2143 unsigned char *p, *q; 2144 krb5_error_code ret; 2145 struct key_data *dkey; 2146 struct encryption_type *et = crypto->et; 2147 2148 checksum_sz = CHECKSUMSIZE(et->keyed_checksum); 2149 2150 sz = et->confoundersize + /* 4 - length */ len; 2151 block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */ 2152 p = calloc(1, block_sz + checksum_sz); 2153 if(p == NULL) 2154 return ENOMEM; 2155 2156 q = p; 2157 krb5_generate_random_block(q, et->confoundersize); /* XXX */ 2158 q += et->confoundersize; 2159 memcpy(q, data, len); 2160 2161 ret = create_checksum(context, 2162 crypto, 2163 INTEGRITY_USAGE(usage), 2164 0, 2165 p, 2166 block_sz, 2167 &cksum); 2168 if(ret == 0 && cksum.checksum.length != checksum_sz) { 2169 free_Checksum (&cksum); 2170 ret = KRB5_CRYPTO_INTERNAL; 2171 } 2172 if(ret) { 2173 memset(p, 0, block_sz + checksum_sz); 2174 free(p); 2175 return ret; 2176 } 2177 memcpy(p + block_sz, cksum.checksum.data, cksum.checksum.length); 2178 free_Checksum (&cksum); 2179 ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); 2180 if(ret) { 2181 memset(p, 0, block_sz + checksum_sz); 2182 free(p); 2183 return ret; 2184 } 2185 ret = _key_schedule(context, dkey); 2186 if(ret) { 2187 memset(p, 0, block_sz); 2188 free(p); 2189 return ret; 2190 } 2191#ifdef CRYPTO_DEBUG 2192 krb5_crypto_debug(context, 1, block_sz, dkey->key); 2193#endif 2194 (*et->encrypt)(dkey, p, block_sz, 1, usage, ivec); 2195 result->data = p; 2196 result->length = block_sz + checksum_sz; 2197 return 0; 2198} 2199 2200static krb5_error_code 2201encrypt_internal(krb5_context context, 2202 krb5_crypto crypto, 2203 void *data, 2204 size_t len, 2205 krb5_data *result, 2206 void *ivec) 2207{ 2208 size_t sz, block_sz, checksum_sz; 2209 Checksum cksum; 2210 unsigned char *p, *q; 2211 krb5_error_code ret; 2212 struct encryption_type *et = crypto->et; 2213 2214 checksum_sz = CHECKSUMSIZE(et->cksumtype); 2215 2216 sz = et->confoundersize + checksum_sz + len; 2217 block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */ 2218 p = calloc(1, block_sz); 2219 if(p == NULL) 2220 return ENOMEM; 2221 2222 q = p; 2223 krb5_generate_random_block(q, et->confoundersize); /* XXX */ 2224 q += et->confoundersize; 2225 memset(q, 0, checksum_sz); 2226 q += checksum_sz; 2227 memcpy(q, data, len); 2228 2229 ret = create_checksum(context, 2230 NULL, 2231 0, 2232 CHECKSUMTYPE(et->cksumtype), 2233 p, 2234 block_sz, 2235 &cksum); 2236 if(ret == 0 && cksum.checksum.length != checksum_sz) { 2237 free_Checksum (&cksum); 2238 ret = KRB5_CRYPTO_INTERNAL; 2239 } 2240 if(ret) { 2241 memset(p, 0, block_sz); 2242 free(p); 2243 free_Checksum(&cksum); 2244 return ret; 2245 } 2246 memcpy(p + et->confoundersize, cksum.checksum.data, cksum.checksum.length); 2247 free_Checksum(&cksum); 2248 ret = _key_schedule(context, &crypto->key); 2249 if(ret) { 2250 memset(p, 0, block_sz); 2251 free(p); 2252 return ret; 2253 } 2254#ifdef CRYPTO_DEBUG 2255 krb5_crypto_debug(context, 1, block_sz, crypto->key.key); 2256#endif 2257 (*et->encrypt)(&crypto->key, p, block_sz, 1, 0, ivec); 2258 result->data = p; 2259 result->length = block_sz; 2260 return 0; 2261} 2262 2263static krb5_error_code 2264encrypt_internal_special(krb5_context context, 2265 krb5_crypto crypto, 2266 int usage, 2267 void *data, 2268 size_t len, 2269 krb5_data *result, 2270 void *ivec) 2271{ 2272 struct encryption_type *et = crypto->et; 2273 size_t cksum_sz = CHECKSUMSIZE(et->cksumtype); 2274 size_t sz = len + cksum_sz + et->confoundersize; 2275 char *tmp, *p; 2276 2277 tmp = malloc (sz); 2278 if (tmp == NULL) 2279 return ENOMEM; 2280 p = tmp; 2281 memset (p, 0, cksum_sz); 2282 p += cksum_sz; 2283 krb5_generate_random_block(p, et->confoundersize); 2284 p += et->confoundersize; 2285 memcpy (p, data, len); 2286 (*et->encrypt)(&crypto->key, tmp, sz, TRUE, usage, ivec); 2287 result->data = tmp; 2288 result->length = sz; 2289 return 0; 2290} 2291 2292static krb5_error_code 2293decrypt_internal_derived(krb5_context context, 2294 krb5_crypto crypto, 2295 unsigned usage, 2296 void *data, 2297 size_t len, 2298 krb5_data *result, 2299 void *ivec) 2300{ 2301 size_t checksum_sz; 2302 Checksum cksum; 2303 unsigned char *p; 2304 krb5_error_code ret; 2305 struct key_data *dkey; 2306 struct encryption_type *et = crypto->et; 2307 unsigned long l; 2308 2309 checksum_sz = CHECKSUMSIZE(et->keyed_checksum); 2310 if (len < checksum_sz) 2311 return EINVAL; /* better error code? */ 2312 2313 p = malloc(len); 2314 if(len != 0 && p == NULL) 2315 return ENOMEM; 2316 memcpy(p, data, len); 2317 2318 len -= checksum_sz; 2319 2320 ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); 2321 if(ret) { 2322 free(p); 2323 return ret; 2324 } 2325 ret = _key_schedule(context, dkey); 2326 if(ret) { 2327 free(p); 2328 return ret; 2329 } 2330#ifdef CRYPTO_DEBUG 2331 krb5_crypto_debug(context, 0, len, dkey->key); 2332#endif 2333 (*et->encrypt)(dkey, p, len, 0, usage, ivec); 2334 2335 cksum.checksum.data = p + len; 2336 cksum.checksum.length = checksum_sz; 2337 cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum); 2338 2339 ret = verify_checksum(context, 2340 crypto, 2341 INTEGRITY_USAGE(usage), 2342 p, 2343 len, 2344 &cksum); 2345 if(ret) { 2346 free(p); 2347 return ret; 2348 } 2349 l = len - et->confoundersize; 2350 memmove(p, p + et->confoundersize, l); 2351 result->data = realloc(p, l); 2352 if(p == NULL) { 2353 free(p); 2354 return ENOMEM; 2355 } 2356 result->length = l; 2357 return 0; 2358} 2359 2360static krb5_error_code 2361decrypt_internal(krb5_context context, 2362 krb5_crypto crypto, 2363 void *data, 2364 size_t len, 2365 krb5_data *result, 2366 void *ivec) 2367{ 2368 krb5_error_code ret; 2369 unsigned char *p; 2370 Checksum cksum; 2371 size_t checksum_sz, l; 2372 struct encryption_type *et = crypto->et; 2373 2374 checksum_sz = CHECKSUMSIZE(et->cksumtype); 2375 p = malloc(len); 2376 if(len != 0 && p == NULL) 2377 return ENOMEM; 2378 memcpy(p, data, len); 2379 2380 ret = _key_schedule(context, &crypto->key); 2381 if(ret) { 2382 free(p); 2383 return ret; 2384 } 2385#ifdef CRYPTO_DEBUG 2386 krb5_crypto_debug(context, 0, len, crypto->key.key); 2387#endif 2388 (*et->encrypt)(&crypto->key, p, len, 0, 0, ivec); 2389 ret = krb5_data_copy(&cksum.checksum, p + et->confoundersize, checksum_sz); 2390 if(ret) { 2391 free(p); 2392 return ret; 2393 } 2394 memset(p + et->confoundersize, 0, checksum_sz); 2395 cksum.cksumtype = CHECKSUMTYPE(et->cksumtype); 2396 ret = verify_checksum(context, NULL, 0, p, len, &cksum); 2397 free_Checksum(&cksum); 2398 if(ret) { 2399 free(p); 2400 return ret; 2401 } 2402 l = len - et->confoundersize - checksum_sz; 2403 memmove(p, p + et->confoundersize + checksum_sz, l); 2404 result->data = realloc(p, l); 2405 if(result->data == NULL) { 2406 free(p); 2407 return ENOMEM; 2408 } 2409 result->length = l; 2410 return 0; 2411} 2412 2413static krb5_error_code 2414decrypt_internal_special(krb5_context context, 2415 krb5_crypto crypto, 2416 int usage, 2417 void *data, 2418 size_t len, 2419 krb5_data *result, 2420 void *ivec) 2421{ 2422 struct encryption_type *et = crypto->et; 2423 size_t cksum_sz = CHECKSUMSIZE(et->cksumtype); 2424 size_t sz = len - cksum_sz - et->confoundersize; 2425 char *cdata = (char *)data; 2426 char *tmp; 2427 2428 tmp = malloc (sz); 2429 if (tmp == NULL) 2430 return ENOMEM; 2431 2432 (*et->encrypt)(&crypto->key, data, len, FALSE, usage, ivec); 2433 2434 memcpy (tmp, cdata + cksum_sz + et->confoundersize, sz); 2435 2436 result->data = tmp; 2437 result->length = sz; 2438 return 0; 2439} 2440 2441 2442krb5_error_code 2443krb5_encrypt_ivec(krb5_context context, 2444 krb5_crypto crypto, 2445 unsigned usage, 2446 void *data, 2447 size_t len, 2448 krb5_data *result, 2449 void *ivec) 2450{ 2451 if(derived_crypto(context, crypto)) 2452 return encrypt_internal_derived(context, crypto, usage, 2453 data, len, result, ivec); 2454 else if (special_crypto(context, crypto)) 2455 return encrypt_internal_special (context, crypto, usage, 2456 data, len, result, ivec); 2457 else 2458 return encrypt_internal(context, crypto, data, len, result, ivec); 2459} 2460 2461krb5_error_code 2462krb5_encrypt(krb5_context context, 2463 krb5_crypto crypto, 2464 unsigned usage, 2465 void *data, 2466 size_t len, 2467 krb5_data *result) 2468{ 2469 return krb5_encrypt_ivec(context, crypto, usage, data, len, result, NULL); 2470} 2471 2472krb5_error_code 2473krb5_encrypt_EncryptedData(krb5_context context, 2474 krb5_crypto crypto, 2475 unsigned usage, 2476 void *data, 2477 size_t len, 2478 int kvno, 2479 EncryptedData *result) 2480{ 2481 result->etype = CRYPTO_ETYPE(crypto); 2482 if(kvno){ 2483 ALLOC(result->kvno, 1); 2484 *result->kvno = kvno; 2485 }else 2486 result->kvno = NULL; 2487 return krb5_encrypt(context, crypto, usage, data, len, &result->cipher); 2488} 2489 2490krb5_error_code 2491krb5_decrypt_ivec(krb5_context context, 2492 krb5_crypto crypto, 2493 unsigned usage, 2494 void *data, 2495 size_t len, 2496 krb5_data *result, 2497 void *ivec) 2498{ 2499 if(derived_crypto(context, crypto)) 2500 return decrypt_internal_derived(context, crypto, usage, 2501 data, len, result, ivec); 2502 else if (special_crypto (context, crypto)) 2503 return decrypt_internal_special(context, crypto, usage, 2504 data, len, result, ivec); 2505 else 2506 return decrypt_internal(context, crypto, data, len, result, ivec); 2507} 2508 2509krb5_error_code 2510krb5_decrypt(krb5_context context, 2511 krb5_crypto crypto, 2512 unsigned usage, 2513 void *data, 2514 size_t len, 2515 krb5_data *result) 2516{ 2517 return krb5_decrypt_ivec (context, crypto, usage, data, len, result, 2518 NULL); 2519} 2520 2521krb5_error_code 2522krb5_decrypt_EncryptedData(krb5_context context, 2523 krb5_crypto crypto, 2524 unsigned usage, 2525 const EncryptedData *e, 2526 krb5_data *result) 2527{ 2528 return krb5_decrypt(context, crypto, usage, 2529 e->cipher.data, e->cipher.length, result); 2530} 2531 2532/************************************************************ 2533 * * 2534 ************************************************************/ 2535 2536void 2537krb5_generate_random_block(void *buf, size_t len) 2538{ 2539 des_cblock key, out; 2540 static des_cblock counter; 2541 static des_key_schedule schedule; 2542 int i; 2543 static int initialized = 0; 2544 2545 if(!initialized) { 2546 des_new_random_key(&key); 2547 des_set_key(&key, schedule); 2548 memset(&key, 0, sizeof(key)); 2549 des_new_random_key(&counter); 2550 } 2551 while(len > 0) { 2552 des_ecb_encrypt(&counter, &out, schedule, DES_ENCRYPT); 2553 for(i = 7; i >=0; i--) 2554 if(counter[i]++) 2555 break; 2556 memcpy(buf, out, min(len, sizeof(out))); 2557 len -= min(len, sizeof(out)); 2558 buf = (char*)buf + sizeof(out); 2559 } 2560} 2561 2562static void 2563DES3_postproc(krb5_context context, 2564 unsigned char *k, size_t len, struct key_data *key) 2565{ 2566 unsigned char x[24]; 2567 int i, j; 2568 2569 memset(x, 0, sizeof(x)); 2570 for (i = 0; i < 3; ++i) { 2571 unsigned char foo; 2572 2573 for (j = 0; j < 7; ++j) { 2574 unsigned char b = k[7 * i + j]; 2575 2576 x[8 * i + j] = b; 2577 } 2578 foo = 0; 2579 for (j = 6; j >= 0; --j) { 2580 foo |= k[7 * i + j] & 1; 2581 foo <<= 1; 2582 } 2583 x[8 * i + 7] = foo; 2584 } 2585 k = key->key->keyvalue.data; 2586 memcpy(k, x, 24); 2587 memset(x, 0, sizeof(x)); 2588 if (key->schedule) { 2589 krb5_free_data(context, key->schedule); 2590 key->schedule = NULL; 2591 } 2592 des_set_odd_parity((des_cblock*)k); 2593 des_set_odd_parity((des_cblock*)(k + 8)); 2594 des_set_odd_parity((des_cblock*)(k + 16)); 2595} 2596 2597static krb5_error_code 2598derive_key(krb5_context context, 2599 struct encryption_type *et, 2600 struct key_data *key, 2601 void *constant, 2602 size_t len) 2603{ 2604 unsigned char *k; 2605 unsigned int nblocks = 0, i; 2606 krb5_error_code ret = 0; 2607 2608 struct key_type *kt = et->keytype; 2609 ret = _key_schedule(context, key); 2610 if(ret) 2611 return ret; 2612 if(et->blocksize * 8 < kt->bits || 2613 len != et->blocksize) { 2614 nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8); 2615 k = malloc(nblocks * et->blocksize); 2616 if(k == NULL) 2617 return ENOMEM; 2618 _krb5_n_fold(constant, len, k, et->blocksize); 2619 for(i = 0; i < nblocks; i++) { 2620 if(i > 0) 2621 memcpy(k + i * et->blocksize, 2622 k + (i - 1) * et->blocksize, 2623 et->blocksize); 2624 (*et->encrypt)(key, k + i * et->blocksize, et->blocksize, 1, 0, 2625 NULL); 2626 } 2627 } else { 2628 /* this case is probably broken, but won't be run anyway */ 2629 void *c = malloc(len); 2630 size_t res_len = (kt->bits + 7) / 8; 2631 2632 if(len != 0 && c == NULL) 2633 return ENOMEM; 2634 memcpy(c, constant, len); 2635 (*et->encrypt)(key, c, len, 1, 0, NULL); 2636 k = malloc(res_len); 2637 if(res_len != 0 && k == NULL) 2638 return ENOMEM; 2639 _krb5_n_fold(c, len, k, res_len); 2640 free(c); 2641 } 2642 2643 /* XXX keytype dependent post-processing */ 2644 switch(kt->type) { 2645 case KEYTYPE_DES3: 2646 DES3_postproc(context, k, nblocks * et->blocksize, key); 2647 break; 2648 default: 2649 krb5_warnx(context, "derive_key() called with unknown keytype (%u)", 2650 kt->type); 2651 ret = KRB5_CRYPTO_INTERNAL; 2652 break; 2653 } 2654 memset(k, 0, nblocks * et->blocksize); 2655 free(k); 2656 return ret; 2657} 2658 2659static struct key_data * 2660_new_derived_key(krb5_crypto crypto, unsigned usage) 2661{ 2662 struct key_usage *d = crypto->key_usage; 2663 d = realloc(d, (crypto->num_key_usage + 1) * sizeof(*d)); 2664 if(d == NULL) 2665 return NULL; 2666 crypto->key_usage = d; 2667 d += crypto->num_key_usage++; 2668 memset(d, 0, sizeof(*d)); 2669 d->usage = usage; 2670 return &d->key; 2671} 2672 2673static krb5_error_code 2674_get_derived_key(krb5_context context, 2675 krb5_crypto crypto, 2676 unsigned usage, 2677 struct key_data **key) 2678{ 2679 int i; 2680 struct key_data *d; 2681 unsigned char constant[5]; 2682 2683 for(i = 0; i < crypto->num_key_usage; i++) 2684 if(crypto->key_usage[i].usage == usage) { 2685 *key = &crypto->key_usage[i].key; 2686 return 0; 2687 } 2688 d = _new_derived_key(crypto, usage); 2689 if(d == NULL) 2690 return ENOMEM; 2691 krb5_copy_keyblock(context, crypto->key.key, &d->key); 2692 _krb5_put_int(constant, usage, 5); 2693 derive_key(context, crypto->et, d, constant, sizeof(constant)); 2694 *key = d; 2695 return 0; 2696} 2697 2698 2699krb5_error_code 2700krb5_crypto_init(krb5_context context, 2701 krb5_keyblock *key, 2702 krb5_enctype etype, 2703 krb5_crypto *crypto) 2704{ 2705 krb5_error_code ret; 2706 ALLOC(*crypto, 1); 2707 if(*crypto == NULL) 2708 return ENOMEM; 2709 if(etype == ETYPE_NULL) 2710 etype = key->keytype; 2711 (*crypto)->et = _find_enctype(etype); 2712 if((*crypto)->et == NULL) { 2713 free(*crypto); 2714 return KRB5_PROG_ETYPE_NOSUPP; 2715 } 2716 ret = krb5_copy_keyblock(context, key, &(*crypto)->key.key); 2717 if(ret) { 2718 free(*crypto); 2719 return ret; 2720 } 2721 (*crypto)->key.schedule = NULL; 2722 (*crypto)->num_key_usage = 0; 2723 (*crypto)->key_usage = NULL; 2724 return 0; 2725} 2726 2727static void 2728free_key_data(krb5_context context, struct key_data *key) 2729{ 2730 krb5_free_keyblock(context, key->key); 2731 if(key->schedule) { 2732 memset(key->schedule->data, 0, key->schedule->length); 2733 krb5_free_data(context, key->schedule); 2734 } 2735} 2736 2737static void 2738free_key_usage(krb5_context context, struct key_usage *ku) 2739{ 2740 free_key_data(context, &ku->key); 2741} 2742 2743krb5_error_code 2744krb5_crypto_destroy(krb5_context context, 2745 krb5_crypto crypto) 2746{ 2747 int i; 2748 2749 for(i = 0; i < crypto->num_key_usage; i++) 2750 free_key_usage(context, &crypto->key_usage[i]); 2751 free(crypto->key_usage); 2752 free_key_data(context, &crypto->key); 2753 free (crypto); 2754 return 0; 2755} 2756 2757krb5_error_code 2758krb5_string_to_key_derived(krb5_context context, 2759 const void *str, 2760 size_t len, 2761 krb5_enctype etype, 2762 krb5_keyblock *key) 2763{ 2764 struct encryption_type *et = _find_enctype(etype); 2765 krb5_error_code ret; 2766 struct key_data kd; 2767 u_char *tmp; 2768 2769 if(et == NULL) 2770 return KRB5_PROG_ETYPE_NOSUPP; 2771 ALLOC(kd.key, 1); 2772 kd.key->keytype = etype; 2773 tmp = malloc (et->keytype->bits / 8); 2774 _krb5_n_fold(str, len, tmp, et->keytype->bits / 8); 2775 krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); 2776 kd.schedule = NULL; 2777 DES3_postproc (context, tmp, et->keytype->bits / 8, &kd); /* XXX */ 2778 ret = derive_key(context, 2779 et, 2780 &kd, 2781 "kerberos", /* XXX well known constant */ 2782 strlen("kerberos")); 2783 ret = krb5_copy_keyblock_contents(context, kd.key, key); 2784 free_key_data(context, &kd); 2785 return ret; 2786} 2787 2788static size_t 2789wrapped_length (krb5_context context, 2790 krb5_crypto crypto, 2791 size_t data_len) 2792{ 2793 struct encryption_type *et = crypto->et; 2794 size_t blocksize = et->blocksize; 2795 size_t res; 2796 2797 res = et->confoundersize + et->cksumtype->checksumsize + data_len; 2798 res = (res + blocksize - 1) / blocksize * blocksize; 2799 return res; 2800} 2801 2802static size_t 2803wrapped_length_dervied (krb5_context context, 2804 krb5_crypto crypto, 2805 size_t data_len) 2806{ 2807 struct encryption_type *et = crypto->et; 2808 size_t blocksize = et->blocksize; 2809 size_t res; 2810 2811 res = et->confoundersize + data_len; 2812 res = (res + blocksize - 1) / blocksize * blocksize; 2813 res += et->cksumtype->checksumsize; 2814 return res; 2815} 2816 2817/* 2818 * Return the size of an encrypted packet of length `data_len' 2819 */ 2820 2821size_t 2822krb5_get_wrapped_length (krb5_context context, 2823 krb5_crypto crypto, 2824 size_t data_len) 2825{ 2826 if (derived_crypto (context, crypto)) 2827 return wrapped_length_dervied (context, crypto, data_len); 2828 else 2829 return wrapped_length (context, crypto, data_len); 2830} 2831 2832#ifdef CRYPTO_DEBUG 2833 2834static krb5_error_code 2835krb5_get_keyid(krb5_context context, 2836 krb5_keyblock *key, 2837 u_int32_t *keyid) 2838{ 2839 MD5_CTX md5; 2840 unsigned char tmp[16]; 2841 2842 MD5_Init (&md5); 2843 MD5_Update (&md5, key->keyvalue.data, key->keyvalue.length); 2844 MD5_Final (tmp, &md5); 2845 *keyid = (tmp[12] << 24) | (tmp[13] << 16) | (tmp[14] << 8) | tmp[15]; 2846 return 0; 2847} 2848 2849static void 2850krb5_crypto_debug(krb5_context context, 2851 int encrypt, 2852 size_t len, 2853 krb5_keyblock *key) 2854{ 2855 u_int32_t keyid; 2856 char *kt; 2857 krb5_get_keyid(context, key, &keyid); 2858 krb5_enctype_to_string(context, key->keytype, &kt); 2859 krb5_warnx(context, "%s %lu bytes with key-id %#x (%s)", 2860 encrypt ? "encrypting" : "decrypting", 2861 (unsigned long)len, 2862 keyid, 2863 kt); 2864 free(kt); 2865} 2866 2867#endif /* CRYPTO_DEBUG */ 2868 2869#if 0 2870int 2871main() 2872{ 2873#if 0 2874 int i; 2875 krb5_context context; 2876 krb5_crypto crypto; 2877 struct key_data *d; 2878 krb5_keyblock key; 2879 char constant[4]; 2880 unsigned usage = ENCRYPTION_USAGE(3); 2881 krb5_error_code ret; 2882 2883 ret = krb5_init_context(&context); 2884 if (ret) 2885 errx (1, "krb5_init_context failed: %d", ret); 2886 2887 key.keytype = ETYPE_NEW_DES3_CBC_SHA1; 2888 key.keyvalue.data = "\xb3\x85\x58\x94\xd9\xdc\x7c\xc8" 2889 "\x25\xe9\x85\xab\x3e\xb5\xfb\x0e" 2890 "\xc8\xdf\xab\x26\x86\x64\x15\x25"; 2891 key.keyvalue.length = 24; 2892 2893 krb5_crypto_init(context, &key, 0, &crypto); 2894 2895 d = _new_derived_key(crypto, usage); 2896 if(d == NULL) 2897 return ENOMEM; 2898 krb5_copy_keyblock(context, crypto->key.key, &d->key); 2899 _krb5_put_int(constant, usage, 4); 2900 derive_key(context, crypto->et, d, constant, sizeof(constant)); 2901 return 0; 2902#else 2903 int i; 2904 krb5_context context; 2905 krb5_crypto crypto; 2906 struct key_data *d; 2907 krb5_keyblock key; 2908 krb5_error_code ret; 2909 Checksum res; 2910 2911 char *data = "what do ya want for nothing?"; 2912 2913 ret = krb5_init_context(&context); 2914 if (ret) 2915 errx (1, "krb5_init_context failed: %d", ret); 2916 2917 key.keytype = ETYPE_NEW_DES3_CBC_SHA1; 2918 key.keyvalue.data = "Jefe"; 2919 /* "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" 2920 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */ 2921 key.keyvalue.length = 4; 2922 2923 d = calloc(1, sizeof(*d)); 2924 2925 d->key = &key; 2926 res.checksum.length = 20; 2927 res.checksum.data = malloc(res.checksum.length); 2928 HMAC_SHA1_DES3_checksum(context, d, data, 28, &res); 2929 2930 return 0; 2931#endif 2932} 2933#endif 2934