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