1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

gpg: Support OCB encryption.

* g10/build-packet.c (do_encrypted_aead): New.
(do_symkey_enc): Handle version 5.
(build_packet): Support the ENCRYPTED_AEAD packet.
* g10/cipher.c (MIN_PARTIAL_SIZE): Remove unused macro.
(AEAD_ENC_BUFFER_SIZE): New macro.
(my_iobuf_write): New.
(write_header): Rename to write_cfb_header.  Adjust caller.
(set_ocb_nonce_and_ad): New.
(write_ocb_header): New.
(write_ocb_auth_tag): New.
(write_ocb_final_chunk): New.
(do_ocb_flush): New.
(do_ocb_free): New.
(cipher_filter_ocb): New.
* g10/filter.h (cipher_filter_context_t): Add fields for AEAD.
* g10/encrypt.c (encrypt_symmetric): For the use of a session key in
OCB mode.
(encrypt_seskey): Revamp to support OCB.
(use_aead): New.
(encrypt_simple): Support OCB.
(write_symkey_enc): Ditto.
(encrypt_crypt): Ditto.
(encrypt_filter): Handle OCB.
* g10/options.h (opt): Add field force_ocb.
* g10/gpg.c (oForceOCB): New.
(opts): New option "--force-ocb".
(main): Set force_ocb option.
* g10/gpgcompose.c (encrypt_seskey): New.
* g10/keygen.c (aead_available): New global var.
(keygen_set_std_prefs): Set AEAD feature by default in GNUPG mode. Add
parings of aead feature flag.
(keygen_get_std_prefs): Set aead flag.
(add_feature_aead): New.
(keygen_upd_std_prefs): Set OCB as preference if AEAD is enabled.
* g10/pkclist.c (select_aead_from_pklist): New.
(warn_missing_aead_from_pklist): New.
(select_mdc_from_pklist): Remove this unused function.
--

This extends the long available OCB and EAX decryption feature.  Due
to the meanwhile expired patent on OCB there is no more reason for
using EAX.  Thus we forcefully use OCB if the AEAD feature flag is set
on a key.

In GNUPG mode new keys are now created with the AEAD feature flag set.
Option --rfc4880 is one way to disable this.

GnuPG-bug-id: 6263
This commit is contained in:
Werner Koch 2022-10-31 14:33:10 +01:00
parent aa397fdcdb
commit a545e14e8a
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
15 changed files with 942 additions and 126 deletions

View file

@ -135,6 +135,8 @@ static int nhash_prefs;
static byte zip_prefs[MAX_PREFS];
static int nzip_prefs;
static int mdc_available,ks_modify;
static int aead_available;
static gpg_error_t parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
const char *algostr, const char *usagestr,
@ -354,8 +356,12 @@ keygen_set_std_prefs (const char *string,int personal)
byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS];
int nsym=0, nhash=0, nzip=0, val, rc=0;
int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */
int ocb;
char dummy_string[20*4+1]; /* Enough for 20 items. */
/* Use OCB as default in GnuPG and de-vs mode. */
ocb = GNUPG;
if (!string || !ascii_strcasecmp (string, "default"))
{
if (opt.def_preference_list)
@ -480,14 +486,24 @@ keygen_set_std_prefs (const char *string,int personal)
if(set_one_pref(val,3,tok,zip,&nzip))
rc=-1;
}
else if (ascii_strcasecmp(tok,"mdc")==0)
else if (!ascii_strcasecmp(tok, "mdc")
|| !ascii_strcasecmp(tok, "[mdc]"))
mdc=1;
else if (ascii_strcasecmp(tok,"no-mdc")==0)
else if (!ascii_strcasecmp(tok, "no-mdc")
|| !ascii_strcasecmp(tok, "[no-mdc]"))
mdc=0;
else if (ascii_strcasecmp(tok,"ks-modify")==0)
else if (!ascii_strcasecmp(tok, "ks-modify")
|| !ascii_strcasecmp(tok, "[ks-modify]"))
modify=1;
else if (ascii_strcasecmp(tok,"no-ks-modify")==0)
else if (!ascii_strcasecmp(tok,"no-ks-modify")
|| !ascii_strcasecmp(tok,"[no-ks-modify]"))
modify=0;
else if (!ascii_strcasecmp(tok,"aead")
|| !ascii_strcasecmp(tok,"[aead]"))
ocb = 1;
else if (!ascii_strcasecmp(tok,"no-aead")
|| !ascii_strcasecmp(tok,"[no-aead]"))
ocb = 0;
else
{
log_info (_("invalid item '%s' in preference string\n"),tok);
@ -578,6 +594,7 @@ keygen_set_std_prefs (const char *string,int personal)
memcpy (hash_prefs, hash, (nhash_prefs=nhash));
memcpy (zip_prefs, zip, (nzip_prefs=nzip));
mdc_available = mdc;
aead_available = ocb;
ks_modify = modify;
prefs_initialized = 1;
}
@ -586,6 +603,7 @@ keygen_set_std_prefs (const char *string,int personal)
return rc;
}
/* Return a fake user ID containing the preferences. Caller must
free. */
PKT_user_id *
@ -624,6 +642,7 @@ keygen_get_std_prefs(void)
uid->prefs[j].value=0;
uid->flags.mdc=mdc_available;
uid->flags.aead=aead_available;
uid->flags.ks_modify=ks_modify;
return uid;
@ -670,6 +689,49 @@ add_feature_mdc (PKT_signature *sig,int enabled)
xfree (buf);
}
static void
add_feature_aead (PKT_signature *sig, int enabled)
{
const byte *s;
size_t n;
int i;
char *buf;
s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n );
if (s && n && ((enabled && (s[0] & 0x02)) || (!enabled && !(s[0] & 0x02))))
return; /* Already set or cleared */
if (!s || !n)
{ /* Create a new one */
n = 1;
buf = xmalloc_clear (n);
}
else
{
buf = xmalloc (n);
memcpy (buf, s, n);
}
if (enabled)
buf[0] |= 0x02; /* AEAD supported */
else
buf[0] &= ~0x02;
/* Are there any bits set? */
for (i=0; i < n; i++)
if (buf[i])
break;
if (i == n)
delete_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES);
else
build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n);
xfree (buf);
}
static void
add_keyserver_modify (PKT_signature *sig,int enabled)
{
@ -731,6 +793,14 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque)
delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_SYM);
}
if (aead_available) /* The only preference is AEAD_ALGO_OCB. */
build_sig_subpkt (sig, SIGSUBPKT_PREF_AEAD, "\x02", 1);
else
{
delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_AEAD);
delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_AEAD);
}
if (nhash_prefs)
build_sig_subpkt (sig, SIGSUBPKT_PREF_HASH, hash_prefs, nhash_prefs);
else
@ -747,8 +817,9 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque)
delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_COMPR);
}
/* Make sure that the MDC feature flag is set if needed. */
/* Make sure that the MDC and AEAD feature flags are set as needed. */
add_feature_mdc (sig,mdc_available);
add_feature_aead (sig, aead_available);
add_keyserver_modify (sig,ks_modify);
keygen_add_keyserver_url(sig,NULL);