Re: [openpgp] AEAD Chunk Size

"Neal H. Walfield" <> Thu, 07 March 2019 17:09 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id AC9DB129A86 for <>; Thu, 7 Mar 2019 09:09:31 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.9
X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001] autolearn=ham autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 05E9zvDBGkXZ for <>; Thu, 7 Mar 2019 09:09:29 -0800 (PST)
Received: from ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id BE730126C7E for <>; Thu, 7 Mar 2019 09:09:29 -0800 (PST)
Received: from ([] by with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.86_2) (envelope-from <>) id 1h1wWG-0000E4-6v; Thu, 07 Mar 2019 17:09:20 +0000
Date: Thu, 07 Mar 2019 18:09:19 +0100
Message-ID: <>
From: "Neal H. Walfield" <>
To: Tobias Mueller <>
Cc: Jon Callas <>, Bart Butler <>, "" <>, Vincent Breitmoser <>
In-Reply-To: <>
References: <> <> <> <> <> <> <> <>
User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM/1.14.9 (=?ISO-8859-4?Q?Goj=F2?=) APEL/10.8 EasyPG/1.0.0 Emacs/24.5 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO)
MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue")
Content-Type: text/plain; charset=US-ASCII
Archived-At: <>
Subject: Re: [openpgp] AEAD Chunk Size
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Ongoing discussion of OpenPGP issues." <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Thu, 07 Mar 2019 17:09:36 -0000

Hi Tobi,

On Sun, 03 Mar 2019 19:36:08 +0100,
Tobias Mueller wrote:
> By fixing a "chunk size" you take away the ability to benefit from AE
> for messages bigger than that size.
> Implementations could easily collect all chunks and only release the
> plaintext once all chunks check out successfully. But that could go
> wrong. And depending on implementations to get things right and clients
> to use those implementations correctly is exactly what enabled Efail to
> become an issue. I think it'd be much nicer if the protocol already
> ensures that my emails do indeed enjoy protection against modification
> rather than me having to rely too much on clients getting it right.

You're afraid of bugs.  So am I.  Dynamically resizing buffers is
error prone.  Even computing AEAD's chunk size is hard:

  #include <stdio.h>

  int chunk_size(int c) {
    return 2 << (c + 6);

  main(int argc, char *argv[]) {
    printf("%d\n", chunk_size(32));

  $ gcc -Wall a.c
  $ ./a.out

(Note that gcc doesn't even produce a warning!)

But, that's not all.  If there is the possibility of failing due to a
lack of buffer space, implementors won't bother.  And they won't
bother for a very good reason: users want to get work done.  If a
security policy prevents them from getting their work done, they will
disable it.  Or, an implementation will ignore it.  And, because it is
only a problem if there is an attack, users will be thankful for the
more "powerful" solution.

The secure implementation must be easy for both developers and users.
And the secure implementation is a small, fixed sized buffer, even if
that means the client may have to worry about truncation.

> Having said that, I understand the desire for fixing a chunk size to
> reduce complexity for implementers.  My desire as a user is to have a
> strong and resilient protocol.

Perhaps you're not a typical user :D.

> Is there another way to do real AE?

Chunked AE is still real AE: it still has ciphertext integrity; it is
just susceptible to truncation attacks.  That's not to say that
truncation attacks are not a serious issue, but I'd rather have
truncation attacks than truncation attacks *and* ciphertext modication

:) Neal

P.S.  Consider realloc.  It is only marginally easier to write this
wrong code:

  p = realloc(p, 2 * size);
  if (! p) {
      // Oops, p has been leaked!
      return ENOMEM;

than this code:

  void *temp = realloc(p, 2 * size);
  if (! temp) {
      return ENOMEM;
  p = temp;

but I see lots of instances of the former when reading code.