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