aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Howard <lukeh@padl.com>2010-05-22 19:19:37 +0000
committerLuke Howard <lukeh@padl.com>2010-05-22 19:19:37 +0000
commite298fa488b7d7153956c39b52b3864c7526d470a (patch)
tree70c6a9c0fb4e162993e72f2b501dfdf47c267572
parentf1dd1977c775b63f92af88bd60c3c92e2a8fb43a (diff)
downloadkrb5-e298fa488b7d7153956c39b52b3864c7526d470a.zip
krb5-e298fa488b7d7153956c39b52b3864c7526d470a.tar.gz
krb5-e298fa488b7d7153956c39b52b3864c7526d470a.tar.bz2
support possible truncation of GMAC checksum
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/camellia-ccm@24088 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/krb/dk/dk_ccm.c1
-rw-r--r--src/lib/crypto/krb/dk/dk_gcm.c20
2 files changed, 12 insertions, 9 deletions
diff --git a/src/lib/crypto/krb/dk/dk_ccm.c b/src/lib/crypto/krb/dk/dk_ccm.c
index 75a9cd5..4d950dc 100644
--- a/src/lib/crypto/krb/dk/dk_ccm.c
+++ b/src/lib/crypto/krb/dk/dk_ccm.c
@@ -312,6 +312,7 @@ ccm_encrypt(const struct krb5_keytypes *ktp,
}
header->data.length = header_len;
+ trailer->data.length = trailer_len;
/* Initialize nonce */
ret = krb5_c_random_make_octets(NULL, &header->data);
diff --git a/src/lib/crypto/krb/dk/dk_gcm.c b/src/lib/crypto/krb/dk/dk_gcm.c
index 4c79841..a3c1387 100644
--- a/src/lib/crypto/krb/dk/dk_gcm.c
+++ b/src/lib/crypto/krb/dk/dk_gcm.c
@@ -85,7 +85,7 @@ krb5int_dk_gcm_crypto_length(const struct krb5_keytypes *ktp,
case KRB5_CRYPTO_TYPE_TRAILER:
case KRB5_CRYPTO_TYPE_CHECKSUM:
length = ktp->enc->block_size;
- assert(length == BLOCK_SIZE); /* SP-800-38D requires this */
+ assert(length <= BLOCK_SIZE); /* SP-800-38D requires this */
break;
default:
assert(0 && "invalid cryptotype passed to gcm_crypto_length");
@@ -293,13 +293,13 @@ krb5int_gcm_encrypt(const struct krb5_keytypes *ktp,
size_t plain_len = 0, adata_len = 0;
char len_buf[BLOCK_SIZE];
unsigned char H[BLOCK_SIZE], J0[BLOCK_SIZE];
- unsigned char ICB[BLOCK_SIZE];
+ unsigned char ICB[BLOCK_SIZE], S[BLOCK_SIZE];
krb5_data counter;
header_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER);
header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
- if (header == NULL || header->data.length != header_len) {
+ if (header == NULL || header->data.length < header_len) {
ret = KRB5_BAD_MSIZE;
goto cleanup;
}
@@ -307,7 +307,7 @@ krb5int_gcm_encrypt(const struct krb5_keytypes *ktp,
trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
- if (trailer == NULL || trailer->data.length != trailer_len) {
+ if (trailer == NULL || trailer->data.length < trailer_len) {
ret = KRB5_BAD_MSIZE;
goto cleanup;
}
@@ -388,22 +388,24 @@ krb5int_gcm_encrypt(const struct krb5_keytypes *ktp,
num_sign_data++;
/* Make checksum */
- ret = GHASH(H, sign_data, num_sign_data,
- (unsigned char *)trailer->data.data);
+ ret = GHASH(H, sign_data, num_sign_data, S);
if (ret != 0)
goto cleanup;
- /* Encrypt checksum in trailer */
+ /* Encrypt checksum and place (possibly truncated) into trailer */
{
krb5_data J0_data = make_data((char *)J0, sizeof(J0));
krb5_crypto_iov cksum[1];
cksum[0].flags = KRB5_CRYPTO_TYPE_DATA;
- cksum[0].data = trailer->data;
+ cksum[0].data = make_data(S, sizeof(S));
ret = ktp->enc->encrypt(kg, &J0_data, cksum, 1);
if (ret != 0)
goto cleanup;
+
+ memcpy(trailer->data.data, S, trailer_len);
+ trailer->data.length = trailer_len;
}
if (state != NULL)
@@ -411,6 +413,7 @@ krb5int_gcm_encrypt(const struct krb5_keytypes *ktp,
cleanup:
free(sign_data);
+ zap(S, sizeof(S));
zap(ICB, sizeof(ICB));
zap(J0, sizeof(J0));
zap(H, sizeof(H));
@@ -480,7 +483,6 @@ krb5int_gcm_decrypt(const struct krb5_keytypes *ktp,
}
trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
- assert(trailer_len <= sizeof(made_cksum));
trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
if (trailer == NULL || trailer->data.length < trailer_len) {