1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

gpg: Support decryption of the new AEAD packet

* common/openpgpdefs.h (aead_algo_t): New.
(pkttype_t): Add PKT_ENCRYPTED_AEAD.
* g10/decrypt-data.c (struct decode_filter_context_s): Add fields for
AEAD.
(aead_set_nonce_and_ad): New.
(aead_checktag): New.
(decrypt_data): Support AEAD.
(aead_underflow): New.
(aead_decode_filter): New.
* g10/dek.h (DEK): Add field use_aead.  Turn use_mdc,
algo_info_printed, and symmetric into bit flags.
* g10/mainproc.c (struct mainproc_context): Add field
seen_pkt_encrypted_aead.
(release_list): Clear it.
(have_seen_pkt_encrypted_aead): New.
(symkey_decrypt_seskey): Support AEAD.
(proc_symkey_enc): Ditto.
(proc_encrypted): Ditto.
(proc_plaintext): Ditto.
* g10/misc.c (MY_GCRY_CIPHER_MODE_EAX): New.
(openpgp_aead_test_algo): New.
(openpgp_aead_algo_name): New.
(openpgp_aead_algo_info): New.
* g10/packet.h (PKT_symkey_enc): Add field use_aead.
(PKT_user_id): Add field flags.aead
(PKT_public_key): Ditto.
(PKT_encrypted): Add fields for AEAD.
* g10/parse-packet.c (parse): Handle PKT_ENCRYPTED_AEAD.
(parse_symkeyenc): Support AEAD.
(parse_encrypted): Ditto.
(dump_sig_subpkt): Dump AEAD preference packet.
(parse_encrypted_aead): New.
--

This patch allows to decrypt data encrypted using the new AEAD
mechanism as specified in rfc4880bis.  Although preferences are used
to enable this new mode, it is useful to have at least a decryption
option in case a user switches between GnuPG 2.2 and newer versions.

The new AEAD mechanism is much faster than the current CFB+MDC and
thus 2.2 will allow faster decryption of symmetric only decryption.

This patch is based on the current master (2.3) code base and includes
a few other patches.  In particular
commit 44be675b75
(gpg: More check for symmetric key encryption.)
is included.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-04-16 08:06:27 +02:00
parent 144b95cc9d
commit 1dfe71c62b
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
10 changed files with 907 additions and 68 deletions

View file

@ -70,6 +70,10 @@
#include "../common/i18n.h"
#include "../common/zb32.h"
/* FIXME: Libgcrypt 1.9 will support EAX. Until we name this a
* requirement we hardwire the enum used for EAX. */
#define MY_GCRY_CIPHER_MODE_EAX 14
#ifdef ENABLE_SELINUX_HACKS
/* A object and a global variable to keep track of files marked as
@ -602,6 +606,80 @@ openpgp_cipher_algo_name (cipher_algo_t algo)
}
/* Return 0 if ALGO is supported. Return an error if not. */
gpg_error_t
openpgp_aead_test_algo (aead_algo_t algo)
{
/* FIXME: We currently have no easy way to test whether libgcrypt
* implements a mode. The only way we can do this is to open a
* cipher context with that mode and close it immediately. That is
* a bit costly. So we look at the libgcrypt version and assume
* nothing has been patched out. */
switch (algo)
{
case AEAD_ALGO_NONE:
break;
case AEAD_ALGO_EAX:
#if GCRYPT_VERSION_NUMBER < 0x010900
break;
#else
return 0;
#endif
case AEAD_ALGO_OCB:
return 0;
}
return gpg_error (GPG_ERR_INV_CIPHER_MODE);
}
/* Map the OpenPGP AEAD algorithm with ID ALGO to a string
* representation of the algorithm name. For unknown algorithm IDs
* this function returns "?". */
const char *
openpgp_aead_algo_name (aead_algo_t algo)
{
switch (algo)
{
case AEAD_ALGO_NONE: break;
case AEAD_ALGO_EAX: return "EAX";
case AEAD_ALGO_OCB: return "OCB";
}
return "?";
}
/* Return information for the AEAD algorithm ALGO. The corresponding
* Libgcrypt ciphermode is stored at R_MODE and the required number of
* octets for the nonce at R_NONCELEN. On error and error code is
* returned. Note that the taglen is always 128 bits. */
gpg_error_t
openpgp_aead_algo_info (aead_algo_t algo, enum gcry_cipher_modes *r_mode,
unsigned int *r_noncelen)
{
switch (algo)
{
case AEAD_ALGO_OCB:
*r_mode = GCRY_CIPHER_MODE_OCB;
*r_noncelen = 15;
break;
case AEAD_ALGO_EAX:
*r_mode = MY_GCRY_CIPHER_MODE_EAX;
*r_noncelen = 16;
break;
default:
log_error ("unsupported AEAD algo %d\n", algo);
return gpg_error (GPG_ERR_INV_CIPHER_MODE);
}
return 0;
}
/* Return 0 if ALGO is a supported OpenPGP public key algorithm. */
int
openpgp_pk_test_algo (pubkey_algo_t algo)