aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/cipher-aead.c81
-rw-r--r--g10/decrypt-data.c16
2 files changed, 55 insertions, 42 deletions
diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c
index 1457baaa5..f9a996c80 100644
--- a/g10/cipher-aead.c
+++ b/g10/cipher-aead.c
@@ -200,9 +200,6 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a)
if (err)
return err;
- err = set_nonce_and_ad (cfx, 0);
- if (err)
- return err;
cfx->wrote_header = 1;
leave:
@@ -238,9 +235,6 @@ write_final_chunk (cipher_filter_context_t *cfx, iobuf_t a)
gpg_error_t err;
char dummy[1];
- if (cfx->chunklen)
- cfx->chunkindex++;
-
err = set_nonce_and_ad (cfx, 1);
if (err)
goto leave;
@@ -297,8 +291,18 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
if (cfx->buflen == cfx->bufsize || finalize)
{
if (DBG_FILTER)
- log_debug ("encrypting: buflen=%zu %s n=%zu\n",
- cfx->buflen, finalize?"(finalize)":"", n);
+ log_debug ("encrypting: size=%zu buflen=%zu %s n=%zu\n",
+ size, cfx->buflen, finalize?"(finalize)":"", n);
+
+ if (!cfx->chunklen)
+ {
+ if (DBG_FILTER)
+ log_debug ("start encrypting a new chunk\n");
+ err = set_nonce_and_ad (cfx, 0);
+ if (err)
+ goto leave;
+ }
+
if (finalize)
gcry_cipher_final (cfx->cipher_hd);
if (DBG_FILTER)
@@ -314,8 +318,10 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
* be called after gcry_cipher_final and before
* gcry_cipher_gettag - at least with libgcrypt 1.8 and OCB
* mode. */
- gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen,
- NULL, 0);
+ err = gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen,
+ NULL, 0);
+ if (err)
+ goto leave;
if (finalize && DBG_FILTER)
log_printhex (cfx->buffer, cfx->buflen, "ciphr(1):");
err = my_iobuf_write (a, cfx->buffer, cfx->buflen);
@@ -328,19 +334,14 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
if (finalize)
{
if (DBG_FILTER)
- log_debug ("chunklen=%ju total=%ju\n",
+ log_debug ("writing tag: chunklen=%ju total=%ju\n",
(uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
err = write_auth_tag (cfx, a);
if (err)
goto leave;
- if (DBG_FILTER)
- log_debug ("starting a new chunk (cur size=%zu)\n", size);
cfx->chunkindex++;
cfx->chunklen = 0;
- err = set_nonce_and_ad (cfx, 0);
- if (err)
- goto leave;
finalize = 0;
}
}
@@ -361,38 +362,42 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a)
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? */
-
- /* Call finalize which will also allow us to flush out and encrypt
- * the last arbitrary length buffer. */
- gcry_cipher_final (cfx->cipher_hd);
-
- /* Encrypt any remaining bytes. */
if (cfx->buflen)
{
if (DBG_FILTER)
- log_debug ("processing last %zu bytes of the last chunk\n",
- cfx->buflen);
- gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen, NULL, 0);
+ log_debug ("encrypting last %zu bytes of the last chunk\n",cfx->buflen);
+
+ if (!cfx->chunklen)
+ {
+ if (DBG_FILTER)
+ log_debug ("start encrypting a new chunk\n");
+ err = set_nonce_and_ad (cfx, 0);
+ if (err)
+ goto leave;
+ }
+
+ gcry_cipher_final (cfx->cipher_hd);
+ err = gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen,
+ NULL, 0);
+ if (err)
+ goto leave;
err = my_iobuf_write (a, cfx->buffer, cfx->buflen);
if (err)
goto leave;
/* log_printhex (cfx->buffer, cfx->buflen, "wrote:"); */
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)
- log_debug ("chunklen=%ju total=%ju\n",
- (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
- err = write_auth_tag (cfx, a);
- if (err)
- goto leave;
+ /* Get and write the authentication tag. */
+ if (DBG_FILTER)
+ log_debug ("writing tag: chunklen=%ju total=%ju\n",
+ (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
+ err = write_auth_tag (cfx, a);
+ if (err)
+ goto leave;
+ cfx->chunkindex++;
+ cfx->chunklen = 0;
+ }
/* Write the final chunk. */
if (DBG_FILTER)
diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
index 5594d9055..a3151b5ed 100644
--- a/g10/decrypt-data.c
+++ b/g10/decrypt-data.c
@@ -770,17 +770,25 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
if (dfx->eof_seen)
{
- if (DBG_FILTER)
- log_debug ("eof seen: holdback buffer has the last and final tag\n");
- log_assert (dfx->holdbacklen >= 32);
if (dfx->chunklen)
{
+ if (DBG_FILTER)
+ log_debug ("eof seen: holdback has the last and final tag\n");
+ log_assert (dfx->holdbacklen >= 32);
err = aead_checktag (dfx, 0, dfx->holdback);
if (err)
goto leave;
dfx->chunklen = 0;
dfx->chunkindex++;
+ off = 16;
+ }
+ else
+ {
+ if (DBG_FILTER)
+ log_debug ("eof seen: holdback has the final tag\n");
+ log_assert (dfx->holdbacklen >= 16);
+ off = 0;
}
/* Check the final chunk. */
@@ -796,7 +804,7 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
gpg_strerror (err));
goto leave;
}
- err = aead_checktag (dfx, 1, dfx->holdback+16);
+ err = aead_checktag (dfx, 1, dfx->holdback+off);
if (err)
goto leave;
err = gpg_error (GPG_ERR_EOF);