1 /* $NetBSD: aes-test.c,v 1.1.1.1 2011/04/13 18:15:31 elric Exp $ */ 2 3 /* 4 * Copyright (c) 2003 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of KTH nor the names of its contributors may be 20 * used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 34 35 #include "krb5_locl.h" 36 #include <krb5/hex.h> 37 #include <err.h> 38 #include <assert.h> 39 40 #ifdef HAVE_OPENSSL 41 #include <openssl/evp.h> 42 #endif 43 44 static int verbose = 0; 45 46 static void 47 hex_dump_data(const void *data, size_t length) 48 { 49 char *p; 50 51 hex_encode(data, length, &p); 52 printf("%s\n", p); 53 free(p); 54 } 55 56 struct { 57 char *password; 58 char *salt; 59 int saltlen; 60 int iterations; 61 krb5_enctype enctype; 62 size_t keylen; 63 char *pbkdf2; 64 char *key; 65 } keys[] = { 66 { 67 "password", "ATHENA.MIT.EDUraeburn", -1, 68 1, 69 ETYPE_AES128_CTS_HMAC_SHA1_96, 16, 70 "\xcd\xed\xb5\x28\x1b\xb2\xf8\x01\x56\x5a\x11\x22\xb2\x56\x35\x15", 71 "\x42\x26\x3c\x6e\x89\xf4\xfc\x28\xb8\xdf\x68\xee\x09\x79\x9f\x15" 72 }, 73 { 74 "password", "ATHENA.MIT.EDUraeburn", -1, 75 1, 76 ETYPE_AES256_CTS_HMAC_SHA1_96, 32, 77 "\xcd\xed\xb5\x28\x1b\xb2\xf8\x01\x56\x5a\x11\x22\xb2\x56\x35\x15" 78 "\x0a\xd1\xf7\xa0\x4b\xb9\xf3\xa3\x33\xec\xc0\xe2\xe1\xf7\x08\x37", 79 "\xfe\x69\x7b\x52\xbc\x0d\x3c\xe1\x44\x32\xba\x03\x6a\x92\xe6\x5b" 80 "\xbb\x52\x28\x09\x90\xa2\xfa\x27\x88\x39\x98\xd7\x2a\xf3\x01\x61" 81 }, 82 { 83 "password", "ATHENA.MIT.EDUraeburn", -1, 84 2, 85 ETYPE_AES128_CTS_HMAC_SHA1_96, 16, 86 "\x01\xdb\xee\x7f\x4a\x9e\x24\x3e\x98\x8b\x62\xc7\x3c\xda\x93\x5d", 87 "\xc6\x51\xbf\x29\xe2\x30\x0a\xc2\x7f\xa4\x69\xd6\x93\xbd\xda\x13" 88 }, 89 { 90 "password", "ATHENA.MIT.EDUraeburn", -1, 91 2, 92 ETYPE_AES256_CTS_HMAC_SHA1_96, 32, 93 "\x01\xdb\xee\x7f\x4a\x9e\x24\x3e\x98\x8b\x62\xc7\x3c\xda\x93\x5d" 94 "\xa0\x53\x78\xb9\x32\x44\xec\x8f\x48\xa9\x9e\x61\xad\x79\x9d\x86", 95 "\xa2\xe1\x6d\x16\xb3\x60\x69\xc1\x35\xd5\xe9\xd2\xe2\x5f\x89\x61" 96 "\x02\x68\x56\x18\xb9\x59\x14\xb4\x67\xc6\x76\x22\x22\x58\x24\xff" 97 }, 98 { 99 "password", "ATHENA.MIT.EDUraeburn", -1, 100 1200, 101 ETYPE_AES128_CTS_HMAC_SHA1_96, 16, 102 "\x5c\x08\xeb\x61\xfd\xf7\x1e\x4e\x4e\xc3\xcf\x6b\xa1\xf5\x51\x2b", 103 "\x4c\x01\xcd\x46\xd6\x32\xd0\x1e\x6d\xbe\x23\x0a\x01\xed\x64\x2a" 104 }, 105 { 106 "password", "ATHENA.MIT.EDUraeburn", -1, 107 1200, 108 ETYPE_AES256_CTS_HMAC_SHA1_96, 32, 109 "\x5c\x08\xeb\x61\xfd\xf7\x1e\x4e\x4e\xc3\xcf\x6b\xa1\xf5\x51\x2b" 110 "\xa7\xe5\x2d\xdb\xc5\xe5\x14\x2f\x70\x8a\x31\xe2\xe6\x2b\x1e\x13", 111 "\x55\xa6\xac\x74\x0a\xd1\x7b\x48\x46\x94\x10\x51\xe1\xe8\xb0\xa7" 112 "\x54\x8d\x93\xb0\xab\x30\xa8\xbc\x3f\xf1\x62\x80\x38\x2b\x8c\x2a" 113 }, 114 { 115 "password", "\x12\x34\x56\x78\x78\x56\x34\x12", 8, 116 5, 117 ETYPE_AES128_CTS_HMAC_SHA1_96, 16, 118 "\xd1\xda\xa7\x86\x15\xf2\x87\xe6\xa1\xc8\xb1\x20\xd7\x06\x2a\x49", 119 "\xe9\xb2\x3d\x52\x27\x37\x47\xdd\x5c\x35\xcb\x55\xbe\x61\x9d\x8e" 120 }, 121 { 122 "password", "\x12\x34\x56\x78\x78\x56\x34\x12", 8, 123 5, 124 ETYPE_AES256_CTS_HMAC_SHA1_96, 32, 125 "\xd1\xda\xa7\x86\x15\xf2\x87\xe6\xa1\xc8\xb1\x20\xd7\x06\x2a\x49" 126 "\x3f\x98\xd2\x03\xe6\xbe\x49\xa6\xad\xf4\xfa\x57\x4b\x6e\x64\xee", 127 "\x97\xa4\xe7\x86\xbe\x20\xd8\x1a\x38\x2d\x5e\xbc\x96\xd5\x90\x9c" 128 "\xab\xcd\xad\xc8\x7c\xa4\x8f\x57\x45\x04\x15\x9f\x16\xc3\x6e\x31" 129 }, 130 { 131 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 132 "pass phrase equals block size", -1, 133 1200, 134 ETYPE_AES128_CTS_HMAC_SHA1_96, 16, 135 "\x13\x9c\x30\xc0\x96\x6b\xc3\x2b\xa5\x5f\xdb\xf2\x12\x53\x0a\xc9", 136 "\x59\xd1\xbb\x78\x9a\x82\x8b\x1a\xa5\x4e\xf9\xc2\x88\x3f\x69\xed" 137 }, 138 { 139 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 140 "pass phrase equals block size", -1, 141 1200, 142 ETYPE_AES256_CTS_HMAC_SHA1_96, 32, 143 "\x13\x9c\x30\xc0\x96\x6b\xc3\x2b\xa5\x5f\xdb\xf2\x12\x53\x0a\xc9" 144 "\xc5\xec\x59\xf1\xa4\x52\xf5\xcc\x9a\xd9\x40\xfe\xa0\x59\x8e\xd1", 145 "\x89\xad\xee\x36\x08\xdb\x8b\xc7\x1f\x1b\xfb\xfe\x45\x94\x86\xb0" 146 "\x56\x18\xb7\x0c\xba\xe2\x20\x92\x53\x4e\x56\xc5\x53\xba\x4b\x34" 147 }, 148 { 149 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 150 "pass phrase exceeds block size", -1, 151 1200, 152 ETYPE_AES128_CTS_HMAC_SHA1_96, 16, 153 "\x9c\xca\xd6\xd4\x68\x77\x0c\xd5\x1b\x10\xe6\xa6\x87\x21\xbe\x61", 154 "\xcb\x80\x05\xdc\x5f\x90\x17\x9a\x7f\x02\x10\x4c\x00\x18\x75\x1d" 155 }, 156 { 157 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 158 "pass phrase exceeds block size", -1, 159 1200, 160 ETYPE_AES256_CTS_HMAC_SHA1_96, 32, 161 "\x9c\xca\xd6\xd4\x68\x77\x0c\xd5\x1b\x10\xe6\xa6\x87\x21\xbe\x61" 162 "\x1a\x8b\x4d\x28\x26\x01\xdb\x3b\x36\xbe\x92\x46\x91\x5e\xc8\x2a", 163 "\xd7\x8c\x5c\x9c\xb8\x72\xa8\xc9\xda\xd4\x69\x7f\x0b\xb5\xb2\xd2" 164 "\x14\x96\xc8\x2b\xeb\x2c\xae\xda\x21\x12\xfc\xee\xa0\x57\x40\x1b" 165 166 }, 167 { 168 "\xf0\x9d\x84\x9e" /* g-clef */, "EXAMPLE.COMpianist", -1, 169 50, 170 ETYPE_AES128_CTS_HMAC_SHA1_96, 16, 171 "\x6b\x9c\xf2\x6d\x45\x45\x5a\x43\xa5\xb8\xbb\x27\x6a\x40\x3b\x39", 172 "\xf1\x49\xc1\xf2\xe1\x54\xa7\x34\x52\xd4\x3e\x7f\xe6\x2a\x56\xe5" 173 }, 174 { 175 "\xf0\x9d\x84\x9e" /* g-clef */, "EXAMPLE.COMpianist", -1, 176 50, 177 ETYPE_AES256_CTS_HMAC_SHA1_96, 32, 178 "\x6b\x9c\xf2\x6d\x45\x45\x5a\x43\xa5\xb8\xbb\x27\x6a\x40\x3b\x39" 179 "\xe7\xfe\x37\xa0\xc4\x1e\x02\xc2\x81\xff\x30\x69\xe1\xe9\x4f\x52", 180 "\x4b\x6d\x98\x39\xf8\x44\x06\xdf\x1f\x09\xcc\x16\x6d\xb4\xb8\x3c" 181 "\x57\x18\x48\xb7\x84\xa3\xd6\xbd\xc3\x46\x58\x9a\x3e\x39\x3f\x9e" 182 }, 183 { 184 "foo", "", -1, 185 0, 186 ETYPE_ARCFOUR_HMAC_MD5, 16, 187 NULL, 188 "\xac\x8e\x65\x7f\x83\xdf\x82\xbe\xea\x5d\x43\xbd\xaf\x78\x00\xcc" 189 }, 190 { 191 "test", "", -1, 192 0, 193 ETYPE_ARCFOUR_HMAC_MD5, 16, 194 NULL, 195 "\x0c\xb6\x94\x88\x05\xf7\x97\xbf\x2a\x82\x80\x79\x73\xb8\x95\x37" 196 } 197 }; 198 199 static int 200 string_to_key_test(krb5_context context) 201 { 202 krb5_data password, opaque; 203 krb5_error_code ret; 204 krb5_salt salt; 205 int i, val = 0; 206 char iter[4]; 207 208 for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) { 209 210 password.data = keys[i].password; 211 password.length = strlen(password.data); 212 213 salt.salttype = KRB5_PW_SALT; 214 salt.saltvalue.data = keys[i].salt; 215 if (keys[i].saltlen == -1) 216 salt.saltvalue.length = strlen(salt.saltvalue.data); 217 else 218 salt.saltvalue.length = keys[i].saltlen; 219 220 opaque.data = iter; 221 opaque.length = sizeof(iter); 222 _krb5_put_int(iter, keys[i].iterations, 4); 223 224 if (keys[i].pbkdf2) { 225 unsigned char keyout[32]; 226 227 if (keys[i].keylen > sizeof(keyout)) 228 abort(); 229 230 PKCS5_PBKDF2_HMAC_SHA1(password.data, password.length, 231 salt.saltvalue.data, salt.saltvalue.length, 232 keys[i].iterations, 233 keys[i].keylen, keyout); 234 235 if (memcmp(keyout, keys[i].pbkdf2, keys[i].keylen) != 0) { 236 krb5_warnx(context, "%d: pbkdf2", i); 237 val = 1; 238 continue; 239 } 240 241 if (verbose) { 242 printf("PBKDF2:\n"); 243 hex_dump_data(keyout, keys[i].keylen); 244 } 245 } 246 247 { 248 krb5_keyblock key; 249 250 ret = krb5_string_to_key_data_salt_opaque (context, 251 keys[i].enctype, 252 password, 253 salt, 254 opaque, 255 &key); 256 if (ret) { 257 krb5_warn(context, ret, "%d: string_to_key_data_salt_opaque", 258 i); 259 val = 1; 260 continue; 261 } 262 263 if (key.keyvalue.length != keys[i].keylen) { 264 krb5_warnx(context, "%d: key wrong length (%lu/%lu)", 265 i, (unsigned long)key.keyvalue.length, 266 (unsigned long)keys[i].keylen); 267 val = 1; 268 continue; 269 } 270 271 if (memcmp(key.keyvalue.data, keys[i].key, keys[i].keylen) != 0) { 272 krb5_warnx(context, "%d: key wrong", i); 273 val = 1; 274 continue; 275 } 276 277 if (verbose) { 278 printf("key:\n"); 279 hex_dump_data(key.keyvalue.data, key.keyvalue.length); 280 } 281 krb5_free_keyblock_contents(context, &key); 282 } 283 } 284 return val; 285 } 286 287 static int 288 krb_enc(krb5_context context, 289 krb5_crypto crypto, 290 unsigned usage, 291 krb5_data *cipher, 292 krb5_data *clear) 293 { 294 krb5_data decrypt; 295 krb5_error_code ret; 296 297 krb5_data_zero(&decrypt); 298 299 ret = krb5_decrypt(context, 300 crypto, 301 usage, 302 cipher->data, 303 cipher->length, 304 &decrypt); 305 306 if (ret) { 307 krb5_warn(context, ret, "krb5_decrypt"); 308 return ret; 309 } 310 311 if (decrypt.length != clear->length || 312 memcmp(decrypt.data, clear->data, decrypt.length) != 0) { 313 krb5_warnx(context, "clear text not same"); 314 return EINVAL; 315 } 316 317 krb5_data_free(&decrypt); 318 319 return 0; 320 } 321 322 static int 323 krb_enc_iov2(krb5_context context, 324 krb5_crypto crypto, 325 unsigned usage, 326 size_t cipher_len, 327 krb5_data *clear) 328 { 329 krb5_crypto_iov iov[4]; 330 krb5_data decrypt; 331 int ret; 332 char *p, *q; 333 size_t len, i; 334 335 p = clear->data; 336 len = clear->length; 337 338 iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; 339 krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length); 340 iov[0].data.data = emalloc(iov[0].data.length); 341 342 iov[1].flags = KRB5_CRYPTO_TYPE_DATA; 343 iov[1].data.length = len; 344 iov[1].data.data = emalloc(iov[1].data.length); 345 memcpy(iov[1].data.data, p, iov[1].data.length); 346 347 /* padding buffer */ 348 iov[2].flags = KRB5_CRYPTO_TYPE_PADDING; 349 krb5_crypto_length(context, crypto, KRB5_CRYPTO_TYPE_PADDING, &iov[2].data.length); 350 iov[2].data.data = emalloc(iov[2].data.length); 351 352 iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER; 353 krb5_crypto_length(context, crypto, iov[3].flags, &iov[3].data.length); 354 iov[3].data.data = emalloc(iov[3].data.length); 355 356 ret = krb5_encrypt_iov_ivec(context, crypto, usage, 357 iov, sizeof(iov)/sizeof(iov[0]), NULL); 358 if (ret) 359 errx(1, "encrypt iov failed: %d", ret); 360 361 /* check len */ 362 for (i = 0, len = 0; i < sizeof(iov)/sizeof(iov[0]); i++) 363 len += iov[i].data.length; 364 if (len != cipher_len) 365 errx(1, "cipher len wrong"); 366 367 /* 368 * Plain decrypt 369 */ 370 371 p = q = emalloc(len); 372 for (i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { 373 memcpy(q, iov[i].data.data, iov[i].data.length); 374 q += iov[i].data.length; 375 } 376 377 ret = krb5_decrypt(context, crypto, usage, p, len, &decrypt); 378 if (ret) 379 krb5_err(context, 1, ret, "krb5_decrypt"); 380 else 381 krb5_data_free(&decrypt); 382 383 free(p); 384 385 /* 386 * Now decrypt use iov 387 */ 388 389 /* padding turn into data */ 390 p = q = emalloc(iov[1].data.length + iov[2].data.length); 391 392 memcpy(q, iov[1].data.data, iov[1].data.length); 393 q += iov[1].data.length; 394 memcpy(q, iov[2].data.data, iov[2].data.length); 395 396 free(iov[1].data.data); 397 free(iov[2].data.data); 398 399 iov[1].data.data = p; 400 iov[1].data.length += iov[2].data.length; 401 402 iov[2].flags = KRB5_CRYPTO_TYPE_EMPTY; 403 iov[2].data.length = 0; 404 405 ret = krb5_decrypt_iov_ivec(context, crypto, usage, 406 iov, sizeof(iov)/sizeof(iov[0]), NULL); 407 free(iov[0].data.data); 408 free(iov[3].data.data); 409 410 if (ret) 411 krb5_err(context, 1, ret, "decrypt iov failed: %d", ret); 412 413 if (clear->length != iov[1].data.length) 414 errx(1, "length incorrect"); 415 416 p = clear->data; 417 if (memcmp(iov[1].data.data, p, iov[1].data.length) != 0) 418 errx(1, "iov[1] incorrect"); 419 420 free(iov[1].data.data); 421 422 return 0; 423 } 424 425 426 static int 427 krb_enc_iov(krb5_context context, 428 krb5_crypto crypto, 429 unsigned usage, 430 krb5_data *cipher, 431 krb5_data *clear) 432 { 433 krb5_crypto_iov iov[3]; 434 int ret; 435 char *p; 436 size_t len; 437 438 p = cipher->data; 439 len = cipher->length; 440 441 iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; 442 krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length); 443 iov[0].data.data = emalloc(iov[0].data.length); 444 memcpy(iov[0].data.data, p, iov[0].data.length); 445 p += iov[0].data.length; 446 len -= iov[0].data.length; 447 448 iov[1].flags = KRB5_CRYPTO_TYPE_TRAILER; 449 krb5_crypto_length(context, crypto, iov[1].flags, &iov[1].data.length); 450 iov[1].data.data = emalloc(iov[1].data.length); 451 memcpy(iov[1].data.data, p + len - iov[1].data.length, iov[1].data.length); 452 len -= iov[1].data.length; 453 454 iov[2].flags = KRB5_CRYPTO_TYPE_DATA; 455 iov[2].data.length = len; 456 iov[2].data.data = emalloc(len); 457 memcpy(iov[2].data.data, p, len); 458 459 ret = krb5_decrypt_iov_ivec(context, crypto, usage, 460 iov, sizeof(iov)/sizeof(iov[0]), NULL); 461 if (ret) 462 krb5_err(context, 1, ret, "krb_enc_iov decrypt iov failed: %d", ret); 463 464 if (clear->length != iov[2].data.length) 465 errx(1, "length incorrect"); 466 467 p = clear->data; 468 if (memcmp(iov[2].data.data, p, iov[2].data.length) != 0) 469 errx(1, "iov[2] incorrect"); 470 471 free(iov[0].data.data); 472 free(iov[1].data.data); 473 free(iov[2].data.data); 474 475 476 return 0; 477 } 478 479 static int 480 krb_checksum_iov(krb5_context context, 481 krb5_crypto crypto, 482 unsigned usage, 483 krb5_data *plain) 484 { 485 krb5_crypto_iov iov[4]; 486 int ret; 487 char *p; 488 size_t len; 489 490 p = plain->data; 491 len = plain->length; 492 493 iov[0].flags = KRB5_CRYPTO_TYPE_CHECKSUM; 494 krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length); 495 iov[0].data.data = emalloc(iov[0].data.length); 496 497 iov[1].flags = KRB5_CRYPTO_TYPE_DATA; 498 iov[1].data.length = len; 499 iov[1].data.data = p; 500 501 iov[2].flags = KRB5_CRYPTO_TYPE_TRAILER; 502 krb5_crypto_length(context, crypto, iov[0].flags, &iov[2].data.length); 503 iov[2].data.data = malloc(iov[2].data.length); 504 505 ret = krb5_create_checksum_iov(context, crypto, usage, 506 iov, sizeof(iov)/sizeof(iov[0]), NULL); 507 if (ret) 508 krb5_err(context, 1, ret, "krb5_create_checksum_iov failed"); 509 510 ret = krb5_verify_checksum_iov(context, crypto, usage, iov, sizeof(iov)/sizeof(iov[0]), NULL); 511 if (ret) 512 krb5_err(context, 1, ret, "krb5_verify_checksum_iov"); 513 514 free(iov[0].data.data); 515 free(iov[2].data.data); 516 517 return 0; 518 } 519 520 521 static int 522 krb_enc_mit(krb5_context context, 523 krb5_enctype enctype, 524 krb5_keyblock *key, 525 unsigned usage, 526 krb5_data *cipher, 527 krb5_data *clear) 528 { 529 #ifndef HEIMDAL_SMALLER 530 krb5_error_code ret; 531 krb5_enc_data e; 532 krb5_data decrypt; 533 size_t len; 534 535 e.kvno = 0; 536 e.enctype = enctype; 537 e.ciphertext = *cipher; 538 539 ret = krb5_c_decrypt(context, *key, usage, NULL, &e, &decrypt); 540 if (ret) 541 return ret; 542 543 if (decrypt.length != clear->length || 544 memcmp(decrypt.data, clear->data, decrypt.length) != 0) { 545 krb5_warnx(context, "clear text not same"); 546 return EINVAL; 547 } 548 549 krb5_data_free(&decrypt); 550 551 ret = krb5_c_encrypt_length(context, enctype, clear->length, &len); 552 if (ret) 553 return ret; 554 555 if (len != cipher->length) { 556 krb5_warnx(context, "c_encrypt_length wrong %lu != %lu", 557 (unsigned long)len, (unsigned long)cipher->length); 558 return EINVAL; 559 } 560 #endif /* HEIMDAL_SMALLER */ 561 return 0; 562 } 563 564 565 struct { 566 krb5_enctype enctype; 567 unsigned usage; 568 size_t keylen; 569 void *key; 570 size_t elen; 571 void* edata; 572 size_t plen; 573 void *pdata; 574 } krbencs[] = { 575 { 576 ETYPE_AES256_CTS_HMAC_SHA1_96, 577 7, 578 32, 579 "\x47\x75\x69\x64\x65\x6c\x69\x6e\x65\x73\x20\x74\x6f\x20\x41\x75" 580 "\x74\x68\x6f\x72\x73\x20\x6f\x66\x20\x49\x6e\x74\x65\x72\x6e\x65", 581 44, 582 "\xcf\x79\x8f\x0d\x76\xf3\xe0\xbe\x8e\x66\x94\x70\xfa\xcc\x9e\x91" 583 "\xa9\xec\x1c\x5c\x21\xfb\x6e\xef\x1a\x7a\xc8\xc1\xcc\x5a\x95\x24" 584 "\x6f\x9f\xf4\xd5\xbe\x5d\x59\x97\x44\xd8\x47\xcd", 585 16, 586 "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x2e\x0a" 587 } 588 }; 589 590 591 static int 592 krb_enc_test(krb5_context context) 593 { 594 krb5_error_code ret; 595 krb5_crypto crypto; 596 krb5_keyblock kb; 597 krb5_data cipher, plain; 598 int i; 599 600 for (i = 0; i < sizeof(krbencs)/sizeof(krbencs[0]); i++) { 601 602 kb.keytype = krbencs[i].enctype; 603 kb.keyvalue.length = krbencs[i].keylen; 604 kb.keyvalue.data = krbencs[i].key; 605 606 ret = krb5_crypto_init(context, &kb, krbencs[i].enctype, &crypto); 607 608 cipher.length = krbencs[i].elen; 609 cipher.data = krbencs[i].edata; 610 plain.length = krbencs[i].plen; 611 plain.data = krbencs[i].pdata; 612 613 ret = krb_enc(context, crypto, krbencs[i].usage, &cipher, &plain); 614 615 if (ret) 616 errx(1, "krb_enc failed with %d for test %d", ret, i); 617 618 ret = krb_enc_iov(context, crypto, krbencs[i].usage, &cipher, &plain); 619 if (ret) 620 errx(1, "krb_enc_iov failed with %d for test %d", ret, i); 621 622 ret = krb_enc_iov2(context, crypto, krbencs[i].usage, 623 cipher.length, &plain); 624 if (ret) 625 errx(1, "krb_enc_iov2 failed with %d for test %d", ret, i); 626 627 ret = krb_checksum_iov(context, crypto, krbencs[i].usage, &plain); 628 if (ret) 629 errx(1, "krb_checksum_iov failed with %d for test %d", ret, i); 630 631 krb5_crypto_destroy(context, crypto); 632 633 ret = krb_enc_mit(context, krbencs[i].enctype, &kb, 634 krbencs[i].usage, &cipher, &plain); 635 if (ret) 636 errx(1, "krb_enc_mit failed with %d for test %d", ret, i); 637 } 638 639 return 0; 640 } 641 642 static int 643 iov_test(krb5_context context) 644 { 645 krb5_enctype enctype = ENCTYPE_AES256_CTS_HMAC_SHA1_96; 646 krb5_error_code ret; 647 krb5_crypto crypto; 648 krb5_keyblock key; 649 krb5_data signonly, in, in2; 650 krb5_crypto_iov iov[6]; 651 size_t len, i; 652 unsigned char *base, *p; 653 654 ret = krb5_generate_random_keyblock(context, enctype, &key); 655 if (ret) 656 krb5_err(context, 1, ret, "krb5_generate_random_keyblock"); 657 658 ret = krb5_crypto_init(context, &key, 0, &crypto); 659 if (ret) 660 krb5_err(context, 1, ret, "krb5_crypto_init"); 661 662 663 ret = krb5_crypto_length(context, crypto, KRB5_CRYPTO_TYPE_HEADER, &len); 664 if (ret) 665 krb5_err(context, 1, ret, "krb5_crypto_length"); 666 667 signonly.data = "This should be signed"; 668 signonly.length = strlen(signonly.data); 669 in.data = "inputdata"; 670 in.length = strlen(in.data); 671 672 in2.data = "INPUTDATA"; 673 in2.length = strlen(in2.data); 674 675 676 memset(iov, 0, sizeof(iov)); 677 678 iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; 679 iov[1].flags = KRB5_CRYPTO_TYPE_DATA; 680 iov[1].data = in; 681 iov[2].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; 682 iov[2].data = signonly; 683 iov[3].flags = KRB5_CRYPTO_TYPE_EMPTY; 684 iov[4].flags = KRB5_CRYPTO_TYPE_PADDING; 685 iov[5].flags = KRB5_CRYPTO_TYPE_TRAILER; 686 687 ret = krb5_crypto_length_iov(context, crypto, iov, 688 sizeof(iov)/sizeof(iov[0])); 689 if (ret) 690 krb5_err(context, 1, ret, "krb5_crypto_length_iov"); 691 692 for (len = 0, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { 693 if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) 694 continue; 695 len += iov[i].data.length; 696 } 697 698 base = emalloc(len); 699 700 /* 701 * Allocate data for the fields 702 */ 703 704 for (p = base, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { 705 if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) 706 continue;; 707 iov[i].data.data = p; 708 p += iov[i].data.length; 709 } 710 assert(iov[1].data.length == in.length); 711 memcpy(iov[1].data.data, in.data, iov[1].data.length); 712 713 /* 714 * Encrypt 715 */ 716 717 ret = krb5_encrypt_iov_ivec(context, crypto, 7, iov, 718 sizeof(iov)/sizeof(iov[0]), NULL); 719 if (ret) 720 krb5_err(context, 1, ret, "krb5_encrypt_iov_ivec"); 721 722 /* 723 * Decrypt 724 */ 725 726 ret = krb5_decrypt_iov_ivec(context, crypto, 7, 727 iov, sizeof(iov)/sizeof(iov[0]), NULL); 728 if (ret) 729 krb5_err(context, 1, ret, "krb5_decrypt_iov_ivec"); 730 731 /* 732 * Verify data 733 */ 734 735 if (krb5_data_cmp(&iov[1].data, &in) != 0) 736 krb5_errx(context, 1, "decrypted data not same"); 737 738 /* 739 * Free memory 740 */ 741 742 free(base); 743 744 /* Set up for second try */ 745 746 iov[3].flags = KRB5_CRYPTO_TYPE_DATA; 747 iov[3].data = in; 748 749 ret = krb5_crypto_length_iov(context, crypto, 750 iov, sizeof(iov)/sizeof(iov[0])); 751 if (ret) 752 krb5_err(context, 1, ret, "krb5_crypto_length_iov"); 753 754 for (len = 0, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { 755 if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) 756 continue; 757 len += iov[i].data.length; 758 } 759 760 base = emalloc(len); 761 762 /* 763 * Allocate data for the fields 764 */ 765 766 for (p = base, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { 767 if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) 768 continue;; 769 iov[i].data.data = p; 770 p += iov[i].data.length; 771 } 772 assert(iov[1].data.length == in.length); 773 memcpy(iov[1].data.data, in.data, iov[1].data.length); 774 775 assert(iov[3].data.length == in2.length); 776 memcpy(iov[3].data.data, in2.data, iov[3].data.length); 777 778 779 780 /* 781 * Encrypt 782 */ 783 784 ret = krb5_encrypt_iov_ivec(context, crypto, 7, 785 iov, sizeof(iov)/sizeof(iov[0]), NULL); 786 if (ret) 787 krb5_err(context, 1, ret, "krb5_encrypt_iov_ivec"); 788 789 /* 790 * Decrypt 791 */ 792 793 ret = krb5_decrypt_iov_ivec(context, crypto, 7, 794 iov, sizeof(iov)/sizeof(iov[0]), NULL); 795 if (ret) 796 krb5_err(context, 1, ret, "krb5_decrypt_iov_ivec"); 797 798 /* 799 * Verify data 800 */ 801 802 if (krb5_data_cmp(&iov[1].data, &in) != 0) 803 krb5_errx(context, 1, "decrypted data 2.1 not same"); 804 805 if (krb5_data_cmp(&iov[3].data, &in2) != 0) 806 krb5_errx(context, 1, "decrypted data 2.2 not same"); 807 808 /* 809 * Free memory 810 */ 811 812 free(base); 813 814 krb5_crypto_destroy(context, crypto); 815 816 krb5_free_keyblock_contents(context, &key); 817 818 return 0; 819 } 820 821 822 823 static int 824 random_to_key(krb5_context context) 825 { 826 krb5_error_code ret; 827 krb5_keyblock key; 828 829 ret = krb5_random_to_key(context, 830 ETYPE_DES3_CBC_SHA1, 831 "\x21\x39\x04\x58\x6A\xBD\x7F" 832 "\x21\x39\x04\x58\x6A\xBD\x7F" 833 "\x21\x39\x04\x58\x6A\xBD\x7F", 834 21, 835 &key); 836 if (ret){ 837 krb5_warn(context, ret, "random_to_key"); 838 return 1; 839 } 840 if (key.keyvalue.length != 24) 841 return 1; 842 843 if (memcmp(key.keyvalue.data, 844 "\x20\x38\x04\x58\x6b\xbc\x7f\xc7" 845 "\x20\x38\x04\x58\x6b\xbc\x7f\xc7" 846 "\x20\x38\x04\x58\x6b\xbc\x7f\xc7", 847 24) != 0) 848 return 1; 849 850 krb5_free_keyblock_contents(context, &key); 851 852 return 0; 853 } 854 855 int 856 main(int argc, char **argv) 857 { 858 krb5_error_code ret; 859 krb5_context context; 860 int val = 0; 861 862 ret = krb5_init_context (&context); 863 if (ret) 864 errx (1, "krb5_init_context failed: %d", ret); 865 866 val |= string_to_key_test(context); 867 868 val |= krb_enc_test(context); 869 val |= random_to_key(context); 870 val |= iov_test(context); 871 872 if (verbose && val == 0) 873 printf("all ok\n"); 874 if (val) 875 printf("tests failed\n"); 876 877 krb5_free_context(context); 878 879 return val; 880 } 881