diff options
author | Greg Hudson <ghudson@mit.edu> | 2010-08-02 03:49:54 +0000 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2010-08-02 03:49:54 +0000 |
commit | 6a6092fe00b799ab172d28233e77452a5ef43328 (patch) | |
tree | 4d1a873d43deaf4c80ec736e8e9df47e392c7325 | |
parent | f45f4fb0a07c68643bc5164f839a2b4331c219b6 (diff) | |
download | krb5-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.c | 4 | ||||
-rw-r--r-- | src/lib/crypto/crypto_tests/vectors.c | 4 | ||||
-rw-r--r-- | src/lib/crypto/krb/checksum/cmac.c | 9 | ||||
-rw-r--r-- | src/lib/crypto/krb/combine_keys.c | 5 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/checksum_cmac.c | 2 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/checksum_hmac.c | 2 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/derive.c | 46 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/dk.h | 25 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/dk_aead.c | 8 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/dk_ccm.c | 4 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/stringtokey.c | 31 | ||||
-rw-r--r-- | src/lib/crypto/krb/etypes.h | 20 | ||||
-rw-r--r-- | src/lib/crypto/krb/prf/cmac_prf.c | 3 | ||||
-rw-r--r-- | src/lib/crypto/krb/prf/dk_prf.c | 2 |
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; |