[Openpgp-dt] SEDfail and open questions

Justus Winter <justus@sequoia-pgp.org> Wed, 13 October 2021 15:42 UTC

Return-Path: <justus@sequoia-pgp.org>
X-Original-To: openpgp-dt@ietfa.amsl.com
Delivered-To: openpgp-dt@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 7D3AD3A0B9D for <openpgp-dt@ietfa.amsl.com>; Wed, 13 Oct 2021 08:42:07 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.897
X-Spam-Level:
X-Spam-Status: No, score=-1.897 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_NONE=0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FYpxWeJOQo77 for <openpgp-dt@ietfa.amsl.com>; Wed, 13 Oct 2021 08:42:02 -0700 (PDT)
Received: from harrington.uberspace.de (harrington.uberspace.de [185.26.156.85]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id E1D863A0A3F for <openpgp-dt@ietf.org>; Wed, 13 Oct 2021 08:42:00 -0700 (PDT)
Received: (qmail 9608 invoked from network); 13 Oct 2021 15:41:55 -0000
Received: from localhost (HELO localhost) (127.0.0.1) by harrington.uberspace.de with SMTP; 13 Oct 2021 15:41:55 -0000
From: Justus Winter <justus@sequoia-pgp.org>
To: "openpgp-dt@ietf.org" <openpgp-dt@ietf.org>
Date: Wed, 13 Oct 2021 17:41:54 +0200
Message-ID: <87pms9q6d9.fsf@europ.lan>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="==-=-="; micalg="pgp-sha512"; protocol="application/pgp-signature"
Archived-At: <https://mailarchive.ietf.org/arch/msg/openpgp-dt/TfFavKog0qQSMBjDeb4nSVOeErA>
Subject: [Openpgp-dt] SEDfail and open questions
X-BeenThere: openpgp-dt@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OpenPGP working group design team <openpgp-dt.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/openpgp-dt>, <mailto:openpgp-dt-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/openpgp-dt/>
List-Post: <mailto:openpgp-dt@ietf.org>
List-Help: <mailto:openpgp-dt-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/openpgp-dt>, <mailto:openpgp-dt-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 13 Oct 2021 15:42:08 -0000

Hello,

tl;dr: I think SED support is broken in many implementations, including
GnuPG, and this creates a accidental compatibility with SEIPD,
exacerbating the Efail problem.

I was in the process of writing a stern warning against the
Symmetrically Encrypted Data (SED) packet.  I always thought that you
could convert a Symmetrically Encrypted Integrity Protected Data (SEIPD)
packet into a SED packet by changing the header and stripping off the
MDC packet.  However, I don't think that is true, with a caveat.

The reason why you cannot (at least trivially) convert a SEIPD packet
into a SED packet is that the SED packet uses CFB with a special
re-synchronization step (see [0]) after the initialization, whereas
SEIPD does not do this step.  Therefore, the ciphers modes should not be
compatible.

0: https://openpgp-wg.gitlab.io/rfc4880bis/#name-openpgp-cfb-mode

Then, I wanted to confirm that my reading of the RFC wrt the
re-synchronization step matches what is actually implemented.  I set out
to read some implementations.

For GnuPG, this is handled in libgcrypt by the function cipher_sync.  It
is activated using the flag GCRY_CIPHER_ENABLE_SYNC.  However, I don't
think passing this flag to gcry_cipher_open actually causes the sync
operation to be executed.  I have written a program that seems to
support this (see attachment):

cargo run
   Compiling gcrypt-cfb-sync-test v0.1.0 (/home/teythoon/repos/pep/tmp/gcrypt-cfb-sync-test)
    Finished dev [unoptimized + debuginfo] target(s) in 0.26s
     Running `/home/teythoon/repos/pep/tmp/gcrypt-cfb-sync-test/target/debug/gcrypt-cfb-sync-test`
Encrypting without sync, decrypting without sync... expecting success, decryption successful.
Encrypting without sync, decrypting with sync... expecting failure, decryption successful.
Encrypting with sync, decrypting without sync... expecting failure, decryption successful.
Encrypting with sync, decrypting with sync... expecting success, decryption successful.

It follows that GnuPG (and dkgpg which also uses libgcrypt) does not
correctly implement SED, but a SED variant that does not do the CFB
re-synchronization step.

Reading OpenPGP.js, I don't see the re-synchronization either.

Reading RNP, I see that they are doing the re-synchronization.

What's the takeaway?  If SED is broken in GnuPG and noone complained,
that likely means that SED is no longer in use, and that is a good
thing.  However, the accidental compatibility allows the conversion of
SEIPD packets into SED packets, paving the way for Efail-style attacks
on implementations willing to decrypt SED packets via the packet
downgrade.

Please check my findings.

Justus