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