summaryrefslogtreecommitdiffstats
path: root/src/lib/crypto
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-11-30 21:20:49 +0000
committerGreg Hudson <ghudson@mit.edu>2010-11-30 21:20:49 +0000
commit1c411f836063e4e6d67390d205e043149302fdd9 (patch)
treea8909e74c2c23b7b1c5b1282cf8dd4119c92c989 /src/lib/crypto
parenta87789f75f1a7563982953e088927135bb5d6e85 (diff)
downloadkrb5-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.c9
-rw-r--r--src/lib/crypto/krb/cksumtypes.c8
-rw-r--r--src/lib/crypto/krb/dk/checksum_hmac.c10
-rw-r--r--src/lib/crypto/krb/dk/derive.c2
-rw-r--r--src/lib/crypto/krb/etypes.c6
-rw-r--r--src/lib/crypto/krb/etypes.h4
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;