aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2008-12-01 16:44:26 +0000
committerSam Hartman <hartmans@mit.edu>2008-12-01 16:44:26 +0000
commit0d17a0945cc7869aebf8cb52471836d42eddad30 (patch)
tree2756abee1e3e68200ba27217932ac558a6208a68
parentce3096bed2784699499e0bc944a8f4ad08c0d199 (diff)
downloadkrb5-0d17a0945cc7869aebf8cb52471836d42eddad30.zip
krb5-0d17a0945cc7869aebf8cb52471836d42eddad30.tar.gz
krb5-0d17a0945cc7869aebf8cb52471836d42eddad30.tar.bz2
Change the behaviour of KRB5_CRYPTO_TYPE_STREAM slightly: STREAM should
be the concatenation of HEADER | DATA | PADDING | TRAILER (without any SIGN_ONLY buffers). When passing STREAM into decrypt, any additional SIGN_ONLY buffers should be included as input, ordered relative to the (output) DATA buffer as they were on encrypt. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/mskrb-integ-crypto-iov@21248 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/aead.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/src/lib/crypto/aead.c b/src/lib/crypto/aead.c
index e7d86d4..9e44e86 100644
--- a/src/lib/crypto/aead.c
+++ b/src/lib/crypto/aead.c
@@ -224,7 +224,7 @@ pad_to_boundary_p(const krb5_crypto_iov *data,
/* Don't consider adjacent buffers of the same type as a boundary */
if (i < num_data - 1 &&
(data[i].flags == data[i + 1].flags ||
- data[i].flags == KRB5_CRYPTO_TYPE_HEADER && SIGN_IOV(&data[i])))
+ (data[i].flags == KRB5_CRYPTO_TYPE_HEADER && SIGN_IOV(&data[i + 1]))))
return 0;
return 1;
@@ -327,16 +327,14 @@ krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
{
krb5_error_code ret;
size_t header_len, trailer_len, padding_len;
- krb5_crypto_iov iov[4];
- krb5_crypto_iov *stream, *s_data;
+ krb5_crypto_iov *iov;
+ krb5_crypto_iov *stream;
+ size_t i, j;
+ int got_data = 0;
stream = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_STREAM);
assert(stream != NULL);
- s_data = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_DATA);
- if (s_data == NULL)
- return KRB5_BAD_MSIZE;
-
ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER, &header_len);
if (ret != 0)
return ret;
@@ -352,26 +350,50 @@ krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
if (stream->data.length < header_len + trailer_len)
return KRB5_BAD_MSIZE;
- iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
- iov[0].data.data = stream->data.data;
- iov[0].data.length = header_len;
+ iov = (krb5_crypto_iov *)calloc(num_data + 2, sizeof(krb5_crypto_iov));
+ if (iov == NULL)
+ return ENOMEM;
+
+ i = 0;
+
+ iov[i].flags = KRB5_CRYPTO_TYPE_HEADER; /* takes place of STREAM */
+ iov[i].data.data = stream->data.data;
+ iov[i].data.length = header_len;
+ i++;
+
+ for (j = 0; j < num_data; j++) {
+ if (data[j].flags == KRB5_CRYPTO_TYPE_DATA) {
+ if (got_data) {
+ free(iov);
+ return KRB5_BAD_MSIZE;
+ }
- iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
- iov[1].data.data = iov[0].data.data + iov[0].data.length;
- iov[1].data.length = stream->data.length - header_len - trailer_len;
+ got_data++;
+
+ data[j].data.data = stream->data.data + header_len;
+ data[j].data.length = stream->data.length - header_len - trailer_len;
+ }
+ if (data[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY ||
+ data[j].flags == KRB5_CRYPTO_TYPE_DATA)
+ iov[i++] = data[j];
+ }
/* XXX not self-describing with respect to length, this is the best we can do */
- iov[2].flags = KRB5_CRYPTO_TYPE_PADDING;
- iov[2].data.data = NULL;
- iov[2].data.length = 0;
+ iov[i].flags = KRB5_CRYPTO_TYPE_PADDING;
+ iov[i].data.data = NULL;
+ iov[i].data.length = 0;
+ i++;
+
+ iov[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+ iov[i].data.data = stream->data.data + stream->data.length - trailer_len;
+ iov[i].data.length = trailer_len;
+ i++;
+
+ assert(i <= num_data + 2);
- iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER;
- iov[3].data.data = stream->data.data + stream->data.length - trailer_len;
- iov[3].data.length = trailer_len;
+ ret = aead->decrypt_iov(aead, enc, hash, key, keyusage, ivec, iov, i);
- ret = aead->decrypt_iov(aead, enc, hash, key, keyusage, ivec, iov, sizeof(iov)/sizeof(iov[0]));
- if (ret == 0)
- *s_data = iov[1];
+ free(iov);
return ret;
}