diff options
| author | Greg Hudson <ghudson@mit.edu> | 2010-11-30 21:20:49 +0000 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2010-11-30 21:20:49 +0000 |
| commit | 1c411f836063e4e6d67390d205e043149302fdd9 (patch) | |
| tree | a8909e74c2c23b7b1c5b1282cf8dd4119c92c989 /src/lib/crypto | |
| parent | a87789f75f1a7563982953e088927135bb5d6e85 (diff) | |
| download | krb5-1c411f836063e4e6d67390d205e043149302fdd9.tar.gz krb5-1c411f836063e4e6d67390d205e043149302fdd9.tar.xz krb5-1c411f836063e4e6d67390d205e043149302fdd9.zip | |
SA-2010-007 Checksum vulnerabilities (CVE-2010-1324 and others)
Fix multiple checksum handling bugs, as described in:
CVE-2010-1324
CVE-2010-1323
CVE-2010-4020
CVE-2010-4021
* Return the correct (keyed) checksums as the mandatory checksum type
for DES enctypes.
* Restrict simplified-profile checksums to their corresponding etypes.
* Add internal checks to reduce the risk of stream ciphers being used
with simplified-profile key derivation or other algorithms relying
on the block encryption primitive.
* Use the mandatory checksum type for the PKINIT KDC signature,
instead of the first-listed keyed checksum.
* Use the mandatory checksum type when sending KRB-SAFE messages by
default, instead of the first-listed keyed checksum.
* Use the mandatory checksum type for the t_kperf test program.
* Use the mandatory checksum type (without additional logic) for the
FAST request checksum.
* Preserve the existing checksum choices (unkeyed checksums for DES
enctypes) for the authenticator checksum, using explicit logic.
* Ensure that SAM checksums received from the KDC are keyed.
* Ensure that PAC checksums are keyed.
ticket: 6827
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24538 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/crypto')
| -rw-r--r-- | src/lib/crypto/crypto_tests/t_kperf.c | 9 | ||||
| -rw-r--r-- | src/lib/crypto/krb/cksumtypes.c | 8 | ||||
| -rw-r--r-- | src/lib/crypto/krb/dk/checksum_hmac.c | 10 | ||||
| -rw-r--r-- | src/lib/crypto/krb/dk/derive.c | 2 | ||||
| -rw-r--r-- | src/lib/crypto/krb/etypes.c | 6 | ||||
| -rw-r--r-- | src/lib/crypto/krb/etypes.h | 4 |
6 files changed, 14 insertions, 25 deletions
diff --git a/src/lib/crypto/crypto_tests/t_kperf.c b/src/lib/crypto/crypto_tests/t_kperf.c index 8c36e902f..a07a364dd 100644 --- a/src/lib/crypto/crypto_tests/t_kperf.c +++ b/src/lib/crypto/crypto_tests/t_kperf.c @@ -49,9 +49,8 @@ main(int argc, char **argv) krb5_keyblock kblock; krb5_key key; krb5_enctype enctype; - krb5_cksumtype cktype, *cktypelist; + krb5_cksumtype cktype; int blocksize, num_blocks, intf, op, i; - unsigned int count; size_t outlen, cklen; krb5_data block; krb5_enc_data outblock; @@ -69,11 +68,6 @@ main(int argc, char **argv) blocksize = atoi(argv[3]); num_blocks = atoi(argv[4]); - /* Pick the first available keyed checksum type. */ - krb5_c_keyed_checksum_types(NULL, enctype, &count, &cktypelist); - assert(count > 0); - cktype = cktypelist[0]; - block.data = "notrandom"; block.length = 9; krb5_c_random_seed(NULL, &block); @@ -89,6 +83,7 @@ main(int argc, char **argv) outblock.ciphertext.length = outlen; outblock.ciphertext.data = calloc(1, outlen); + krb5int_c_mandatory_cksumtype(NULL, enctype, &cktype); krb5_c_checksum_length(NULL, cktype, &cklen); sum.checksum_type = cktype; sum.length = cklen; diff --git a/src/lib/crypto/krb/cksumtypes.c b/src/lib/crypto/krb/cksumtypes.c index bcd514011..a8b1c8729 100644 --- a/src/lib/crypto/krb/cksumtypes.c +++ b/src/lib/crypto/krb/cksumtypes.c @@ -76,7 +76,7 @@ const struct krb5_cksumtypes krb5int_cksumtypes_list[] = { { CKSUMTYPE_HMAC_SHA1_DES3, "hmac-sha1-des3", { "hmac-sha1-des3-kd" }, "HMAC-SHA1 DES3 key", - NULL, &krb5int_hash_sha1, + &krb5int_enc_des3, &krb5int_hash_sha1, krb5int_dk_checksum, NULL, 20, 20, 0 }, @@ -89,19 +89,19 @@ const struct krb5_cksumtypes krb5int_cksumtypes_list[] = { { CKSUMTYPE_HMAC_SHA1_96_AES128, "hmac-sha1-96-aes128", { 0 }, "HMAC-SHA1 AES128 key", - NULL, &krb5int_hash_sha1, + &krb5int_enc_aes128, &krb5int_hash_sha1, krb5int_dk_checksum, NULL, 20, 12, 0 }, { CKSUMTYPE_HMAC_SHA1_96_AES256, "hmac-sha1-96-aes256", { 0 }, "HMAC-SHA1 AES256 key", - NULL, &krb5int_hash_sha1, + &krb5int_enc_aes256, &krb5int_hash_sha1, krb5int_dk_checksum, NULL, 20, 12, 0 }, { CKSUMTYPE_MD5_HMAC_ARCFOUR, "md5-hmac-rc4", { 0 }, "Microsoft MD5 HMAC", - NULL, &krb5int_hash_md5, + &krb5int_enc_arcfour, &krb5int_hash_md5, krb5int_hmacmd5_checksum, NULL, 16, 16, 0 }, diff --git a/src/lib/crypto/krb/dk/checksum_hmac.c b/src/lib/crypto/krb/dk/checksum_hmac.c index ae51aa38f..5f333af57 100644 --- a/src/lib/crypto/krb/dk/checksum_hmac.c +++ b/src/lib/crypto/krb/dk/checksum_hmac.c @@ -39,20 +39,12 @@ krb5int_dk_checksum(const struct krb5_cksumtypes *ctp, krb5_data *output) { const struct krb5_keytypes *ktp; - const struct krb5_enc_provider *enc; + const struct krb5_enc_provider *enc = ctp->enc; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data datain; krb5_key kc; - /* Use the key's enctype (more flexible than setting an enctype in ctp). */ - ktp = find_enctype(key->keyblock.enctype); - if (ktp == NULL) - return KRB5_BAD_ENCTYPE; - enc = ktp->enc; - if (key->keyblock.length != enc->keylength) - return KRB5_BAD_KEYSIZE; - /* Derive the key. */ datain = make_data(constantdata, K5CLENGTH); store_32_be(usage, constantdata); diff --git a/src/lib/crypto/krb/dk/derive.c b/src/lib/crypto/krb/dk/derive.c index d309206f1..3e9af2854 100644 --- a/src/lib/crypto/krb/dk/derive.c +++ b/src/lib/crypto/krb/dk/derive.c @@ -91,6 +91,8 @@ derive_random_rfc3961(const struct krb5_enc_provider *enc, blocksize = enc->block_size; keybytes = enc->keybytes; + if (blocksize == 1) + return KRB5_BAD_ENCTYPE; if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes) return KRB5_CRYPTO_INTERNAL; diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c index 9703a939b..ec9fb1d1b 100644 --- a/src/lib/crypto/krb/etypes.c +++ b/src/lib/crypto/krb/etypes.c @@ -51,7 +51,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { krb5int_des_string_to_key, krb5int_des_prf, krb5int_init_state_enc, krb5int_free_state_enc, - CKSUMTYPE_RSA_MD5, + CKSUMTYPE_RSA_MD5_DES, ETYPE_WEAK }, { ENCTYPE_DES_CBC_MD4, "des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4", @@ -61,7 +61,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { krb5int_des_string_to_key, krb5int_des_prf, krb5int_init_state_enc, krb5int_free_state_enc, - CKSUMTYPE_RSA_MD4, + CKSUMTYPE_RSA_MD4_DES, ETYPE_WEAK }, { ENCTYPE_DES_CBC_MD5, "des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5", @@ -71,7 +71,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { krb5int_des_string_to_key, krb5int_des_prf, krb5int_init_state_enc, krb5int_free_state_enc, - CKSUMTYPE_RSA_MD5, + CKSUMTYPE_RSA_MD5_DES, ETYPE_WEAK }, { ENCTYPE_DES_CBC_RAW, "des-cbc-raw", { 0 }, "DES cbc mode raw", diff --git a/src/lib/crypto/krb/etypes.h b/src/lib/crypto/krb/etypes.h index 70cb7bcae..bbf2bf3b8 100644 --- a/src/lib/crypto/krb/etypes.h +++ b/src/lib/crypto/krb/etypes.h @@ -108,8 +108,8 @@ encrypt_block(const struct krb5_enc_provider *enc, krb5_key key, { krb5_crypto_iov iov; - /* Verify that block is the right length. */ - if (block->length != enc->block_size) + /* Verify that this is a block cipher and block is the right length. */ + if (block->length != enc->block_size || enc->block_size == 1) return EINVAL; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *block; |
