diff options
author | Werner Koch <wk@gnupg.org> | 2018-01-24 13:45:05 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2018-01-24 13:45:05 +0100 |
commit | ff1bdc23d9f1693c1add7c1fe8d218b7bf743e31 (patch) | |
tree | b4d831af02681bd7cbf7531d9a1d3eb9cd39e8e0 /g10/cipher-aead.c | |
parent | gpg: Rename a variable in decrypt-data for clarity. (diff) | |
download | gnupg2-ff1bdc23d9f1693c1add7c1fe8d218b7bf743e31.tar.xz gnupg2-ff1bdc23d9f1693c1add7c1fe8d218b7bf743e31.zip |
gpg: Fix AEAD encryption for chunk sizes other than 64 KiB.
* g10/cipher-aead.c (do_flush): Init ERR. Fix remaining chunklen
computation.
(do_free): Add dummy encryption. Close the cipher handle.
* g10/decrypt-data.c (aead_underflow): Rewrite.
--
Until we have integrated test into the test suite extensive tests can
also be done with a script like this:
--8<---------------cut here---------------start------------->8---
#!/bin/sh
set -e
GPG="../g10/gpg --rfc4880bis --pinentry-mode=loopback"
GPG="$GPG --passphrase abc --batch"
MKTDATA="$HOME/b/gnupg-2.0/tools/mk-tdata"
for chunksize in 6 7 12 13 14 30; do
for count in $(seq 1 200) $(seq 8100 8200) \
$(seq 16350 16400) $(seq 20000 20100); do
if [ ! -f "testfile-$count" ]; then
$MKTDATA $count >"testfile-$count"
fi
echo "testing chunk size 2^$chunksize with $count bytes"
$GPG --force-aead --aead-algo ocb --s2k-mode 0 --cipher AES -v -z 0 \
-c --chunk-size $chunksize \
<"testfile-$count" >"testfile-$count.gpg" 2>/dev/null
$GPG -vd <"testfile-$count.gpg" >"testfile-$count.out" 2>/dev/null
if ! cmp "testfile-$count" "testfile-$count.out"; then
echo "FAILED comparing count $count" >&2
exit 1
fi
done
done
echo All good
--8<---------------cut here---------------end--------------->8---
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g10/cipher-aead.c')
-rw-r--r-- | g10/cipher-aead.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c index 9cb57bdc6..573bb43fb 100644 --- a/g10/cipher-aead.c +++ b/g10/cipher-aead.c @@ -271,7 +271,7 @@ write_final_chunk (cipher_filter_context_t *cfx, iobuf_t a) static gpg_error_t do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) { - gpg_error_t err; + gpg_error_t err = 0; int newchunk = 0; size_t n; @@ -285,9 +285,9 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) else n = cfx->bufsize - cfx->buflen; - if (cfx->chunklen + n >= cfx->chunksize) + if (cfx->chunklen + cfx->buflen + n >= cfx->chunksize) { - size_t n1 = cfx->chunksize - cfx->chunklen; + size_t n1 = cfx->chunksize - (cfx->chunklen + cfx->buflen); newchunk = 1; if (DBG_FILTER) log_debug ("chunksize %ju reached;" @@ -305,8 +305,8 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) if (cfx->buflen == cfx->bufsize || newchunk) { if (DBG_FILTER) - log_debug ("encrypting: buflen=%zu %s %p\n", - cfx->buflen, newchunk?"(newchunk)":"", cfx->cipher_hd); + log_debug ("encrypting: buflen=%zu %s n=%zu\n", + cfx->buflen, newchunk?"(newchunk)":"", n); if (newchunk) gcry_cipher_final (cfx->cipher_hd); if (!DBG_FILTER) @@ -372,6 +372,9 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a) { gpg_error_t err = 0; + if (DBG_FILTER) + log_debug ("do_free: buflen=%zu\n", cfx->buflen); + /* FIXME: Check what happens if we just wrote the last chunk and no * more bytes were to encrypt. We should then not call finalize and * write the auth tag again, right? May this at all happen? */ @@ -394,6 +397,8 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a) cfx->chunklen += cfx->buflen; cfx->total += cfx->buflen; } + else /* Dummy encryption. */ + gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, 0, NULL, 0); /* Get and write the authentication tag. */ if (DBG_FILTER) @@ -411,8 +416,8 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a) leave: xfree (cfx->buffer); cfx->buffer = NULL; - /* gcry_cipher_close (cfx->cipher_hd); */ - /* cfx->cipher_hd = NULL; */ + gcry_cipher_close (cfx->cipher_hd); + cfx->cipher_hd = NULL; return err; } |