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