krb5: implement draft-ietf-kitten-aes-cts-hmac-sha2-07

This commit is contained in:
Luke Howard
2015-11-27 18:55:30 +11:00
parent a3bece16c7
commit 7b720cf61c
32 changed files with 1662 additions and 382 deletions

View File

@@ -26,6 +26,7 @@ TESTS = \
derived-key-test \
n-fold-test \
parse-name-test \
pseudo-random-test \
store-test \
string-to-key-test \
test_acl \
@@ -133,7 +134,8 @@ dist_libkrb5_la_SOURCES = \
creds.c \
crypto.c \
crypto.h \
crypto-aes.c \
crypto-aes-sha1.c \
crypto-aes-sha2.c \
crypto-algs.c \
crypto-arcfour.c \
crypto-des.c \
@@ -215,10 +217,12 @@ dist_libkrb5_la_SOURCES = \
recvauth.c \
replay.c \
salt.c \
salt-aes.c \
salt-aes-sha1.c \
salt-aes-sha2.c \
salt-arcfour.c \
salt-des.c \
salt-des3.c \
sp800-108-kdf.c \
scache.c \
send_to_kdc.c \
sendauth.c \
@@ -274,7 +278,8 @@ librfc3961_la_SOURCES = \
crc.c \
crypto.c \
crypto.h \
crypto-aes.c \
crypto-aes-sha1.c \
crypto-aes-sha2.c \
crypto-algs.c \
crypto-arcfour.c \
crypto-des.c \
@@ -291,10 +296,12 @@ librfc3961_la_SOURCES = \
keyblock.c \
n-fold.c \
salt.c \
salt-aes.c \
salt-aes-sha1.c \
salt-aes-sha2.c \
salt-arcfour.c \
salt-des.c \
salt-des3.c \
sp800-108-kdf.c \
store-int.c \
warn.c

View File

@@ -56,7 +56,8 @@ libkrb5_OBJS = \
$(OBJ)\crc.obj \
$(OBJ)\creds.obj \
$(OBJ)\crypto.obj \
$(OBJ)\crypto-aes.obj \
$(OBJ)\crypto-aes-sha1.obj \
$(OBJ)\crypto-aes-sha2.obj \
$(OBJ)\crypto-algs.obj \
$(OBJ)\crypto-arcfour.obj \
$(OBJ)\crypto-des-common.obj \
@@ -133,7 +134,8 @@ libkrb5_OBJS = \
$(OBJ)\read_message.obj \
$(OBJ)\recvauth.obj \
$(OBJ)\replay.obj \
$(OBJ)\salt-aes.obj \
$(OBJ)\salt-aes-sha1.obj \
$(OBJ)\salt-aes-sha2.obj \
$(OBJ)\salt-arcfour.obj \
$(OBJ)\salt-des.obj \
$(OBJ)\salt-des3.obj \
@@ -143,6 +145,7 @@ libkrb5_OBJS = \
$(OBJ)\sendauth.obj \
$(OBJ)\set_default_realm.obj \
$(OBJ)\sock_principal.obj \
$(OBJ)\sp800-108-kdf.obj \
$(OBJ)\store.obj \
$(OBJ)\store-int.obj \
$(OBJ)\store_emem.obj \
@@ -206,7 +209,8 @@ dist_libkrb5_la_SOURCES = \
creds.c \
crypto.c \
crypto.h \
crypto-aes.c \
crypto-aes-sha1.c \
crypto-aes-sha2.c \
crypto-algs.c \
crypto-arcfour.c \
crypto-des.c \
@@ -285,7 +289,8 @@ dist_libkrb5_la_SOURCES = \
recvauth.c \
replay.c \
salt.c \
salt-aes.c \
salt-aes-sha1.c \
salt-aes-sha2.c \
salt-arcfour.c \
salt-des.c \
salt-des3.c \
@@ -294,6 +299,7 @@ dist_libkrb5_la_SOURCES = \
sendauth.c \
set_default_realm.c \
sock_principal.c \
sp800-108-kdf.c \
store.c \
store-int.c \
store-int.h \
@@ -368,7 +374,8 @@ clean::
librfc3961_OBJS=\
$(OBJ)\crc.obj \
$(OBJ)\crypto.obj \
$(OBJ)\crypto-aes.obj \
$(OBJ)\crypto-aes-sha1.obj \
$(OBJ)\crypto-aes-sha2.obj \
$(OBJ)\crypto-algs.obj \
$(OBJ)\crypto-arcfour.obj \
$(OBJ)\crypto-des.obj \
@@ -384,10 +391,12 @@ librfc3961_OBJS=\
$(OBJ)\keyblock.obj \
$(OBJ)\n-fold.obj \
$(OBJ)\salt.obj \
$(OBJ)\salt-aes.obj \
$(OBJ)\salt-aes-sha1.obj \
$(OBJ)\salt-aes-sha2.obj \
$(OBJ)\salt-arcfour.obj \
$(OBJ)\salt-des.obj \
$(OBJ)\salt-des3.obj \
$(OBJ)\sp800-108-kdf.obj \
$(OBJ)\store-int.obj \
$(OBJ)\warn.obj
@@ -428,6 +437,7 @@ test_binaries = \
$(OBJ)\krbhst-test.exe \
$(OBJ)\n-fold-test.exe \
$(OBJ)\parse-name-test.exe \
$(OBJ)\pseudo-random-test.exe \
$(OBJ)\store-test.exe \
$(OBJ)\string-to-key-test.exe \
$(OBJ)\test_acl.exe \
@@ -467,6 +477,7 @@ test-run:
-krbhst-test.exe
-n-fold-test.exe
-parse-name-test.exe
-pseudo-random-test.exe
-store-test.exe
-string-to-key-test.exe
-test_acl.exe

View File

@@ -57,6 +57,29 @@ struct {
char *pbkdf2;
char *key;
} keys[] = {
{
"password",
"\x10\xDF\x9D\xD7\x83\xE5\xBC\x8A\xCE\xA1\x73\x0E\x74\x35\x5F\x61"
"ATHENA.MIT.EDUraeburn",
37,
32768,
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
16,
NULL,
"\x08\x9B\xCA\x48\xB1\x05\xEA\x6E\xA7\x7C\xA5\xD2\xF3\x9D\xC5\xE7"
},
{
"password",
"\x10\xDF\x9D\xD7\x83\xE5\xBC\x8A\xCE\xA1\x73\x0E\x74\x35\x5F\x61"
"ATHENA.MIT.EDUraeburn",
37,
32768,
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192,
32,
NULL,
"\x45\xBD\x80\x6D\xBF\x6A\x83\x3A\x9C\xFF\xC1\xC9\x45\x89\xA2\x22"
"\x36\x7A\x79\xBC\x21\xC4\x13\x71\x89\x06\xE9\xF5\x78\xA7\x84\x67"
},
{
"password", "ATHENA.MIT.EDUraeburn", -1,
1,
@@ -156,7 +179,6 @@ struct {
"\x1a\x8b\x4d\x28\x26\x01\xdb\x3b\x36\xbe\x92\x46\x91\x5e\xc8\x2a",
"\xd7\x8c\x5c\x9c\xb8\x72\xa8\xc9\xda\xd4\x69\x7f\x0b\xb5\xb2\xd2"
"\x14\x96\xc8\x2b\xeb\x2c\xae\xda\x21\x12\xfc\xee\xa0\x57\x40\x1b"
},
{
"\xf0\x9d\x84\x9e" /* g-clef */, "EXAMPLE.COMpianist", -1,
@@ -221,10 +243,10 @@ string_to_key_test(krb5_context context)
if (keys[i].keylen > sizeof(keyout))
abort();
PKCS5_PBKDF2_HMAC_SHA1(password.data, password.length,
salt.saltvalue.data, salt.saltvalue.length,
keys[i].iterations,
keys[i].keylen, keyout);
PKCS5_PBKDF2_HMAC(password.data, password.length,
salt.saltvalue.data, salt.saltvalue.length,
keys[i].iterations, EVP_sha1(),
keys[i].keylen, keyout);
if (memcmp(keyout, keys[i].pbkdf2, keys[i].keylen) != 0) {
krb5_warnx(context, "%d: pbkdf2", i);
@@ -477,9 +499,10 @@ static int
krb_checksum_iov(krb5_context context,
krb5_crypto crypto,
unsigned usage,
krb5_data *plain)
krb5_data *plain,
krb5_data *verify)
{
krb5_crypto_iov iov[4];
krb5_crypto_iov iov[3];
int ret;
char *p;
size_t len;
@@ -488,8 +511,12 @@ krb_checksum_iov(krb5_context context,
len = plain->length;
iov[0].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length);
iov[0].data.data = emalloc(iov[0].data.length);
if (verify) {
iov[0].data = *verify;
} else {
krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length);
iov[0].data.data = emalloc(iov[0].data.length);
}
iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
iov[1].data.length = len;
@@ -499,16 +526,19 @@ krb_checksum_iov(krb5_context context,
krb5_crypto_length(context, crypto, iov[0].flags, &iov[2].data.length);
iov[2].data.data = malloc(iov[2].data.length);
ret = krb5_create_checksum_iov(context, crypto, usage,
iov, sizeof(iov)/sizeof(iov[0]), NULL);
if (ret)
krb5_err(context, 1, ret, "krb5_create_checksum_iov failed");
if (verify == NULL) {
ret = krb5_create_checksum_iov(context, crypto, usage,
iov, sizeof(iov)/sizeof(iov[0]), NULL);
if (ret)
krb5_err(context, 1, ret, "krb5_create_checksum_iov failed");
}
ret = krb5_verify_checksum_iov(context, crypto, usage, iov, sizeof(iov)/sizeof(iov[0]), NULL);
if (ret)
krb5_err(context, 1, ret, "krb5_verify_checksum_iov");
free(iov[0].data.data);
if (verify == NULL)
free(iov[0].data.data);
free(iov[2].data.data);
return 0;
@@ -558,7 +588,6 @@ krb_enc_mit(krb5_context context,
return 0;
}
struct {
krb5_enctype enctype;
unsigned usage;
@@ -568,6 +597,8 @@ struct {
void* edata;
size_t plen;
void *pdata;
size_t clen; /* checksum length */
void *cdata; /* checksum data */
} krbencs[] = {
{
ETYPE_AES256_CTS_HMAC_SHA1_96,
@@ -580,11 +611,133 @@ struct {
"\xa9\xec\x1c\x5c\x21\xfb\x6e\xef\x1a\x7a\xc8\xc1\xcc\x5a\x95\x24"
"\x6f\x9f\xf4\xd5\xbe\x5d\x59\x97\x44\xd8\x47\xcd",
16,
"\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x2e\x0a"
"\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x2e\x0a",
0,
NULL
},
{
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
2,
16,
"\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C",
32,
"\xEF\x85\xFB\x89\x0B\xB8\x47\x2F\x4D\xAB\x20\x39\x4D\xCA\x78\x1D"
"\xAD\x87\x7E\xDA\x39\xD5\x0C\x87\x0C\x0D\x5A\x0A\x8E\x48\xC7\x18",
0,
"",
0,
NULL
},
{
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
2,
16,
"\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C",
38,
"\x84\xD7\xF3\x07\x54\xED\x98\x7B\xAB\x0B\xF3\x50\x6B\xEB\x09\xCF"
"\xB5\x54\x02\xCE\xF7\xE6\x87\x7C\xE9\x9E\x24\x7E\x52\xD1\x6E\xD4"
"\x42\x1D\xFD\xF8\x97\x6C",
6,
"\x00\x01\x02\x03\x04\x05",
0,
NULL
},
{
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
2,
16,
"\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C",
48,
"\x35\x17\xD6\x40\xF5\x0D\xDC\x8A\xD3\x62\x87\x22\xB3\x56\x9D\x2A"
"\xE0\x74\x93\xFA\x82\x63\x25\x40\x80\xEA\x65\xC1\x00\x8E\x8F\xC2"
"\x95\xFB\x48\x52\xE7\xD8\x3E\x1E\x7C\x48\xC3\x7E\xEB\xE6\xB0\xD3",
16,
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
0,
NULL
},
{
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
2,
16,
"\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C",
53,
"\x72\x0F\x73\xB1\x8D\x98\x59\xCD\x6C\xCB\x43\x46\x11\x5C\xD3\x36"
"\xC7\x0F\x58\xED\xC0\xC4\x43\x7C\x55\x73\x54\x4C\x31\xC8\x13\xBC"
"\xE1\xE6\xD0\x72\xC1\x86\xB3\x9A\x41\x3C\x2F\x92\xCA\x9B\x83\x34"
"\xA2\x87\xFF\xCB\xFC",
21,
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
"\x10\x11\x12\x13\x14",
16,
"\xD7\x83\x67\x18\x66\x43\xD6\x7B\x41\x1C\xBA\x91\x39\xFC\x1D\xEE"
},
{
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192,
2,
32,
"\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98"
"\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52",
40,
"\x41\xF5\x3F\xA5\xBF\xE7\x02\x6D\x91\xFA\xF9\xBE\x95\x91\x95\xA0"
"\x58\x70\x72\x73\xA9\x6A\x40\xF0\xA0\x19\x60\x62\x1A\xC6\x12\x74"
"\x8B\x9B\xBF\xBE\x7E\xB4\xCE\x3C",
0,
"",
0,
NULL
},
{
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192,
2,
32,
"\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98"
"\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52",
46,
"\x4E\xD7\xB3\x7C\x2B\xCA\xC8\xF7\x4F\x23\xC1\xCF\x07\xE6\x2B\xC7"
"\xB7\x5F\xB3\xF6\x37\xB9\xF5\x59\xC7\xF6\x64\xF6\x9E\xAB\x7B\x60"
"\x92\x23\x75\x26\xEA\x0D\x1F\x61\xCB\x20\xD6\x9D\x10\xF2",
6,
"\x00\x01\x02\x03\x04\x05",
0,
NULL
},
{
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192,
2,
32,
"\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98"
"\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52",
56,
"\xBC\x47\xFF\xEC\x79\x98\xEB\x91\xE8\x11\x5C\xF8\xD1\x9D\xAC\x4B"
"\xBB\xE2\xE1\x63\xE8\x7D\xD3\x7F\x49\xBE\xCA\x92\x02\x77\x64\xF6"
"\x8C\xF5\x1F\x14\xD7\x98\xC2\x27\x3F\x35\xDF\x57\x4D\x1F\x93\x2E"
"\x40\xC4\xFF\x25\x5B\x36\xA2\x66",
16,
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
0,
NULL
},
{
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192,
2,
32,
"\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98"
"\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52",
61,
"\x40\x01\x3E\x2D\xF5\x8E\x87\x51\x95\x7D\x28\x78\xBC\xD2\xD6\xFE"
"\x10\x1C\xCF\xD5\x56\xCB\x1E\xAE\x79\xDB\x3C\x3E\xE8\x64\x29\xF2"
"\xB2\xA6\x02\xAC\x86\xFE\xF6\xEC\xB6\x47\xD6\x29\x5F\xAE\x07\x7A"
"\x1F\xEB\x51\x75\x08\xD2\xC1\x6B\x41\x92\xE0\x1F\x62",
21,
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
"\x10\x11\x12\x13\x14",
24,
"\x45\xEE\x79\x15\x67\xEE\xFC\xA3\x7F\x4A\xC1\xE0\x22\x2D\xE8\x0D"
"\x43\xC3\xBF\xA0\x66\x99\x67\x2A"
}
};
static int
krb_enc_test(krb5_context context)
{
@@ -621,10 +774,22 @@ krb_enc_test(krb5_context context)
if (ret)
errx(1, "krb_enc_iov2 failed with %d for test %d", ret, i);
ret = krb_checksum_iov(context, crypto, krbencs[i].usage, &plain);
ret = krb_checksum_iov(context, crypto, krbencs[i].usage, &plain, NULL);
if (ret)
errx(1, "krb_checksum_iov failed with %d for test %d", ret, i);
if (krbencs[i].cdata) {
krb5_data checksum;
checksum.length = krbencs[i].clen;
checksum.data = krbencs[i].cdata;
ret = krb_checksum_iov(context, crypto, krbencs[i].usage,
&plain, &checksum);
if (ret)
errx(1, "krb_checksum_iov(2) failed with %d for test %d", ret, i);
}
krb5_crypto_destroy(context, crypto);
ret = krb_enc_mit(context, krbencs[i].enctype, &kb,
@@ -637,9 +802,8 @@ krb_enc_test(krb5_context context)
}
static int
iov_test(krb5_context context)
iov_test(krb5_context context, krb5_enctype enctype)
{
krb5_enctype enctype = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96;
krb5_error_code ret;
krb5_crypto crypto;
krb5_keyblock key;
@@ -867,7 +1031,9 @@ main(int argc, char **argv)
val |= krb_enc_test(context);
val |= random_to_key(context);
val |= iov_test(context);
val |= iov_test(context, KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96);
val |= iov_test(context, KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128);
val |= iov_test(context, KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192);
if (verbose && val == 0)
printf("all ok\n");

View File

@@ -928,6 +928,8 @@ krb5_kerberos_enctypes(krb5_context context)
static const krb5_enctype p[] = {
ETYPE_AES256_CTS_HMAC_SHA1_96,
ETYPE_AES128_CTS_HMAC_SHA1_96,
ETYPE_AES256_CTS_HMAC_SHA384_192,
ETYPE_AES128_CTS_HMAC_SHA256_128,
ETYPE_DES3_CBC_SHA1,
ETYPE_ARCFOUR_HMAC_MD5,
ETYPE_NULL
@@ -936,6 +938,8 @@ krb5_kerberos_enctypes(krb5_context context)
static const krb5_enctype weak[] = {
ETYPE_AES256_CTS_HMAC_SHA1_96,
ETYPE_AES128_CTS_HMAC_SHA1_96,
ETYPE_AES256_CTS_HMAC_SHA384_192,
ETYPE_AES128_CTS_HMAC_SHA256_128,
ETYPE_DES3_CBC_SHA1,
ETYPE_DES3_CBC_MD5,
ETYPE_ARCFOUR_HMAC_MD5,

View File

@@ -37,7 +37,7 @@
* AES
*/
static struct _krb5_key_type keytype_aes128 = {
static struct _krb5_key_type keytype_aes128_sha1 = {
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96,
"aes-128",
128,
@@ -45,13 +45,13 @@ static struct _krb5_key_type keytype_aes128 = {
sizeof(struct _krb5_evp_schedule),
NULL,
_krb5_evp_schedule,
_krb5_AES_salt,
_krb5_AES_SHA1_salt,
NULL,
_krb5_evp_cleanup,
EVP_aes_128_cbc
};
static struct _krb5_key_type keytype_aes256 = {
static struct _krb5_key_type keytype_aes256_sha1 = {
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96,
"aes-256",
256,
@@ -59,7 +59,7 @@ static struct _krb5_key_type keytype_aes256 = {
sizeof(struct _krb5_evp_schedule),
NULL,
_krb5_evp_schedule,
_krb5_AES_salt,
_krb5_AES_SHA1_salt,
NULL,
_krb5_evp_cleanup,
EVP_aes_256_cbc
@@ -86,10 +86,10 @@ struct _krb5_checksum_type _krb5_checksum_hmac_sha1_aes256 = {
};
static krb5_error_code
AES_PRF(krb5_context context,
krb5_crypto crypto,
const krb5_data *in,
krb5_data *out)
AES_SHA1_PRF(krb5_context context,
krb5_crypto crypto,
const krb5_data *in,
krb5_data *out)
{
struct _krb5_checksum_type *ct = crypto->et->checksum;
krb5_error_code ret;
@@ -146,13 +146,13 @@ struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha1 = {
16,
1,
16,
&keytype_aes128,
&keytype_aes128_sha1,
&_krb5_checksum_sha1,
&_krb5_checksum_hmac_sha1_aes128,
F_DERIVED,
F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
_krb5_evp_encrypt_cts,
16,
AES_PRF
AES_SHA1_PRF
};
struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha1 = {
@@ -162,11 +162,11 @@ struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha1 = {
16,
1,
16,
&keytype_aes256,
&keytype_aes256_sha1,
&_krb5_checksum_sha1,
&_krb5_checksum_hmac_sha1_aes256,
F_DERIVED,
F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
_krb5_evp_encrypt_cts,
16,
AES_PRF
AES_SHA1_PRF
};

194
lib/krb5/crypto-aes-sha2.c Normal file
View File

@@ -0,0 +1,194 @@
/*
* Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "krb5_locl.h"
/*
* AES HMAC-SHA2
*/
krb5_error_code
_krb5_aes_sha2_md_for_enctype(krb5_context context,
krb5_enctype enctype,
const EVP_MD **md)
{
switch (enctype) {
case ETYPE_AES128_CTS_HMAC_SHA256_128:
*md = EVP_sha256();
break;
case ETYPE_AES256_CTS_HMAC_SHA384_192:
*md = EVP_sha384();
break;
default:
return KRB5_PROG_ETYPE_NOSUPP;
break;
}
return 0;
}
static krb5_error_code
SP_HMAC_SHA2_checksum(krb5_context context,
struct _krb5_key_data *key,
const void *data,
size_t len,
unsigned usage,
Checksum *result)
{
krb5_error_code ret;
const EVP_MD *md;
unsigned char hmac[EVP_MAX_MD_SIZE];
unsigned int hmaclen = sizeof(hmac);
ret = _krb5_aes_sha2_md_for_enctype(context, key->key->keytype, &md);
if (ret)
return ret;
HMAC(md, key->key->keyvalue.data, key->key->keyvalue.length,
data, len, hmac, &hmaclen);
heim_assert(result->checksum.length <= hmaclen, "SHA2 internal error");
memcpy(result->checksum.data, hmac, result->checksum.length);
return 0;
}
static struct _krb5_key_type keytype_aes128_sha2 = {
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
"aes-128-sha2",
128,
16,
sizeof(struct _krb5_evp_schedule),
NULL,
_krb5_evp_schedule,
_krb5_AES_SHA2_salt,
NULL,
_krb5_evp_cleanup,
EVP_aes_128_cbc
};
static struct _krb5_key_type keytype_aes256_sha2 = {
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192,
"aes-256-sha2",
256,
32,
sizeof(struct _krb5_evp_schedule),
NULL,
_krb5_evp_schedule,
_krb5_AES_SHA2_salt,
NULL,
_krb5_evp_cleanup,
EVP_aes_256_cbc
};
struct _krb5_checksum_type _krb5_checksum_hmac_sha256_128_aes128 = {
CKSUMTYPE_HMAC_SHA256_128_AES128,
"hmac-sha256-128-aes128",
64,
16,
F_KEYED | F_CPROOF | F_DERIVED,
SP_HMAC_SHA2_checksum,
NULL
};
struct _krb5_checksum_type _krb5_checksum_hmac_sha384_192_aes256 = {
CKSUMTYPE_HMAC_SHA384_192_AES256,
"hmac-sha384-192-aes256",
128,
24,
F_KEYED | F_CPROOF | F_DERIVED,
SP_HMAC_SHA2_checksum,
NULL
};
static krb5_error_code
AES_SHA2_PRF(krb5_context context,
krb5_crypto crypto,
const krb5_data *in,
krb5_data *out)
{
krb5_error_code ret;
krb5_data label;
const EVP_MD *md = NULL;
ret = _krb5_aes_sha2_md_for_enctype(context, crypto->et->type, &md);
if (ret)
return ret;
label.data = "prf";
label.length = 3;
ret = krb5_data_alloc(out, EVP_MD_size(md));
if (ret)
return ret;
ret = _krb5_SP800_108_HMAC_KDF(context, &crypto->key.key->keyvalue,
&label, in, md, out);
if (ret)
krb5_data_free(out);
return ret;
}
struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha256_128 = {
ETYPE_AES128_CTS_HMAC_SHA256_128,
"aes128-cts-hmac-sha256-128",
"aes128-cts-sha256",
16,
1,
16,
&keytype_aes128_sha2,
NULL, /* should never be called */
&_krb5_checksum_hmac_sha256_128_aes128,
F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF,
_krb5_evp_encrypt_cts,
16,
AES_SHA2_PRF
};
struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha384_192 = {
ETYPE_AES256_CTS_HMAC_SHA384_192,
"aes256-cts-hmac-sha384-192",
"aes256-cts-sha384",
16,
1,
16,
&keytype_aes256_sha2,
NULL, /* should never be called */
&_krb5_checksum_hmac_sha384_192_aes256,
F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF,
_krb5_evp_encrypt_cts,
16,
AES_SHA2_PRF
};

View File

@@ -53,6 +53,8 @@ struct _krb5_checksum_type *_krb5_checksum_types[] = {
&_krb5_checksum_hmac_sha1_des3,
&_krb5_checksum_hmac_sha1_aes128,
&_krb5_checksum_hmac_sha1_aes256,
&_krb5_checksum_hmac_sha256_128_aes128,
&_krb5_checksum_hmac_sha384_192_aes256,
&_krb5_checksum_hmac_md5
};
@@ -64,6 +66,8 @@ int _krb5_num_checksums
* (only relevant for !F_PSEUDO) */
struct _krb5_encryption_type *_krb5_etypes[] = {
&_krb5_enctype_aes256_cts_hmac_sha384_192,
&_krb5_enctype_aes128_cts_hmac_sha256_128,
&_krb5_enctype_aes256_cts_hmac_sha1,
&_krb5_enctype_aes128_cts_hmac_sha1,
&_krb5_enctype_des3_cbc_sha1,

View File

@@ -208,7 +208,7 @@ struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1 = {
&keytype_des3_derived,
&_krb5_checksum_sha1,
&_krb5_checksum_hmac_sha1_des3,
F_DERIVED,
F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
_krb5_evp_encrypt,
16,
DES3_prf

File diff suppressed because it is too large Load Diff

View File

@@ -52,14 +52,22 @@ struct krb5_crypto_data {
#define CRYPTO_ETYPE(C) ((C)->et->type)
/* bits for `flags' below */
#define F_KEYED 1 /* checksum is keyed */
#define F_CPROOF 2 /* checksum is collision proof */
#define F_DERIVED 4 /* uses derived keys */
#define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
#define F_PSEUDO 16 /* not a real protocol type */
#define F_SPECIAL 32 /* backwards */
#define F_DISABLED 64 /* enctype/checksum disabled */
#define F_WEAK 128 /* enctype is considered weak */
#define F_KEYED 0x0001 /* checksum is keyed */
#define F_CPROOF 0x0002 /* checksum is collision proof */
#define F_DERIVED 0x0004 /* uses derived keys */
#define F_VARIANT 0x0008 /* uses `variant' keys (6.4.3) */
#define F_PSEUDO 0x0010 /* not a real protocol type */
#define F_DISABLED 0x0020 /* enctype/checksum disabled */
#define F_WEAK 0x0040 /* enctype is considered weak */
#define F_RFC3961_ENC 0x0100 /* RFC3961 simplified profile */
#define F_SPECIAL 0x0200 /* backwards */
#define F_ENC_THEN_CKSUM 0x0400 /* checksum is over encrypted data */
#define F_CRYPTO_MASK 0x0F00
#define F_RFC3961_KDF 0x1000 /* RFC3961 KDF */
#define F_SP800_108_HMAC_KDF 0x2000 /* SP800-108 HMAC KDF */
#define F_KDF_MASK 0xF000
struct salt_type {
krb5_salttype type;
@@ -138,15 +146,19 @@ extern struct _krb5_checksum_type _krb5_checksum_rsa_md5;
extern struct _krb5_checksum_type _krb5_checksum_hmac_sha1_des3;
extern struct _krb5_checksum_type _krb5_checksum_hmac_sha1_aes128;
extern struct _krb5_checksum_type _krb5_checksum_hmac_sha1_aes256;
extern struct _krb5_checksum_type _krb5_checksum_hmac_sha256_128_aes128;
extern struct _krb5_checksum_type _krb5_checksum_hmac_sha384_192_aes256;
extern struct _krb5_checksum_type _krb5_checksum_hmac_md5;
extern struct _krb5_checksum_type _krb5_checksum_sha1;
extern struct _krb5_checksum_type _krb5_checksum_sha2;
extern struct _krb5_checksum_type *_krb5_checksum_types[];
extern int _krb5_num_checksums;
/* Salts */
extern struct salt_type _krb5_AES_salt[];
extern struct salt_type _krb5_AES_SHA1_salt[];
extern struct salt_type _krb5_AES_SHA2_salt[];
extern struct salt_type _krb5_arcfour_salt[];
extern struct salt_type _krb5_des_salt[];
extern struct salt_type _krb5_des3_salt[];
@@ -156,6 +168,8 @@ extern struct salt_type _krb5_des3_salt_derived[];
extern struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha1;
extern struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha1;
extern struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha256_128;
extern struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha384_192;
extern struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1;
extern struct _krb5_encryption_type _krb5_enctype_des3_cbc_md5;
extern struct _krb5_encryption_type _krb5_enctype_des3_cbc_none;

View File

@@ -33,7 +33,7 @@
#include "krb5_locl.h"
#include <err.h>
enum { MAXSIZE = 24 };
enum { MAXSIZE = 32 };
static struct testcase {
krb5_enctype enctype;
@@ -72,6 +72,30 @@ static struct testcase {
{ETYPE_DES3_CBC_SHA1, {0x00, 0x00, 0x00, 0x01, 0xaa}, 5,
{0x26, 0xdc, 0xe3, 0x34, 0xb5, 0x45, 0x29, 0x2f, 0x2f, 0xea, 0xb9, 0xa8, 0x70, 0x1a, 0x89, 0xa4, 0xb9, 0x9e, 0xb9, 0x94, 0x2c, 0xec, 0xd0, 0x16},
{0xf4, 0x8f, 0xfd, 0x6e, 0x83, 0xf8, 0x3e, 0x73, 0x54, 0xe6, 0x94, 0xfd, 0x25, 0x2c, 0xf8, 0x3b, 0xfe, 0x58, 0xf7, 0xd5, 0xba, 0x37, 0xec, 0x5d}},
{ETYPE_AES128_CTS_HMAC_SHA256_128, {0x00, 0x00, 0x00, 0x02, 0x99}, 5,
{0x37, 0x05, 0xD9, 0x60, 0x80, 0xC1, 0x77, 0x28, 0xA0, 0xE8, 0x00, 0xEA, 0xB6, 0xE0, 0xD2, 0x3C},
{0xB3, 0x1A, 0x01, 0x8A, 0x48, 0xF5, 0x47, 0x76, 0xF4, 0x03, 0xE9, 0xA3, 0x96, 0x32, 0x5D, 0xC3}},
{ETYPE_AES128_CTS_HMAC_SHA256_128, {0x00, 0x00, 0x00, 0x02, 0xAA}, 5,
{0x37, 0x05, 0xD9, 0x60, 0x80, 0xC1, 0x77, 0x28, 0xA0, 0xE8, 0x00, 0xEA, 0xB6, 0xE0, 0xD2, 0x3C},
{0x9B, 0x19, 0x7D, 0xD1, 0xE8, 0xC5, 0x60, 0x9D, 0x6E, 0x67, 0xC3, 0xE3, 0x7C, 0x62, 0xC7, 0x2E}},
{ETYPE_AES128_CTS_HMAC_SHA256_128, {0x00, 0x00, 0x00, 0x02, 0x55}, 5,
{0x37, 0x05, 0xD9, 0x60, 0x80, 0xC1, 0x77, 0x28, 0xA0, 0xE8, 0x00, 0xEA, 0xB6, 0xE0, 0xD2, 0x3C},
{0x9F, 0xDA, 0x0E, 0x56, 0xAB, 0x2D, 0x85, 0xE1, 0x56, 0x9A, 0x68, 0x86, 0x96, 0xC2, 0x6A, 0x6C}},
{ETYPE_AES256_CTS_HMAC_SHA384_192, {0x00, 0x00, 0x00, 0x02, 0x99}, 5,
{0x6D, 0x40, 0x4D, 0x37, 0xFA, 0xF7, 0x9F, 0x9D, 0xF0, 0xD3, 0x35, 0x68, 0xD3, 0x20, 0x66, 0x98,
0x00, 0xEB, 0x48, 0x36, 0x47, 0x2E, 0xA8, 0xA0, 0x26, 0xD1, 0x6B, 0x71, 0x82, 0x46, 0x0C, 0x52},
{0xEF, 0x57, 0x18, 0xBE, 0x86, 0xCC, 0x84, 0x96, 0x3D, 0x8B, 0xBB, 0x50, 0x31, 0xE9, 0xF5, 0xC4,
0xBA, 0x41, 0xF2, 0x8F, 0xAF, 0x69, 0xE7, 0x3D }},
{ETYPE_AES256_CTS_HMAC_SHA384_192, {0x00, 0x00, 0x00, 0x02, 0xAA}, 5,
{0x6D, 0x40, 0x4D, 0x37, 0xFA, 0xF7, 0x9F, 0x9D, 0xF0, 0xD3, 0x35, 0x68, 0xD3, 0x20, 0x66, 0x98,
0x00, 0xEB, 0x48, 0x36, 0x47, 0x2E, 0xA8, 0xA0, 0x26, 0xD1, 0x6B, 0x71, 0x82, 0x46, 0x0C, 0x52},
{0x56, 0xAB, 0x22, 0xBE, 0xE6, 0x3D, 0x82, 0xD7, 0xBC, 0x52, 0x27, 0xF6, 0x77, 0x3F, 0x8E, 0xA7,
0xA5, 0xEB, 0x1C, 0x82, 0x51, 0x60, 0xC3, 0x83, 0x12, 0x98, 0x0C, 0x44, 0x2E, 0x5C, 0x7E, 0x49}},
{ETYPE_AES256_CTS_HMAC_SHA384_192, {0x00, 0x00, 0x00, 0x02, 0x55}, 5,
{0x6D, 0x40, 0x4D, 0x37, 0xFA, 0xF7, 0x9F, 0x9D, 0xF0, 0xD3, 0x35, 0x68, 0xD3, 0x20, 0x66, 0x98,
0x00, 0xEB, 0x48, 0x36, 0x47, 0x2E, 0xA8, 0xA0, 0x26, 0xD1, 0x6B, 0x71, 0x82, 0x46, 0x0C, 0x52},
{0x69, 0xB1, 0x65, 0x14, 0xE3, 0xCD, 0x8E, 0x56, 0xB8, 0x20, 0x10, 0xD5, 0xC7, 0x30, 0x12, 0xB6,
0x22, 0xC4, 0xD0, 0x0F, 0xFC, 0x23, 0xED, 0x1F}},
{0, {0}, 0, {0}, {0}}
};
@@ -91,8 +115,8 @@ main(int argc, char **argv)
krb5_keyblock key;
krb5_keyblock *dkey;
key.keytype = KEYTYPE_DES3;
key.keyvalue.length = MAXSIZE;
key.keytype = t->enctype;
krb5_enctype_keysize(context, t->enctype, &key.keyvalue.length);
key.keyvalue.data = t->key;
ret = krb5_derive_key(context, &key, t->enctype, t->constant,
@@ -103,7 +127,7 @@ main(int argc, char **argv)
const unsigned char *p = dkey->keyvalue.data;
int i;
printf ("derive_key failed\n");
printf ("derive_key failed (enctype %d)\n", t->enctype);
printf ("should be: ");
for (i = 0; i < dkey->keyvalue.length; ++i)
printf ("%02x", t->res[i]);

View File

@@ -150,6 +150,8 @@ enum {
ETYPE_DES3_CBC_SHA1 = KRB5_ENCTYPE_DES3_CBC_SHA1,
ETYPE_AES128_CTS_HMAC_SHA1_96 = KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96,
ETYPE_AES256_CTS_HMAC_SHA1_96 = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96,
ETYPE_AES128_CTS_HMAC_SHA256_128 = KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
ETYPE_AES256_CTS_HMAC_SHA384_192 = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192,
ETYPE_ARCFOUR_HMAC_MD5 = KRB5_ENCTYPE_ARCFOUR_HMAC_MD5,
ETYPE_ARCFOUR_HMAC_MD5_56 = KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56,
ETYPE_ENCTYPE_PK_CROSS = KRB5_ENCTYPE_ENCTYPE_PK_CROSS,

View File

@@ -747,7 +747,8 @@ EXPORTS
_krb5_build_authenticator
; Shared with libkdc
_krb5_AES_string_to_default_iterator
_krb5_AES_SHA1_string_to_default_iterator
_krb5_AES_SHA2_string_to_default_iterator
_krb5_dh_group_ok
_krb5_get_host_realm_int
_krb5_get_int
@@ -759,6 +760,7 @@ EXPORTS
_krb5_pk_mk_ContentInfo
_krb5_pk_octetstring2key
_krb5_plugin_run_f
_krb5_enctype_requires_random_salt
_krb5_principal2principalname
_krb5_principalname2krb5_principal
_krb5_put_int

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of KTH nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "krb5_locl.h"
#include <err.h>
enum { MAXSIZE = 48 };
static struct testcase {
krb5_enctype enctype;
unsigned char constant[MAXSIZE];
size_t constant_len;
unsigned char key[MAXSIZE];
unsigned char res[MAXSIZE];
} tests[] = {
{ETYPE_AES128_CTS_HMAC_SHA256_128, "test", 4,
{0x37, 0x05, 0xD9, 0x60, 0x80, 0xC1, 0x77, 0x28, 0xA0, 0xE8, 0x00, 0xEA, 0xB6, 0xE0, 0xD2, 0x3C},
{0x9D, 0x18, 0x86, 0x16, 0xF6, 0x38, 0x52, 0xFE, 0x86, 0x91, 0x5B, 0xB8, 0x40, 0xB4, 0xA8, 0x86,
0xFF, 0x3E, 0x6B, 0xB0, 0xF8, 0x19, 0xB4, 0x9B, 0x89, 0x33, 0x93, 0xD3, 0x93, 0x85, 0x42, 0x95}},
{ETYPE_AES256_CTS_HMAC_SHA384_192, "test", 4,
{0x6D, 0x40, 0x4D, 0x37, 0xFA, 0xF7, 0x9F, 0x9D, 0xF0, 0xD3, 0x35, 0x68, 0xD3, 0x20, 0x66, 0x98,
0x00, 0xEB, 0x48, 0x36, 0x47, 0x2E, 0xA8, 0xA0, 0x26, 0xD1, 0x6B, 0x71, 0x82, 0x46, 0x0C, 0x52},
{0x98, 0x01, 0xF6, 0x9A, 0x36, 0x8C, 0x2B, 0xF6, 0x75, 0xE5, 0x95, 0x21, 0xE1, 0x77, 0xD9, 0xA0,
0x7F, 0x67, 0xEF, 0xE1, 0xCF, 0xDE, 0x8D, 0x3C, 0x8D, 0x6F, 0x6A, 0x02, 0x56, 0xE3, 0xB1, 0x7D,
0xB3, 0xC1, 0xB6, 0x2A, 0xD1, 0xB8, 0x55, 0x33, 0x60, 0xD1, 0x73, 0x67, 0xEB, 0x15, 0x14, 0xD2}},
{0, {0}, 0, {0}, {0}}
};
int
main(int argc, char **argv)
{
struct testcase *t;
krb5_context context;
krb5_error_code ret;
int val = 0;
ret = krb5_init_context (&context);
if (ret)
errx (1, "krb5_init_context failed: %d", ret);
for (t = tests; t->enctype != 0; ++t) {
krb5_keyblock key;
krb5_crypto crypto;
krb5_data constant, prf;
krb5_data_zero(&prf);
key.keytype = t->enctype;
krb5_enctype_keysize(context, t->enctype, &key.keyvalue.length);
key.keyvalue.data = t->key;
ret = krb5_crypto_init(context, &key, 0, &crypto);
if (ret)
krb5_err (context, 1, ret, "krb5_crypto_init");
constant.data = t->constant;
constant.length = t->constant_len;
ret = krb5_crypto_prf(context, crypto, &constant, &prf);
if (ret)
krb5_err (context, 1, ret, "krb5_crypto_prf");
if (memcmp(prf.data, t->res, prf.length) != 0) {
const unsigned char *p = prf.data;
int i;
printf ("PRF failed (enctype %d)\n", t->enctype);
printf ("should be: ");
for (i = 0; i < prf.length; ++i)
printf ("%02x", t->res[i]);
printf ("\nresult was: ");
for (i = 0; i < prf.length; ++i)
printf ("%02x", p[i]);
printf ("\n");
val = 1;
}
krb5_data_free(&prf);
krb5_crypto_destroy(context, crypto);
}
krb5_free_context(context);
return val;
}

View File

@@ -33,15 +33,15 @@
#include "krb5_locl.h"
int _krb5_AES_string_to_default_iterator = 4096;
int _krb5_AES_SHA1_string_to_default_iterator = 4096;
static krb5_error_code
AES_string_to_key(krb5_context context,
krb5_enctype enctype,
krb5_data password,
krb5_salt salt,
krb5_data opaque,
krb5_keyblock *key)
AES_SHA1_string_to_key(krb5_context context,
krb5_enctype enctype,
krb5_data password,
krb5_salt salt,
krb5_data opaque,
krb5_keyblock *key)
{
krb5_error_code ret;
uint32_t iter;
@@ -49,7 +49,7 @@ AES_string_to_key(krb5_context context,
struct _krb5_key_data kd;
if (opaque.length == 0)
iter = _krb5_AES_string_to_default_iterator;
iter = _krb5_AES_SHA1_string_to_default_iterator;
else if (opaque.length == 4) {
unsigned long v;
_krb5_get_int(opaque.data, &v, 4);
@@ -72,10 +72,11 @@ AES_string_to_key(krb5_context context,
return ret;
}
ret = PKCS5_PBKDF2_HMAC_SHA1(password.data, password.length,
salt.saltvalue.data, salt.saltvalue.length,
iter,
et->keytype->size, kd.key->keyvalue.data);
ret = PKCS5_PBKDF2_HMAC(password.data, password.length,
salt.saltvalue.data, salt.saltvalue.length,
iter,
EVP_sha1(),
et->keytype->size, kd.key->keyvalue.data);
if (ret != 1) {
_krb5_free_key_data(context, &kd, et);
krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
@@ -91,11 +92,11 @@ AES_string_to_key(krb5_context context,
return ret;
}
struct salt_type _krb5_AES_salt[] = {
struct salt_type _krb5_AES_SHA1_salt[] = {
{
KRB5_PW_SALT,
"pw-salt",
AES_string_to_key
AES_SHA1_string_to_key
},
{ 0, NULL, NULL }
};

135
lib/krb5/salt-aes-sha2.c Normal file
View File

@@ -0,0 +1,135 @@
/*
* Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "krb5_locl.h"
int _krb5_AES_SHA2_string_to_default_iterator = 32768;
static krb5_error_code
AES_SHA2_string_to_key(krb5_context context,
krb5_enctype enctype,
krb5_data password,
krb5_salt salt,
krb5_data opaque,
krb5_keyblock *key)
{
krb5_error_code ret;
uint32_t iter;
struct _krb5_encryption_type *et = NULL;
struct _krb5_key_data kd;
krb5_data saltp;
size_t enctypesz;
const EVP_MD *md = NULL;
krb5_data_zero(&saltp);
kd.key = NULL;
kd.schedule = NULL;
if (opaque.length == 0) {
iter = _krb5_AES_SHA2_string_to_default_iterator;
} else if (opaque.length == 4) {
unsigned long v;
_krb5_get_int(opaque.data, &v, 4);
iter = ((uint32_t)v);
} else {
ret = KRB5_PROG_KEYTYPE_NOSUPP; /* XXX */
goto cleanup;
}
et = _krb5_find_enctype(enctype);
if (et == NULL) {
ret = KRB5_PROG_KEYTYPE_NOSUPP;
goto cleanup;
}
kd.schedule = NULL;
ALLOC(kd.key, 1);
if (kd.key == NULL) {
ret = krb5_enomem(context);
goto cleanup;
}
kd.key->keytype = enctype;
ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
if (ret) {
ret = krb5_enomem(context);
goto cleanup;
}
enctypesz = strlen(et->name) + 1;
ret = krb5_data_alloc(&saltp, enctypesz + salt.saltvalue.length);
if (ret) {
ret = krb5_enomem(context);
goto cleanup;
}
memcpy(saltp.data, et->name, enctypesz);
memcpy((unsigned char *)saltp.data + enctypesz,
salt.saltvalue.data, salt.saltvalue.length);
ret = _krb5_aes_sha2_md_for_enctype(context, enctype, &md);
if (ret)
goto cleanup;
ret = PKCS5_PBKDF2_HMAC(password.data, password.length,
saltp.data, saltp.length,
iter, md,
et->keytype->size, kd.key->keyvalue.data);
if (ret != 1) {
krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
"Error calculating s2k");
ret = KRB5_PROG_KEYTYPE_NOSUPP;
goto cleanup;
}
ret = _krb5_derive_key(context, et, &kd, "kerberos", strlen("kerberos"));
if (ret)
goto cleanup;
ret = krb5_copy_keyblock_contents(context, kd.key, key);
if (ret)
goto cleanup;
cleanup:
krb5_data_free(&saltp);
_krb5_free_key_data(context, &kd, et);
return ret;
}
struct salt_type _krb5_AES_SHA2_salt[] = {
{
KRB5_PW_SALT,
"pw-salt",
AES_SHA2_string_to_key
},
{ 0, NULL, NULL }
};

97
lib/krb5/sp800-108-kdf.c Executable file
View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2015, Secure Endpoints Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "krb5_locl.h"
/*
* SP800-108 KDF
*/
/**
* As described in SP800-108 5.1 (for HMAC)
*
* @param context Kerberos 5 context
* @param kdc_K1 Base key material.
* @param kdf_label A string that identifies the purpose for the derived key.
* @param kdf_context A binary string containing parties, nonce, etc.
* @param md Message digest function to use for PRF.
* @param kdf_K0 Derived key data.
*
* @return Return an error code for an failure or 0 on success.
* @ingroup krb5_crypto
*/
krb5_error_code
_krb5_SP800_108_HMAC_KDF(krb5_context context,
const krb5_data *kdf_K1,
const krb5_data *kdf_label,
const krb5_data *kdf_context,
const EVP_MD *md,
krb5_data *kdf_K0)
{
HMAC_CTX c;
unsigned char *p = kdf_K0->data;
size_t i, n, left = kdf_K0->length;
unsigned char hmac[EVP_MAX_MD_SIZE];
unsigned int h = EVP_MD_size(md);
const size_t L = kdf_K0->length;
heim_assert(md != NULL, "SP800-108 KDF internal error");
HMAC_CTX_init(&c);
n = L / h;
for (i = 0; i <= n; i++) {
unsigned char tmp[4];
size_t len;
HMAC_Init_ex(&c, kdf_K1->data, kdf_K1->length, md, NULL);
_krb5_put_int(tmp, i + 1, 4);
HMAC_Update(&c, tmp, 4);
HMAC_Update(&c, kdf_label->data, kdf_label->length);
HMAC_Update(&c, (unsigned char *)"", 1);
if (kdf_context)
HMAC_Update(&c, kdf_context->data, kdf_context->length);
_krb5_put_int(tmp, L * 8, 4);
HMAC_Update(&c, tmp, 4);
HMAC_Final(&c, hmac, &h);
len = h > left ? left : h;
memcpy(p, hmac, len);
p += len;
left -= len;
}
HMAC_CTX_cleanup(&c);
return 0;
}

View File

@@ -164,7 +164,9 @@ main(int argc, char **argv)
ETYPE_ARCFOUR_HMAC_MD5,
#endif
ETYPE_AES128_CTS_HMAC_SHA1_96,
ETYPE_AES256_CTS_HMAC_SHA1_96
ETYPE_AES256_CTS_HMAC_SHA1_96,
ETYPE_AES128_CTS_HMAC_SHA256_128,
ETYPE_AES256_CTS_HMAC_SHA384_192
};
setprogname(argv[0]);

View File

@@ -131,7 +131,9 @@ main(int argc, char **argv)
ETYPE_DES3_CBC_SHA1,
ETYPE_ARCFOUR_HMAC_MD5,
ETYPE_AES128_CTS_HMAC_SHA1_96,
ETYPE_AES256_CTS_HMAC_SHA1_96
ETYPE_AES256_CTS_HMAC_SHA1_96,
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192
};
setprogname(argv[0]);

View File

@@ -162,7 +162,9 @@ main(int argc, char **argv)
ETYPE_DES3_CBC_SHA1,
ETYPE_ARCFOUR_HMAC_MD5,
ETYPE_AES128_CTS_HMAC_SHA1_96,
ETYPE_AES256_CTS_HMAC_SHA1_96
ETYPE_AES256_CTS_HMAC_SHA1_96,
ETYPE_AES128_CTS_HMAC_SHA256_128,
ETYPE_AES256_CTS_HMAC_SHA384_192
};
setprogname(argv[0]);

View File

@@ -732,6 +732,7 @@ HEIMDAL_KRB5_2.0 {
# shared with HDB
_krb5_plugin_run_f;
_krb5_enctype_requires_random_salt;
# Shared with GSSAPI krb5
_krb5_crc_init_table;
@@ -740,7 +741,8 @@ HEIMDAL_KRB5_2.0 {
_krb5_build_authenticator;
# Shared with libkdc
_krb5_AES_string_to_default_iterator;
_krb5_AES_SHA1_string_to_default_iterator;
_krb5_AES_SHA2_string_to_default_iterator;
_krb5_dh_group_ok;
_krb5_get_host_realm_int;
_krb5_get_int;