aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-08-02 03:49:54 +0000
committerGreg Hudson <ghudson@mit.edu>2010-08-02 03:49:54 +0000
commit6a6092fe00b799ab172d28233e77452a5ef43328 (patch)
tree4d1a873d43deaf4c80ec736e8e9df47e392c7325
parentf45f4fb0a07c68643bc5164f839a2b4331c219b6 (diff)
downloadkrb5-6a6092fe00b799ab172d28233e77452a5ef43328.zip
krb5-6a6092fe00b799ab172d28233e77452a5ef43328.tar.gz
krb5-6a6092fe00b799ab172d28233e77452a5ef43328.tar.bz2
Parameterize krb5int_derive_random() instead of guessing which
algorithm to use based on the enc provider methods. Add an encrypt_block() helper function, since the introduce of counter-mode enc providers makes it a little trickier to do simple block encryption. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/camellia-ccm@24223 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/builtin/enc_provider/camellia_ctr.c4
-rw-r--r--src/lib/crypto/crypto_tests/vectors.c4
-rw-r--r--src/lib/crypto/krb/checksum/cmac.c9
-rw-r--r--src/lib/crypto/krb/combine_keys.c5
-rw-r--r--src/lib/crypto/krb/dk/checksum_cmac.c2
-rw-r--r--src/lib/crypto/krb/dk/checksum_hmac.c2
-rw-r--r--src/lib/crypto/krb/dk/derive.c46
-rw-r--r--src/lib/crypto/krb/dk/dk.h25
-rw-r--r--src/lib/crypto/krb/dk/dk_aead.c8
-rw-r--r--src/lib/crypto/krb/dk/dk_ccm.c4
-rw-r--r--src/lib/crypto/krb/dk/stringtokey.c31
-rw-r--r--src/lib/crypto/krb/etypes.h20
-rw-r--r--src/lib/crypto/krb/prf/cmac_prf.c3
-rw-r--r--src/lib/crypto/krb/prf/dk_prf.c2
14 files changed, 91 insertions, 74 deletions
diff --git a/src/lib/crypto/builtin/enc_provider/camellia_ctr.c b/src/lib/crypto/builtin/enc_provider/camellia_ctr.c
index 0764468..a71e03b 100644
--- a/src/lib/crypto/builtin/enc_provider/camellia_ctr.c
+++ b/src/lib/crypto/builtin/enc_provider/camellia_ctr.c
@@ -94,8 +94,8 @@ krb5int_camellia_encrypt_ctr(krb5_key key,
input_pos.ignore_header = output_pos.ignore_header = 1;
input_pos.pad_to_boundary = output_pos.pad_to_boundary = 1;
- assert(ivec != NULL);
-
+ if (ivec == NULL)
+ return EINVAL;
if (ivec->length != BLOCK_SIZE)
return KRB5_BAD_MSIZE;
diff --git a/src/lib/crypto/crypto_tests/vectors.c b/src/lib/crypto/crypto_tests/vectors.c
index a6f1bbe..f984a17 100644
--- a/src/lib/crypto/crypto_tests/vectors.c
+++ b/src/lib/crypto/crypto_tests/vectors.c
@@ -213,13 +213,13 @@ extern struct krb5_enc_provider krb5int_enc_aes128, krb5int_enc_aes256;
void DK (krb5_keyblock *out, krb5_keyblock *in, const krb5_data *usage) {
krb5_error_code r;
- r = krb5int_derive_key (enc, in, out, usage);
+ r = krb5int_derive_key (enc, in, out, usage, DERIVE_RFC3961);
CHECK;
}
void DR (krb5_data *out, krb5_keyblock *in, const krb5_data *usage) {
krb5_error_code r;
- r = krb5int_derive_random (enc, in, out, usage);
+ r = krb5int_derive_random (enc, in, out, usage, DERIVE_RFC3961);
CHECK;
}
diff --git a/src/lib/crypto/krb/checksum/cmac.c b/src/lib/crypto/krb/checksum/cmac.c
index d660911..5bbabd3 100644
--- a/src/lib/crypto/krb/checksum/cmac.c
+++ b/src/lib/crypto/krb/checksum/cmac.c
@@ -86,20 +86,15 @@ generate_subkey(const struct krb5_enc_provider *enc,
unsigned char *K1,
unsigned char *K2)
{
- unsigned char Z[BLOCK_SIZE];
unsigned char L[BLOCK_SIZE];
unsigned char tmp[BLOCK_SIZE];
- krb5_crypto_iov iov[1];
krb5_data d;
krb5_error_code ret;
/* L := encrypt(K, const_Zero) */
- memset(Z, 0, sizeof(Z));
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
- iov[0].data = make_data(Z, sizeof(Z));
+ memset(L, 0, sizeof(L));
d = make_data(L, BLOCK_SIZE);
- /* cbc-mac is the same as block encrypt if invoked on a single block. */
- ret = enc->cbc_mac(key, iov, 1, NULL, &d);
+ ret = encrypt_block(enc, key, &d);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/krb/combine_keys.c b/src/lib/crypto/krb/combine_keys.c
index b743538..a6cea2e 100644
--- a/src/lib/crypto/krb/combine_keys.c
+++ b/src/lib/crypto/krb/combine_keys.c
@@ -191,7 +191,7 @@ krb5int_c_combine_keys(krb5_context context, krb5_keyblock *key1,
myalloc = TRUE;
}
- ret = krb5int_derive_keyblock(enc, tkey, outkey, &input);
+ ret = krb5int_derive_keyblock(enc, tkey, outkey, &input, DERIVE_RFC3961);
if (ret) {
if (myalloc) {
free(outkey->contents);
@@ -222,7 +222,8 @@ 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, key, &outdata, in_constant,
+ DERIVE_RFC3961);
krb5_k_free_key(NULL, key);
return ret;
}
diff --git a/src/lib/crypto/krb/dk/checksum_cmac.c b/src/lib/crypto/krb/dk/checksum_cmac.c
index 41e1232..ad036a1 100644
--- a/src/lib/crypto/krb/dk/checksum_cmac.c
+++ b/src/lib/crypto/krb/dk/checksum_cmac.c
@@ -59,7 +59,7 @@ 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);
+ ret = krb5int_derive_key(enc, key, &kc, &datain, DERIVE_SP800_108_CMAC);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/krb/dk/checksum_hmac.c b/src/lib/crypto/krb/dk/checksum_hmac.c
index b64f1f5..47a38d0 100644
--- a/src/lib/crypto/krb/dk/checksum_hmac.c
+++ b/src/lib/crypto/krb/dk/checksum_hmac.c
@@ -57,7 +57,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);
+ ret = krb5int_derive_key(enc, key, &kc, &datain, DERIVE_RFC3961);
if (ret)
return ret;
diff --git a/src/lib/crypto/krb/dk/derive.c b/src/lib/crypto/krb/dk/derive.c
index 24dcb53..9188862 100644
--- a/src/lib/crypto/krb/dk/derive.c
+++ b/src/lib/crypto/krb/dk/derive.c
@@ -85,8 +85,8 @@ derive_random_rfc3961(const struct krb5_enc_provider *enc,
const krb5_data *in_constant)
{
size_t blocksize, keybytes, n;
- krb5_crypto_iov iov;
krb5_error_code ret;
+ krb5_data block = empty_data();
blocksize = enc->block_size;
keybytes = enc->keybytes;
@@ -95,38 +95,37 @@ derive_random_rfc3961(const struct krb5_enc_provider *enc,
return KRB5_CRYPTO_INTERNAL;
/* Allocate encryption data buffer. */
- iov.flags = KRB5_CRYPTO_TYPE_DATA;
- ret = alloc_data(&iov.data, blocksize);
+ ret = alloc_data(&block, blocksize);
if (ret)
return ret;
/* Initialize the input block. */
if (in_constant->length == blocksize) {
- memcpy(iov.data.data, in_constant->data, blocksize);
+ memcpy(block.data, in_constant->data, blocksize);
} else {
krb5int_nfold(in_constant->length * 8,
(unsigned char *) in_constant->data,
- blocksize * 8, (unsigned char *) iov.data.data);
+ blocksize * 8, (unsigned char *) block.data);
}
/* Loop encrypting the blocks until enough key bytes are generated. */
n = 0;
while (n < keybytes) {
- ret = enc->encrypt(inkey, 0, &iov, 1);
+ ret = encrypt_block(enc, inkey, &block);
if (ret)
goto cleanup;
if ((keybytes - n) <= blocksize) {
- memcpy(outrnd->data + n, iov.data.data, (keybytes - n));
+ memcpy(outrnd->data + n, block.data, (keybytes - n));
break;
}
- memcpy(outrnd->data + n, iov.data.data, blocksize);
+ memcpy(outrnd->data + n, block.data, blocksize);
n += blocksize;
}
cleanup:
- zapfree(iov.data.data, blocksize);
+ zapfree(block.data, blocksize);
return ret;
}
@@ -200,16 +199,16 @@ cleanup:
krb5_error_code
krb5int_derive_random(const struct krb5_enc_provider *enc,
krb5_key inkey, krb5_data *outrnd,
- const krb5_data *in_constant)
+ const krb5_data *in_constant, enum deriv_alg alg)
{
- krb5_error_code ret;
-
- if (enc->cbc_mac)
- ret = derive_random_sp800_cmac(enc, inkey, outrnd, in_constant);
- else
- ret = derive_random_rfc3961(enc, inkey, outrnd, in_constant);
-
- return ret;
+ switch (alg) {
+ case DERIVE_RFC3961:
+ return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
+ case DERIVE_SP800_108_CMAC:
+ return derive_random_sp800_cmac(enc, inkey, outrnd, in_constant);
+ default:
+ return EINVAL;
+ }
}
/*
@@ -221,7 +220,7 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
krb5_error_code
krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
krb5_key inkey, krb5_keyblock *outkey,
- const krb5_data *in_constant)
+ const krb5_data *in_constant, enum deriv_alg alg)
{
krb5_error_code ret;
krb5_data rawkey = empty_data();
@@ -232,7 +231,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);
+ ret = krb5int_derive_random(enc, inkey, &rawkey, in_constant, alg);
if (ret)
goto cleanup;
@@ -247,7 +246,7 @@ cleanup:
krb5_error_code
krb5int_derive_key(const struct krb5_enc_provider *enc,
krb5_key inkey, krb5_key *outkey,
- const krb5_data *in_constant)
+ const krb5_data *in_constant, enum deriv_alg alg)
{
krb5_keyblock keyblock;
krb5_error_code ret;
@@ -265,13 +264,10 @@ krb5int_derive_key(const struct krb5_enc_provider *enc,
/* Derive into a temporary keyblock. */
keyblock.length = enc->keylength;
keyblock.contents = malloc(keyblock.length);
- /* Set the enctype as the krb5_k_free_key will iterate over list
- or derived keys and invoke krb5_k_free_key which will lookup
- the enctype for key_cleanup handler */
keyblock.enctype = inkey->keyblock.enctype;
if (keyblock.contents == NULL)
return ENOMEM;
- ret = krb5int_derive_keyblock(enc, inkey, &keyblock, in_constant);
+ ret = krb5int_derive_keyblock(enc, inkey, &keyblock, in_constant, alg);
if (ret)
goto cleanup;
diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h
index 49c898d..4adf7a0 100644
--- a/src/lib/crypto/krb/dk/dk.h
+++ b/src/lib/crypto/krb/dk/dk.h
@@ -62,23 +62,26 @@ krb5int_aes_string_to_key(const struct krb5_keytypes *enc,
const krb5_data *params, krb5_keyblock *key);
krb5_error_code
-krb5int_peppered_string_to_key(const struct krb5_keytypes *enc,
- const krb5_data *string, const krb5_data *salt,
- const krb5_data *params, krb5_keyblock *key);
+krb5int_camellia_ccm_string_to_key(const struct krb5_keytypes *enc,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key);
-#define krb5int_camellia_ccm_string_to_key krb5int_peppered_string_to_key
+enum deriv_alg {
+ DERIVE_RFC3961, /* RFC 3961 section 5.1 */
+ DERIVE_SP800_108_CMAC /* NIST SP 800-108 with CMAC as PRF */
+};
krb5_error_code
krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
- krb5_key inkey,
- krb5_keyblock *outkey,
- const krb5_data *in_constant);
+ 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,
- krb5_key inkey,
- krb5_key *outkey,
- const krb5_data *in_constant);
+ krb5_key inkey, krb5_key *outkey,
+ const krb5_data *in_constant, enum deriv_alg alg);
krb5_error_code
krb5int_dk_checksum(const struct krb5_cksumtypes *ctp,
@@ -89,7 +92,7 @@ krb5int_dk_checksum(const struct krb5_cksumtypes *ctp,
krb5_error_code
krb5int_derive_random(const struct krb5_enc_provider *enc,
krb5_key inkey, krb5_data *outrnd,
- const krb5_data *in_constant);
+ const krb5_data *in_constant, enum deriv_alg alg);
unsigned int
krb5int_dk_ccm_crypto_length(const struct krb5_keytypes *ktp,
diff --git a/src/lib/crypto/krb/dk/dk_aead.c b/src/lib/crypto/krb/dk/dk_aead.c
index b5ef456..ee3a210 100644
--- a/src/lib/crypto/krb/dk/dk_aead.c
+++ b/src/lib/crypto/krb/dk/dk_aead.c
@@ -152,13 +152,13 @@ krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
d1.data[4] = 0xAA;
- ret = krb5int_derive_key(enc, key, &ke, &d1);
+ ret = krb5int_derive_key(enc, key, &ke, &d1, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
d1.data[4] = 0x55;
- ret = krb5int_derive_key(enc, key, &ki, &d1);
+ ret = krb5int_derive_key(enc, key, &ki, &d1, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
@@ -253,13 +253,13 @@ krb5int_dk_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
d1.data[4] = 0xAA;
- ret = krb5int_derive_key(enc, key, &ke, &d1);
+ ret = krb5int_derive_key(enc, key, &ke, &d1, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
d1.data[4] = 0x55;
- ret = krb5int_derive_key(enc, key, &ki, &d1);
+ ret = krb5int_derive_key(enc, key, &ki, &d1, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;
diff --git a/src/lib/crypto/krb/dk/dk_ccm.c b/src/lib/crypto/krb/dk/dk_ccm.c
index 7157024..a598389 100644
--- a/src/lib/crypto/krb/dk/dk_ccm.c
+++ b/src/lib/crypto/krb/dk/dk_ccm.c
@@ -410,7 +410,7 @@ krb5int_dk_ccm_encrypt(const struct krb5_keytypes *ktp,
d1.data[4] = 0xCC;
- ret = krb5int_derive_key(ktp->enc, key, &kc, &d1);
+ ret = krb5int_derive_key(ktp->enc, key, &kc, &d1, DERIVE_SP800_108_CMAC);
if (ret != 0)
return ret;
@@ -587,7 +587,7 @@ krb5int_dk_ccm_decrypt(const struct krb5_keytypes *ktp,
d1.data[4] = 0xCC;
- ret = krb5int_derive_key(ktp->enc, key, &kc, &d1);
+ ret = krb5int_derive_key(ktp->enc, key, &kc, &d1, DERIVE_SP800_108_CMAC);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/krb/dk/stringtokey.c b/src/lib/crypto/krb/dk/stringtokey.c
index fd4bf28..b8ed055 100644
--- a/src/lib/crypto/krb/dk/stringtokey.c
+++ b/src/lib/crypto/krb/dk/stringtokey.c
@@ -87,7 +87,8 @@ krb5int_dk_string_to_key(const struct krb5_keytypes *ktp,
indata.length = kerberos_len;
indata.data = (char *) kerberos;
- ret = krb5int_derive_keyblock(enc, foldkey, keyblock, &indata);
+ ret = krb5int_derive_keyblock(enc, foldkey, keyblock, &indata,
+ DERIVE_RFC3961);
if (ret != 0)
memset(keyblock->contents, 0, keyblock->length);
@@ -104,12 +105,10 @@ cleanup:
#define MAX_ITERATION_COUNT 0x1000000L
static krb5_error_code
-pbkdf2_string_to_key(const struct krb5_keytypes *ktp,
- const krb5_data *string,
- const krb5_data *salt,
- const krb5_data *pepper,
- const krb5_data *params,
- krb5_keyblock *key)
+pbkdf2_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string,
+ const krb5_data *salt, const krb5_data *pepper,
+ const krb5_data *params, krb5_keyblock *key,
+ enum deriv_alg deriv_alg)
{
unsigned long iter_count;
krb5_data out;
@@ -164,7 +163,7 @@ pbkdf2_string_to_key(const struct krb5_keytypes *ktp,
if (err)
goto cleanup;
- err = krb5int_derive_keyblock(ktp->enc, tempkey, key, &usage);
+ err = krb5int_derive_keyblock(ktp->enc, tempkey, key, &usage, deriv_alg);
cleanup:
if (sandp.data)
@@ -182,18 +181,20 @@ krb5int_aes_string_to_key(const struct krb5_keytypes *ktp,
const krb5_data *params,
krb5_keyblock *key)
{
- return pbkdf2_string_to_key(ktp, string, salt, NULL, params, key);
+ return pbkdf2_string_to_key(ktp, string, salt, NULL, params, key,
+ DERIVE_RFC3961);
}
krb5_error_code
-krb5int_peppered_string_to_key(const struct krb5_keytypes *ktp,
- const krb5_data *string,
- const krb5_data *salt,
- const krb5_data *params,
- krb5_keyblock *key)
+krb5int_camellia_ccm_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);
+ return pbkdf2_string_to_key(ktp, string, salt, &pepper, params, key,
+ DERIVE_SP800_108_CMAC);
}
diff --git a/src/lib/crypto/krb/etypes.h b/src/lib/crypto/krb/etypes.h
index a45a6c7..5b4d49c 100644
--- a/src/lib/crypto/krb/etypes.h
+++ b/src/lib/crypto/krb/etypes.h
@@ -89,4 +89,24 @@ find_enctype(krb5_enctype enctype)
return &krb5int_enctypes_list[i];
}
+/* This belongs with the declaration of struct krb5_enc_provider... but not
+ * while that's still in k5-int.h. */
+/* Encrypt one block of plaintext in place. */
+static inline krb5_error_code
+encrypt_block(const struct krb5_enc_provider *enc, krb5_key key,
+ krb5_data *block)
+{
+ krb5_crypto_iov iov;
+
+ /* Verify that block is the right length. */
+ if (block->length != enc->block_size)
+ return EINVAL;
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *block;
+ if (enc->cbc_mac != NULL) /* One-block cbc-mac with no ivec. */
+ return enc->cbc_mac(key, &iov, 1, NULL, block);
+ else /* Assume cbc-mode encrypt. */
+ return enc->encrypt(key, 0, &iov, 1);
+}
+
#endif
diff --git a/src/lib/crypto/krb/prf/cmac_prf.c b/src/lib/crypto/krb/prf/cmac_prf.c
index 5b14a86..b7c2851 100644
--- a/src/lib/crypto/krb/prf/cmac_prf.c
+++ b/src/lib/crypto/krb/prf/cmac_prf.c
@@ -49,7 +49,8 @@ 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, key, &kp, &prfconst,
+ DERIVE_SP800_108_CMAC);
if (ret != 0)
goto cleanup;
diff --git a/src/lib/crypto/krb/prf/dk_prf.c b/src/lib/crypto/krb/prf/dk_prf.c
index 9851ce7..a824e2b 100644
--- a/src/lib/crypto/krb/prf/dk_prf.c
+++ b/src/lib/crypto/krb/prf/dk_prf.c
@@ -55,7 +55,7 @@ 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);
+ ret = krb5int_derive_key(ktp->enc, key, &kp, &prfconst, DERIVE_RFC3961);
if (ret != 0)
goto cleanup;