diff options
author | Sam Hartman <hartmans@mit.edu> | 2008-12-01 16:44:26 +0000 |
---|---|---|
committer | Sam Hartman <hartmans@mit.edu> | 2008-12-01 16:44:26 +0000 |
commit | 0d17a0945cc7869aebf8cb52471836d42eddad30 (patch) | |
tree | 2756abee1e3e68200ba27217932ac558a6208a68 | |
parent | ce3096bed2784699499e0bc944a8f4ad08c0d199 (diff) | |
download | krb5-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.c | 66 |
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; } |