From a6706b261c6968621ebfb9398ca23da77df61c85 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Tue, 1 Dec 2009 01:32:02 +0000 Subject: [PATCH] Make krb5int_c_decrypt_aead_compat more efficient by building the buffers explicitly rather than using stream decryption. Sidesteps some machinery and avoids copying the output. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23396 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/crypto/krb/aead.c | 64 +++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/src/lib/crypto/krb/aead.c b/src/lib/crypto/krb/aead.c index 04fdab008..378d8c946 100644 --- a/src/lib/crypto/krb/aead.c +++ b/src/lib/crypto/krb/aead.c @@ -530,38 +530,56 @@ krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { - krb5_crypto_iov iov[2]; + krb5_crypto_iov iov[4]; krb5_error_code ret; + unsigned int header_len = 0, trailer_len = 0, plain_len; + char *scratch = NULL; - iov[0].flags = KRB5_CRYPTO_TYPE_STREAM; - iov[0].data.data = malloc(input->length); - if (iov[0].data.data == NULL) - return ENOMEM; + ret = (*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER, + &header_len); + if (ret != 0) + return ret; - memcpy(iov[0].data.data, input->data, input->length); - iov[0].data.length = input->length; + ret = (*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, + &trailer_len); + if (ret != 0) + return ret; - iov[1].flags = KRB5_CRYPTO_TYPE_DATA; - iov[1].data.data = NULL; - iov[1].data.length = 0; + if (input->length < header_len + trailer_len) + return KRB5_BAD_MSIZE; + plain_len = input->length - header_len - trailer_len; + if (output->length < input->length - header_len - trailer_len) + return KRB5_BAD_MSIZE; - ret = krb5int_c_iov_decrypt_stream(aead, enc, hash, key, - usage, ivec, - iov, sizeof(iov)/sizeof(iov[0])); - if (ret != 0) - goto cleanup; + scratch = k5alloc(header_len + trailer_len, &ret); + if (scratch == NULL) + return ret; - if (output->length < iov[1].data.length) { - ret = KRB5_BAD_MSIZE; - goto cleanup; - } + iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; + iov[0].data = make_data(scratch, header_len); + memcpy(iov[0].data.data, input->data, header_len); - memcpy(output->data, iov[1].data.data, iov[1].data.length); - output->length = iov[1].data.length; + iov[1].flags = KRB5_CRYPTO_TYPE_DATA; + iov[1].data = make_data(output->data, plain_len); + memcpy(iov[1].data.data, input->data + header_len, input->length); -cleanup: - zapfree(iov[0].data.data, iov[0].data.length); + /* Use empty padding since tokens don't indicate the padding length. */ + iov[2].flags = KRB5_CRYPTO_TYPE_PADDING; + iov[2].data = empty_data(); + + iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER; + iov[3].data = make_data(scratch + header_len, trailer_len); + memcpy(iov[3].data.data, input->data + header_len + plain_len, + trailer_len); + + ret = (*aead->decrypt_iov)(aead, enc, hash, key, usage, ivec, + iov, sizeof(iov) / sizeof(iov[0])); + if (ret != 0) + zap(output->data, plain_len); + else + output->length = plain_len; + zapfree(scratch, header_len + trailer_len); return ret; } -- 2.26.2