krb5 commit: Add aes-sha2 enctype support
Greg Hudson
ghudson at mit.edu
Mon Oct 3 16:02:42 EDT 2016
https://github.com/krb5/krb5/commit/135a9ac3c58b444998361a3b13f5decfdece2105
commit 135a9ac3c58b444998361a3b13f5decfdece2105
Author: Greg Hudson <ghudson at mit.edu>
Date: Sat Dec 5 19:36:57 2015 -0500
Add aes-sha2 enctype support
Add support to libk5crypto for the aes128-cts-hmac-sha256-128 and
aes256-cts-hmac-sha384-192 encryption types, and the
hmac-sha256-128-aes128 and hmac-sha384-192-aes256 checksum types.
Key derivation for the new encryption types uses a hash, so we need to
add a hash parameter to the krb5int_derive_ functions, which can be
null except when DERIVE_SP800_108_HMAC is given. Rename the helper
function derive_random_sp800_108_cmac() to
derive_random_sp800_108_feedback_cmac() to make it clear that feedback
mode is used, since the new enctype uses counter mode.
ticket: 8490
src/include/krb5/krb5.hin | 20 ++-
src/lib/crypto/crypto_tests/t_derive.c | 2 +-
src/lib/crypto/krb/Makefile.in | 9 +
src/lib/crypto/krb/checksum_dk_cmac.c | 3 +-
src/lib/crypto/krb/checksum_dk_hmac.c | 2 +-
src/lib/crypto/krb/checksum_etm.c | 65 ++++++++
src/lib/crypto/krb/cksumtypes.c | 12 ++
src/lib/crypto/krb/combine_keys.c | 5 +-
src/lib/crypto/krb/crypto_int.h | 31 ++++-
src/lib/crypto/krb/derive.c | 74 +++++++++-
src/lib/crypto/krb/enc_dk_cmac.c | 6 +-
src/lib/crypto/krb/enc_dk_hmac.c | 8 +-
src/lib/crypto/krb/enc_etm.c | 257 ++++++++++++++++++++++++++++++++
src/lib/crypto/krb/etypes.c | 21 +++
src/lib/crypto/krb/prf_aes2.c | 42 +++++
src/lib/crypto/krb/prf_cmac.c | 2 +-
src/lib/crypto/krb/prf_dk.c | 3 +-
src/lib/crypto/krb/s2k_pbkdf2.c | 16 ++-
18 files changed, 548 insertions(+), 30 deletions(-)
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 44c8bfa..64b0d0f 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -423,14 +423,16 @@ typedef struct _krb5_crypto_iov {
#define ENCTYPE_RSA_ES_OAEP_ENV 0x000e /**< RSA w/OEAP encryption, CMS enveloped data */
#define ENCTYPE_DES3_CBC_ENV 0x000f /**< DES-3 cbc mode, CMS enveloped data */
-#define ENCTYPE_DES3_CBC_SHA1 0x0010
-#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011 /**< RFC 3962 */
-#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012 /**< RFC 3962 */
-#define ENCTYPE_ARCFOUR_HMAC 0x0017
-#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
-#define ENCTYPE_CAMELLIA128_CTS_CMAC 0x0019 /**< RFC 6803 */
-#define ENCTYPE_CAMELLIA256_CTS_CMAC 0x001a /**< RFC 6803 */
-#define ENCTYPE_UNKNOWN 0x01ff
+#define ENCTYPE_DES3_CBC_SHA1 0x0010
+#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011 /**< RFC 3962 */
+#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012 /**< RFC 3962 */
+#define ENCTYPE_AES128_CTS_HMAC_SHA256_128 0x0013
+#define ENCTYPE_AES256_CTS_HMAC_SHA384_192 0x0014
+#define ENCTYPE_ARCFOUR_HMAC 0x0017
+#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
+#define ENCTYPE_CAMELLIA128_CTS_CMAC 0x0019 /**< RFC 6803 */
+#define ENCTYPE_CAMELLIA256_CTS_CMAC 0x001a /**< RFC 6803 */
+#define ENCTYPE_UNKNOWN 0x01ff
#define CKSUMTYPE_CRC32 0x0001
#define CKSUMTYPE_RSA_MD4 0x0002
@@ -446,6 +448,8 @@ typedef struct _krb5_crypto_iov {
ENCTYPE_AES128_CTS_HMAC_SHA1_96 */
#define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010 /**< RFC 3962. Used with
ENCTYPE_AES256_CTS_HMAC_SHA1_96 */
+#define CKSUMTYPE_HMAC_SHA256_128_AES128 0x0013
+#define CKSUMTYPE_HMAC_SHA384_192_AES256 0x0014
#define CKSUMTYPE_CMAC_CAMELLIA128 0x0011 /**< RFC 6803 */
#define CKSUMTYPE_CMAC_CAMELLIA256 0x0012 /**< RFC 6803 */
#define CKSUMTYPE_MD5_HMAC_ARCFOUR -137 /*Microsoft netlogon cksumtype*/
diff --git a/src/lib/crypto/crypto_tests/t_derive.c b/src/lib/crypto/crypto_tests/t_derive.c
index fe28751..f8c3291 100644
--- a/src/lib/crypto/crypto_tests/t_derive.c
+++ b/src/lib/crypto/crypto_tests/t_derive.c
@@ -259,7 +259,7 @@ main(int argc, char **argv)
ret = krb5_k_create_key(context, &kb, &inkey);
assert(!ret);
enc = get_enc_provider(test->enctype);
- ret = krb5int_derive_key(enc, inkey, &outkey, &test->constant,
+ ret = krb5int_derive_key(enc, NULL, inkey, &outkey, &test->constant,
test->alg);
assert(!ret);
if (verbose) {
diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in
index 7b59839..c5660c5 100644
--- a/src/lib/crypto/krb/Makefile.in
+++ b/src/lib/crypto/krb/Makefile.in
@@ -14,6 +14,7 @@ STLIBOBJS=\
checksum_confounder.o \
checksum_dk_cmac.o \
checksum_dk_hmac.o \
+ checksum_etm.o \
checksum_hmac_md5.o \
checksum_unkeyed.o \
checksum_length.o \
@@ -35,6 +36,7 @@ STLIBOBJS=\
enctype_util.o \
enc_dk_cmac.o \
enc_dk_hmac.o \
+ enc_etm.o \
enc_old.o \
enc_raw.o \
enc_rc4.o \
@@ -51,6 +53,7 @@ STLIBOBJS=\
nfold.o \
old_api_glue.o \
prf.o \
+ prf_aes2.o \
prf_cmac.o \
prf_des.o \
prf_dk.o \
@@ -76,6 +79,7 @@ OBJS=\
$(OUTPRE)checksum_confounder.$(OBJEXT) \
$(OUTPRE)checksum_dk_cmac.$(OBJEXT) \
$(OUTPRE)checksum_dk_hmac.$(OBJEXT) \
+ $(OUTPRE)checksum_etm.$(OBJEXT) \
$(OUTPRE)checksum_hmac_md5.$(OBJEXT) \
$(OUTPRE)checksum_unkeyed.$(OBJEXT) \
$(OUTPRE)checksum_length.$(OBJEXT) \
@@ -97,6 +101,7 @@ OBJS=\
$(OUTPRE)enctype_util.$(OBJEXT) \
$(OUTPRE)enc_dk_cmac.$(OBJEXT) \
$(OUTPRE)enc_dk_hmac.$(OBJEXT) \
+ $(OUTPRE)enc_etm.$(OBJEXT) \
$(OUTPRE)enc_old.$(OBJEXT) \
$(OUTPRE)enc_raw.$(OBJEXT) \
$(OUTPRE)enc_rc4.$(OBJEXT) \
@@ -113,6 +118,7 @@ OBJS=\
$(OUTPRE)nfold.$(OBJEXT) \
$(OUTPRE)old_api_glue.$(OBJEXT) \
$(OUTPRE)prf.$(OBJEXT) \
+ $(OUTPRE)prf_aes2.$(OBJEXT) \
$(OUTPRE)prf_cmac.$(OBJEXT) \
$(OUTPRE)prf_des.$(OBJEXT) \
$(OUTPRE)prf_dk.$(OBJEXT) \
@@ -138,6 +144,7 @@ SRCS=\
$(srcdir)/checksum_confounder.c \
$(srcdir)/checksum_dk_cmac.c \
$(srcdir)/checksum_dk_hmac.c \
+ $(srcdir)/checksum_etm.c \
$(srcdir)/checksum_hmac_md5.c \
$(srcdir)/checksum_unkeyed.c \
$(srcdir)/checksum_length.c \
@@ -159,6 +166,7 @@ SRCS=\
$(srcdir)/enctype_util.c \
$(srcdir)/enc_dk_cmac.c \
$(srcdir)/enc_dk_hmac.c \
+ $(srcdir)/enc_etm.c \
$(srcdir)/enc_old.c \
$(srcdir)/enc_raw.c \
$(srcdir)/enc_rc4.c \
@@ -175,6 +183,7 @@ SRCS=\
$(srcdir)/nfold.c \
$(srcdir)/old_api_glue.c \
$(srcdir)/prf.c \
+ $(srcdir)/prf_aes2.c \
$(srcdir)/prf_cmac.c \
$(srcdir)/prf_des.c \
$(srcdir)/prf_dk.c \
diff --git a/src/lib/crypto/krb/checksum_dk_cmac.c b/src/lib/crypto/krb/checksum_dk_cmac.c
index 59d5c5a..809f9d7 100644
--- a/src/lib/crypto/krb/checksum_dk_cmac.c
+++ b/src/lib/crypto/krb/checksum_dk_cmac.c
@@ -44,7 +44,8 @@ krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp,
datain = make_data(constantdata, K5CLENGTH);
store_32_be(usage, constantdata);
constantdata[4] = (char) 0x99;
- ret = krb5int_derive_key(enc, key, &kc, &datain, DERIVE_SP800_108_CMAC);
+ ret = krb5int_derive_key(enc, NULL, key, &kc, &datain,
+ DERIVE_SP800_108_CMAC);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/krb/checksum_dk_hmac.c b/src/lib/crypto/krb/checksum_dk_hmac.c
index 517a5f3..64ab899 100644
--- a/src/lib/crypto/krb/checksum_dk_hmac.c
+++ b/src/lib/crypto/krb/checksum_dk_hmac.c
@@ -45,7 +45,7 @@ krb5int_dk_checksum(const struct krb5_cksumtypes *ctp,
datain = make_data(constantdata, K5CLENGTH);
store_32_be(usage, constantdata);
constantdata[4] = (char) 0x99;
- ret = krb5int_derive_key(enc, key, &kc, &datain, DERIVE_RFC3961);
+ ret = krb5int_derive_key(enc, NULL, key, &kc, &datain, DERIVE_RFC3961);
if (ret)
return ret;
diff --git a/src/lib/crypto/krb/checksum_etm.c b/src/lib/crypto/krb/checksum_etm.c
new file mode 100644
index 0000000..eaa85b2
--- /dev/null
+++ b/src/lib/crypto/krb/checksum_etm.c
@@ -0,0 +1,65 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/krb/checksum_etm.c - checksum for encrypt-then-mac enctypes */
+/*
+ * Copyright (C) 2015 by the Massachusetts Institute of Technology.
+ * 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 "crypto_int.h"
+
+krb5_error_code
+krb5int_etm_checksum(const struct krb5_cksumtypes *ctp, krb5_key key,
+ krb5_keyusage usage, const krb5_crypto_iov *data,
+ size_t num_data, krb5_data *output)
+{
+ krb5_error_code ret;
+ uint8_t label[5];
+ krb5_data label_data = make_data(label, 5), kc = empty_data();
+ krb5_keyblock kb = { 0 };
+
+ /* Derive the checksum key. */
+ store_32_be(usage, label);
+ label[4] = 0x99;
+ label_data = make_data(label, 5);
+ ret = alloc_data(&kc, ctp->hash->hashsize / 2);
+ if (ret)
+ goto cleanup;
+ ret = krb5int_derive_random(ctp->enc, ctp->hash, key, &kc, &label_data,
+ DERIVE_SP800_108_HMAC);
+ if (ret)
+ goto cleanup;
+
+ /* Compute an HMAC with kc over the data. */
+ kb.length = kc.length;
+ kb.contents = (uint8_t *)kc.data;
+ ret = krb5int_hmac_keyblock(ctp->hash, &kb, data, num_data, output);
+
+cleanup:
+ zapfree(kc.data, kc.length);
+ return ret;
+}
diff --git a/src/lib/crypto/krb/cksumtypes.c b/src/lib/crypto/krb/cksumtypes.c
index a1ced98..85967f9 100644
--- a/src/lib/crypto/krb/cksumtypes.c
+++ b/src/lib/crypto/krb/cksumtypes.c
@@ -112,6 +112,18 @@ const struct krb5_cksumtypes krb5int_cksumtypes_list[] = {
&krb5int_enc_camellia256, NULL,
krb5int_dk_cmac_checksum, NULL,
16, 16, 0 },
+
+ { CKSUMTYPE_HMAC_SHA256_128_AES128,
+ "hmac-sha256-128-aes128", { 0 }, "HMAC-SHA256 AES128 key",
+ &krb5int_enc_aes128, &krb5int_hash_sha256,
+ krb5int_etm_checksum, NULL,
+ 32, 16, 0 },
+
+ { CKSUMTYPE_HMAC_SHA384_192_AES256,
+ "hmac-sha384-192-aes256", { 0 }, "HMAC-SHA384 AES256 key",
+ &krb5int_enc_aes256, &krb5int_hash_sha384,
+ krb5int_etm_checksum, NULL,
+ 48, 24, 0 },
};
const size_t krb5int_cksumtypes_length =
diff --git a/src/lib/crypto/krb/combine_keys.c b/src/lib/crypto/krb/combine_keys.c
index 9ab0ac4..90905c5 100644
--- a/src/lib/crypto/krb/combine_keys.c
+++ b/src/lib/crypto/krb/combine_keys.c
@@ -191,7 +191,8 @@ krb5int_c_combine_keys(krb5_context context, krb5_keyblock *key1,
myalloc = TRUE;
}
- ret = krb5int_derive_keyblock(enc, tkey, outkey, &input, DERIVE_RFC3961);
+ ret = krb5int_derive_keyblock(enc, NULL, tkey, outkey, &input,
+ DERIVE_RFC3961);
if (ret) {
if (myalloc) {
free(outkey->contents);
@@ -222,7 +223,7 @@ dr(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey,
ret = krb5_k_create_key(NULL, inkey, &key);
if (ret != 0)
return ret;
- ret = krb5int_derive_random(enc, key, &outdata, in_constant,
+ ret = krb5int_derive_random(enc, NULL, key, &outdata, in_constant,
DERIVE_RFC3961);
krb5_k_free_key(NULL, key);
return ret;
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index fec0eab..d75b49c 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -184,6 +184,8 @@ unsigned int krb5int_aes_crypto_length(const struct krb5_keytypes *ktp,
krb5_cryptotype type);
unsigned int krb5int_camellia_crypto_length(const struct krb5_keytypes *ktp,
krb5_cryptotype type);
+unsigned int krb5int_aes2_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type);
/* Encrypt */
krb5_error_code krb5int_old_encrypt(const struct krb5_keytypes *ktp,
@@ -208,6 +210,10 @@ krb5_error_code krb5int_dk_cmac_encrypt(const struct krb5_keytypes *ktp,
const krb5_data *ivec,
krb5_crypto_iov *data,
size_t num_data);
+krb5_error_code krb5int_etm_encrypt(const struct krb5_keytypes *ktp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data);
/* Decrypt */
krb5_error_code krb5int_old_decrypt(const struct krb5_keytypes *ktp,
@@ -232,6 +238,10 @@ krb5_error_code krb5int_dk_cmac_decrypt(const struct krb5_keytypes *ktp,
const krb5_data *ivec,
krb5_crypto_iov *data,
size_t num_data);
+krb5_error_code krb5int_etm_decrypt(const struct krb5_keytypes *ktp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data);
/* String to key */
krb5_error_code krb5int_des_string_to_key(const struct krb5_keytypes *ktp,
@@ -259,6 +269,11 @@ krb5_error_code krb5int_camellia_string_to_key(const struct krb5_keytypes *enc,
const krb5_data *salt,
const krb5_data *params,
krb5_keyblock *key);
+krb5_error_code krb5int_aes2_string_to_key(const struct krb5_keytypes *enc,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key);
/* Random to key */
krb5_error_code k5_rand2key_direct(const krb5_data *randombits,
@@ -280,6 +295,8 @@ krb5_error_code krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key,
krb5_error_code krb5int_dk_cmac_prf(const struct krb5_keytypes *ktp,
krb5_key key, const krb5_data *in,
krb5_data *out);
+krb5_error_code krb5int_aes2_prf(const struct krb5_keytypes *ktp, krb5_key key,
+ const krb5_data *in, krb5_data *out);
/*** Prototypes for cksumtype handler functions ***/
@@ -317,26 +334,38 @@ krb5_error_code krb5int_confounder_verify(const struct krb5_cksumtypes *ctp,
size_t num_data,
const krb5_data *input,
krb5_boolean *valid);
+krb5_error_code krb5int_etm_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data,
+ size_t num_data, krb5_data *output);
/*** Key derivation functions ***/
enum deriv_alg {
DERIVE_RFC3961, /* RFC 3961 section 5.1 */
- DERIVE_SP800_108_CMAC /* NIST SP 800-108 with CMAC as PRF */
+ DERIVE_SP800_108_CMAC, /* NIST SP 800-108 with CMAC as PRF */
+ DERIVE_SP800_108_HMAC /* NIST SP 800-108 with HMAC as PRF */
};
krb5_error_code krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_keyblock *outkey,
const krb5_data *in_constant,
enum deriv_alg alg);
krb5_error_code krb5int_derive_key(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_key *outkey,
const krb5_data *in_constant,
enum deriv_alg alg);
krb5_error_code krb5int_derive_random(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_data *outrnd,
const krb5_data *in_constant,
enum deriv_alg alg);
+krb5_error_code
+k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *label, const krb5_data *context);
/*** Miscellaneous prototypes ***/
diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
index f15fec1..6707a73 100644
--- a/src/lib/crypto/krb/derive.c
+++ b/src/lib/crypto/krb/derive.c
@@ -139,9 +139,9 @@ cleanup:
* - Four bytes are used to encode the output length in the PRF input.
*/
static krb5_error_code
-derive_random_sp800_108_cmac(const struct krb5_enc_provider *enc,
- krb5_key inkey, krb5_data *outrnd,
- const krb5_data *in_constant)
+derive_random_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *in_constant)
{
size_t blocksize, keybytes, n;
krb5_crypto_iov iov[6];
@@ -204,16 +204,75 @@ cleanup:
return ret;
}
+/*
+ * NIST SP800-108 KDF in counter mode (section 5.1).
+ * Parameters:
+ * - HMAC (with hash as the hash provider) is the PRF.
+ * - A block counter of four bytes is used.
+ * - Four bytes are used to encode the output length in the PRF input.
+ *
+ * There are no uses requiring more than a single PRF invocation.
+ */
+krb5_error_code
+k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *label, const krb5_data *context)
+{
+ krb5_crypto_iov iov[5];
+ krb5_error_code ret;
+ krb5_data prf;
+ unsigned char ibuf[4], lbuf[4];
+
+ if (hash == NULL || outrnd->length > hash->hashsize)
+ return KRB5_CRYPTO_INTERNAL;
+
+ /* Allocate encryption data buffer. */
+ ret = alloc_data(&prf, hash->hashsize);
+ if (ret)
+ return ret;
+
+ /* [i]2: four-byte big-endian binary string giving the block counter (1) */
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[0].data = make_data(ibuf, sizeof(ibuf));
+ store_32_be(1, ibuf);
+ /* Label */
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[1].data = *label;
+ /* 0x00: separator byte */
+ iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[2].data = make_data("", 1);
+ /* Context */
+ iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[3].data = *context;
+ /* [L]2: four-byte big-endian binary string giving the output length */
+ iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[4].data = make_data(lbuf, sizeof(lbuf));
+ store_32_be(outrnd->length * 8, lbuf);
+
+ ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
+ if (!ret)
+ memcpy(outrnd->data, prf.data, outrnd->length);
+ zapfree(prf.data, prf.length);
+ return ret;
+}
+
krb5_error_code
krb5int_derive_random(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_data *outrnd,
const krb5_data *in_constant, enum deriv_alg alg)
{
+ krb5_data empty = empty_data();
+
switch (alg) {
case DERIVE_RFC3961:
return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
case DERIVE_SP800_108_CMAC:
- return derive_random_sp800_108_cmac(enc, inkey, outrnd, in_constant);
+ return derive_random_sp800_108_feedback_cmac(enc, inkey, outrnd,
+ in_constant);
+ case DERIVE_SP800_108_HMAC:
+ return k5_sp800_108_counter_hmac(hash, inkey, outrnd, in_constant,
+ &empty);
default:
return EINVAL;
}
@@ -227,6 +286,7 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
*/
krb5_error_code
krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_keyblock *outkey,
const krb5_data *in_constant, enum deriv_alg alg)
{
@@ -239,7 +299,7 @@ krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
goto cleanup;
/* Derive pseudo-random data for the key bytes. */
- ret = krb5int_derive_random(enc, inkey, &rawkey, in_constant, alg);
+ ret = krb5int_derive_random(enc, hash, inkey, &rawkey, in_constant, alg);
if (ret)
goto cleanup;
@@ -253,6 +313,7 @@ cleanup:
krb5_error_code
krb5int_derive_key(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_key *outkey,
const krb5_data *in_constant, enum deriv_alg alg)
{
@@ -275,7 +336,8 @@ krb5int_derive_key(const struct krb5_enc_provider *enc,
keyblock.enctype = inkey->keyblock.enctype;
if (keyblock.contents == NULL)
return ENOMEM;
- ret = krb5int_derive_keyblock(enc, inkey, &keyblock, in_constant, alg);
+ ret = krb5int_derive_keyblock(enc, hash, inkey, &keyblock, in_constant,
+ alg);
if (ret)
goto cleanup;
diff --git a/src/lib/crypto/krb/enc_dk_cmac.c b/src/lib/crypto/krb/enc_dk_cmac.c
index 9bb3dba..b65b9b7 100644
--- a/src/lib/crypto/krb/enc_dk_cmac.c
+++ b/src/lib/crypto/krb/enc_dk_cmac.c
@@ -64,13 +64,15 @@ derive_keys(const struct krb5_enc_provider *enc, krb5_key key,
/* Derive the encryption key. */
store_32_be(usage, buf);
buf[4] = 0xAA;
- ret = krb5int_derive_key(enc, key, &ke, &constant, DERIVE_SP800_108_CMAC);
+ ret = krb5int_derive_key(enc, NULL, key, &ke, &constant,
+ DERIVE_SP800_108_CMAC);
if (ret != 0)
return ret;
/* Derive the integrity key. */
buf[4] = 0x55;
- ret = krb5int_derive_key(enc, key, &ki, &constant, DERIVE_SP800_108_CMAC);
+ ret = krb5int_derive_key(enc, NULL, key, &ki, &constant,
+ DERIVE_SP800_108_CMAC);
if (ret != 0) {
krb5_k_free_key(NULL, ke);
return ret;
diff --git a/src/lib/crypto/krb/enc_dk_hmac.c b/src/lib/crypto/krb/enc_dk_hmac.c
index f16459e..713044c 100644
--- a/src/lib/crypto/krb/enc_dk_hmac.c
+++ b/src/lib/crypto/krb/enc_dk_hmac.c
@@ -131,13 +131,13 @@ krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
d1.data[4] = 0xAA;
- ret = krb5int_derive_key(enc, key, &ke, &d1, DERIVE_RFC3961);
+ ret = krb5int_derive_key(enc, NULL, key, &ke, &d1, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
d1.data[4] = 0x55;
- ret = krb5int_derive_key(enc, key, &ki, &d1, DERIVE_RFC3961);
+ ret = krb5int_derive_key(enc, NULL, key, &ki, &d1, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
@@ -232,13 +232,13 @@ krb5int_dk_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
d1.data[4] = 0xAA;
- ret = krb5int_derive_key(enc, key, &ke, &d1, DERIVE_RFC3961);
+ ret = krb5int_derive_key(enc, NULL, key, &ke, &d1, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
d1.data[4] = 0x55;
- ret = krb5int_derive_key(enc, key, &ki, &d1, DERIVE_RFC3961);
+ ret = krb5int_derive_key(enc, NULL, key, &ki, &d1, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
diff --git a/src/lib/crypto/krb/enc_etm.c b/src/lib/crypto/krb/enc_etm.c
new file mode 100644
index 0000000..3135dd5
--- /dev/null
+++ b/src/lib/crypto/krb/enc_etm.c
@@ -0,0 +1,257 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/krb/enc_etm.c - encrypt-then-mac construction for aes-sha2 */
+/*
+ * Copyright (C) 2015 by the Massachusetts Institute of Technology.
+ * 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 "crypto_int.h"
+
+unsigned int
+krb5int_aes2_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type)
+{
+ switch (type) {
+ case KRB5_CRYPTO_TYPE_HEADER:
+ return ktp->enc->block_size;
+ case KRB5_CRYPTO_TYPE_PADDING:
+ return 0;
+ case KRB5_CRYPTO_TYPE_TRAILER:
+ case KRB5_CRYPTO_TYPE_CHECKSUM:
+ return ktp->hash->hashsize / 2;
+ default:
+ assert(0 && "invalid cryptotype passed to krb5int_aes2_crypto_length");
+ return 0;
+ }
+}
+
+/* Derive encryption and integrity keys for CMAC-using enctypes. */
+static krb5_error_code
+derive_keys(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, krb5_key *ke_out, krb5_data *ki_out)
+{
+ krb5_error_code ret;
+ uint8_t label[5];
+ krb5_data label_data = make_data(label, 5), ki = empty_data();
+ krb5_key ke = NULL;
+
+ *ke_out = NULL;
+ *ki_out = empty_data();
+
+ /* Derive the encryption key. */
+ store_32_be(usage, label);
+ label[4] = 0xAA;
+ ret = krb5int_derive_key(ktp->enc, ktp->hash, key, &ke, &label_data,
+ DERIVE_SP800_108_HMAC);
+ if (ret)
+ goto cleanup;
+
+ /* Derive the integrity key. */
+ label[4] = 0x55;
+ ret = alloc_data(&ki, ktp->hash->hashsize / 2);
+ if (ret)
+ goto cleanup;
+ ret = krb5int_derive_random(NULL, ktp->hash, key, &ki, &label_data,
+ DERIVE_SP800_108_HMAC);
+ if (ret)
+ goto cleanup;
+
+ *ke_out = ke;
+ ke = NULL;
+ *ki_out = ki;
+ ki = empty_data();
+
+cleanup:
+ krb5_k_free_key(NULL, ke);
+ zapfree(ki.data, ki.length);
+ return ret;
+}
+
+/* Compute an HMAC checksum over the cipher state and data. Allocate enough
+ * space in *out for the checksum. */
+static krb5_error_code
+hmac_ivec_data(const struct krb5_keytypes *ktp, const krb5_data *ki,
+ const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data,
+ krb5_data *out)
+{
+ krb5_error_code ret;
+ krb5_data zeroivec = empty_data();
+ krb5_crypto_iov *iovs = NULL;
+ krb5_keyblock kb = { 0 };
+
+ if (ivec == NULL) {
+ ret = ktp->enc->init_state(NULL, 0, &zeroivec);
+ if (ret)
+ goto cleanup;
+ ivec = &zeroivec;
+ }
+
+ /* Make a copy of data with an extra iov at the beginning for the ivec. */
+ iovs = k5calloc(num_data + 1, sizeof(*iovs), &ret);
+ if (iovs == NULL)
+ goto cleanup;
+ iovs[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ iovs[0].data = *ivec;
+ memcpy(iovs + 1, data, num_data * sizeof(*iovs));
+
+ ret = alloc_data(out, ktp->hash->hashsize);
+ if (ret)
+ goto cleanup;
+ kb.length = ki->length;
+ kb.contents = (uint8_t *)ki->data;
+ ret = krb5int_hmac_keyblock(ktp->hash, &kb, iovs, num_data + 1, out);
+
+cleanup:
+ if (zeroivec.data != NULL)
+ ktp->enc->free_state(&zeroivec);
+ free(iovs);
+ return ret;
+}
+
+krb5_error_code
+krb5int_etm_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ krb5_error_code ret;
+ krb5_data ivcopy = empty_data(), cksum = empty_data();
+ krb5_crypto_iov *header, *trailer, *padding;
+ krb5_key ke = NULL;
+ krb5_data ki = empty_data();
+ unsigned int trailer_len;
+
+ /* E(Confounder | Plaintext) | Checksum(IV | ciphertext) */
+
+ trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
+
+ /* Validate header and trailer lengths, and zero out padding length. */
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL || header->data.length < enc->block_size)
+ return KRB5_BAD_MSIZE;
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer == NULL || trailer->data.length < trailer_len)
+ return KRB5_BAD_MSIZE;
+ padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
+ if (padding != NULL)
+ padding->data.length = 0;
+
+ if (ivec != NULL) {
+ ret = alloc_data(&ivcopy, ivec->length);
+ if (ret)
+ goto cleanup;
+ memcpy(ivcopy.data, ivec->data, ivec->length);
+ }
+
+ /* Derive the encryption and integrity keys. */
+ ret = derive_keys(ktp, key, usage, &ke, &ki);
+ if (ret)
+ goto cleanup;
+
+ /* Generate confounder. */
+ header->data.length = enc->block_size;
+ ret = krb5_c_random_make_octets(NULL, &header->data);
+ if (ret)
+ goto cleanup;
+
+ /* Encrypt the plaintext (header | data). */
+ ret = enc->encrypt(ke, (ivec == NULL) ? NULL : &ivcopy, data, num_data);
+ if (ret)
+ goto cleanup;
+
+ /* HMAC the IV, confounder, and ciphertext with sign-only data. */
+ ret = hmac_ivec_data(ktp, &ki, ivec, data, num_data, &cksum);
+ if (ret)
+ goto cleanup;
+
+ /* Truncate the HMAC checksum to the trailer length. */
+ assert(trailer_len <= cksum.length);
+ memcpy(trailer->data.data, cksum.data, trailer_len);
+ trailer->data.length = trailer_len;
+
+ /* Copy out the updated ivec if desired. */
+ if (ivec != NULL)
+ memcpy(ivec->data, ivcopy.data, ivcopy.length);
+
+cleanup:
+ krb5_k_free_key(NULL, ke);
+ zapfree(ki.data, ki.length);
+ free(cksum.data);
+ zapfree(ivcopy.data, ivcopy.length);
+ return ret;
+}
+
+krb5_error_code
+krb5int_etm_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ krb5_error_code ret;
+ krb5_data cksum = empty_data();
+ krb5_crypto_iov *header, *trailer;
+ krb5_key ke = NULL;
+ krb5_data ki = empty_data();
+ unsigned int trailer_len;
+
+ trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
+
+ /* Validate header and trailer lengths. */
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL || header->data.length != enc->block_size)
+ return KRB5_BAD_MSIZE;
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer == NULL || trailer->data.length != trailer_len)
+ return KRB5_BAD_MSIZE;
+
+ /* Derive the encryption and integrity keys. */
+ ret = derive_keys(ktp, key, usage, &ke, &ki);
+ if (ret)
+ goto cleanup;
+
+ /* HMAC the IV, confounder, and ciphertext with sign-only data. */
+ ret = hmac_ivec_data(ktp, &ki, ivec, data, num_data, &cksum);
+ if (ret)
+ goto cleanup;
+
+ /* Compare only the possibly truncated length. */
+ assert(trailer_len <= cksum.length);
+ if (k5_bcmp(cksum.data, trailer->data.data, trailer_len) != 0) {
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ goto cleanup;
+ }
+
+ /* Decrypt the ciphertext (header | data | padding). */
+ ret = enc->decrypt(ke, ivec, data, num_data);
+
+cleanup:
+ krb5_k_free_key(NULL, ke);
+ zapfree(ki.data, ki.length);
+ zapfree(cksum.data, cksum.length);
+ return ret;
+}
diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c
index 53be1d5..112ae08 100644
--- a/src/lib/crypto/krb/etypes.c
+++ b/src/lib/crypto/krb/etypes.c
@@ -167,6 +167,27 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_cmac_prf,
CKSUMTYPE_CMAC_CAMELLIA256,
0 /*flags */ },
+
+ { ENCTYPE_AES128_CTS_HMAC_SHA256_128,
+ "aes128-cts-hmac-sha256-128", { "aes128-sha2" },
+ "AES-128 CTS mode with 128-bit SHA-256 HMAC",
+ &krb5int_enc_aes128, &krb5int_hash_sha256,
+ 32,
+ krb5int_aes2_crypto_length, krb5int_etm_encrypt, krb5int_etm_decrypt,
+ krb5int_aes2_string_to_key, k5_rand2key_direct,
+ krb5int_aes2_prf,
+ CKSUMTYPE_HMAC_SHA256_128_AES128,
+ 0 /*flags*/ },
+ { ENCTYPE_AES256_CTS_HMAC_SHA384_192,
+ "aes256-cts-hmac-sha384-192", { "aes256-sha2" },
+ "AES-256 CTS mode with 192-bit SHA-384 HMAC",
+ &krb5int_enc_aes256, &krb5int_hash_sha384,
+ 48,
+ krb5int_aes2_crypto_length, krb5int_etm_encrypt, krb5int_etm_decrypt,
+ krb5int_aes2_string_to_key, k5_rand2key_direct,
+ krb5int_aes2_prf,
+ CKSUMTYPE_HMAC_SHA384_192_AES256,
+ 0 /*flags*/ },
};
const int krb5int_enctypes_length =
diff --git a/src/lib/crypto/krb/prf_aes2.c b/src/lib/crypto/krb/prf_aes2.c
new file mode 100644
index 0000000..9a5cffc
--- /dev/null
+++ b/src/lib/crypto/krb/prf_aes2.c
@@ -0,0 +1,42 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/krb/prf_aes2.c - PRF for aes-sha2 enctypes */
+/*
+ * Copyright (C) 2015 by the Massachusetts Institute of Technology.
+ * 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 "crypto_int.h"
+
+krb5_error_code
+krb5int_aes2_prf(const struct krb5_keytypes *ktp, krb5_key key,
+ const krb5_data *in, krb5_data *out)
+{
+ krb5_data label = string2data("prf");
+
+ return k5_sp800_108_counter_hmac(ktp->hash, key, out, &label, in);
+}
diff --git a/src/lib/crypto/krb/prf_cmac.c b/src/lib/crypto/krb/prf_cmac.c
index 131c36d..1d4cc4c 100644
--- a/src/lib/crypto/krb/prf_cmac.c
+++ b/src/lib/crypto/krb/prf_cmac.c
@@ -42,7 +42,7 @@ krb5int_dk_cmac_prf(const struct krb5_keytypes *ktp, krb5_key key,
iov.data = *in;
/* Derive a key using the PRF constant. */
- ret = krb5int_derive_key(ktp->enc, key, &kp, &prfconst,
+ ret = krb5int_derive_key(ktp->enc, NULL, key, &kp, &prfconst,
DERIVE_SP800_108_CMAC);
if (ret != 0)
goto cleanup;
diff --git a/src/lib/crypto/krb/prf_dk.c b/src/lib/crypto/krb/prf_dk.c
index bf8d522..544418b 100644
--- a/src/lib/crypto/krb/prf_dk.c
+++ b/src/lib/crypto/krb/prf_dk.c
@@ -48,7 +48,8 @@ krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key,
goto cleanup;
/* Derive a key using the PRF constant. */
- ret = krb5int_derive_key(ktp->enc, key, &kp, &prfconst, DERIVE_RFC3961);
+ ret = krb5int_derive_key(ktp->enc, NULL, key, &kp, &prfconst,
+ DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
diff --git a/src/lib/crypto/krb/s2k_pbkdf2.c b/src/lib/crypto/krb/s2k_pbkdf2.c
index 316f59a..ec5856c 100644
--- a/src/lib/crypto/krb/s2k_pbkdf2.c
+++ b/src/lib/crypto/krb/s2k_pbkdf2.c
@@ -87,7 +87,7 @@ krb5int_dk_string_to_key(const struct krb5_keytypes *ktp,
indata.length = kerberos_len;
indata.data = (char *) kerberos;
- ret = krb5int_derive_keyblock(ktp->enc, foldkey, keyblock, &indata,
+ ret = krb5int_derive_keyblock(ktp->enc, NULL, foldkey, keyblock, &indata,
DERIVE_RFC3961);
if (ret != 0)
memset(keyblock->contents, 0, keyblock->length);
@@ -168,7 +168,8 @@ pbkdf2_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string,
if (err)
goto cleanup;
- err = krb5int_derive_keyblock(ktp->enc, tempkey, key, &usage, deriv_alg);
+ err = krb5int_derive_keyblock(ktp->enc, ktp->hash, tempkey, key, &usage,
+ deriv_alg);
cleanup:
if (sandp.data)
@@ -202,3 +203,14 @@ krb5int_camellia_string_to_key(const struct krb5_keytypes *ktp,
return pbkdf2_string_to_key(ktp, string, salt, &pepper, params, key,
DERIVE_SP800_108_CMAC, 32768);
}
+
+krb5_error_code
+krb5int_aes2_string_to_key(const struct krb5_keytypes *ktp,
+ const krb5_data *string, const krb5_data *salt,
+ const krb5_data *params, krb5_keyblock *key)
+{
+ krb5_data pepper = string2data(ktp->name);
+
+ return pbkdf2_string_to_key(ktp, string, salt, &pepper, params, key,
+ DERIVE_SP800_108_HMAC, 32768);
+}
More information about the cvs-krb5
mailing list