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.66 2002/09/03 19:58:15 joda 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 krb5_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 krb5_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 krb5_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 krb5_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 krb5_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 krb5_DES_AFS3_Transarc_string_to_key(password, salt.saltvalue, &tmp); 306 else 307 krb5_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, (const 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, (const 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 krb5_DES_random_key, 513 krb5_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 krb5_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 *ivec) 1681 { 1682 des_cblock local_ivec; 1683 des_key_schedule *s = key->schedule->data; 1684 if(ivec == NULL) { 1685 ivec = &local_ivec; 1686 memset(local_ivec, 0, sizeof(local_ivec)); 1687 } 1688 des_ede3_cbc_encrypt(data, data, len, s[0], s[1], s[2], ivec, encrypt); 1689 return 0; 1690 } 1691 1692 static krb5_error_code 1693 DES_CFB64_encrypt_null_ivec(krb5_context context, 1694 struct key_data *key, 1695 void *data, 1696 size_t len, 1697 krb5_boolean encrypt, 1698 int usage, 1699 void *ignore_ivec) 1700 { 1701 des_cblock ivec; 1702 int num = 0; 1703 des_key_schedule *s = key->schedule->data; 1704 memset(&ivec, 0, sizeof(ivec)); 1705 1706 des_cfb64_encrypt(data, data, len, *s, &ivec, &num, encrypt); 1707 return 0; 1708 } 1709 1710 static krb5_error_code 1711 DES_PCBC_encrypt_key_ivec(krb5_context context, 1712 struct key_data *key, 1713 void *data, 1714 size_t len, 1715 krb5_boolean encrypt, 1716 int usage, 1717 void *ignore_ivec) 1718 { 1719 des_cblock ivec; 1720 des_key_schedule *s = key->schedule->data; 1721 memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec)); 1722 1723 des_pcbc_encrypt(data, data, len, *s, &ivec, encrypt); 1724 return 0; 1725 } 1726 1727 /* 1728 * section 6 of draft-brezak-win2k-krb-rc4-hmac-03 1729 * 1730 * warning: not for small children 1731 */ 1732 1733 static krb5_error_code 1734 ARCFOUR_subencrypt(krb5_context context, 1735 struct key_data *key, 1736 void *data, 1737 size_t len, 1738 int usage, 1739 void *ivec) 1740 { 1741 struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); 1742 Checksum k1_c, k2_c, k3_c, cksum; 1743 struct key_data ke; 1744 krb5_keyblock kb; 1745 unsigned char t[4]; 1746 RC4_KEY rc4_key; 1747 unsigned char *cdata = data; 1748 unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16]; 1749 1750 t[0] = (usage >> 0) & 0xFF; 1751 t[1] = (usage >> 8) & 0xFF; 1752 t[2] = (usage >> 16) & 0xFF; 1753 t[3] = (usage >> 24) & 0xFF; 1754 1755 k1_c.checksum.length = sizeof(k1_c_data); 1756 k1_c.checksum.data = k1_c_data; 1757 1758 hmac(NULL, c, t, sizeof(t), 0, key, &k1_c); 1759 1760 memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data)); 1761 1762 k2_c.checksum.length = sizeof(k2_c_data); 1763 k2_c.checksum.data = k2_c_data; 1764 1765 ke.key = &kb; 1766 kb.keyvalue = k2_c.checksum; 1767 1768 cksum.checksum.length = 16; 1769 cksum.checksum.data = data; 1770 1771 hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum); 1772 1773 ke.key = &kb; 1774 kb.keyvalue = k1_c.checksum; 1775 1776 k3_c.checksum.length = sizeof(k3_c_data); 1777 k3_c.checksum.data = k3_c_data; 1778 1779 hmac(NULL, c, data, 16, 0, &ke, &k3_c); 1780 1781 RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data); 1782 RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16); 1783 memset (k1_c_data, 0, sizeof(k1_c_data)); 1784 memset (k2_c_data, 0, sizeof(k2_c_data)); 1785 memset (k3_c_data, 0, sizeof(k3_c_data)); 1786 return 0; 1787 } 1788 1789 static krb5_error_code 1790 ARCFOUR_subdecrypt(krb5_context context, 1791 struct key_data *key, 1792 void *data, 1793 size_t len, 1794 int usage, 1795 void *ivec) 1796 { 1797 struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); 1798 Checksum k1_c, k2_c, k3_c, cksum; 1799 struct key_data ke; 1800 krb5_keyblock kb; 1801 unsigned char t[4]; 1802 RC4_KEY rc4_key; 1803 unsigned char *cdata = data; 1804 unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16]; 1805 unsigned char cksum_data[16]; 1806 1807 t[0] = (usage >> 0) & 0xFF; 1808 t[1] = (usage >> 8) & 0xFF; 1809 t[2] = (usage >> 16) & 0xFF; 1810 t[3] = (usage >> 24) & 0xFF; 1811 1812 k1_c.checksum.length = sizeof(k1_c_data); 1813 k1_c.checksum.data = k1_c_data; 1814 1815 hmac(NULL, c, t, sizeof(t), 0, key, &k1_c); 1816 1817 memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data)); 1818 1819 k2_c.checksum.length = sizeof(k2_c_data); 1820 k2_c.checksum.data = k2_c_data; 1821 1822 ke.key = &kb; 1823 kb.keyvalue = k1_c.checksum; 1824 1825 k3_c.checksum.length = sizeof(k3_c_data); 1826 k3_c.checksum.data = k3_c_data; 1827 1828 hmac(NULL, c, cdata, 16, 0, &ke, &k3_c); 1829 1830 RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data); 1831 RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16); 1832 1833 ke.key = &kb; 1834 kb.keyvalue = k2_c.checksum; 1835 1836 cksum.checksum.length = 16; 1837 cksum.checksum.data = cksum_data; 1838 1839 hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum); 1840 1841 memset (k1_c_data, 0, sizeof(k1_c_data)); 1842 memset (k2_c_data, 0, sizeof(k2_c_data)); 1843 memset (k3_c_data, 0, sizeof(k3_c_data)); 1844 1845 if (memcmp (cksum.checksum.data, data, 16) != 0) { 1846 krb5_clear_error_string (context); 1847 return KRB5KRB_AP_ERR_BAD_INTEGRITY; 1848 } else { 1849 return 0; 1850 } 1851 } 1852 1853 /* 1854 * convert the usage numbers used in 1855 * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in 1856 * draft-brezak-win2k-krb-rc4-hmac-03.txt 1857 */ 1858 1859 static krb5_error_code 1860 usage2arcfour (krb5_context context, int *usage) 1861 { 1862 switch (*usage) { 1863 case KRB5_KU_PA_ENC_TIMESTAMP : 1864 *usage = 1; 1865 return 0; 1866 case KRB5_KU_TICKET : 1867 *usage = 8; 1868 case KRB5_KU_AS_REP_ENC_PART : 1869 *usage = 8; 1870 return 0; 1871 case KRB5_KU_TGS_REQ_AUTH_DAT_SESSION : 1872 case KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY : 1873 case KRB5_KU_TGS_REQ_AUTH_CKSUM : 1874 case KRB5_KU_TGS_REQ_AUTH : 1875 *usage = 7; 1876 return 0; 1877 case KRB5_KU_TGS_REP_ENC_PART_SESSION : 1878 case KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : 1879 *usage = 8; 1880 return 0; 1881 case KRB5_KU_AP_REQ_AUTH_CKSUM : 1882 case KRB5_KU_AP_REQ_AUTH : 1883 case KRB5_KU_AP_REQ_ENC_PART : 1884 *usage = 11; 1885 return 0; 1886 case KRB5_KU_KRB_PRIV : 1887 *usage = 0; 1888 return 0; 1889 case KRB5_KU_KRB_CRED : 1890 case KRB5_KU_KRB_SAFE_CKSUM : 1891 case KRB5_KU_OTHER_ENCRYPTED : 1892 case KRB5_KU_OTHER_CKSUM : 1893 case KRB5_KU_KRB_ERROR : 1894 case KRB5_KU_AD_KDC_ISSUED : 1895 case KRB5_KU_MANDATORY_TICKET_EXTENSION : 1896 case KRB5_KU_AUTH_DATA_TICKET_EXTENSION : 1897 case KRB5_KU_USAGE_SEAL : 1898 case KRB5_KU_USAGE_SIGN : 1899 case KRB5_KU_USAGE_SEQ : 1900 default : 1901 krb5_set_error_string(context, "unknown arcfour usage type %d", *usage); 1902 return KRB5_PROG_ETYPE_NOSUPP; 1903 } 1904 } 1905 1906 static krb5_error_code 1907 ARCFOUR_encrypt(krb5_context context, 1908 struct key_data *key, 1909 void *data, 1910 size_t len, 1911 krb5_boolean encrypt, 1912 int usage, 1913 void *ivec) 1914 { 1915 krb5_error_code ret; 1916 if((ret = usage2arcfour (context, &usage)) != 0) 1917 return ret; 1918 1919 if (encrypt) 1920 return ARCFOUR_subencrypt (context, key, data, len, usage, ivec); 1921 else 1922 return ARCFOUR_subdecrypt (context, key, data, len, usage, ivec); 1923 } 1924 1925 1926 /* 1927 * these should currently be in reverse preference order. 1928 * (only relevant for !F_PSEUDO) */ 1929 1930 static struct encryption_type enctype_null = { 1931 ETYPE_NULL, 1932 "null", 1933 1, 1934 0, 1935 &keytype_null, 1936 &checksum_none, 1937 NULL, 1938 0, 1939 NULL_encrypt, 1940 }; 1941 static struct encryption_type enctype_des_cbc_crc = { 1942 ETYPE_DES_CBC_CRC, 1943 "des-cbc-crc", 1944 8, 1945 8, 1946 &keytype_des, 1947 &checksum_crc32, 1948 NULL, 1949 0, 1950 DES_CBC_encrypt_key_ivec, 1951 }; 1952 static struct encryption_type enctype_des_cbc_md4 = { 1953 ETYPE_DES_CBC_MD4, 1954 "des-cbc-md4", 1955 8, 1956 8, 1957 &keytype_des, 1958 &checksum_rsa_md4, 1959 &checksum_rsa_md4_des, 1960 0, 1961 DES_CBC_encrypt_null_ivec, 1962 }; 1963 static struct encryption_type enctype_des_cbc_md5 = { 1964 ETYPE_DES_CBC_MD5, 1965 "des-cbc-md5", 1966 8, 1967 8, 1968 &keytype_des, 1969 &checksum_rsa_md5, 1970 &checksum_rsa_md5_des, 1971 0, 1972 DES_CBC_encrypt_null_ivec, 1973 }; 1974 static struct encryption_type enctype_arcfour_hmac_md5 = { 1975 ETYPE_ARCFOUR_HMAC_MD5, 1976 "arcfour-hmac-md5", 1977 1, 1978 8, 1979 &keytype_arcfour, 1980 &checksum_hmac_md5, 1981 &checksum_hmac_md5_enc, 1982 F_SPECIAL, 1983 ARCFOUR_encrypt 1984 }; 1985 static struct encryption_type enctype_des3_cbc_md5 = { 1986 ETYPE_DES3_CBC_MD5, 1987 "des3-cbc-md5", 1988 8, 1989 8, 1990 &keytype_des3, 1991 &checksum_rsa_md5, 1992 &checksum_rsa_md5_des3, 1993 0, 1994 DES3_CBC_encrypt, 1995 }; 1996 static struct encryption_type enctype_des3_cbc_sha1 = { 1997 ETYPE_DES3_CBC_SHA1, 1998 "des3-cbc-sha1", 1999 8, 2000 8, 2001 &keytype_des3_derived, 2002 &checksum_sha1, 2003 &checksum_hmac_sha1_des3, 2004 F_DERIVED, 2005 DES3_CBC_encrypt, 2006 }; 2007 static struct encryption_type enctype_old_des3_cbc_sha1 = { 2008 ETYPE_OLD_DES3_CBC_SHA1, 2009 "old-des3-cbc-sha1", 2010 8, 2011 8, 2012 &keytype_des3, 2013 &checksum_sha1, 2014 &checksum_hmac_sha1_des3, 2015 0, 2016 DES3_CBC_encrypt, 2017 }; 2018 static struct encryption_type enctype_des_cbc_none = { 2019 ETYPE_DES_CBC_NONE, 2020 "des-cbc-none", 2021 8, 2022 0, 2023 &keytype_des, 2024 &checksum_none, 2025 NULL, 2026 F_PSEUDO, 2027 DES_CBC_encrypt_null_ivec, 2028 }; 2029 static struct encryption_type enctype_des_cfb64_none = { 2030 ETYPE_DES_CFB64_NONE, 2031 "des-cfb64-none", 2032 1, 2033 0, 2034 &keytype_des, 2035 &checksum_none, 2036 NULL, 2037 F_PSEUDO, 2038 DES_CFB64_encrypt_null_ivec, 2039 }; 2040 static struct encryption_type enctype_des_pcbc_none = { 2041 ETYPE_DES_PCBC_NONE, 2042 "des-pcbc-none", 2043 8, 2044 0, 2045 &keytype_des, 2046 &checksum_none, 2047 NULL, 2048 F_PSEUDO, 2049 DES_PCBC_encrypt_key_ivec, 2050 }; 2051 static struct encryption_type enctype_des3_cbc_none = { 2052 ETYPE_DES3_CBC_NONE, 2053 "des3-cbc-none", 2054 8, 2055 0, 2056 &keytype_des3_derived, 2057 &checksum_none, 2058 NULL, 2059 F_PSEUDO, 2060 DES3_CBC_encrypt, 2061 }; 2062 2063 static struct encryption_type *etypes[] = { 2064 &enctype_null, 2065 &enctype_des_cbc_crc, 2066 &enctype_des_cbc_md4, 2067 &enctype_des_cbc_md5, 2068 &enctype_arcfour_hmac_md5, 2069 &enctype_des3_cbc_md5, 2070 &enctype_des3_cbc_sha1, 2071 &enctype_old_des3_cbc_sha1, 2072 &enctype_des_cbc_none, 2073 &enctype_des_cfb64_none, 2074 &enctype_des_pcbc_none, 2075 &enctype_des3_cbc_none 2076 }; 2077 2078 static unsigned num_etypes = sizeof(etypes) / sizeof(etypes[0]); 2079 2080 2081 static struct encryption_type * 2082 _find_enctype(krb5_enctype type) 2083 { 2084 int i; 2085 for(i = 0; i < num_etypes; i++) 2086 if(etypes[i]->type == type) 2087 return etypes[i]; 2088 return NULL; 2089 } 2090 2091 2092 krb5_error_code 2093 krb5_enctype_to_string(krb5_context context, 2094 krb5_enctype etype, 2095 char **string) 2096 { 2097 struct encryption_type *e; 2098 e = _find_enctype(etype); 2099 if(e == NULL) { 2100 krb5_set_error_string (context, "encryption type %d not supported", 2101 etype); 2102 return KRB5_PROG_ETYPE_NOSUPP; 2103 } 2104 *string = strdup(e->name); 2105 if(*string == NULL) { 2106 krb5_set_error_string(context, "malloc: out of memory"); 2107 return ENOMEM; 2108 } 2109 return 0; 2110 } 2111 2112 krb5_error_code 2113 krb5_string_to_enctype(krb5_context context, 2114 const char *string, 2115 krb5_enctype *etype) 2116 { 2117 int i; 2118 for(i = 0; i < num_etypes; i++) 2119 if(strcasecmp(etypes[i]->name, string) == 0){ 2120 *etype = etypes[i]->type; 2121 return 0; 2122 } 2123 krb5_set_error_string (context, "encryption type %s not supported", 2124 string); 2125 return KRB5_PROG_ETYPE_NOSUPP; 2126 } 2127 2128 krb5_error_code 2129 krb5_enctype_to_keytype(krb5_context context, 2130 krb5_enctype etype, 2131 krb5_keytype *keytype) 2132 { 2133 struct encryption_type *e = _find_enctype(etype); 2134 if(e == NULL) { 2135 krb5_set_error_string (context, "encryption type %d not supported", 2136 etype); 2137 return KRB5_PROG_ETYPE_NOSUPP; 2138 } 2139 *keytype = e->keytype->type; /* XXX */ 2140 return 0; 2141 } 2142 2143 #if 0 2144 krb5_error_code 2145 krb5_keytype_to_enctype(krb5_context context, 2146 krb5_keytype keytype, 2147 krb5_enctype *etype) 2148 { 2149 struct key_type *kt = _find_keytype(keytype); 2150 krb5_warnx(context, "krb5_keytype_to_enctype(%u)", keytype); 2151 if(kt == NULL) 2152 return KRB5_PROG_KEYTYPE_NOSUPP; 2153 *etype = kt->best_etype; 2154 return 0; 2155 } 2156 #endif 2157 2158 krb5_error_code 2159 krb5_keytype_to_enctypes (krb5_context context, 2160 krb5_keytype keytype, 2161 unsigned *len, 2162 krb5_enctype **val) 2163 { 2164 int i; 2165 unsigned n = 0; 2166 krb5_enctype *ret; 2167 2168 for (i = num_etypes - 1; i >= 0; --i) { 2169 if (etypes[i]->keytype->type == keytype 2170 && !(etypes[i]->flags & F_PSEUDO)) 2171 ++n; 2172 } 2173 ret = malloc(n * sizeof(*ret)); 2174 if (ret == NULL && n != 0) { 2175 krb5_set_error_string(context, "malloc: out of memory"); 2176 return ENOMEM; 2177 } 2178 n = 0; 2179 for (i = num_etypes - 1; i >= 0; --i) { 2180 if (etypes[i]->keytype->type == keytype 2181 && !(etypes[i]->flags & F_PSEUDO)) 2182 ret[n++] = etypes[i]->type; 2183 } 2184 *len = n; 2185 *val = ret; 2186 return 0; 2187 } 2188 2189 /* 2190 * First take the configured list of etypes for `keytype' if available, 2191 * else, do `krb5_keytype_to_enctypes'. 2192 */ 2193 2194 krb5_error_code 2195 krb5_keytype_to_enctypes_default (krb5_context context, 2196 krb5_keytype keytype, 2197 unsigned *len, 2198 krb5_enctype **val) 2199 { 2200 int i, n; 2201 krb5_enctype *ret; 2202 2203 if (keytype != KEYTYPE_DES || context->etypes_des == NULL) 2204 return krb5_keytype_to_enctypes (context, keytype, len, val); 2205 2206 for (n = 0; context->etypes_des[n]; ++n) 2207 ; 2208 ret = malloc (n * sizeof(*ret)); 2209 if (ret == NULL && n != 0) { 2210 krb5_set_error_string(context, "malloc: out of memory"); 2211 return ENOMEM; 2212 } 2213 for (i = 0; i < n; ++i) 2214 ret[i] = context->etypes_des[i]; 2215 *len = n; 2216 *val = ret; 2217 return 0; 2218 } 2219 2220 krb5_error_code 2221 krb5_enctype_valid(krb5_context context, 2222 krb5_enctype etype) 2223 { 2224 return _find_enctype(etype) != NULL; 2225 } 2226 2227 /* if two enctypes have compatible keys */ 2228 krb5_boolean 2229 krb5_enctypes_compatible_keys(krb5_context context, 2230 krb5_enctype etype1, 2231 krb5_enctype etype2) 2232 { 2233 struct encryption_type *e1 = _find_enctype(etype1); 2234 struct encryption_type *e2 = _find_enctype(etype2); 2235 return e1 != NULL && e2 != NULL && e1->keytype == e2->keytype; 2236 } 2237 2238 static krb5_boolean 2239 derived_crypto(krb5_context context, 2240 krb5_crypto crypto) 2241 { 2242 return (crypto->et->flags & F_DERIVED) != 0; 2243 } 2244 2245 static krb5_boolean 2246 special_crypto(krb5_context context, 2247 krb5_crypto crypto) 2248 { 2249 return (crypto->et->flags & F_SPECIAL) != 0; 2250 } 2251 2252 #define CHECKSUMSIZE(C) ((C)->checksumsize) 2253 #define CHECKSUMTYPE(C) ((C)->type) 2254 2255 static krb5_error_code 2256 encrypt_internal_derived(krb5_context context, 2257 krb5_crypto crypto, 2258 unsigned usage, 2259 void *data, 2260 size_t len, 2261 krb5_data *result, 2262 void *ivec) 2263 { 2264 size_t sz, block_sz, checksum_sz, total_sz; 2265 Checksum cksum; 2266 unsigned char *p, *q; 2267 krb5_error_code ret; 2268 struct key_data *dkey; 2269 const struct encryption_type *et = crypto->et; 2270 2271 checksum_sz = CHECKSUMSIZE(et->keyed_checksum); 2272 2273 sz = et->confoundersize + len; 2274 block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */ 2275 total_sz = block_sz + checksum_sz; 2276 p = calloc(1, total_sz); 2277 if(p == NULL) { 2278 krb5_set_error_string(context, "malloc: out of memory"); 2279 return ENOMEM; 2280 } 2281 2282 q = p; 2283 krb5_generate_random_block(q, et->confoundersize); /* XXX */ 2284 q += et->confoundersize; 2285 memcpy(q, data, len); 2286 2287 ret = create_checksum(context, 2288 crypto, 2289 INTEGRITY_USAGE(usage), 2290 et->keyed_checksum->type, 2291 p, 2292 block_sz, 2293 &cksum); 2294 if(ret == 0 && cksum.checksum.length != checksum_sz) { 2295 free_Checksum (&cksum); 2296 krb5_clear_error_string (context); 2297 ret = KRB5_CRYPTO_INTERNAL; 2298 } 2299 if(ret) 2300 goto fail; 2301 memcpy(p + block_sz, cksum.checksum.data, cksum.checksum.length); 2302 free_Checksum (&cksum); 2303 ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); 2304 if(ret) 2305 goto fail; 2306 ret = _key_schedule(context, dkey); 2307 if(ret) 2308 goto fail; 2309 #ifdef CRYPTO_DEBUG 2310 krb5_crypto_debug(context, 1, block_sz, dkey->key); 2311 #endif 2312 ret = (*et->encrypt)(context, dkey, p, block_sz, 1, usage, ivec); 2313 if (ret) 2314 goto fail; 2315 result->data = p; 2316 result->length = total_sz; 2317 return 0; 2318 fail: 2319 memset(p, 0, total_sz); 2320 free(p); 2321 return ret; 2322 } 2323 2324 2325 static krb5_error_code 2326 encrypt_internal(krb5_context context, 2327 krb5_crypto crypto, 2328 void *data, 2329 size_t len, 2330 krb5_data *result, 2331 void *ivec) 2332 { 2333 size_t sz, block_sz, checksum_sz; 2334 Checksum cksum; 2335 unsigned char *p, *q; 2336 krb5_error_code ret; 2337 const struct encryption_type *et = crypto->et; 2338 2339 checksum_sz = CHECKSUMSIZE(et->checksum); 2340 2341 sz = et->confoundersize + checksum_sz + len; 2342 block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */ 2343 p = calloc(1, block_sz); 2344 if(p == NULL) { 2345 krb5_set_error_string(context, "malloc: out of memory"); 2346 return ENOMEM; 2347 } 2348 2349 q = p; 2350 krb5_generate_random_block(q, et->confoundersize); /* XXX */ 2351 q += et->confoundersize; 2352 memset(q, 0, checksum_sz); 2353 q += checksum_sz; 2354 memcpy(q, data, len); 2355 2356 ret = create_checksum(context, 2357 crypto, 2358 0, 2359 et->checksum->type, 2360 p, 2361 block_sz, 2362 &cksum); 2363 if(ret == 0 && cksum.checksum.length != checksum_sz) { 2364 krb5_clear_error_string (context); 2365 free_Checksum(&cksum); 2366 ret = KRB5_CRYPTO_INTERNAL; 2367 } 2368 if(ret) 2369 goto fail; 2370 memcpy(p + et->confoundersize, cksum.checksum.data, cksum.checksum.length); 2371 free_Checksum(&cksum); 2372 ret = _key_schedule(context, &crypto->key); 2373 if(ret) 2374 goto fail; 2375 #ifdef CRYPTO_DEBUG 2376 krb5_crypto_debug(context, 1, block_sz, crypto->key.key); 2377 #endif 2378 ret = (*et->encrypt)(context, &crypto->key, p, block_sz, 1, 0, ivec); 2379 if (ret) { 2380 memset(p, 0, block_sz); 2381 free(p); 2382 return ret; 2383 } 2384 result->data = p; 2385 result->length = block_sz; 2386 return 0; 2387 fail: 2388 memset(p, 0, block_sz); 2389 free(p); 2390 return ret; 2391 } 2392 2393 static krb5_error_code 2394 encrypt_internal_special(krb5_context context, 2395 krb5_crypto crypto, 2396 int usage, 2397 void *data, 2398 size_t len, 2399 krb5_data *result, 2400 void *ivec) 2401 { 2402 struct encryption_type *et = crypto->et; 2403 size_t cksum_sz = CHECKSUMSIZE(et->checksum); 2404 size_t sz = len + cksum_sz + et->confoundersize; 2405 char *tmp, *p; 2406 krb5_error_code ret; 2407 2408 tmp = malloc (sz); 2409 if (tmp == NULL) { 2410 krb5_set_error_string(context, "malloc: out of memory"); 2411 return ENOMEM; 2412 } 2413 p = tmp; 2414 memset (p, 0, cksum_sz); 2415 p += cksum_sz; 2416 krb5_generate_random_block(p, et->confoundersize); 2417 p += et->confoundersize; 2418 memcpy (p, data, len); 2419 ret = (*et->encrypt)(context, &crypto->key, tmp, sz, TRUE, usage, ivec); 2420 if (ret) { 2421 memset(tmp, 0, sz); 2422 free(tmp); 2423 return ret; 2424 } 2425 result->data = tmp; 2426 result->length = sz; 2427 return 0; 2428 } 2429 2430 static krb5_error_code 2431 decrypt_internal_derived(krb5_context context, 2432 krb5_crypto crypto, 2433 unsigned usage, 2434 void *data, 2435 size_t len, 2436 krb5_data *result, 2437 void *ivec) 2438 { 2439 size_t checksum_sz; 2440 Checksum cksum; 2441 unsigned char *p; 2442 krb5_error_code ret; 2443 struct key_data *dkey; 2444 struct encryption_type *et = crypto->et; 2445 unsigned long l; 2446 2447 checksum_sz = CHECKSUMSIZE(et->keyed_checksum); 2448 if (len < checksum_sz) { 2449 krb5_clear_error_string (context); 2450 return EINVAL; /* XXX - better error code? */ 2451 } 2452 2453 p = malloc(len); 2454 if(len != 0 && p == NULL) { 2455 krb5_set_error_string(context, "malloc: out of memory"); 2456 return ENOMEM; 2457 } 2458 memcpy(p, data, len); 2459 2460 len -= checksum_sz; 2461 2462 ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); 2463 if(ret) { 2464 free(p); 2465 return ret; 2466 } 2467 ret = _key_schedule(context, dkey); 2468 if(ret) { 2469 free(p); 2470 return ret; 2471 } 2472 #ifdef CRYPTO_DEBUG 2473 krb5_crypto_debug(context, 0, len, dkey->key); 2474 #endif 2475 ret = (*et->encrypt)(context, dkey, p, len, 0, usage, ivec); 2476 if (ret) { 2477 free(p); 2478 return ret; 2479 } 2480 2481 cksum.checksum.data = p + len; 2482 cksum.checksum.length = checksum_sz; 2483 cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum); 2484 2485 ret = verify_checksum(context, 2486 crypto, 2487 INTEGRITY_USAGE(usage), 2488 p, 2489 len, 2490 &cksum); 2491 if(ret) { 2492 free(p); 2493 return ret; 2494 } 2495 l = len - et->confoundersize; 2496 memmove(p, p + et->confoundersize, l); 2497 result->data = realloc(p, l); 2498 if(result->data == NULL) { 2499 free(p); 2500 krb5_set_error_string(context, "malloc: out of memory"); 2501 return ENOMEM; 2502 } 2503 result->length = l; 2504 return 0; 2505 } 2506 2507 static krb5_error_code 2508 decrypt_internal(krb5_context context, 2509 krb5_crypto crypto, 2510 void *data, 2511 size_t len, 2512 krb5_data *result, 2513 void *ivec) 2514 { 2515 krb5_error_code ret; 2516 unsigned char *p; 2517 Checksum cksum; 2518 size_t checksum_sz, l; 2519 struct encryption_type *et = crypto->et; 2520 2521 checksum_sz = CHECKSUMSIZE(et->checksum); 2522 p = malloc(len); 2523 if(len != 0 && p == NULL) { 2524 krb5_set_error_string(context, "malloc: out of memory"); 2525 return ENOMEM; 2526 } 2527 memcpy(p, data, len); 2528 2529 ret = _key_schedule(context, &crypto->key); 2530 if(ret) { 2531 free(p); 2532 return ret; 2533 } 2534 #ifdef CRYPTO_DEBUG 2535 krb5_crypto_debug(context, 0, len, crypto->key.key); 2536 #endif 2537 ret = (*et->encrypt)(context, &crypto->key, p, len, 0, 0, ivec); 2538 if (ret) { 2539 free(p); 2540 return ret; 2541 } 2542 ret = krb5_data_copy(&cksum.checksum, p + et->confoundersize, checksum_sz); 2543 if(ret) { 2544 free(p); 2545 return ret; 2546 } 2547 memset(p + et->confoundersize, 0, checksum_sz); 2548 cksum.cksumtype = CHECKSUMTYPE(et->checksum); 2549 ret = verify_checksum(context, NULL, 0, p, len, &cksum); 2550 free_Checksum(&cksum); 2551 if(ret) { 2552 free(p); 2553 return ret; 2554 } 2555 l = len - et->confoundersize - checksum_sz; 2556 memmove(p, p + et->confoundersize + checksum_sz, l); 2557 result->data = realloc(p, l); 2558 if(result->data == NULL) { 2559 free(p); 2560 krb5_set_error_string(context, "malloc: out of memory"); 2561 return ENOMEM; 2562 } 2563 result->length = l; 2564 return 0; 2565 } 2566 2567 static krb5_error_code 2568 decrypt_internal_special(krb5_context context, 2569 krb5_crypto crypto, 2570 int usage, 2571 void *data, 2572 size_t len, 2573 krb5_data *result, 2574 void *ivec) 2575 { 2576 struct encryption_type *et = crypto->et; 2577 size_t cksum_sz = CHECKSUMSIZE(et->checksum); 2578 size_t sz = len - cksum_sz - et->confoundersize; 2579 char *cdata = (char *)data; 2580 char *tmp; 2581 krb5_error_code ret; 2582 2583 tmp = malloc (sz); 2584 if (tmp == NULL) { 2585 krb5_set_error_string(context, "malloc: out of memory"); 2586 return ENOMEM; 2587 } 2588 2589 ret = (*et->encrypt)(context, &crypto->key, data, len, FALSE, usage, ivec); 2590 if (ret) { 2591 free(tmp); 2592 return ret; 2593 } 2594 2595 memcpy (tmp, cdata + cksum_sz + et->confoundersize, sz); 2596 2597 result->data = tmp; 2598 result->length = sz; 2599 return 0; 2600 } 2601 2602 2603 krb5_error_code 2604 krb5_encrypt_ivec(krb5_context context, 2605 krb5_crypto crypto, 2606 unsigned usage, 2607 void *data, 2608 size_t len, 2609 krb5_data *result, 2610 void *ivec) 2611 { 2612 if(derived_crypto(context, crypto)) 2613 return encrypt_internal_derived(context, crypto, usage, 2614 data, len, result, ivec); 2615 else if (special_crypto(context, crypto)) 2616 return encrypt_internal_special (context, crypto, usage, 2617 data, len, result, ivec); 2618 else 2619 return encrypt_internal(context, crypto, data, len, result, ivec); 2620 } 2621 2622 krb5_error_code 2623 krb5_encrypt(krb5_context context, 2624 krb5_crypto crypto, 2625 unsigned usage, 2626 void *data, 2627 size_t len, 2628 krb5_data *result) 2629 { 2630 return krb5_encrypt_ivec(context, crypto, usage, data, len, result, NULL); 2631 } 2632 2633 krb5_error_code 2634 krb5_encrypt_EncryptedData(krb5_context context, 2635 krb5_crypto crypto, 2636 unsigned usage, 2637 void *data, 2638 size_t len, 2639 int kvno, 2640 EncryptedData *result) 2641 { 2642 result->etype = CRYPTO_ETYPE(crypto); 2643 if(kvno){ 2644 ALLOC(result->kvno, 1); 2645 *result->kvno = kvno; 2646 }else 2647 result->kvno = NULL; 2648 return krb5_encrypt(context, crypto, usage, data, len, &result->cipher); 2649 } 2650 2651 krb5_error_code 2652 krb5_decrypt_ivec(krb5_context context, 2653 krb5_crypto crypto, 2654 unsigned usage, 2655 void *data, 2656 size_t len, 2657 krb5_data *result, 2658 void *ivec) 2659 { 2660 if(derived_crypto(context, crypto)) 2661 return decrypt_internal_derived(context, crypto, usage, 2662 data, len, result, ivec); 2663 else if (special_crypto (context, crypto)) 2664 return decrypt_internal_special(context, crypto, usage, 2665 data, len, result, ivec); 2666 else 2667 return decrypt_internal(context, crypto, data, len, result, ivec); 2668 } 2669 2670 krb5_error_code 2671 krb5_decrypt(krb5_context context, 2672 krb5_crypto crypto, 2673 unsigned usage, 2674 void *data, 2675 size_t len, 2676 krb5_data *result) 2677 { 2678 return krb5_decrypt_ivec (context, crypto, usage, data, len, result, 2679 NULL); 2680 } 2681 2682 krb5_error_code 2683 krb5_decrypt_EncryptedData(krb5_context context, 2684 krb5_crypto crypto, 2685 unsigned usage, 2686 const EncryptedData *e, 2687 krb5_data *result) 2688 { 2689 return krb5_decrypt(context, crypto, usage, 2690 e->cipher.data, e->cipher.length, result); 2691 } 2692 2693 /************************************************************ 2694 * * 2695 ************************************************************/ 2696 2697 #ifdef HAVE_OPENSSL 2698 #include <openssl/rand.h> 2699 2700 /* From openssl/crypto/rand/rand_lcl.h */ 2701 #define ENTROPY_NEEDED 20 2702 static int 2703 seed_something(void) 2704 { 2705 int fd = -1; 2706 char buf[1024], seedfile[256]; 2707 2708 /* If there is a seed file, load it. But such a file cannot be trusted, 2709 so use 0 for the entropy estimate */ 2710 if (RAND_file_name(seedfile, sizeof(seedfile))) { 2711 fd = open(seedfile, O_RDONLY); 2712 if (fd >= 0) { 2713 read(fd, buf, sizeof(buf)); 2714 /* Use the full buffer anyway */ 2715 RAND_add(buf, sizeof(buf), 0.0); 2716 } else 2717 seedfile[0] = '\0'; 2718 } else 2719 seedfile[0] = '\0'; 2720 2721 /* Calling RAND_status() will try to use /dev/urandom if it exists so 2722 we do not have to deal with it. */ 2723 if (RAND_status() != 1) { 2724 krb5_context context; 2725 const char *p; 2726 2727 /* Try using egd */ 2728 if (!krb5_init_context(&context)) { 2729 p = krb5_config_get_string(context, NULL, "libdefaults", 2730 "egd_socket", NULL); 2731 if (p != NULL) 2732 RAND_egd_bytes(p, ENTROPY_NEEDED); 2733 krb5_free_context(context); 2734 } 2735 } 2736 2737 if (RAND_status() == 1) { 2738 /* Update the seed file */ 2739 if (seedfile[0]) 2740 RAND_write_file(seedfile); 2741 2742 return 0; 2743 } else 2744 return -1; 2745 } 2746 2747 void 2748 krb5_generate_random_block(void *buf, size_t len) 2749 { 2750 static int rng_initialized = 0; 2751 2752 if (!rng_initialized) { 2753 if (seed_something()) 2754 krb5_abortx(NULL, "Fatal: could not seed the random number generator"); 2755 2756 rng_initialized = 1; 2757 } 2758 RAND_bytes(buf, len); 2759 } 2760 2761 #else 2762 2763 void 2764 krb5_generate_random_block(void *buf, size_t len) 2765 { 2766 des_cblock key, out; 2767 static des_cblock counter; 2768 static des_key_schedule schedule; 2769 int i; 2770 static int initialized = 0; 2771 2772 if(!initialized) { 2773 des_new_random_key(&key); 2774 des_set_key(&key, schedule); 2775 memset(&key, 0, sizeof(key)); 2776 des_new_random_key(&counter); 2777 } 2778 while(len > 0) { 2779 des_ecb_encrypt(&counter, &out, schedule, DES_ENCRYPT); 2780 for(i = 7; i >=0; i--) 2781 if(counter[i]++) 2782 break; 2783 memcpy(buf, out, min(len, sizeof(out))); 2784 len -= min(len, sizeof(out)); 2785 buf = (char*)buf + sizeof(out); 2786 } 2787 } 2788 #endif 2789 2790 static void 2791 DES3_postproc(krb5_context context, 2792 unsigned char *k, size_t len, struct key_data *key) 2793 { 2794 unsigned char x[24]; 2795 int i, j; 2796 2797 memset(x, 0, sizeof(x)); 2798 for (i = 0; i < 3; ++i) { 2799 unsigned char foo; 2800 2801 for (j = 0; j < 7; ++j) { 2802 unsigned char b = k[7 * i + j]; 2803 2804 x[8 * i + j] = b; 2805 } 2806 foo = 0; 2807 for (j = 6; j >= 0; --j) { 2808 foo |= k[7 * i + j] & 1; 2809 foo <<= 1; 2810 } 2811 x[8 * i + 7] = foo; 2812 } 2813 k = key->key->keyvalue.data; 2814 memcpy(k, x, 24); 2815 memset(x, 0, sizeof(x)); 2816 if (key->schedule) { 2817 krb5_free_data(context, key->schedule); 2818 key->schedule = NULL; 2819 } 2820 des_set_odd_parity((des_cblock*)k); 2821 des_set_odd_parity((des_cblock*)(k + 8)); 2822 des_set_odd_parity((des_cblock*)(k + 16)); 2823 } 2824 2825 static krb5_error_code 2826 derive_key(krb5_context context, 2827 struct encryption_type *et, 2828 struct key_data *key, 2829 const void *constant, 2830 size_t len) 2831 { 2832 unsigned char *k; 2833 unsigned int nblocks = 0, i; 2834 krb5_error_code ret = 0; 2835 2836 struct key_type *kt = et->keytype; 2837 ret = _key_schedule(context, key); 2838 if(ret) 2839 return ret; 2840 if(et->blocksize * 8 < kt->bits || 2841 len != et->blocksize) { 2842 nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8); 2843 k = malloc(nblocks * et->blocksize); 2844 if(k == NULL) { 2845 krb5_set_error_string(context, "malloc: out of memory"); 2846 return ENOMEM; 2847 } 2848 _krb5_n_fold(constant, len, k, et->blocksize); 2849 for(i = 0; i < nblocks; i++) { 2850 if(i > 0) 2851 memcpy(k + i * et->blocksize, 2852 k + (i - 1) * et->blocksize, 2853 et->blocksize); 2854 (*et->encrypt)(context, key, k + i * et->blocksize, et->blocksize, 2855 1, 0, NULL); 2856 } 2857 } else { 2858 /* this case is probably broken, but won't be run anyway */ 2859 void *c = malloc(len); 2860 size_t res_len = (kt->bits + 7) / 8; 2861 2862 if(len != 0 && c == NULL) { 2863 krb5_set_error_string(context, "malloc: out of memory"); 2864 return ENOMEM; 2865 } 2866 memcpy(c, constant, len); 2867 (*et->encrypt)(context, key, c, len, 1, 0, NULL); 2868 k = malloc(res_len); 2869 if(res_len != 0 && k == NULL) { 2870 free(c); 2871 krb5_set_error_string(context, "malloc: out of memory"); 2872 return ENOMEM; 2873 } 2874 _krb5_n_fold(c, len, k, res_len); 2875 free(c); 2876 } 2877 2878 /* XXX keytype dependent post-processing */ 2879 switch(kt->type) { 2880 case KEYTYPE_DES3: 2881 DES3_postproc(context, k, nblocks * et->blocksize, key); 2882 break; 2883 default: 2884 krb5_set_error_string(context, 2885 "derive_key() called with unknown keytype (%u)", 2886 kt->type); 2887 ret = KRB5_CRYPTO_INTERNAL; 2888 break; 2889 } 2890 memset(k, 0, nblocks * et->blocksize); 2891 free(k); 2892 return ret; 2893 } 2894 2895 static struct key_data * 2896 _new_derived_key(krb5_crypto crypto, unsigned usage) 2897 { 2898 struct key_usage *d = crypto->key_usage; 2899 d = realloc(d, (crypto->num_key_usage + 1) * sizeof(*d)); 2900 if(d == NULL) 2901 return NULL; 2902 crypto->key_usage = d; 2903 d += crypto->num_key_usage++; 2904 memset(d, 0, sizeof(*d)); 2905 d->usage = usage; 2906 return &d->key; 2907 } 2908 2909 krb5_error_code 2910 krb5_derive_key(krb5_context context, 2911 const krb5_keyblock *key, 2912 krb5_enctype etype, 2913 const void *constant, 2914 size_t constant_len, 2915 krb5_keyblock **derived_key) 2916 { 2917 krb5_error_code ret; 2918 struct encryption_type *et; 2919 struct key_data d; 2920 2921 et = _find_enctype (etype); 2922 if (et == NULL) { 2923 krb5_set_error_string(context, "encryption type %d not supported", 2924 etype); 2925 return KRB5_PROG_ETYPE_NOSUPP; 2926 } 2927 2928 ret = krb5_copy_keyblock(context, key, derived_key); 2929 if (ret) 2930 return ret; 2931 2932 d.key = *derived_key; 2933 d.schedule = NULL; 2934 ret = derive_key(context, et, &d, constant, constant_len); 2935 if (ret) 2936 return ret; 2937 ret = krb5_copy_keyblock(context, d.key, derived_key); 2938 return ret; 2939 } 2940 2941 static krb5_error_code 2942 _get_derived_key(krb5_context context, 2943 krb5_crypto crypto, 2944 unsigned usage, 2945 struct key_data **key) 2946 { 2947 int i; 2948 struct key_data *d; 2949 unsigned char constant[5]; 2950 2951 for(i = 0; i < crypto->num_key_usage; i++) 2952 if(crypto->key_usage[i].usage == usage) { 2953 *key = &crypto->key_usage[i].key; 2954 return 0; 2955 } 2956 d = _new_derived_key(crypto, usage); 2957 if(d == NULL) { 2958 krb5_set_error_string(context, "malloc: out of memory"); 2959 return ENOMEM; 2960 } 2961 krb5_copy_keyblock(context, crypto->key.key, &d->key); 2962 _krb5_put_int(constant, usage, 5); 2963 derive_key(context, crypto->et, d, constant, sizeof(constant)); 2964 *key = d; 2965 return 0; 2966 } 2967 2968 2969 krb5_error_code 2970 krb5_crypto_init(krb5_context context, 2971 const krb5_keyblock *key, 2972 krb5_enctype etype, 2973 krb5_crypto *crypto) 2974 { 2975 krb5_error_code ret; 2976 ALLOC(*crypto, 1); 2977 if(*crypto == NULL) { 2978 krb5_set_error_string(context, "malloc: out of memory"); 2979 return ENOMEM; 2980 } 2981 if(etype == ETYPE_NULL) 2982 etype = key->keytype; 2983 (*crypto)->et = _find_enctype(etype); 2984 if((*crypto)->et == NULL) { 2985 free(*crypto); 2986 krb5_set_error_string (context, "encryption type %d not supported", 2987 etype); 2988 return KRB5_PROG_ETYPE_NOSUPP; 2989 } 2990 if((*crypto)->et->keytype->size != key->keyvalue.length) { 2991 free(*crypto); 2992 krb5_set_error_string (context, "encryption key has bad length"); 2993 return KRB5_BAD_KEYSIZE; 2994 } 2995 ret = krb5_copy_keyblock(context, key, &(*crypto)->key.key); 2996 if(ret) { 2997 free(*crypto); 2998 return ret; 2999 } 3000 (*crypto)->key.schedule = NULL; 3001 (*crypto)->num_key_usage = 0; 3002 (*crypto)->key_usage = NULL; 3003 return 0; 3004 } 3005 3006 static void 3007 free_key_data(krb5_context context, struct key_data *key) 3008 { 3009 krb5_free_keyblock(context, key->key); 3010 if(key->schedule) { 3011 memset(key->schedule->data, 0, key->schedule->length); 3012 krb5_free_data(context, key->schedule); 3013 } 3014 } 3015 3016 static void 3017 free_key_usage(krb5_context context, struct key_usage *ku) 3018 { 3019 free_key_data(context, &ku->key); 3020 } 3021 3022 krb5_error_code 3023 krb5_crypto_destroy(krb5_context context, 3024 krb5_crypto crypto) 3025 { 3026 int i; 3027 3028 for(i = 0; i < crypto->num_key_usage; i++) 3029 free_key_usage(context, &crypto->key_usage[i]); 3030 free(crypto->key_usage); 3031 free_key_data(context, &crypto->key); 3032 free (crypto); 3033 return 0; 3034 } 3035 3036 krb5_error_code 3037 krb5_crypto_getblocksize(krb5_context context, 3038 krb5_crypto crypto, 3039 size_t *blocksize) 3040 { 3041 *blocksize = crypto->et->blocksize; 3042 return 0; 3043 } 3044 3045 krb5_error_code 3046 krb5_string_to_key_derived(krb5_context context, 3047 const void *str, 3048 size_t len, 3049 krb5_enctype etype, 3050 krb5_keyblock *key) 3051 { 3052 struct encryption_type *et = _find_enctype(etype); 3053 krb5_error_code ret; 3054 struct key_data kd; 3055 size_t keylen = et->keytype->bits / 8; 3056 u_char *tmp; 3057 3058 if(et == NULL) { 3059 krb5_set_error_string (context, "encryption type %d not supported", 3060 etype); 3061 return KRB5_PROG_ETYPE_NOSUPP; 3062 } 3063 ALLOC(kd.key, 1); 3064 if(kd.key == NULL) { 3065 krb5_set_error_string (context, "malloc: out of memory"); 3066 return ENOMEM; 3067 } 3068 ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); 3069 if(ret) { 3070 free(kd.key); 3071 return ret; 3072 } 3073 kd.key->keytype = etype; 3074 tmp = malloc (keylen); 3075 if(tmp == NULL) { 3076 krb5_free_keyblock(context, kd.key); 3077 krb5_set_error_string (context, "malloc: out of memory"); 3078 return ENOMEM; 3079 } 3080 _krb5_n_fold(str, len, tmp, keylen); 3081 kd.schedule = NULL; 3082 DES3_postproc (context, tmp, keylen, &kd); /* XXX */ 3083 memset(tmp, 0, keylen); 3084 free(tmp); 3085 ret = derive_key(context, 3086 et, 3087 &kd, 3088 "kerberos", /* XXX well known constant */ 3089 strlen("kerberos")); 3090 ret = krb5_copy_keyblock_contents(context, kd.key, key); 3091 free_key_data(context, &kd); 3092 return ret; 3093 } 3094 3095 static size_t 3096 wrapped_length (krb5_context context, 3097 krb5_crypto crypto, 3098 size_t data_len) 3099 { 3100 struct encryption_type *et = crypto->et; 3101 size_t blocksize = et->blocksize; 3102 size_t res; 3103 3104 res = et->confoundersize + et->checksum->checksumsize + data_len; 3105 res = (res + blocksize - 1) / blocksize * blocksize; 3106 return res; 3107 } 3108 3109 static size_t 3110 wrapped_length_dervied (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 + data_len; 3119 res = (res + blocksize - 1) / blocksize * blocksize; 3120 res += et->checksum->checksumsize; 3121 return res; 3122 } 3123 3124 /* 3125 * Return the size of an encrypted packet of length `data_len' 3126 */ 3127 3128 size_t 3129 krb5_get_wrapped_length (krb5_context context, 3130 krb5_crypto crypto, 3131 size_t data_len) 3132 { 3133 if (derived_crypto (context, crypto)) 3134 return wrapped_length_dervied (context, crypto, data_len); 3135 else 3136 return wrapped_length (context, crypto, data_len); 3137 } 3138 3139 #ifdef CRYPTO_DEBUG 3140 3141 static krb5_error_code 3142 krb5_get_keyid(krb5_context context, 3143 krb5_keyblock *key, 3144 u_int32_t *keyid) 3145 { 3146 MD5_CTX md5; 3147 unsigned char tmp[16]; 3148 3149 MD5_Init (&md5); 3150 MD5_Update (&md5, key->keyvalue.data, key->keyvalue.length); 3151 MD5_Final (tmp, &md5); 3152 *keyid = (tmp[12] << 24) | (tmp[13] << 16) | (tmp[14] << 8) | tmp[15]; 3153 return 0; 3154 } 3155 3156 static void 3157 krb5_crypto_debug(krb5_context context, 3158 int encrypt, 3159 size_t len, 3160 krb5_keyblock *key) 3161 { 3162 u_int32_t keyid; 3163 char *kt; 3164 krb5_get_keyid(context, key, &keyid); 3165 krb5_enctype_to_string(context, key->keytype, &kt); 3166 krb5_warnx(context, "%s %lu bytes with key-id %#x (%s)", 3167 encrypt ? "encrypting" : "decrypting", 3168 (unsigned long)len, 3169 keyid, 3170 kt); 3171 free(kt); 3172 } 3173 3174 #endif /* CRYPTO_DEBUG */ 3175 3176 #if 0 3177 int 3178 main() 3179 { 3180 #if 0 3181 int i; 3182 krb5_context context; 3183 krb5_crypto crypto; 3184 struct key_data *d; 3185 krb5_keyblock key; 3186 char constant[4]; 3187 unsigned usage = ENCRYPTION_USAGE(3); 3188 krb5_error_code ret; 3189 3190 ret = krb5_init_context(&context); 3191 if (ret) 3192 errx (1, "krb5_init_context failed: %d", ret); 3193 3194 key.keytype = ETYPE_NEW_DES3_CBC_SHA1; 3195 key.keyvalue.data = "\xb3\x85\x58\x94\xd9\xdc\x7c\xc8" 3196 "\x25\xe9\x85\xab\x3e\xb5\xfb\x0e" 3197 "\xc8\xdf\xab\x26\x86\x64\x15\x25"; 3198 key.keyvalue.length = 24; 3199 3200 krb5_crypto_init(context, &key, 0, &crypto); 3201 3202 d = _new_derived_key(crypto, usage); 3203 if(d == NULL) 3204 return ENOMEM; 3205 krb5_copy_keyblock(context, crypto->key.key, &d->key); 3206 _krb5_put_int(constant, usage, 4); 3207 derive_key(context, crypto->et, d, constant, sizeof(constant)); 3208 return 0; 3209 #else 3210 int i; 3211 krb5_context context; 3212 krb5_crypto crypto; 3213 struct key_data *d; 3214 krb5_keyblock key; 3215 krb5_error_code ret; 3216 Checksum res; 3217 3218 char *data = "what do ya want for nothing?"; 3219 3220 ret = krb5_init_context(&context); 3221 if (ret) 3222 errx (1, "krb5_init_context failed: %d", ret); 3223 3224 key.keytype = ETYPE_NEW_DES3_CBC_SHA1; 3225 key.keyvalue.data = "Jefe"; 3226 /* "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" 3227 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */ 3228 key.keyvalue.length = 4; 3229 3230 d = calloc(1, sizeof(*d)); 3231 3232 d->key = &key; 3233 res.checksum.length = 20; 3234 res.checksum.data = malloc(res.checksum.length); 3235 HMAC_SHA1_DES3_checksum(context, d, data, 28, &res); 3236 3237 return 0; 3238 #endif 3239 } 3240 #endif 3241