[PATCH GnuPG] g10/mainproc: avoid extra hash contexts when decrypting MDC input

Jussi Kivilinna jussi.kivilinna at iki.fi
Tue Feb 8 18:22:30 CET 2022


* g10/mainproc.c (mainproc_context): New member
'seen_pkt_encrypted_mdc'.
(release_list): Clear 'seen_pkt_encrypted_mdc'.
(proc_encrypted): Set 'seen_pkt_encrypted_mdc'.
(have_seen_pkt_encrypted_aead): Rename to...
(have_seen_pkt_encrypted_aead_or_mdc): ...this and add check for
'seen_pkt_encrypted_mdc'.
(proc_plaintext): Do not enable extra hash contexts when decrypting
MDC input.
--

Avoiding extra hash contexts speeds up CFB/MDC decryption quite
a lot. For example, decrypting symmetric-key AES-256 encrypted
4 GiB file from RAM to /dev/null sees ~3.4x speed increase on
AMD Ryzen 5800X:

 AES256.CFB encryption: 783 MB/s
 AES256.CFB decryption: 386 MB/s (before)
 AES256.CFB encryption: 1.3 GB/s (after patch)

Note, AEAD is still significantly faster:

 AES256.OCB encryption: 2.2 GB/s
 AES256.OCB decryption: 3.0 GB/s

GnuPG-bug-id: T5820
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 g10/mainproc.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/g10/mainproc.c b/g10/mainproc.c
index 1ee5b9a6e..aa028e91b 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -88,6 +88,7 @@ struct mainproc_context
   ulong symkeys;    /* Number of symmetrically encrypted session keys.  */
   struct pubkey_enc_list *pkenc_list; /* List of encryption packets. */
   int seen_pkt_encrypted_aead; /* PKT_ENCRYPTED_AEAD packet seen. */
+  int seen_pkt_encrypted_mdc;  /* PKT_ENCRYPTED_MDC packet seen. */
   struct {
     unsigned int sig_seen:1;      /* Set to true if a signature packet
                                      has been seen. */
@@ -140,6 +141,7 @@ release_list( CTX c )
   c->any.uncompress_failed = 0;
   c->last_was_session_key = 0;
   c->seen_pkt_encrypted_aead = 0;
+  c->seen_pkt_encrypted_mdc = 0;
   xfree (c->dek);
   c->dek = NULL;
 }
@@ -547,6 +549,8 @@ proc_encrypted (CTX c, PACKET *pkt)
 
   if (pkt->pkttype == PKT_ENCRYPTED_AEAD)
     c->seen_pkt_encrypted_aead = 1;
+  if (pkt->pkttype == PKT_ENCRYPTED_MDC)
+    c->seen_pkt_encrypted_mdc = 1;
 
   if (early_plaintext)
     {
@@ -823,7 +827,7 @@ proc_encrypted (CTX c, PACKET *pkt)
 
 
 static int
-have_seen_pkt_encrypted_aead( CTX c )
+have_seen_pkt_encrypted_aead_or_mdc( CTX c )
 {
   CTX cc;
 
@@ -831,6 +835,8 @@ have_seen_pkt_encrypted_aead( CTX c )
     {
       if (cc->seen_pkt_encrypted_aead)
 	return 1;
+      if (cc->seen_pkt_encrypted_mdc)
+	return 1;
     }
 
   return 0;
@@ -914,7 +920,7 @@ proc_plaintext( CTX c, PACKET *pkt )
         }
     }
 
-  if (!any && !opt.skip_verify && !have_seen_pkt_encrypted_aead(c))
+  if (!any && !opt.skip_verify && !have_seen_pkt_encrypted_aead_or_mdc(c))
     {
       /* This is for the old GPG LITERAL+SIG case.  It's not legal
          according to 2440, so hopefully it won't come up that often.
-- 
2.32.0




More information about the Gnupg-devel mailing list