Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
  • Loading branch information
greghudson committed Oct 3, 2016
1 parent dc967ce commit 135a9ac
Show file tree
Hide file tree
Showing 18 changed files with 548 additions and 30 deletions.
20 changes: 12 additions & 8 deletions src/include/krb5/krb5.hin
Expand Up @@ -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
Expand All @@ -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*/
Expand Down
2 changes: 1 addition & 1 deletion src/lib/crypto/crypto_tests/t_derive.c
Expand Up @@ -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) {
Expand Down
9 changes: 9 additions & 0 deletions src/lib/crypto/krb/Makefile.in
Expand Up @@ -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 \
Expand All @@ -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 \
Expand All @@ -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 \
Expand All @@ -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) \
Expand All @@ -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) \
Expand All @@ -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) \
Expand All @@ -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 \
Expand All @@ -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 \
Expand All @@ -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 \
Expand Down
3 changes: 2 additions & 1 deletion src/lib/crypto/krb/checksum_dk_cmac.c
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/lib/crypto/krb/checksum_dk_hmac.c
Expand Up @@ -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;

Expand Down
65 changes: 65 additions & 0 deletions 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;
}
12 changes: 12 additions & 0 deletions src/lib/crypto/krb/cksumtypes.c
Expand Up @@ -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 =
Expand Down
5 changes: 3 additions & 2 deletions src/lib/crypto/krb/combine_keys.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
31 changes: 30 additions & 1 deletion src/lib/crypto/krb/crypto_int.h
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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 ***/

Expand Down Expand Up @@ -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 ***/

Expand Down

0 comments on commit 135a9ac

Please sign in to comment.