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