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