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

@@ -1106,11 +1106,33 @@ get_pa_etype_info(krb5_context context,
*
*/
extern int _krb5_AES_string_to_default_iterator;
extern int _krb5_AES_SHA1_string_to_default_iterator;
extern int _krb5_AES_SHA2_string_to_default_iterator;
static krb5_error_code
make_s2kparams(int value, size_t len, krb5_data **ps2kparams)
{
krb5_data *s2kparams;
krb5_error_code ret;
ALLOC(s2kparams);
if (s2kparams == NULL)
return ENOMEM;
ret = krb5_data_alloc(s2kparams, len);
if (ret) {
free(s2kparams);
return ret;
}
_krb5_put_int(s2kparams->data, value, len);
*ps2kparams = s2kparams;
return 0;
}
static krb5_error_code
make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
{
krb5_error_code ret;
ent->etype = key->key.keytype;
if(key->salt) {
ALLOC(ent->salt);
@@ -1132,44 +1154,28 @@ make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
switch (key->key.keytype) {
case ETYPE_AES128_CTS_HMAC_SHA1_96:
case ETYPE_AES256_CTS_HMAC_SHA1_96:
ALLOC(ent->s2kparams);
if (ent->s2kparams == NULL)
return ENOMEM;
ent->s2kparams->length = 4;
ent->s2kparams->data = malloc(ent->s2kparams->length);
if (ent->s2kparams->data == NULL) {
free(ent->s2kparams);
ent->s2kparams = NULL;
return ENOMEM;
}
_krb5_put_int(ent->s2kparams->data,
_krb5_AES_string_to_default_iterator,
ent->s2kparams->length);
ret = make_s2kparams(_krb5_AES_SHA1_string_to_default_iterator,
4, &ent->s2kparams);
break;
case KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128:
case KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192:
ret = make_s2kparams(_krb5_AES_SHA2_string_to_default_iterator,
4, &ent->s2kparams);
break;
case ETYPE_DES_CBC_CRC:
case ETYPE_DES_CBC_MD4:
case ETYPE_DES_CBC_MD5:
/* Check if this was a AFS3 salted key */
if(key->salt && key->salt->type == hdb_afs3_salt){
ALLOC(ent->s2kparams);
if (ent->s2kparams == NULL)
return ENOMEM;
ent->s2kparams->length = 1;
ent->s2kparams->data = malloc(ent->s2kparams->length);
if (ent->s2kparams->data == NULL) {
free(ent->s2kparams);
ent->s2kparams = NULL;
return ENOMEM;
}
_krb5_put_int(ent->s2kparams->data,
1,
ent->s2kparams->length);
}
if(key->salt && key->salt->type == hdb_afs3_salt)
ret = make_s2kparams(1, 1, &ent->s2kparams);
else
ret = 0;
break;
default:
ret = 0;
break;
}
return 0;
return ret;
}
/*

View File

@@ -233,6 +233,8 @@ CKSUMTYPE ::= INTEGER {
CKSUMTYPE_SHA1(14),
CKSUMTYPE_HMAC_SHA1_96_AES_128(15),
CKSUMTYPE_HMAC_SHA1_96_AES_256(16),
CKSUMTYPE_HMAC_SHA256_128_AES128(19),
CKSUMTYPE_HMAC_SHA384_192_AES256(20),
CKSUMTYPE_GSSAPI(0x8003),
CKSUMTYPE_HMAC_MD5(-138), -- unofficial microsoft number
CKSUMTYPE_HMAC_MD5_ENC(-1138) -- even more unofficial
@@ -252,6 +254,8 @@ ENCTYPE ::= INTEGER {
KRB5_ENCTYPE_DES3_CBC_SHA1(16), -- with key derivation
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96(17),
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96(18),
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128(19),
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192(20),
KRB5_ENCTYPE_ARCFOUR_HMAC_MD5(23),
KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56(24),
KRB5_ENCTYPE_ENCTYPE_PK_CROSS(48),

View File

@@ -423,16 +423,10 @@ init_auth
/*
* This is hideous glue for (NFS) clients that wants to limit the
* available enctypes to what it can support (encryption in
* kernel). If there is no enctypes selected for this credential,
* reset it to the default set of enctypes.
* kernel).
*/
{
krb5_enctype *enctypes = NULL;
if (cred && cred->enctypes)
enctypes = cred->enctypes;
krb5_set_default_in_tkt_etypes(context, enctypes);
}
if (cred && cred->enctypes)
krb5_set_default_in_tkt_etypes(context, cred->enctypes);
ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
ctx, name, time_req, time_rec);

View File

@@ -98,6 +98,7 @@
#define EVP_sha256 hc_EVP_sha256
#define EVP_sha384 hc_EVP_sha384
#define EVP_sha512 hc_EVP_sha512
#define PKCS5_PBKDF2_HMAC hc_PKCS5_PBKDF2_HMAC
#define PKCS5_PBKDF2_HMAC_SHA1 hc_PKCS5_PBKDF2_HMAC_SHA1
#define EVP_BytesToKey hc_EVP_BytesToKey
#define EVP_get_cipherbyname hc_EVP_get_cipherbyname
@@ -333,6 +334,9 @@ int EVP_CipherFinal_ex(EVP_CIPHER_CTX *, void *, int *);
int EVP_Cipher(EVP_CIPHER_CTX *,void *,const void *,size_t);
int PKCS5_PBKDF2_HMAC(const void *, size_t, const void *, size_t,
unsigned long, const EVP_MD *, size_t, void *);
int PKCS5_PBKDF2_HMAC_SHA1(const void *, size_t, const void *, size_t,
unsigned long, size_t, void *);

View File

@@ -276,6 +276,7 @@ EXPORTS
hc_OpenSSL_add_all_algorithms_conf
hc_OpenSSL_add_all_algorithms_noconf
hc_PKCS12_key_gen
hc_PKCS5_PBKDF2_HMAC
hc_PKCS5_PBKDF2_HMAC_SHA1
hc_RAND_add
hc_RAND_bytes

View File

@@ -49,6 +49,7 @@
* @param salt Salt
* @param salt_len Length of salt.
* @param iter iteration counter.
* @param md the digest function.
* @param keylen the output key length.
* @param key the output key.
*
@@ -58,21 +59,23 @@
*/
int
PKCS5_PBKDF2_HMAC_SHA1(const void * password, size_t password_len,
const void * salt, size_t salt_len,
unsigned long iter,
size_t keylen, void *key)
PKCS5_PBKDF2_HMAC(const void * password, size_t password_len,
const void * salt, size_t salt_len,
unsigned long iter,
const EVP_MD *md,
size_t keylen, void *key)
{
size_t datalen, leftofkey, checksumsize;
char *data, *tmpcksum;
uint32_t keypart;
const EVP_MD *md;
unsigned long i;
int j;
char *p;
unsigned int hmacsize;
md = EVP_sha1();
if (md == NULL)
return 0;
checksumsize = EVP_MD_size(md);
datalen = salt_len + 4;
@@ -122,3 +125,28 @@ PKCS5_PBKDF2_HMAC_SHA1(const void * password, size_t password_len,
return 1;
}
/**
* As descriped in PKCS5, convert a password, salt, and iteration counter into a crypto key.
*
* @param password Password.
* @param password_len Length of password.
* @param salt Salt
* @param salt_len Length of salt.
* @param iter iteration counter.
* @param keylen the output key length.
* @param key the output key.
*
* @return 1 on success, non 1 on failure.
*
* @ingroup hcrypto_misc
*/
int
PKCS5_PBKDF2_HMAC_SHA1(const void * password, size_t password_len,
const void * salt, size_t salt_len,
unsigned long iter,
size_t keylen, void *key)
{
return PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, iter,
EVP_sha1(), keylen, key);
}

View File

@@ -107,24 +107,24 @@ test_pkcs5_pbe2(const struct tests *t)
unsigned char key[32];
int ret, error = 0;
ret = PKCS5_PBKDF2_HMAC_SHA1(t->password, strlen(t->password),
t->salt, strlen(t->salt),
t->iterations,
16, key);
ret = PKCS5_PBKDF2_HMAC(t->password, strlen(t->password),
t->salt, strlen(t->salt),
t->iterations, EVP_sha1(),
16, key);
if (ret != 1)
errx(1, "PKCS5_PBKDF2_HMAC_SHA1: %d", ret);
errx(1, "PKCS5_PBKDF2_HMAC: %d", ret);
if (memcmp(t->pbkdf2_128, key, 16) != 0) {
printf("incorrect 128 key\n");
error++;
}
ret = PKCS5_PBKDF2_HMAC_SHA1(t->password, strlen(t->password),
t->salt, strlen(t->salt),
t->iterations,
32, key);
ret = PKCS5_PBKDF2_HMAC(t->password, strlen(t->password),
t->salt, strlen(t->salt),
t->iterations, EVP_sha1(),
32, key);
if (ret != 1)
errx(1, "PKCS5_PBKDF2_HMAC_SHA1: %d", ret);
errx(1, "PKCS5_PBKDF2_HMAC: %d", ret);
if (memcmp(t->pbkdf2_256, key, 32) != 0) {
printf("incorrect 256 key\n");

View File

@@ -133,6 +133,7 @@
#undef EVP_sha256
#undef EVP_sha384
#undef EVP_sha512
#undef PKCS5_PBKDF2_HMAC
#undef PKCS5_PBKDF2_HMAC_SHA1
#undef EVP_BytesToKey
#undef EVP_get_cipherbyname

View File

@@ -261,6 +261,7 @@ HEIMDAL_CRYPTO_1.0 {
hc_OpenSSL_add_all_algorithms_conf;
hc_OpenSSL_add_all_algorithms_noconf;
hc_PKCS12_key_gen;
hc_PKCS5_PBKDF2_HMAC;
hc_PKCS5_PBKDF2_HMAC_SHA1;
hc_RAND_add;
hc_RAND_bytes;

View File

@@ -1,4 +1,3 @@
/*
* Copyright (c) 1997 - 2011 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -34,6 +33,21 @@
#include "hdb_locl.h"
struct hx509_certs_data;
struct krb5_pk_identity;
struct krb5_pk_cert;
struct ContentInfo;
struct AlgorithmIdentifier;
struct _krb5_krb_auth_data;
typedef struct krb5_pk_init_ctx_data *krb5_pk_init_ctx;
struct krb5_dh_moduli;
struct _krb5_key_data;
struct _krb5_encryption_type;
struct _krb5_key_type;
#include <pkinit_asn1.h>
#include <krb5-private.h>
#include <base64.h>
/*
* free all the memory used by (len, keys)
*/
@@ -168,9 +182,11 @@ parse_key_set(krb5_context context, const char *key,
/* if no salt was specified make up default salt */
if(salt->saltvalue.data == NULL) {
if(salt->salttype == KRB5_PW_SALT)
if(salt->salttype == KRB5_PW_SALT) {
ret = krb5_get_pw_salt(context, principal, salt);
else if(salt->salttype == KRB5_AFS3_SALT) {
if (ret)
return ret;
} else if(salt->salttype == KRB5_AFS3_SALT) {
krb5_const_realm realm = krb5_principal_get_realm(context, principal);
salt->saltvalue.data = strdup(realm);
if(salt->saltvalue.data == NULL) {
@@ -571,6 +587,41 @@ glob_rules_keys(krb5_context context, krb5_const_principal principal)
return NULL;
}
/*
* NIST guidance in Section 5.1 of [SP800-132] requires that a portion
* of the salt of at least 128 bits shall be randomly generated.
*/
static krb5_error_code
add_random_to_salt(krb5_context context, krb5_salt *in, krb5_salt *out)
{
krb5_error_code ret;
char *p;
unsigned char random[16];
char *s;
int slen;
krb5_generate_random_block(random, sizeof(random));
slen = rk_base64_encode(random, sizeof(random), &s);
if (slen < 0)
return ENOMEM;
ret = krb5_data_alloc(&out->saltvalue, slen + in->saltvalue.length);
if (ret) {
free(s);
return ret;
}
p = out->saltvalue.data;
memcpy(p, s, slen);
memcpy(&p[slen], in->saltvalue.data, in->saltvalue.length);
out->salttype = in->salttype;
free(s);
return 0;
}
/*
* Generate the `key_set' from the [kadmin]default_keys statement. If
* `no_salt' is set, salt is not important (and will not be set) since
@@ -642,6 +693,9 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
}
for (i = 0; i < num_enctypes; i++) {
krb5_salt *saltp = no_salt ? NULL : &salt;
krb5_salt rsalt;
/* find duplicates */
for (j = 0; j < *nkeyset; j++) {
@@ -660,14 +714,27 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
}
}
/* not a duplicate, lets add it */
if (j == *nkeyset) {
if (j < *nkeyset)
continue;
memset(&rsalt, 0, sizeof(rsalt));
/* prepend salt with randomness if required */
if (!no_salt &&
_krb5_enctype_requires_random_salt(context, enctypes[i])) {
saltp = &rsalt;
ret = add_random_to_salt(context, &salt, &rsalt);
}
if (ret == 0)
ret = add_enctype_to_key_set(&key_set, nkeyset, enctypes[i],
no_salt ? NULL : &salt);
if (ret) {
free(enctypes);
krb5_free_salt(context, salt);
goto out;
}
saltp);
krb5_free_salt(context, rsalt);
if (ret) {
free(enctypes);
krb5_free_salt(context, salt);
goto out;
}
}
free(enctypes);
@@ -718,17 +785,17 @@ hdb_generate_key_set_password(krb5_context context,
for (i = 0; i < (*num_keys); i++) {
krb5_salt salt;
Key *key = &(*keys)[i];
salt.salttype = (*keys)[i].salt->type;
salt.saltvalue.length = (*keys)[i].salt->salt.length;
salt.saltvalue.data = (*keys)[i].salt->salt.data;
salt.salttype = key->salt->type;
salt.saltvalue.length = key->salt->salt.length;
salt.saltvalue.data = key->salt->salt.data;
ret = krb5_string_to_key_salt (context,
(*keys)[i].key.keytype,
key->key.keytype,
password,
salt,
&(*keys)[i].key);
&key->key);
if(ret)
break;
}

View File

@@ -374,7 +374,7 @@ _hdb_set_master_key_usage(krb5_context context, HDB *db, unsigned int key_usage)
}
hdb_master_key
_hdb_find_master_key(uint32_t *mkvno, hdb_master_key mkey)
_hdb_find_master_key(int *mkvno, hdb_master_key mkey)
{
hdb_master_key ret = NULL;
while(mkey) {

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;