rnpgp / rnp

RNP: high performance C++ OpenPGP library used by Mozilla Thunderbird
https://www.rnpgp.org
Other
201 stars 55 forks source link

Support AEAD #439

Closed ronaldtse closed 6 years ago

ronaldtse commented 7 years ago

Description

rnp should support AEAD, OCB and GCM. In the latest draft only EAX is supported, we should add OCB and GCM.

OpenPGP AEAD is specified in the ongoing draft of RFC 4880-bis: https://gitlab.com/openpgp-wg/rfc4880bis

Relevant file: https://gitlab.com/openpgp-wg/rfc4880bis/blob/master/middle.mkd

Relevant portions below:

0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
       Symmetric-Key Encrypted Session Key Packets (packet 3)

Symmetric-Key Encrypted Session Key Packets (Tag 3)

{5.3} Symmetric-Key Encrypted Session Key Packets (Tag 3)

The Symmetric-Key Encrypted Session Key packet holds the symmetric-key
encryption of a session key used to encrypt a message.  Zero or more
Public-Key Encrypted Session Key packets and/or Symmetric-Key
Encrypted Session Key packets may precede a Symmetrically Encrypted
Data packet that holds an encrypted message.  The message is encrypted
with a session key, and the session key is itself encrypted and stored
in the Encrypted Session Key packet or the Symmetric-Key Encrypted
Session Key packet.

If the Symmetrically Encrypted Data packet is preceded by one or more
Symmetric-Key Encrypted Session Key packets, each specifies a
passphrase that may be used to decrypt the message.  This allows a
message to be encrypted to a number of public keys, and also to one or
more passphrases.  This packet type is new and is not generated by
PGP 2.x or PGP 5.0.

A version 4 Symmetric-Key Encrypted Session Key packet consists of:

A one-octet version number with value 4.
A one-octet number describing the symmetric algorithm used.
A string-to-key (S2K) specifier, length as defined above.
Optionally, the encrypted session key itself, which is
decrypted with the string-to-key object.

If the encrypted session key is not present (which can be detected on
the basis of packet length and S2K specifier size), then the S2K
algorithm applied to the passphrase produces the session key for
decrypting the file, using the symmetric cipher algorithm from the
Symmetric-Key Encrypted Session Key packet.

If the encrypted session key is present, the result of applying the
S2K algorithm to the passphrase is used to decrypt just that encrypted
session key field, using CFB mode with an IV of all zeros.  The
decryption result consists of a one-octet algorithm identifier that
specifies the symmetric-key encryption algorithm used to encrypt the
following Symmetrically Encrypted Data packet, followed by the session
key octets themselves.

Note: because an all-zero IV is used for this decryption, the S2K
specifier MUST use a salt value, either a Salted S2K or an
Iterated-Salted S2K.  The salt value will ensure that the decryption
key is not repeated even if the passphrase is reused.

A version 5 Symmetric-Key Encrypted Session Key packet consists of:

A one-octet version number with value 5.
A one-octet cipher algorithm.
A one-octet AEAD algorithm.
A string-to-key (S2K) specifier, length as defined above.
A starting initialization vector of size specified by the AEAD
algorithm.
The encrypted session key itself, which is decrypted with the
string-to-key object using the given cipher and AEAD mode.
A final, summary authentication tag for the AEAD mode.

The encrypted session key is encrypted exactly as an AEAD Encrypted Data
packet with a chunk size octet of 10 would be.  This implicit chunk size
octet is included in the normal calculations of additional data.

AEAD Encrypted Data Packet (Tag 20)

This packet contains data encrypted with an authenticated encryption and
additional data (AEAD) construction.  When it has been decrypted, it
will typically contain other packets (often a Literal Data packet or
Compressed Data packet).

The body of this packet consists of:

A one-octet version number.  The only currently defined value
is 1.
A one-octet cipher algorithm.
A one-octet AEAD algorithm.
A one-octet chunk size.
A starting initialization vector of size specified by the AEAD
algorithm.
Encrypted data, the output of the selected symmetric-key cipher
operating in the given AEAD mode.
A final, summary authentication tag for the AEAD mode.

An AEAD encrypted data packet consists of one or more chunks of data.
The plaintext of each chunk is of a size specified using the chunk size
octet using the method specified below.

The encrypted data consists of the encryption of each chunk of
plaintext, followed immediately by the relevant authentication tag.  If
the last chunk of plaintext is smaller than the chunk size, the
ciphertext for that data may be shorter; it is nevertheless followed by
a full authentication tag.

For each chunk, the AEAD construction is given the packet header,
version number, cipher algorithm octet, AEAD algorithm octet, chunk size
octet, and an eight-octet, big-endian chunk index as additional
data.  The index of the first chunk is zero.

After the final chunk, the AEAD algorithm is used to produce a final
authentication tag encrypting the empty string.  This AEAD instance is
given the additional data specified above, plus an eight-octet,
big-endian value specifying the total number of plaintext octets
encrypted.  This allows detection of a truncated ciphertext.

The chunk size octet specifies the size of chunks using the following
formula (in C), where c is the chunk size octet:

    chunk_size = ((uint64_t)1 << (c + 6))
An implementation MUST support chunk size octets with values from 0 to

 Chunk size octets with other values are reserved for future
extensions.

A new random initialization vector MUST be used for each message.

EAX Mode

The only currently defined AEAD algorithm is EAX Mode.
This algorithm can only use block ciphers with 16-octet
blocks.  The starting initialization vector and authentication tag are
both 16 octets long.

The starting initialization vector for this mode MUST be unique and
unpredictable.

The nonce for EAX mode is computed by treating the starting
initialization vector as a 16-octet, big-endian value and
exclusive-oring the low eight octets of it with the chunk index.

The security of EAX requires that the nonce is never reused, hence the
requirement that the starting initialization vector be unique.

AEAD Algorithms

   ID  Algorithm
    1  EAX [](#EAX)
100--110  Private/Experimental algorithm
kriskwiatkowski commented 7 years ago

FYI: I'm happy to take care of this stuff after librepgp

ronaldtse commented 7 years ago

Thanks @flowher ! When do you think we could have this done?

kriskwiatkowski commented 7 years ago

@ronaldtse end of september if I put on hold repgp. I'm assuming OCB, EAX and GCM implementations are in Botan (which seems to be the case). But maybe you would prefer have it done quicker (as I'm working only in the evenings, it will take me more time). So than don't hesitate to assign differently.

ronaldtse commented 7 years ago

@flowher we should definitely finish repgp first. Indeed those implementations are in Botan.

@riboseinc/rnp is anyone interested + have time for AEAD support? Thanks!

ni4 commented 7 years ago

@ronaldtse @flowher I can take this after password encryption - anyway I digged into symmetric crypto.

ni4 commented 6 years ago

@ronaldtse @dewyatt @flowher

During working on AEAD I got the following questions related to rfc4880bis:

AEAD Encrypted Data Packet (Tag 20). For each chunk, the AEAD construction is given the packet header, version number, cipher algorithm octet, AEAD algorithm octet, chunk size octet, and an eight-octet, big-endian chunk index as additional data.

What is meant under the packet header here? While AEAD construction may be used in SESK, AEAD Encrypted data packet and AEAD encrypted secret key, would this mean that 'packet header' will be the full PGP packet header (i.e. tag + flags + packet length bytes)?

{5.1} Public-Key Encrypted Session Key Packets (Tag 1) ...Zero or more Public-Key Encrypted Session Key packets and/or Symmetric-Key Encrypted Session Key packets may precede a Symmetrically Encrypted Data Packet...

and encrypted data is still the old one - one octet of symmetric algorithm + following symmetric key's octets. Should not this be updated for the AEAD, at least mentioning that this packet may precede AEAD Encrypted Data Packet? Given construction still can be used with AEAD without the changes, but probably some clarification should be made in the RFC draft.

kriskwiatkowski commented 6 years ago

will be the full PGP packet header (i.e. tag + flags + packet length bytes)?

That's how I understand it, but it should be OK as long as same information is available during encryption and decryption, isn't? That's just AAD

Should not this be updated for the AEAD?

Indeed, seems draft wasn't updated yet

ronaldtse commented 6 years ago

BTW, I'd like to point out that the latest 4880bis draft is at 03, which includes our patch to include OCB:

https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-03

ni4 commented 6 years ago

@ronaldtse Thanks. OCB looks good, however I think it would be logical to implement it after the AEAD :) Also looks like paragraph with OCB description is missing the clause stating the message IV length (it's logical that it must be 15 octets as a nonce, but)

ronaldtse commented 6 years ago

So @ni4 is pretty much done with AEAD-EAX! This makes RNP the first OpenPGP implementation to support EAX and the new AEAD format in 4880bis 👍

ni4 commented 6 years ago

AEAD is implemented for a while so closing this.