1 /* 2 * Copyright (c) 1997 - 2000 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.29 2000/01/25 23:06:55 assar Exp $"); 36 /* RCSID("$FreeBSD$"); */ 37 38 #undef CRYPTO_DEBUG 39 #ifdef CRYPTO_DEBUG 40 static void krb5_crypto_debug(krb5_context, int, size_t, krb5_keyblock*); 41 #endif 42 43 44 struct key_data { 45 krb5_keyblock *key; 46 krb5_data *schedule; 47 }; 48 49 struct key_usage { 50 unsigned usage; 51 struct key_data key; 52 }; 53 54 struct krb5_crypto_data { 55 struct encryption_type *et; 56 struct key_data key; 57 int num_key_usage; 58 struct key_usage *key_usage; 59 }; 60 61 #define CRYPTO_ETYPE(C) ((C)->et->type) 62 63 /* bits for `flags' below */ 64 #define F_KEYED 1 /* checksum is keyed */ 65 #define F_CPROOF 2 /* checksum is collision proof */ 66 #define F_DERIVED 4 /* uses derived keys */ 67 #define F_VARIANT 8 /* uses `variant' keys (6.4.3) */ 68 #define F_PSEUDO 16 /* not a real protocol type */ 69 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, struct key_data*, void*, size_t, Checksum*); 98 krb5_error_code (*verify)(krb5_context, struct key_data*, 99 void*, size_t, Checksum*); 100 }; 101 102 struct encryption_type { 103 krb5_enctype type; 104 const char *name; 105 size_t blocksize; 106 size_t confoundersize; 107 struct key_type *keytype; 108 struct checksum_type *cksumtype; 109 struct checksum_type *keyed_checksum; 110 unsigned flags; 111 void (*encrypt)(struct key_data *, void *, size_t, int); 112 }; 113 114 #define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA) 115 #define INTEGRITY_USAGE(U) (((U) << 8) | 0x55) 116 #define CHECKSUM_USAGE(U) (((U) << 8) | 0x99) 117 118 static struct checksum_type *_find_checksum(krb5_cksumtype type); 119 static struct encryption_type *_find_enctype(krb5_enctype type); 120 static struct key_type *_find_keytype(krb5_keytype type); 121 static krb5_error_code _get_derived_key(krb5_context, krb5_crypto, 122 unsigned, struct key_data**); 123 static struct key_data *_new_derived_key(krb5_crypto crypto, unsigned usage); 124 125 /************************************************************ 126 * * 127 ************************************************************/ 128 129 static void 130 DES_random_key(krb5_context context, 131 krb5_keyblock *key) 132 { 133 des_cblock *k = key->keyvalue.data; 134 do { 135 krb5_generate_random_block(k, sizeof(des_cblock)); 136 des_set_odd_parity(k); 137 } while(des_is_weak_key(k)); 138 } 139 140 static void 141 DES_schedule(krb5_context context, 142 struct key_data *key) 143 { 144 des_set_key(key->key->keyvalue.data, key->schedule->data); 145 } 146 147 static krb5_error_code 148 DES_string_to_key(krb5_context context, 149 krb5_enctype enctype, 150 krb5_data password, 151 krb5_salt salt, 152 krb5_keyblock *key) 153 { 154 char *s; 155 size_t len; 156 des_cblock tmp; 157 158 len = password.length + salt.saltvalue.length + 1; 159 s = malloc(len); 160 if(s == NULL) 161 return ENOMEM; 162 memcpy(s, password.data, password.length); 163 memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); 164 s[len - 1] = '\0'; 165 des_string_to_key(s, &tmp); 166 key->keytype = enctype; 167 krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp)); 168 memset(&tmp, 0, sizeof(tmp)); 169 memset(s, 0, len); 170 free(s); 171 return 0; 172 } 173 174 /* This defines the Andrew string_to_key function. It accepts a password 175 * string as input and converts its via a one-way encryption algorithm to a DES 176 * encryption key. It is compatible with the original Andrew authentication 177 * service password database. 178 */ 179 180 /* 181 * Short passwords, i.e 8 characters or less. 182 */ 183 static void 184 DES_AFS3_CMU_string_to_key (krb5_data pw, 185 krb5_data cell, 186 des_cblock *key) 187 { 188 char password[8+1]; /* crypt is limited to 8 chars anyway */ 189 int i; 190 191 for(i = 0; i < 8; i++) { 192 char c = ((i < pw.length) ? ((char*)pw.data)[i] : 0) ^ 193 ((i < cell.length) ? ((char*)cell.data)[i] : 0); 194 password[i] = c ? c : 'X'; 195 } 196 password[8] = '\0'; 197 198 memcpy(key, crypt(password, "#~") + 2, sizeof(des_cblock)); 199 200 /* parity is inserted into the LSB so left shift each byte up one 201 bit. This allows ascii characters with a zero MSB to retain as 202 much significance as possible. */ 203 for (i = 0; i < sizeof(des_cblock); i++) 204 ((unsigned char*)key)[i] <<= 1; 205 des_set_odd_parity (key); 206 } 207 208 /* 209 * Long passwords, i.e 9 characters or more. 210 */ 211 static void 212 DES_AFS3_Transarc_string_to_key (krb5_data pw, 213 krb5_data cell, 214 des_cblock *key) 215 { 216 des_key_schedule schedule; 217 des_cblock temp_key; 218 des_cblock ivec; 219 char password[512]; 220 size_t passlen; 221 222 memcpy(password, pw.data, min(pw.length, sizeof(password))); 223 if(pw.length < sizeof(password)) 224 memcpy(password + pw.length, 225 cell.data, min(cell.length, 226 sizeof(password) - pw.length)); 227 passlen = min(sizeof(password), pw.length + cell.length); 228 memcpy(&ivec, "kerberos", 8); 229 memcpy(&temp_key, "kerberos", 8); 230 des_set_odd_parity (&temp_key); 231 des_set_key (&temp_key, schedule); 232 des_cbc_cksum ((const void *)password, &ivec, passlen, 233 schedule, &ivec); 234 235 memcpy(&temp_key, &ivec, 8); 236 des_set_odd_parity (&temp_key); 237 des_set_key (&temp_key, schedule); 238 des_cbc_cksum ((const void *)password, key, passlen, 239 schedule, &ivec); 240 memset(&schedule, 0, sizeof(schedule)); 241 memset(&temp_key, 0, sizeof(temp_key)); 242 memset(&ivec, 0, sizeof(ivec)); 243 memset(password, 0, sizeof(password)); 244 245 des_set_odd_parity (key); 246 } 247 248 static krb5_error_code 249 DES_AFS3_string_to_key(krb5_context context, 250 krb5_enctype enctype, 251 krb5_data password, 252 krb5_salt salt, 253 krb5_keyblock *key) 254 { 255 des_cblock tmp; 256 if(password.length > 8) 257 DES_AFS3_Transarc_string_to_key(password, salt.saltvalue, &tmp); 258 else 259 DES_AFS3_CMU_string_to_key(password, salt.saltvalue, &tmp); 260 key->keytype = enctype; 261 krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp)); 262 memset(&key, 0, sizeof(key)); 263 return 0; 264 } 265 266 static void 267 DES3_random_key(krb5_context context, 268 krb5_keyblock *key) 269 { 270 des_cblock *k = key->keyvalue.data; 271 do { 272 krb5_generate_random_block(k, 3 * sizeof(des_cblock)); 273 des_set_odd_parity(&k[0]); 274 des_set_odd_parity(&k[1]); 275 des_set_odd_parity(&k[2]); 276 } while(des_is_weak_key(&k[0]) || 277 des_is_weak_key(&k[1]) || 278 des_is_weak_key(&k[2])); 279 } 280 281 static void 282 DES3_schedule(krb5_context context, 283 struct key_data *key) 284 { 285 des_cblock *k = key->key->keyvalue.data; 286 des_key_schedule *s = key->schedule->data; 287 des_set_key(&k[0], s[0]); 288 des_set_key(&k[1], s[1]); 289 des_set_key(&k[2], s[2]); 290 } 291 292 /* 293 * A = A xor B. A & B are 8 bytes. 294 */ 295 296 static void 297 xor (des_cblock *key, const unsigned char *b) 298 { 299 unsigned char *a = (unsigned char*)key; 300 a[0] ^= b[0]; 301 a[1] ^= b[1]; 302 a[2] ^= b[2]; 303 a[3] ^= b[3]; 304 a[4] ^= b[4]; 305 a[5] ^= b[5]; 306 a[6] ^= b[6]; 307 a[7] ^= b[7]; 308 } 309 310 static krb5_error_code 311 DES3_string_to_key(krb5_context context, 312 krb5_enctype enctype, 313 krb5_data password, 314 krb5_salt salt, 315 krb5_keyblock *key) 316 { 317 char *str; 318 size_t len; 319 unsigned char tmp[24]; 320 des_cblock keys[3]; 321 322 len = password.length + salt.saltvalue.length; 323 str = malloc(len); 324 if(len != 0 && str == NULL) 325 return ENOMEM; 326 memcpy(str, password.data, password.length); 327 memcpy(str + password.length, salt.saltvalue.data, salt.saltvalue.length); 328 { 329 des_cblock ivec; 330 des_key_schedule s[3]; 331 int i; 332 333 _krb5_n_fold(str, len, tmp, 24); 334 335 for(i = 0; i < 3; i++){ 336 memcpy(keys + i, tmp + i * 8, sizeof(keys[i])); 337 des_set_odd_parity(keys + i); 338 if(des_is_weak_key(keys + i)) 339 xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0"); 340 des_set_key(keys + i, s[i]); 341 } 342 memset(&ivec, 0, sizeof(ivec)); 343 des_ede3_cbc_encrypt((const void *)tmp, 344 (void *)tmp, sizeof(tmp), 345 s[0], s[1], s[2], &ivec, DES_ENCRYPT); 346 memset(s, 0, sizeof(s)); 347 memset(&ivec, 0, sizeof(ivec)); 348 for(i = 0; i < 3; i++){ 349 memcpy(keys + i, tmp + i * 8, sizeof(keys[i])); 350 des_set_odd_parity(keys + i); 351 if(des_is_weak_key(keys + i)) 352 xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0"); 353 } 354 memset(tmp, 0, sizeof(tmp)); 355 } 356 key->keytype = enctype; 357 krb5_data_copy(&key->keyvalue, keys, sizeof(keys)); 358 memset(keys, 0, sizeof(keys)); 359 memset(str, 0, len); 360 free(str); 361 return 0; 362 } 363 364 static krb5_error_code 365 DES3_string_to_key_derived(krb5_context context, 366 krb5_enctype enctype, 367 krb5_data password, 368 krb5_salt salt, 369 krb5_keyblock *key) 370 { 371 krb5_error_code ret; 372 size_t len = password.length + salt.saltvalue.length; 373 char *s; 374 375 s = malloc(len); 376 if(len != 0 && s == NULL) 377 return ENOMEM; 378 memcpy(s, password.data, password.length); 379 memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); 380 ret = krb5_string_to_key_derived(context, 381 s, 382 len, 383 enctype, 384 key); 385 memset(s, 0, len); 386 free(s); 387 return ret; 388 } 389 390 /* 391 * ARCFOUR 392 */ 393 394 static void 395 ARCFOUR_random_key(krb5_context context, krb5_keyblock *key) 396 { 397 krb5_generate_random_block (key->keyvalue.data, 398 key->keyvalue.length); 399 } 400 401 static void 402 ARCFOUR_schedule(krb5_context context, struct key_data *kd) 403 { 404 RC4_set_key (kd->schedule->data, 405 kd->key->keyvalue.length, kd->key->keyvalue.data); 406 } 407 408 static krb5_error_code 409 ARCFOUR_string_to_key(krb5_context context, 410 krb5_enctype enctype, 411 krb5_data password, 412 krb5_salt salt, 413 krb5_keyblock *key) 414 { 415 char *s, *p; 416 size_t len; 417 int i; 418 MD4_CTX m; 419 420 len = 2 * (password.length + salt.saltvalue.length); 421 s = malloc (len); 422 if (len != 0 && s == NULL) 423 return ENOMEM; 424 for (p = s, i = 0; i < password.length; ++i) { 425 *p++ = ((char *)password.data)[i]; 426 *p++ = 0; 427 } 428 for (i = 0; i < salt.saltvalue.length; ++i) { 429 *p++ = ((char *)salt.saltvalue.data)[i]; 430 *p++ = 0; 431 } 432 MD4Init (&m); 433 MD4Update (&m, s, len); 434 key->keytype = enctype; 435 krb5_data_alloc (&key->keyvalue, 16); 436 MD4Final (key->keyvalue.data, &m); 437 memset (s, 0, len); 438 free (s); 439 return 0; 440 } 441 442 extern struct salt_type des_salt[], 443 des3_salt[], des3_salt_derived[], arcfour_salt[]; 444 445 struct key_type keytype_null = { 446 KEYTYPE_NULL, 447 "null", 448 0, 449 0, 450 0, 451 NULL, 452 NULL, 453 NULL 454 }; 455 456 struct key_type keytype_des = { 457 KEYTYPE_DES, 458 "des", 459 56, 460 sizeof(des_cblock), 461 sizeof(des_key_schedule), 462 DES_random_key, 463 DES_schedule, 464 des_salt 465 }; 466 467 struct key_type keytype_des3 = { 468 KEYTYPE_DES3, 469 "des3", 470 168, 471 3 * sizeof(des_cblock), 472 3 * sizeof(des_key_schedule), 473 DES3_random_key, 474 DES3_schedule, 475 des3_salt 476 }; 477 478 struct key_type keytype_des3_derived = { 479 KEYTYPE_DES3, 480 "des3", 481 168, 482 3 * sizeof(des_cblock), 483 3 * sizeof(des_key_schedule), 484 DES3_random_key, 485 DES3_schedule, 486 des3_salt_derived 487 }; 488 489 struct key_type keytype_arcfour = { 490 KEYTYPE_ARCFOUR, 491 "arcfour", 492 128, 493 16, 494 sizeof(RC4_KEY), 495 ARCFOUR_random_key, 496 ARCFOUR_schedule, 497 arcfour_salt 498 }; 499 500 struct key_type *keytypes[] = { 501 &keytype_null, 502 &keytype_des, 503 &keytype_des3_derived, 504 &keytype_des3, 505 &keytype_arcfour 506 }; 507 508 static int num_keytypes = sizeof(keytypes) / sizeof(keytypes[0]); 509 510 static struct key_type * 511 _find_keytype(krb5_keytype type) 512 { 513 int i; 514 for(i = 0; i < num_keytypes; i++) 515 if(keytypes[i]->type == type) 516 return keytypes[i]; 517 return NULL; 518 } 519 520 521 struct salt_type des_salt[] = { 522 { 523 KRB5_PW_SALT, 524 "pw-salt", 525 DES_string_to_key 526 }, 527 { 528 KRB5_AFS3_SALT, 529 "afs3-salt", 530 DES_AFS3_string_to_key 531 }, 532 { 0 } 533 }; 534 535 struct salt_type des3_salt[] = { 536 { 537 KRB5_PW_SALT, 538 "pw-salt", 539 DES3_string_to_key 540 }, 541 { 0 } 542 }; 543 544 struct salt_type des3_salt_derived[] = { 545 { 546 KRB5_PW_SALT, 547 "pw-salt", 548 DES3_string_to_key_derived 549 }, 550 { 0 } 551 }; 552 553 struct salt_type arcfour_salt[] = { 554 { 555 KRB5_PW_SALT, 556 "pw-salt", 557 ARCFOUR_string_to_key 558 }, 559 { 0 } 560 }; 561 562 krb5_error_code 563 krb5_salttype_to_string (krb5_context context, 564 krb5_enctype etype, 565 krb5_salttype stype, 566 char **string) 567 { 568 struct encryption_type *e; 569 struct salt_type *st; 570 571 e = _find_enctype (etype); 572 if (e == NULL) 573 return KRB5_PROG_ETYPE_NOSUPP; 574 for (st = e->keytype->string_to_key; st && st->type; st++) { 575 if (st->type == stype) { 576 *string = strdup (st->name); 577 if (*string == NULL) 578 return ENOMEM; 579 return 0; 580 } 581 } 582 return HEIM_ERR_SALTTYPE_NOSUPP; 583 } 584 585 krb5_error_code 586 krb5_string_to_salttype (krb5_context context, 587 krb5_enctype etype, 588 const char *string, 589 krb5_salttype *salttype) 590 { 591 struct encryption_type *e; 592 struct salt_type *st; 593 594 e = _find_enctype (etype); 595 if (e == NULL) 596 return KRB5_PROG_ETYPE_NOSUPP; 597 for (st = e->keytype->string_to_key; st && st->type; st++) { 598 if (strcasecmp (st->name, string) == 0) { 599 *salttype = st->type; 600 return 0; 601 } 602 } 603 return HEIM_ERR_SALTTYPE_NOSUPP; 604 } 605 606 krb5_error_code 607 krb5_get_pw_salt(krb5_context context, 608 krb5_const_principal principal, 609 krb5_salt *salt) 610 { 611 size_t len; 612 int i; 613 krb5_error_code ret; 614 char *p; 615 616 salt->salttype = KRB5_PW_SALT; 617 len = strlen(principal->realm); 618 for (i = 0; i < principal->name.name_string.len; ++i) 619 len += strlen(principal->name.name_string.val[i]); 620 ret = krb5_data_alloc (&salt->saltvalue, len); 621 if (ret) 622 return ret; 623 p = salt->saltvalue.data; 624 memcpy (p, principal->realm, strlen(principal->realm)); 625 p += strlen(principal->realm); 626 for (i = 0; i < principal->name.name_string.len; ++i) { 627 memcpy (p, 628 principal->name.name_string.val[i], 629 strlen(principal->name.name_string.val[i])); 630 p += strlen(principal->name.name_string.val[i]); 631 } 632 return 0; 633 } 634 635 krb5_error_code 636 krb5_free_salt(krb5_context context, 637 krb5_salt salt) 638 { 639 krb5_data_free(&salt.saltvalue); 640 return 0; 641 } 642 643 krb5_error_code 644 krb5_string_to_key_data (krb5_context context, 645 krb5_enctype enctype, 646 krb5_data password, 647 krb5_principal principal, 648 krb5_keyblock *key) 649 { 650 krb5_error_code ret; 651 krb5_salt salt; 652 653 ret = krb5_get_pw_salt(context, principal, &salt); 654 if(ret) 655 return ret; 656 ret = krb5_string_to_key_data_salt(context, enctype, password, salt, key); 657 krb5_free_salt(context, salt); 658 return ret; 659 } 660 661 krb5_error_code 662 krb5_string_to_key (krb5_context context, 663 krb5_enctype enctype, 664 const char *password, 665 krb5_principal principal, 666 krb5_keyblock *key) 667 { 668 krb5_data pw; 669 pw.data = (void*)password; 670 pw.length = strlen(password); 671 return krb5_string_to_key_data(context, enctype, pw, principal, key); 672 } 673 674 krb5_error_code 675 krb5_string_to_key_data_salt (krb5_context context, 676 krb5_enctype enctype, 677 krb5_data password, 678 krb5_salt salt, 679 krb5_keyblock *key) 680 { 681 struct encryption_type *et =_find_enctype(enctype); 682 struct salt_type *st; 683 if(et == NULL) 684 return KRB5_PROG_ETYPE_NOSUPP; 685 for(st = et->keytype->string_to_key; st && st->type; st++) 686 if(st->type == salt.salttype) 687 return (*st->string_to_key)(context, enctype, password, salt, key); 688 return HEIM_ERR_SALTTYPE_NOSUPP; 689 } 690 691 krb5_error_code 692 krb5_string_to_key_salt (krb5_context context, 693 krb5_enctype enctype, 694 const char *password, 695 krb5_salt salt, 696 krb5_keyblock *key) 697 { 698 krb5_data pw; 699 pw.data = (void*)password; 700 pw.length = strlen(password); 701 return krb5_string_to_key_data_salt(context, enctype, pw, salt, key); 702 } 703 704 krb5_error_code 705 krb5_keytype_to_string(krb5_context context, 706 krb5_keytype keytype, 707 char **string) 708 { 709 struct key_type *kt = _find_keytype(keytype); 710 if(kt == NULL) 711 return KRB5_PROG_KEYTYPE_NOSUPP; 712 *string = strdup(kt->name); 713 if(*string == NULL) 714 return ENOMEM; 715 return 0; 716 } 717 718 krb5_error_code 719 krb5_string_to_keytype(krb5_context context, 720 const char *string, 721 krb5_keytype *keytype) 722 { 723 int i; 724 for(i = 0; i < num_keytypes; i++) 725 if(strcasecmp(keytypes[i]->name, string) == 0){ 726 *keytype = keytypes[i]->type; 727 return 0; 728 } 729 return KRB5_PROG_KEYTYPE_NOSUPP; 730 } 731 732 krb5_error_code 733 krb5_generate_random_keyblock(krb5_context context, 734 krb5_enctype type, 735 krb5_keyblock *key) 736 { 737 krb5_error_code ret; 738 struct encryption_type *et = _find_enctype(type); 739 if(et == NULL) 740 return KRB5_PROG_ETYPE_NOSUPP; 741 ret = krb5_data_alloc(&key->keyvalue, et->keytype->size); 742 if(ret) 743 return ret; 744 key->keytype = type; 745 if(et->keytype->random_key) 746 (*et->keytype->random_key)(context, key); 747 else 748 krb5_generate_random_block(key->keyvalue.data, 749 key->keyvalue.length); 750 return 0; 751 } 752 753 static krb5_error_code 754 _key_schedule(krb5_context context, 755 struct key_data *key) 756 { 757 krb5_error_code ret; 758 struct encryption_type *et = _find_enctype(key->key->keytype); 759 struct key_type *kt = et->keytype; 760 761 if(kt->schedule == NULL) 762 return 0; 763 ALLOC(key->schedule, 1); 764 if(key->schedule == NULL) 765 return ENOMEM; 766 ret = krb5_data_alloc(key->schedule, kt->schedule_size); 767 if(ret) { 768 free(key->schedule); 769 key->schedule = NULL; 770 return ret; 771 } 772 (*kt->schedule)(context, key); 773 return 0; 774 } 775 776 /************************************************************ 777 * * 778 ************************************************************/ 779 780 static void 781 NONE_checksum(krb5_context context, 782 struct key_data *key, 783 void *data, 784 size_t len, 785 Checksum *C) 786 { 787 } 788 789 static void 790 CRC32_checksum(krb5_context context, 791 struct key_data *key, 792 void *data, 793 size_t len, 794 Checksum *C) 795 { 796 u_int32_t crc; 797 unsigned char *r = C->checksum.data; 798 _krb5_crc_init_table (); 799 crc = _krb5_crc_update (data, len, 0); 800 r[0] = crc & 0xff; 801 r[1] = (crc >> 8) & 0xff; 802 r[2] = (crc >> 16) & 0xff; 803 r[3] = (crc >> 24) & 0xff; 804 } 805 806 static void 807 RSA_MD4_checksum(krb5_context context, 808 struct key_data *key, 809 void *data, 810 size_t len, 811 Checksum *C) 812 { 813 MD4_CTX m; 814 815 MD4Init (&m); 816 MD4Update (&m, data, len); 817 MD4Final (C->checksum.data, &m); 818 } 819 820 static void 821 RSA_MD4_DES_checksum(krb5_context context, 822 struct key_data *key, 823 void *data, 824 size_t len, 825 Checksum *cksum) 826 { 827 MD4_CTX md4; 828 des_cblock ivec; 829 unsigned char *p = cksum->checksum.data; 830 831 krb5_generate_random_block(p, 8); 832 MD4Init (&md4); 833 MD4Update (&md4, p, 8); 834 MD4Update (&md4, data, len); 835 MD4Final (p + 8, &md4); 836 memset (&ivec, 0, sizeof(ivec)); 837 des_cbc_encrypt((const void *)p, 838 (void *)p, 839 24, 840 key->schedule->data, 841 &ivec, 842 DES_ENCRYPT); 843 } 844 845 static krb5_error_code 846 RSA_MD4_DES_verify(krb5_context context, 847 struct key_data *key, 848 void *data, 849 size_t len, 850 Checksum *C) 851 { 852 MD4_CTX md4; 853 unsigned char tmp[24]; 854 unsigned char res[16]; 855 des_cblock ivec; 856 krb5_error_code ret = 0; 857 858 memset(&ivec, 0, sizeof(ivec)); 859 des_cbc_encrypt(C->checksum.data, 860 (void*)tmp, 861 C->checksum.length, 862 key->schedule->data, 863 &ivec, 864 DES_DECRYPT); 865 MD4Init (&md4); 866 MD4Update (&md4, tmp, 8); /* confounder */ 867 MD4Update (&md4, data, len); 868 MD4Final (res, &md4); 869 if(memcmp(res, tmp + 8, sizeof(res)) != 0) 870 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 871 memset(tmp, 0, sizeof(tmp)); 872 memset(res, 0, sizeof(res)); 873 return ret; 874 } 875 876 static void 877 RSA_MD5_checksum(krb5_context context, 878 struct key_data *key, 879 void *data, 880 size_t len, 881 Checksum *C) 882 { 883 MD5_CTX m; 884 885 MD5Init (&m); 886 MD5Update(&m, data, len); 887 MD5Final (C->checksum.data, &m); 888 } 889 890 static void 891 RSA_MD5_DES_checksum(krb5_context context, 892 struct key_data *key, 893 void *data, 894 size_t len, 895 Checksum *C) 896 { 897 MD5_CTX md5; 898 des_cblock ivec; 899 unsigned char *p = C->checksum.data; 900 901 krb5_generate_random_block(p, 8); 902 MD5Init (&md5); 903 MD5Update (&md5, p, 8); 904 MD5Update (&md5, data, len); 905 MD5Final (p + 8, &md5); 906 memset (&ivec, 0, sizeof(ivec)); 907 des_cbc_encrypt((const void *)p, 908 (void *)p, 909 24, 910 key->schedule->data, 911 &ivec, 912 DES_ENCRYPT); 913 } 914 915 static krb5_error_code 916 RSA_MD5_DES_verify(krb5_context context, 917 struct key_data *key, 918 void *data, 919 size_t len, 920 Checksum *C) 921 { 922 MD5_CTX md5; 923 unsigned char tmp[24]; 924 unsigned char res[16]; 925 des_cblock ivec; 926 des_key_schedule *sched = key->schedule->data; 927 krb5_error_code ret = 0; 928 929 memset(&ivec, 0, sizeof(ivec)); 930 des_cbc_encrypt(C->checksum.data, 931 (void*)tmp, 932 C->checksum.length, 933 sched[0], 934 &ivec, 935 DES_DECRYPT); 936 MD5Init (&md5); 937 MD5Update (&md5, tmp, 8); /* confounder */ 938 MD5Update (&md5, data, len); 939 MD5Final (res, &md5); 940 if(memcmp(res, tmp + 8, sizeof(res)) != 0) 941 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 942 memset(tmp, 0, sizeof(tmp)); 943 memset(res, 0, sizeof(res)); 944 return ret; 945 } 946 947 static void 948 RSA_MD5_DES3_checksum(krb5_context context, 949 struct key_data *key, 950 void *data, 951 size_t len, 952 Checksum *C) 953 { 954 MD5_CTX md5; 955 des_cblock ivec; 956 unsigned char *p = C->checksum.data; 957 des_key_schedule *sched = key->schedule->data; 958 959 krb5_generate_random_block(p, 8); 960 MD5Init (&md5); 961 MD5Update (&md5, p, 8); 962 MD5Update (&md5, data, len); 963 MD5Final (p + 8, &md5); 964 memset (&ivec, 0, sizeof(ivec)); 965 des_ede3_cbc_encrypt((const void *)p, 966 (void *)p, 967 24, 968 sched[0], sched[1], sched[2], 969 &ivec, 970 DES_ENCRYPT); 971 } 972 973 static krb5_error_code 974 RSA_MD5_DES3_verify(krb5_context context, 975 struct key_data *key, 976 void *data, 977 size_t len, 978 Checksum *C) 979 { 980 MD5_CTX md5; 981 unsigned char tmp[24]; 982 unsigned char res[16]; 983 des_cblock ivec; 984 des_key_schedule *sched = key->schedule->data; 985 krb5_error_code ret = 0; 986 987 memset(&ivec, 0, sizeof(ivec)); 988 des_ede3_cbc_encrypt(C->checksum.data, 989 (void*)tmp, 990 C->checksum.length, 991 sched[0], sched[1], sched[2], 992 &ivec, 993 DES_DECRYPT); 994 MD5Init (&md5); 995 MD5Update (&md5, tmp, 8); /* confounder */ 996 MD5Update (&md5, data, len); 997 MD5Final (res, &md5); 998 if(memcmp(res, tmp + 8, sizeof(res)) != 0) 999 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 1000 memset(tmp, 0, sizeof(tmp)); 1001 memset(res, 0, sizeof(res)); 1002 return ret; 1003 } 1004 1005 static void 1006 SHA1_checksum(krb5_context context, 1007 struct key_data *key, 1008 void *data, 1009 size_t len, 1010 Checksum *C) 1011 { 1012 SHA1_CTX m; 1013 1014 SHA_Init(&m); 1015 SHA_Update(&m, data, len); 1016 SHA_Final(C->checksum.data, &m); 1017 } 1018 1019 /* HMAC according to RFC2104 */ 1020 static void 1021 hmac(krb5_context context, 1022 struct checksum_type *cm, 1023 void *data, 1024 size_t len, 1025 struct key_data *keyblock, 1026 Checksum *result) 1027 { 1028 unsigned char *ipad, *opad; 1029 unsigned char *key; 1030 size_t key_len; 1031 int i; 1032 1033 if(keyblock->key->keyvalue.length > cm->blocksize){ 1034 (*cm->checksum)(context, 1035 keyblock, 1036 keyblock->key->keyvalue.data, 1037 keyblock->key->keyvalue.length, 1038 result); 1039 key = result->checksum.data; 1040 key_len = result->checksum.length; 1041 } else { 1042 key = keyblock->key->keyvalue.data; 1043 key_len = keyblock->key->keyvalue.length; 1044 } 1045 ipad = malloc(cm->blocksize + len); 1046 opad = malloc(cm->blocksize + cm->checksumsize); 1047 memset(ipad, 0x36, cm->blocksize); 1048 memset(opad, 0x5c, cm->blocksize); 1049 for(i = 0; i < key_len; i++){ 1050 ipad[i] ^= key[i]; 1051 opad[i] ^= key[i]; 1052 } 1053 memcpy(ipad + cm->blocksize, data, len); 1054 (*cm->checksum)(context, keyblock, ipad, cm->blocksize + len, result); 1055 memcpy(opad + cm->blocksize, result->checksum.data, 1056 result->checksum.length); 1057 (*cm->checksum)(context, keyblock, opad, 1058 cm->blocksize + cm->checksumsize, result); 1059 memset(ipad, 0, cm->blocksize + len); 1060 free(ipad); 1061 memset(opad, 0, cm->blocksize + cm->checksumsize); 1062 free(opad); 1063 } 1064 1065 static void 1066 HMAC_SHA1_DES3_checksum(krb5_context context, 1067 struct key_data *key, 1068 void *data, 1069 size_t len, 1070 Checksum *result) 1071 { 1072 struct checksum_type *c = _find_checksum(CKSUMTYPE_SHA1); 1073 1074 hmac(context, c, data, len, key, result); 1075 } 1076 1077 struct checksum_type checksum_none = { 1078 CKSUMTYPE_NONE, 1079 "none", 1080 1, 1081 0, 1082 0, 1083 NONE_checksum, 1084 NULL 1085 }; 1086 struct checksum_type checksum_crc32 = { 1087 CKSUMTYPE_CRC32, 1088 "crc32", 1089 1, 1090 4, 1091 0, 1092 CRC32_checksum, 1093 NULL 1094 }; 1095 struct checksum_type checksum_rsa_md4 = { 1096 CKSUMTYPE_RSA_MD4, 1097 "rsa-md4", 1098 64, 1099 16, 1100 F_CPROOF, 1101 RSA_MD4_checksum, 1102 NULL 1103 }; 1104 struct checksum_type checksum_rsa_md4_des = { 1105 CKSUMTYPE_RSA_MD4_DES, 1106 "rsa-md4-des", 1107 64, 1108 24, 1109 F_KEYED | F_CPROOF | F_VARIANT, 1110 RSA_MD4_DES_checksum, 1111 RSA_MD4_DES_verify 1112 }; 1113 #if 0 1114 struct checksum_type checksum_des_mac = { 1115 CKSUMTYPE_DES_MAC, 1116 "des-mac", 1117 0, 1118 0, 1119 0, 1120 DES_MAC_checksum, 1121 }; 1122 struct checksum_type checksum_des_mac_k = { 1123 CKSUMTYPE_DES_MAC_K, 1124 "des-mac-k", 1125 0, 1126 0, 1127 0, 1128 DES_MAC_K_checksum, 1129 }; 1130 struct checksum_type checksum_rsa_md4_des_k = { 1131 CKSUMTYPE_RSA_MD4_DES_K, 1132 "rsa-md4-des-k", 1133 0, 1134 0, 1135 0, 1136 RSA_MD4_DES_K_checksum, 1137 RSA_MD4_DES_K_verify, 1138 }; 1139 #endif 1140 struct checksum_type checksum_rsa_md5 = { 1141 CKSUMTYPE_RSA_MD5, 1142 "rsa-md5", 1143 64, 1144 16, 1145 F_CPROOF, 1146 RSA_MD5_checksum, 1147 NULL 1148 }; 1149 struct checksum_type checksum_rsa_md5_des = { 1150 CKSUMTYPE_RSA_MD5_DES, 1151 "rsa-md5-des", 1152 64, 1153 24, 1154 F_KEYED | F_CPROOF | F_VARIANT, 1155 RSA_MD5_DES_checksum, 1156 RSA_MD5_DES_verify, 1157 }; 1158 struct checksum_type checksum_rsa_md5_des3 = { 1159 CKSUMTYPE_RSA_MD5_DES3, 1160 "rsa-md5-des3", 1161 64, 1162 24, 1163 F_KEYED | F_CPROOF | F_VARIANT, 1164 RSA_MD5_DES3_checksum, 1165 RSA_MD5_DES3_verify, 1166 }; 1167 struct checksum_type checksum_sha1 = { 1168 CKSUMTYPE_SHA1, 1169 "sha1", 1170 64, 1171 20, 1172 F_CPROOF, 1173 SHA1_checksum, 1174 NULL 1175 }; 1176 struct checksum_type checksum_hmac_sha1_des3 = { 1177 CKSUMTYPE_HMAC_SHA1_DES3, 1178 "hmac-sha1-des3", 1179 64, 1180 20, 1181 F_KEYED | F_CPROOF | F_DERIVED, 1182 HMAC_SHA1_DES3_checksum, 1183 NULL 1184 }; 1185 1186 struct checksum_type *checksum_types[] = { 1187 &checksum_none, 1188 &checksum_crc32, 1189 &checksum_rsa_md4, 1190 &checksum_rsa_md4_des, 1191 #if 0 1192 &checksum_des_mac, 1193 &checksum_des_mac_k, 1194 &checksum_rsa_md4_des_k, 1195 #endif 1196 &checksum_rsa_md5, 1197 &checksum_rsa_md5_des, 1198 &checksum_rsa_md5_des3, 1199 &checksum_sha1, 1200 &checksum_hmac_sha1_des3 1201 }; 1202 1203 static int num_checksums = sizeof(checksum_types) / sizeof(checksum_types[0]); 1204 1205 static struct checksum_type * 1206 _find_checksum(krb5_cksumtype type) 1207 { 1208 int i; 1209 for(i = 0; i < num_checksums; i++) 1210 if(checksum_types[i]->type == type) 1211 return checksum_types[i]; 1212 return NULL; 1213 } 1214 1215 static krb5_error_code 1216 get_checksum_key(krb5_context context, 1217 krb5_crypto crypto, 1218 unsigned usage, /* not krb5_key_usage */ 1219 struct checksum_type *ct, 1220 struct key_data **key) 1221 { 1222 krb5_error_code ret = 0; 1223 1224 if(ct->flags & F_DERIVED) 1225 ret = _get_derived_key(context, crypto, usage, key); 1226 else if(ct->flags & F_VARIANT) { 1227 int i; 1228 1229 *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */); 1230 if(*key == NULL) 1231 return ENOMEM; 1232 ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key); 1233 if(ret) 1234 return ret; 1235 for(i = 0; i < (*key)->key->keyvalue.length; i++) 1236 ((unsigned char*)(*key)->key->keyvalue.data)[i] ^= 0xF0; 1237 } else { 1238 *key = &crypto->key; 1239 } 1240 if(ret == 0) 1241 ret = _key_schedule(context, *key); 1242 return ret; 1243 } 1244 1245 static krb5_error_code 1246 do_checksum (krb5_context context, 1247 struct checksum_type *ct, 1248 krb5_crypto crypto, 1249 unsigned usage, 1250 void *data, 1251 size_t len, 1252 Checksum *result) 1253 { 1254 krb5_error_code ret; 1255 struct key_data *dkey; 1256 int keyed_checksum; 1257 1258 keyed_checksum = (ct->flags & F_KEYED) != 0; 1259 if(keyed_checksum && crypto == NULL) 1260 return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ 1261 if(keyed_checksum) 1262 ret = get_checksum_key(context, crypto, usage, ct, &dkey); 1263 else 1264 dkey = NULL; 1265 result->cksumtype = ct->type; 1266 krb5_data_alloc(&result->checksum, ct->checksumsize); 1267 (*ct->checksum)(context, dkey, data, len, result); 1268 return 0; 1269 } 1270 1271 static krb5_error_code 1272 create_checksum(krb5_context context, 1273 krb5_crypto crypto, 1274 unsigned usage, /* not krb5_key_usage */ 1275 krb5_cksumtype type, /* if crypto == NULL */ 1276 void *data, 1277 size_t len, 1278 Checksum *result) 1279 { 1280 struct checksum_type *ct; 1281 1282 if(crypto) { 1283 ct = crypto->et->keyed_checksum; 1284 if(ct == NULL) 1285 ct = crypto->et->cksumtype; 1286 } else 1287 ct = _find_checksum(type); 1288 if(ct == NULL) 1289 return KRB5_PROG_SUMTYPE_NOSUPP; 1290 return do_checksum (context, ct, crypto, usage, data, len, result); 1291 } 1292 1293 krb5_error_code 1294 krb5_create_checksum(krb5_context context, 1295 krb5_crypto crypto, 1296 unsigned usage_or_type, 1297 void *data, 1298 size_t len, 1299 Checksum *result) 1300 { 1301 return create_checksum(context, crypto, 1302 CHECKSUM_USAGE(usage_or_type), 1303 usage_or_type, data, len, result); 1304 } 1305 1306 static krb5_error_code 1307 verify_checksum(krb5_context context, 1308 krb5_crypto crypto, 1309 unsigned usage, /* not krb5_key_usage */ 1310 void *data, 1311 size_t len, 1312 Checksum *cksum) 1313 { 1314 krb5_error_code ret; 1315 struct key_data *dkey; 1316 int keyed_checksum; 1317 Checksum c; 1318 struct checksum_type *ct; 1319 1320 ct = _find_checksum(cksum->cksumtype); 1321 if(ct == NULL) 1322 return KRB5_PROG_SUMTYPE_NOSUPP; 1323 if(ct->checksumsize != cksum->checksum.length) 1324 return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */ 1325 keyed_checksum = (ct->flags & F_KEYED) != 0; 1326 if(keyed_checksum && crypto == NULL) 1327 return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ 1328 if(keyed_checksum) 1329 ret = get_checksum_key(context, crypto, usage, ct, &dkey); 1330 else 1331 dkey = NULL; 1332 if(ct->verify) 1333 return (*ct->verify)(context, dkey, data, len, cksum); 1334 1335 ret = krb5_data_alloc (&c.checksum, ct->checksumsize); 1336 if (ret) 1337 return ret; 1338 1339 (*ct->checksum)(context, dkey, data, len, &c); 1340 1341 if(c.checksum.length != cksum->checksum.length || 1342 memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) 1343 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 1344 else 1345 ret = 0; 1346 krb5_data_free (&c.checksum); 1347 return ret; 1348 } 1349 1350 krb5_error_code 1351 krb5_verify_checksum(krb5_context context, 1352 krb5_crypto crypto, 1353 krb5_key_usage usage, 1354 void *data, 1355 size_t len, 1356 Checksum *cksum) 1357 { 1358 return verify_checksum(context, crypto, 1359 CHECKSUM_USAGE(usage), data, len, cksum); 1360 } 1361 1362 krb5_error_code 1363 krb5_checksumsize(krb5_context context, 1364 krb5_cksumtype type, 1365 size_t *size) 1366 { 1367 struct checksum_type *ct = _find_checksum(type); 1368 if(ct == NULL) 1369 return KRB5_PROG_SUMTYPE_NOSUPP; 1370 *size = ct->checksumsize; 1371 return 0; 1372 } 1373 1374 krb5_boolean 1375 krb5_checksum_is_keyed(krb5_context context, 1376 krb5_cksumtype type) 1377 { 1378 struct checksum_type *ct = _find_checksum(type); 1379 if(ct == NULL) 1380 return KRB5_PROG_SUMTYPE_NOSUPP; 1381 return ct->flags & F_KEYED; 1382 } 1383 1384 krb5_boolean 1385 krb5_checksum_is_collision_proof(krb5_context context, 1386 krb5_cksumtype type) 1387 { 1388 struct checksum_type *ct = _find_checksum(type); 1389 if(ct == NULL) 1390 return KRB5_PROG_SUMTYPE_NOSUPP; 1391 return ct->flags & F_CPROOF; 1392 } 1393 1394 /************************************************************ 1395 * * 1396 ************************************************************/ 1397 1398 static void 1399 NULL_encrypt(struct key_data *key, 1400 void *data, 1401 size_t len, 1402 krb5_boolean encrypt) 1403 { 1404 } 1405 1406 static void 1407 DES_CBC_encrypt_null_ivec(struct key_data *key, 1408 void *data, 1409 size_t len, 1410 krb5_boolean encrypt) 1411 { 1412 des_cblock ivec; 1413 des_key_schedule *s = key->schedule->data; 1414 memset(&ivec, 0, sizeof(ivec)); 1415 des_cbc_encrypt(data, data, len, *s, &ivec, encrypt); 1416 } 1417 1418 static void 1419 DES_CBC_encrypt_key_ivec(struct key_data *key, 1420 void *data, 1421 size_t len, 1422 krb5_boolean encrypt) 1423 { 1424 des_cblock ivec; 1425 des_key_schedule *s = key->schedule->data; 1426 memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec)); 1427 des_cbc_encrypt(data, data, len, *s, &ivec, encrypt); 1428 } 1429 1430 static void 1431 DES3_CBC_encrypt(struct key_data *key, 1432 void *data, 1433 size_t len, 1434 krb5_boolean encrypt) 1435 { 1436 des_cblock ivec; 1437 des_key_schedule *s = key->schedule->data; 1438 memset(&ivec, 0, sizeof(ivec)); 1439 des_ede3_cbc_encrypt(data, data, len, s[0], s[1], s[2], &ivec, encrypt); 1440 } 1441 1442 static void 1443 ARCFOUR_encrypt(struct key_data *key, 1444 void *data, 1445 size_t len, 1446 krb5_boolean encrypt) 1447 { 1448 1449 } 1450 1451 /* 1452 * these should currently be in reverse preference order. 1453 */ 1454 1455 static struct encryption_type etypes[] = { 1456 { 1457 ETYPE_NULL, 1458 "null", 1459 1, 1460 0, 1461 &keytype_null, 1462 &checksum_none, 1463 NULL, 1464 0, 1465 NULL_encrypt, 1466 }, 1467 { 1468 ETYPE_DES_CBC_CRC, 1469 "des-cbc-crc", 1470 8, 1471 8, 1472 &keytype_des, 1473 &checksum_crc32, 1474 NULL, 1475 0, 1476 DES_CBC_encrypt_key_ivec, 1477 }, 1478 { 1479 ETYPE_DES_CBC_MD4, 1480 "des-cbc-md4", 1481 8, 1482 8, 1483 &keytype_des, 1484 &checksum_rsa_md4, 1485 &checksum_rsa_md4_des, 1486 0, 1487 DES_CBC_encrypt_null_ivec, 1488 }, 1489 { 1490 ETYPE_DES_CBC_MD5, 1491 "des-cbc-md5", 1492 8, 1493 8, 1494 &keytype_des, 1495 &checksum_rsa_md5, 1496 &checksum_rsa_md5_des, 1497 0, 1498 DES_CBC_encrypt_null_ivec, 1499 }, 1500 { 1501 ETYPE_DES3_CBC_MD5, 1502 "des3-cbc-md5", 1503 8, 1504 8, 1505 &keytype_des3, 1506 &checksum_rsa_md5, 1507 &checksum_rsa_md5_des3, 1508 0, 1509 DES3_CBC_encrypt, 1510 }, 1511 { 1512 ETYPE_DES3_CBC_SHA1, 1513 "des3-cbc-sha1", 1514 8, 1515 8, 1516 &keytype_des3_derived, 1517 &checksum_sha1, 1518 &checksum_hmac_sha1_des3, 1519 F_DERIVED, 1520 DES3_CBC_encrypt, 1521 }, 1522 { 1523 ETYPE_OLD_DES3_CBC_SHA1, 1524 "old-des3-cbc-sha1", 1525 8, 1526 8, 1527 &keytype_des3, 1528 &checksum_sha1, 1529 &checksum_hmac_sha1_des3, 1530 0, 1531 DES3_CBC_encrypt, 1532 }, 1533 { 1534 ETYPE_DES_CBC_NONE, 1535 "des-cbc-none", 1536 8, 1537 0, 1538 &keytype_des, 1539 &checksum_none, 1540 NULL, 1541 F_PSEUDO, 1542 DES_CBC_encrypt_null_ivec, 1543 }, 1544 { 1545 ETYPE_DES3_CBC_NONE, 1546 "des3-cbc-none", 1547 8, 1548 0, 1549 &keytype_des3_derived, 1550 &checksum_none, 1551 NULL, 1552 F_PSEUDO, 1553 DES_CBC_encrypt_null_ivec, 1554 }, 1555 }; 1556 1557 static unsigned num_etypes = sizeof(etypes) / sizeof(etypes[0]); 1558 1559 1560 static struct encryption_type * 1561 _find_enctype(krb5_enctype type) 1562 { 1563 int i; 1564 for(i = 0; i < num_etypes; i++) 1565 if(etypes[i].type == type) 1566 return &etypes[i]; 1567 return NULL; 1568 } 1569 1570 1571 krb5_error_code 1572 krb5_enctype_to_string(krb5_context context, 1573 krb5_enctype etype, 1574 char **string) 1575 { 1576 struct encryption_type *e; 1577 e = _find_enctype(etype); 1578 if(e == NULL) 1579 return KRB5_PROG_ETYPE_NOSUPP; 1580 *string = strdup(e->name); 1581 if(*string == NULL) 1582 return ENOMEM; 1583 return 0; 1584 } 1585 1586 krb5_error_code 1587 krb5_string_to_enctype(krb5_context context, 1588 const char *string, 1589 krb5_enctype *etype) 1590 { 1591 int i; 1592 for(i = 0; i < num_etypes; i++) 1593 if(strcasecmp(etypes[i].name, string) == 0){ 1594 *etype = etypes[i].type; 1595 return 0; 1596 } 1597 return KRB5_PROG_ETYPE_NOSUPP; 1598 } 1599 1600 krb5_error_code 1601 krb5_enctype_to_keytype(krb5_context context, 1602 krb5_enctype etype, 1603 krb5_keytype *keytype) 1604 { 1605 struct encryption_type *e = _find_enctype(etype); 1606 if(e == NULL) 1607 return KRB5_PROG_ETYPE_NOSUPP; 1608 *keytype = e->keytype->type; /* XXX */ 1609 return 0; 1610 } 1611 1612 #if 0 1613 krb5_error_code 1614 krb5_keytype_to_enctype(krb5_context context, 1615 krb5_keytype keytype, 1616 krb5_enctype *etype) 1617 { 1618 struct key_type *kt = _find_keytype(keytype); 1619 krb5_warnx(context, "krb5_keytype_to_enctype(%u)", keytype); 1620 if(kt == NULL) 1621 return KRB5_PROG_KEYTYPE_NOSUPP; 1622 *etype = kt->best_etype; 1623 return 0; 1624 } 1625 #endif 1626 1627 krb5_error_code 1628 krb5_keytype_to_enctypes (krb5_context context, 1629 krb5_keytype keytype, 1630 unsigned *len, 1631 int **val) 1632 { 1633 int i; 1634 unsigned n = 0; 1635 int *ret; 1636 1637 for (i = num_etypes - 1; i >= 0; --i) { 1638 if (etypes[i].keytype->type == keytype 1639 && !(etypes[i].flags & F_PSEUDO)) 1640 ++n; 1641 } 1642 ret = malloc(n * sizeof(int)); 1643 if (ret == NULL && n != 0) 1644 return ENOMEM; 1645 n = 0; 1646 for (i = num_etypes - 1; i >= 0; --i) { 1647 if (etypes[i].keytype->type == keytype 1648 && !(etypes[i].flags & F_PSEUDO)) 1649 ret[n++] = etypes[i].type; 1650 } 1651 *len = n; 1652 *val = ret; 1653 return 0; 1654 } 1655 1656 /* 1657 * First take the configured list of etypes for `keytype' if available, 1658 * else, do `krb5_keytype_to_enctypes'. 1659 */ 1660 1661 krb5_error_code 1662 krb5_keytype_to_enctypes_default (krb5_context context, 1663 krb5_keytype keytype, 1664 unsigned *len, 1665 int **val) 1666 { 1667 int i, n; 1668 int *ret; 1669 1670 if (keytype != KEYTYPE_DES || context->etypes_des == NULL) 1671 return krb5_keytype_to_enctypes (context, keytype, len, val); 1672 1673 for (n = 0; context->etypes_des[n]; ++n) 1674 ; 1675 ret = malloc (n * sizeof(*ret)); 1676 if (ret == NULL && n != 0) 1677 return ENOMEM; 1678 for (i = 0; i < n; ++i) 1679 ret[i] = context->etypes_des[i]; 1680 *len = n; 1681 *val = ret; 1682 return 0; 1683 } 1684 1685 krb5_error_code 1686 krb5_enctype_valid(krb5_context context, 1687 krb5_enctype etype) 1688 { 1689 return _find_enctype(etype) != NULL; 1690 } 1691 1692 /* if two enctypes have compatible keys */ 1693 krb5_boolean 1694 krb5_enctypes_compatible_keys(krb5_context context, 1695 krb5_enctype etype1, 1696 krb5_enctype etype2) 1697 { 1698 struct encryption_type *e1 = _find_enctype(etype1); 1699 struct encryption_type *e2 = _find_enctype(etype2); 1700 return e1 != NULL && e2 != NULL && e1->keytype == e2->keytype; 1701 } 1702 1703 static krb5_boolean 1704 derived_crypto(krb5_context context, 1705 krb5_crypto crypto) 1706 { 1707 return (crypto->et->flags & F_DERIVED) != 0; 1708 } 1709 1710 1711 #define CHECKSUMSIZE(C) ((C)->checksumsize) 1712 #define CHECKSUMTYPE(C) ((C)->type) 1713 1714 static krb5_error_code 1715 encrypt_internal_derived(krb5_context context, 1716 krb5_crypto crypto, 1717 unsigned usage, 1718 void *data, 1719 size_t len, 1720 krb5_data *result) 1721 { 1722 size_t sz, block_sz, checksum_sz; 1723 Checksum cksum; 1724 unsigned char *p, *q; 1725 krb5_error_code ret; 1726 struct key_data *dkey; 1727 struct encryption_type *et = crypto->et; 1728 1729 checksum_sz = CHECKSUMSIZE(et->keyed_checksum); 1730 1731 sz = et->confoundersize + /* 4 - length */ len; 1732 block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */ 1733 p = calloc(1, block_sz + checksum_sz); 1734 if(p == NULL) 1735 return ENOMEM; 1736 1737 q = p; 1738 krb5_generate_random_block(q, et->confoundersize); /* XXX */ 1739 q += et->confoundersize; 1740 memcpy(q, data, len); 1741 1742 ret = create_checksum(context, 1743 crypto, 1744 INTEGRITY_USAGE(usage), 1745 0, 1746 p, 1747 block_sz, 1748 &cksum); 1749 if(ret == 0 && cksum.checksum.length != checksum_sz) 1750 ret = KRB5_CRYPTO_INTERNAL; 1751 if(ret) { 1752 memset(p, 0, block_sz + checksum_sz); 1753 free(p); 1754 return ret; 1755 } 1756 memcpy(p + block_sz, cksum.checksum.data, cksum.checksum.length); 1757 ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); 1758 if(ret) { 1759 memset(p, 0, block_sz + checksum_sz); 1760 free(p); 1761 return ret; 1762 } 1763 ret = _key_schedule(context, dkey); 1764 if(ret) { 1765 memset(p, 0, block_sz); 1766 free(p); 1767 return ret; 1768 } 1769 #ifdef CRYPTO_DEBUG 1770 krb5_crypto_debug(context, 1, block_sz, dkey->key); 1771 #endif 1772 (*et->encrypt)(dkey, p, block_sz, 1); 1773 result->data = p; 1774 result->length = block_sz + checksum_sz; 1775 return 0; 1776 } 1777 1778 static krb5_error_code 1779 encrypt_internal(krb5_context context, 1780 krb5_crypto crypto, 1781 void *data, 1782 size_t len, 1783 krb5_data *result) 1784 { 1785 size_t sz, block_sz, checksum_sz; 1786 Checksum cksum; 1787 unsigned char *p, *q; 1788 krb5_error_code ret; 1789 struct encryption_type *et = crypto->et; 1790 1791 checksum_sz = CHECKSUMSIZE(et->cksumtype); 1792 1793 sz = et->confoundersize + checksum_sz + len; 1794 block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */ 1795 p = calloc(1, block_sz); 1796 if(p == NULL) 1797 return ENOMEM; 1798 1799 q = p; 1800 krb5_generate_random_block(q, et->confoundersize); /* XXX */ 1801 q += et->confoundersize; 1802 memset(q, 0, checksum_sz); 1803 q += checksum_sz; 1804 memcpy(q, data, len); 1805 1806 ret = create_checksum(context, 1807 NULL, 1808 0, 1809 CHECKSUMTYPE(et->cksumtype), 1810 p, 1811 block_sz, 1812 &cksum); 1813 if(ret == 0 && cksum.checksum.length != checksum_sz) { 1814 free_Checksum (&cksum); 1815 ret = KRB5_CRYPTO_INTERNAL; 1816 } 1817 if(ret) { 1818 memset(p, 0, block_sz); 1819 free(p); 1820 free_Checksum(&cksum); 1821 return ret; 1822 } 1823 memcpy(p + et->confoundersize, cksum.checksum.data, cksum.checksum.length); 1824 free_Checksum(&cksum); 1825 ret = _key_schedule(context, &crypto->key); 1826 if(ret) { 1827 memset(p, 0, block_sz); 1828 free(p); 1829 return ret; 1830 } 1831 #ifdef CRYPTO_DEBUG 1832 krb5_crypto_debug(context, 1, block_sz, crypto->key.key); 1833 #endif 1834 (*et->encrypt)(&crypto->key, p, block_sz, 1); 1835 result->data = p; 1836 result->length = block_sz; 1837 return 0; 1838 } 1839 1840 static krb5_error_code 1841 decrypt_internal_derived(krb5_context context, 1842 krb5_crypto crypto, 1843 unsigned usage, 1844 void *data, 1845 size_t len, 1846 krb5_data *result) 1847 { 1848 size_t checksum_sz; 1849 Checksum cksum; 1850 unsigned char *p; 1851 krb5_error_code ret; 1852 struct key_data *dkey; 1853 struct encryption_type *et = crypto->et; 1854 unsigned long l; 1855 1856 p = malloc(len); 1857 if(len != 0 && p == NULL) 1858 return ENOMEM; 1859 memcpy(p, data, len); 1860 1861 checksum_sz = CHECKSUMSIZE(et->keyed_checksum); 1862 len -= checksum_sz; 1863 1864 ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); 1865 if(ret) { 1866 free(p); 1867 return ret; 1868 } 1869 ret = _key_schedule(context, dkey); 1870 if(ret) { 1871 free(p); 1872 return ret; 1873 } 1874 #ifdef CRYPTO_DEBUG 1875 krb5_crypto_debug(context, 0, len, dkey->key); 1876 #endif 1877 (*et->encrypt)(dkey, p, len, 0); 1878 1879 cksum.checksum.data = p + len; 1880 cksum.checksum.length = checksum_sz; 1881 cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum); 1882 1883 ret = verify_checksum(context, 1884 crypto, 1885 INTEGRITY_USAGE(usage), 1886 p, 1887 len, 1888 &cksum); 1889 if(ret) { 1890 free(p); 1891 return ret; 1892 } 1893 l = len - et->confoundersize; 1894 memmove(p, p + et->confoundersize, l); 1895 result->data = realloc(p, l); 1896 if(p == NULL) { 1897 free(p); 1898 return ENOMEM; 1899 } 1900 result->length = l; 1901 return 0; 1902 } 1903 1904 static krb5_error_code 1905 decrypt_internal(krb5_context context, 1906 krb5_crypto crypto, 1907 void *data, 1908 size_t len, 1909 krb5_data *result) 1910 { 1911 krb5_error_code ret; 1912 unsigned char *p; 1913 Checksum cksum; 1914 size_t checksum_sz, l; 1915 struct encryption_type *et = crypto->et; 1916 1917 checksum_sz = CHECKSUMSIZE(et->cksumtype); 1918 p = malloc(len); 1919 if(len != 0 && p == NULL) 1920 return ENOMEM; 1921 memcpy(p, data, len); 1922 1923 ret = _key_schedule(context, &crypto->key); 1924 if(ret) { 1925 free(p); 1926 return ret; 1927 } 1928 #ifdef CRYPTO_DEBUG 1929 krb5_crypto_debug(context, 0, len, crypto->key.key); 1930 #endif 1931 (*et->encrypt)(&crypto->key, p, len, 0); 1932 ret = krb5_data_copy(&cksum.checksum, p + et->confoundersize, checksum_sz); 1933 if(ret) { 1934 free(p); 1935 return ret; 1936 } 1937 memset(p + et->confoundersize, 0, checksum_sz); 1938 cksum.cksumtype = CHECKSUMTYPE(et->cksumtype); 1939 ret = verify_checksum(context, NULL, 0, p, len, &cksum); 1940 free_Checksum(&cksum); 1941 if(ret) { 1942 free(p); 1943 return ret; 1944 } 1945 l = len - et->confoundersize - checksum_sz; 1946 memmove(p, p + et->confoundersize + checksum_sz, l); 1947 result->data = realloc(p, l); 1948 if(result->data == NULL) { 1949 free(p); 1950 return ENOMEM; 1951 } 1952 result->length = l; 1953 return 0; 1954 } 1955 1956 krb5_error_code 1957 krb5_encrypt(krb5_context context, 1958 krb5_crypto crypto, 1959 unsigned usage, 1960 void *data, 1961 size_t len, 1962 krb5_data *result) 1963 { 1964 if(derived_crypto(context, crypto)) 1965 return encrypt_internal_derived(context, crypto, usage, 1966 data, len, result); 1967 else 1968 return encrypt_internal(context, crypto, data, len, result); 1969 } 1970 1971 krb5_error_code 1972 krb5_encrypt_EncryptedData(krb5_context context, 1973 krb5_crypto crypto, 1974 unsigned usage, 1975 void *data, 1976 size_t len, 1977 int kvno, 1978 EncryptedData *result) 1979 { 1980 result->etype = CRYPTO_ETYPE(crypto); 1981 if(kvno){ 1982 ALLOC(result->kvno, 1); 1983 *result->kvno = kvno; 1984 }else 1985 result->kvno = NULL; 1986 return krb5_encrypt(context, crypto, usage, data, len, &result->cipher); 1987 } 1988 1989 krb5_error_code 1990 krb5_decrypt(krb5_context context, 1991 krb5_crypto crypto, 1992 unsigned usage, 1993 void *data, 1994 size_t len, 1995 krb5_data *result) 1996 { 1997 if(derived_crypto(context, crypto)) 1998 return decrypt_internal_derived(context, crypto, usage, 1999 data, len, result); 2000 else 2001 return decrypt_internal(context, crypto, data, len, result); 2002 } 2003 2004 krb5_error_code 2005 krb5_decrypt_EncryptedData(krb5_context context, 2006 krb5_crypto crypto, 2007 unsigned usage, 2008 EncryptedData *e, 2009 krb5_data *result) 2010 { 2011 return krb5_decrypt(context, crypto, usage, 2012 e->cipher.data, e->cipher.length, result); 2013 } 2014 2015 /************************************************************ 2016 * * 2017 ************************************************************/ 2018 2019 void 2020 krb5_generate_random_block(void *buf, size_t len) 2021 { 2022 des_cblock key, out; 2023 static des_cblock counter; 2024 static des_key_schedule schedule; 2025 int i; 2026 static int initialized = 0; 2027 2028 if(!initialized) { 2029 des_new_random_key(&key); 2030 des_set_key(&key, schedule); 2031 memset(&key, 0, sizeof(key)); 2032 des_new_random_key(&counter); 2033 } 2034 while(len > 0) { 2035 des_ecb_encrypt(&counter, &out, schedule, DES_ENCRYPT); 2036 for(i = 7; i >=0; i--) 2037 if(counter[i]++) 2038 break; 2039 memcpy(buf, out, min(len, sizeof(out))); 2040 len -= min(len, sizeof(out)); 2041 buf = (char*)buf + sizeof(out); 2042 } 2043 } 2044 2045 static void 2046 DES3_postproc(krb5_context context, 2047 unsigned char *k, size_t len, struct key_data *key) 2048 { 2049 unsigned char x[24]; 2050 int i, j; 2051 2052 memset(x, 0, sizeof(x)); 2053 for (i = 0; i < 3; ++i) { 2054 unsigned char foo; 2055 2056 for (j = 0; j < 7; ++j) { 2057 unsigned char b = k[7 * i + j]; 2058 2059 x[8 * i + j] = b; 2060 } 2061 foo = 0; 2062 for (j = 6; j >= 0; --j) { 2063 foo |= k[7 * i + j] & 1; 2064 foo <<= 1; 2065 } 2066 x[8 * i + 7] = foo; 2067 } 2068 k = key->key->keyvalue.data; 2069 memcpy(k, x, 24); 2070 memset(x, 0, sizeof(x)); 2071 if (key->schedule) { 2072 krb5_free_data(context, key->schedule); 2073 key->schedule = NULL; 2074 } 2075 des_set_odd_parity((des_cblock*)k); 2076 des_set_odd_parity((des_cblock*)(k + 8)); 2077 des_set_odd_parity((des_cblock*)(k + 16)); 2078 } 2079 2080 static krb5_error_code 2081 derive_key(krb5_context context, 2082 struct encryption_type *et, 2083 struct key_data *key, 2084 void *constant, 2085 size_t len) 2086 { 2087 unsigned char *k; 2088 unsigned int nblocks = 0, i; 2089 krb5_error_code ret = 0; 2090 2091 struct key_type *kt = et->keytype; 2092 ret = _key_schedule(context, key); 2093 if(ret) 2094 return ret; 2095 if(et->blocksize * 8 < kt->bits || 2096 len != et->blocksize) { 2097 nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8); 2098 k = malloc(nblocks * et->blocksize); 2099 if(k == NULL) 2100 return ENOMEM; 2101 _krb5_n_fold(constant, len, k, et->blocksize); 2102 for(i = 0; i < nblocks; i++) { 2103 if(i > 0) 2104 memcpy(k + i * et->blocksize, 2105 k + (i - 1) * et->blocksize, 2106 et->blocksize); 2107 (*et->encrypt)(key, k + i * et->blocksize, et->blocksize, 1); 2108 } 2109 } else { 2110 void *c = malloc(len); 2111 size_t res_len = (kt->bits + 7) / 8; 2112 2113 if(len != 0 && c == NULL) 2114 return ENOMEM; 2115 memcpy(c, constant, len); 2116 (*et->encrypt)(key, c, len, 1); 2117 k = malloc(res_len); 2118 if(res_len != 0 && k == NULL) 2119 return ENOMEM; 2120 _krb5_n_fold(c, len, k, res_len); 2121 free(c); 2122 } 2123 2124 /* XXX keytype dependent post-processing */ 2125 switch(kt->type) { 2126 case KEYTYPE_DES3: 2127 DES3_postproc(context, k, nblocks * et->blocksize, key); 2128 break; 2129 default: 2130 krb5_warnx(context, "derive_key() called with unknown keytype (%u)", 2131 kt->type); 2132 ret = KRB5_CRYPTO_INTERNAL; 2133 break; 2134 } 2135 memset(k, 0, nblocks * et->blocksize); 2136 free(k); 2137 return ret; 2138 } 2139 2140 static struct key_data * 2141 _new_derived_key(krb5_crypto crypto, unsigned usage) 2142 { 2143 struct key_usage *d = crypto->key_usage; 2144 d = realloc(d, (crypto->num_key_usage + 1) * sizeof(*d)); 2145 if(d == NULL) 2146 return NULL; 2147 crypto->key_usage = d; 2148 d += crypto->num_key_usage++; 2149 memset(d, 0, sizeof(*d)); 2150 d->usage = usage; 2151 return &d->key; 2152 } 2153 2154 static krb5_error_code 2155 _get_derived_key(krb5_context context, 2156 krb5_crypto crypto, 2157 unsigned usage, 2158 struct key_data **key) 2159 { 2160 int i; 2161 struct key_data *d; 2162 unsigned char constant[5]; 2163 2164 for(i = 0; i < crypto->num_key_usage; i++) 2165 if(crypto->key_usage[i].usage == usage) { 2166 *key = &crypto->key_usage[i].key; 2167 return 0; 2168 } 2169 d = _new_derived_key(crypto, usage); 2170 if(d == NULL) 2171 return ENOMEM; 2172 krb5_copy_keyblock(context, crypto->key.key, &d->key); 2173 _krb5_put_int(constant, usage, 5); 2174 derive_key(context, crypto->et, d, constant, sizeof(constant)); 2175 *key = d; 2176 return 0; 2177 } 2178 2179 2180 krb5_error_code 2181 krb5_crypto_init(krb5_context context, 2182 krb5_keyblock *key, 2183 krb5_enctype etype, 2184 krb5_crypto *crypto) 2185 { 2186 krb5_error_code ret; 2187 ALLOC(*crypto, 1); 2188 if(*crypto == NULL) 2189 return ENOMEM; 2190 if(etype == ETYPE_NULL) 2191 etype = key->keytype; 2192 (*crypto)->et = _find_enctype(etype); 2193 if((*crypto)->et == NULL) { 2194 free(*crypto); 2195 return KRB5_PROG_ETYPE_NOSUPP; 2196 } 2197 ret = krb5_copy_keyblock(context, key, &(*crypto)->key.key); 2198 if(ret) { 2199 free(*crypto); 2200 return ret; 2201 } 2202 (*crypto)->key.schedule = NULL; 2203 (*crypto)->num_key_usage = 0; 2204 (*crypto)->key_usage = NULL; 2205 return 0; 2206 } 2207 2208 static void 2209 free_key_data(krb5_context context, struct key_data *key) 2210 { 2211 krb5_free_keyblock(context, key->key); 2212 if(key->schedule) { 2213 memset(key->schedule->data, 0, key->schedule->length); 2214 krb5_free_data(context, key->schedule); 2215 } 2216 } 2217 2218 static void 2219 free_key_usage(krb5_context context, struct key_usage *ku) 2220 { 2221 free_key_data(context, &ku->key); 2222 } 2223 2224 krb5_error_code 2225 krb5_crypto_destroy(krb5_context context, 2226 krb5_crypto crypto) 2227 { 2228 int i; 2229 2230 for(i = 0; i < crypto->num_key_usage; i++) 2231 free_key_usage(context, &crypto->key_usage[i]); 2232 free(crypto->key_usage); 2233 free_key_data(context, &crypto->key); 2234 free (crypto); 2235 return 0; 2236 } 2237 2238 krb5_error_code 2239 krb5_string_to_key_derived(krb5_context context, 2240 const void *str, 2241 size_t len, 2242 krb5_enctype etype, 2243 krb5_keyblock *key) 2244 { 2245 struct encryption_type *et = _find_enctype(etype); 2246 krb5_error_code ret; 2247 struct key_data kd; 2248 u_char *tmp; 2249 2250 if(et == NULL) 2251 return KRB5_PROG_ETYPE_NOSUPP; 2252 ALLOC(kd.key, 1); 2253 kd.key->keytype = etype; 2254 tmp = malloc (et->keytype->bits / 8); 2255 _krb5_n_fold(str, len, tmp, et->keytype->bits / 8); 2256 krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); 2257 kd.schedule = NULL; 2258 DES3_postproc (context, tmp, et->keytype->bits / 8, &kd); /* XXX */ 2259 ret = derive_key(context, 2260 et, 2261 &kd, 2262 "kerberos", /* XXX well known constant */ 2263 strlen("kerberos")); 2264 ret = krb5_copy_keyblock_contents(context, kd.key, key); 2265 free_key_data(context, &kd); 2266 return ret; 2267 } 2268 2269 /* 2270 * Return the size of an encrypted packet of length `data_len' 2271 */ 2272 2273 size_t 2274 krb5_get_wrapped_length (krb5_context context, 2275 krb5_crypto crypto, 2276 size_t data_len) 2277 { 2278 struct encryption_type *et = crypto->et; 2279 size_t blocksize = et->blocksize; 2280 size_t res; 2281 2282 res = (data_len + blocksize - 1) / blocksize * blocksize; 2283 res = res + et->confoundersize + et->cksumtype->checksumsize; 2284 return res; 2285 } 2286 2287 #ifdef CRYPTO_DEBUG 2288 2289 static krb5_error_code 2290 krb5_get_keyid(krb5_context context, 2291 krb5_keyblock *key, 2292 u_int32_t *keyid) 2293 { 2294 MD5_CTX md5; 2295 unsigned char tmp[16]; 2296 2297 MD5Init (&md5); 2298 MD5Update (&md5, key->keyvalue.data, key->keyvalue.length); 2299 MD5Final (tmp, &md5); 2300 *keyid = (tmp[12] << 24) | (tmp[13] << 16) | (tmp[14] << 8) | tmp[15]; 2301 return 0; 2302 } 2303 2304 static void 2305 krb5_crypto_debug(krb5_context context, 2306 int encrypt, 2307 size_t len, 2308 krb5_keyblock *key) 2309 { 2310 u_int32_t keyid; 2311 char *kt; 2312 krb5_get_keyid(context, key, &keyid); 2313 krb5_enctype_to_string(context, key->keytype, &kt); 2314 krb5_warnx(context, "%s %lu bytes with key-id %#x (%s)", 2315 encrypt ? "encrypting" : "decrypting", 2316 (unsigned long)len, 2317 keyid, 2318 kt); 2319 free(kt); 2320 } 2321 2322 #endif /* CRYPTO_DEBUG */ 2323