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