mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-30 16:17:02 +01:00
gpg: Add option and preference framework for AEAD.
* common/openpgpdefs.h (aead_algo_t): New. (SIGSUBPKT_PREF_AEAD): New. * g10/gpg.c (oAEADAlgo, oPersonalAEADPreferences): New. (opts): New options --aead-algo and --personal-aead-preferences. (set_compliance_option): Clar aead algo. (main): Parse and check the new options * g10/options.h (struct opt): Add fields def_aead_algo and personal_aead_prefs. * g10/packet.h (PREFTYPE_AEAD): New enum value. (PKT_user_id): Add field flags.aead. (PKT_public_key): Add field flags.aead. * g10/pkclist.c (select_algo_from_prefs): Support PREFTYPE_AEAD. * g10/getkey.c (fixup_uidnode): Set AEAD flag. (merge_selfsigs): Ditto. * g10/kbnode.c (dump_kbnode): Show aead flag. * g10/keyedit.c (show_prefs): Ditto. (show_key_with_all_names_colon): Ditto. * g10/keygen.c (aead_presf, n_aead_prefs): New vars. (set_one_pref): Suppport PREFTYPE_AEAD. (keygen_set_std_prefs): Parse AEAD preferences. (keygen_get_std_prefs): Ditto. (add_feature_aead): New. (keygen_upd_std_prefs): Call that and build AEAD pref packet. * g10/main.h (DEFAULT_AEAD_ALGO): New const. * g10/misc.c (openpgp_aead_test_algo): New. (openpgp_aead_algo_name): New. (string_to_aead_algo): New. (default_aead_algo): New. -- This is only used in --rfc4880bis mode and not really tested. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
945381c4c2
commit
8217cd4936
@ -115,7 +115,8 @@ typedef enum
|
||||
SIGSUBPKT_FEATURES = 30, /* Feature flags. */
|
||||
|
||||
SIGSUBPKT_SIGNATURE = 32, /* Embedded signature. */
|
||||
SIGSUBPKT_ISSUER_FPR = 33, /* EXPERIMENTAL: Issuer fingerprint. */
|
||||
SIGSUBPKT_ISSUER_FPR = 33, /* Issuer fingerprint. */
|
||||
SIGSUBPKT_PREF_AEAD = 34, /* Preferred AEAD algorithms. */
|
||||
|
||||
SIGSUBPKT_FLAG_CRITICAL = 128
|
||||
}
|
||||
@ -142,6 +143,15 @@ typedef enum
|
||||
cipher_algo_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AEAD_ALGO_NONE = 0,
|
||||
AEAD_ALGO_EAX = 1,
|
||||
AEAD_ALGO_OCB = 2
|
||||
}
|
||||
aead_algo_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PUBKEY_ALGO_RSA = 1,
|
||||
|
11
g10/getkey.c
11
g10/getkey.c
@ -2539,6 +2539,12 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
|
||||
if (p && n && (p[0] & 0x01))
|
||||
uid->flags.mdc = 1;
|
||||
|
||||
/* See whether we have the AEAD feature. */
|
||||
uid->flags.aead = 0;
|
||||
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
|
||||
if (p && n && (p[0] & 0x01))
|
||||
uid->flags.aead = 1;
|
||||
|
||||
/* And the keyserver modify flag. */
|
||||
uid->flags.ks_modify = 1;
|
||||
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n);
|
||||
@ -3357,6 +3363,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
||||
PKT_public_key *main_pk;
|
||||
prefitem_t *prefs;
|
||||
unsigned int mdc_feature;
|
||||
unsigned int aead_feature;
|
||||
|
||||
if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
|
||||
{
|
||||
@ -3418,7 +3425,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
||||
* all preferences.
|
||||
* Do a similar thing for the MDC feature flag. */
|
||||
prefs = NULL;
|
||||
mdc_feature = 0;
|
||||
mdc_feature = aead_feature = 0;
|
||||
for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next)
|
||||
{
|
||||
if (k->pkt->pkttype == PKT_USER_ID
|
||||
@ -3427,6 +3434,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
||||
{
|
||||
prefs = k->pkt->pkt.user_id->prefs;
|
||||
mdc_feature = k->pkt->pkt.user_id->flags.mdc;
|
||||
aead_feature = k->pkt->pkt.user_id->flags.aead;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3440,6 +3448,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
||||
xfree (pk->prefs);
|
||||
pk->prefs = copy_prefs (prefs);
|
||||
pk->flags.mdc = mdc_feature;
|
||||
pk->flags.aead = aead_feature;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
g10/gpg.c
40
g10/gpg.c
@ -245,6 +245,7 @@ enum cmd_and_opt_values
|
||||
oRFC2440Text,
|
||||
oNoRFC2440Text,
|
||||
oCipherAlgo,
|
||||
oAEADAlgo,
|
||||
oDigestAlgo,
|
||||
oCertDigestAlgo,
|
||||
oCompressAlgo,
|
||||
@ -371,6 +372,7 @@ enum cmd_and_opt_values
|
||||
oDefaultPreferenceList,
|
||||
oDefaultKeyserverURL,
|
||||
oPersonalCipherPreferences,
|
||||
oPersonalAEADPreferences,
|
||||
oPersonalDigestPreferences,
|
||||
oPersonalCompressPreferences,
|
||||
oAgentProgram,
|
||||
@ -668,6 +670,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
|
||||
ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
|
||||
ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
|
||||
ARGPARSE_s_s (oAEADAlgo, "aead-algo", "@"),
|
||||
ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
|
||||
ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
|
||||
ARGPARSE_s_s (oCompressAlgo,"compress-algo", "@"),
|
||||
@ -824,6 +827,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
ARGPARSE_s_s (oDefaultPreferenceList, "default-preference-list", "@"),
|
||||
ARGPARSE_s_s (oDefaultKeyserverURL, "default-keyserver-url", "@"),
|
||||
ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-preferences","@"),
|
||||
ARGPARSE_s_s (oPersonalAEADPreferences, "personal-aead-preferences","@"),
|
||||
ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-preferences","@"),
|
||||
ARGPARSE_s_s (oPersonalCompressPreferences,
|
||||
"personal-compress-preferences", "@"),
|
||||
@ -835,6 +839,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
/* Aliases. I constantly mistype these, and assume other people do
|
||||
as well. */
|
||||
ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-prefs", "@"),
|
||||
ARGPARSE_s_s (oPersonalAEADPreferences, "personal-aead-prefs", "@"),
|
||||
ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-prefs", "@"),
|
||||
ARGPARSE_s_s (oPersonalCompressPreferences, "personal-compress-prefs", "@"),
|
||||
|
||||
@ -2125,6 +2130,7 @@ set_compliance_option (enum cmd_and_opt_values option)
|
||||
opt.escape_from = 1;
|
||||
opt.not_dash_escaped = 0;
|
||||
opt.def_cipher_algo = 0;
|
||||
opt.def_aead_algo = 0;
|
||||
opt.def_digest_algo = 0;
|
||||
opt.cert_digest_algo = 0;
|
||||
opt.compress_algo = -1;
|
||||
@ -2141,6 +2147,7 @@ set_compliance_option (enum cmd_and_opt_values option)
|
||||
opt.escape_from = 0;
|
||||
opt.not_dash_escaped = 0;
|
||||
opt.def_cipher_algo = 0;
|
||||
opt.def_aead_algo = 0;
|
||||
opt.def_digest_algo = 0;
|
||||
opt.cert_digest_algo = 0;
|
||||
opt.compress_algo = -1;
|
||||
@ -2157,6 +2164,7 @@ set_compliance_option (enum cmd_and_opt_values option)
|
||||
set_compliance_option (oOpenPGP);
|
||||
opt.compliance = CO_DE_VS;
|
||||
opt.force_mdc = 1;
|
||||
opt.def_aead_algo = 0;
|
||||
/* Fixme: Change other options. */
|
||||
break;
|
||||
|
||||
@ -2286,12 +2294,14 @@ main (int argc, char **argv)
|
||||
const char *trustdb_name = NULL;
|
||||
#endif /*!NO_TRUST_MODELS*/
|
||||
char *def_cipher_string = NULL;
|
||||
char *def_aead_string = NULL;
|
||||
char *def_digest_string = NULL;
|
||||
char *compress_algo_string = NULL;
|
||||
char *cert_digest_string = NULL;
|
||||
char *s2k_cipher_string = NULL;
|
||||
char *s2k_digest_string = NULL;
|
||||
char *pers_cipher_list = NULL;
|
||||
char *pers_aead_list = NULL;
|
||||
char *pers_digest_list = NULL;
|
||||
char *pers_compress_list = NULL;
|
||||
int eyes_only=0;
|
||||
@ -2355,6 +2365,7 @@ main (int argc, char **argv)
|
||||
opt.bz2_compress_level = -1; /* defaults to standard compress level */
|
||||
/* note: if you change these lines, look at oOpenPGP */
|
||||
opt.def_cipher_algo = 0;
|
||||
opt.def_aead_algo = 0;
|
||||
opt.def_digest_algo = 0;
|
||||
opt.cert_digest_algo = 0;
|
||||
opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
|
||||
@ -3113,6 +3124,9 @@ main (int argc, char **argv)
|
||||
case oCipherAlgo:
|
||||
def_cipher_string = xstrdup(pargs.r.ret_str);
|
||||
break;
|
||||
case oAEADAlgo:
|
||||
def_aead_string = xstrdup (pargs.r.ret_str);
|
||||
break;
|
||||
case oDigestAlgo:
|
||||
def_digest_string = xstrdup(pargs.r.ret_str);
|
||||
break;
|
||||
@ -3392,6 +3406,9 @@ main (int argc, char **argv)
|
||||
case oPersonalCipherPreferences:
|
||||
pers_cipher_list=pargs.r.ret_str;
|
||||
break;
|
||||
case oPersonalAEADPreferences:
|
||||
pers_aead_list = pargs.r.ret_str;
|
||||
break;
|
||||
case oPersonalDigestPreferences:
|
||||
pers_digest_list=pargs.r.ret_str;
|
||||
break;
|
||||
@ -3737,6 +3754,13 @@ main (int argc, char **argv)
|
||||
if ( openpgp_cipher_test_algo (opt.def_cipher_algo) )
|
||||
log_error(_("selected cipher algorithm is invalid\n"));
|
||||
}
|
||||
if (def_aead_string)
|
||||
{
|
||||
opt.def_aead_algo = string_to_aead_algo (def_aead_string);
|
||||
xfree (def_aead_string); def_aead_string = NULL;
|
||||
if (openpgp_aead_test_algo (opt.def_aead_algo))
|
||||
log_error(_("selected AEAD algorithm is invalid\n"));
|
||||
}
|
||||
if( def_digest_string ) {
|
||||
opt.def_digest_algo = string_to_digest_algo (def_digest_string);
|
||||
xfree(def_digest_string); def_digest_string = NULL;
|
||||
@ -3796,6 +3820,9 @@ main (int argc, char **argv)
|
||||
keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
|
||||
log_error(_("invalid personal cipher preferences\n"));
|
||||
|
||||
if (pers_aead_list && keygen_set_std_prefs (pers_aead_list, PREFTYPE_AEAD))
|
||||
log_error(_("invalid personal AEAD preferences\n"));
|
||||
|
||||
if(pers_digest_list &&
|
||||
keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
|
||||
log_error(_("invalid personal digest preferences\n"));
|
||||
@ -3861,6 +3888,12 @@ main (int argc, char **argv)
|
||||
badalg = openpgp_cipher_algo_name (opt.def_cipher_algo);
|
||||
badtype = PREFTYPE_SYM;
|
||||
}
|
||||
else if(opt.def_aead_algo
|
||||
&& !algo_available(PREFTYPE_AEAD, opt.def_aead_algo, NULL))
|
||||
{
|
||||
badalg = openpgp_aead_algo_name (opt.def_aead_algo);
|
||||
badtype = PREFTYPE_AEAD;
|
||||
}
|
||||
else if(opt.def_digest_algo
|
||||
&& !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
|
||||
{
|
||||
@ -3890,6 +3923,12 @@ main (int argc, char **argv)
|
||||
badalg,
|
||||
gnupg_compliance_option_string (opt.compliance));
|
||||
break;
|
||||
case PREFTYPE_AEAD:
|
||||
log_info (_("AEAD algorithm '%s'"
|
||||
" may not be used in %s mode\n"),
|
||||
badalg,
|
||||
gnupg_compliance_option_string (opt.compliance));
|
||||
break;
|
||||
case PREFTYPE_HASH:
|
||||
log_info (_("digest algorithm '%s'"
|
||||
" may not be used in %s mode\n"),
|
||||
@ -3915,6 +3954,7 @@ main (int argc, char **argv)
|
||||
* is not. This is us being nice to the user informing her early
|
||||
* that the chosen algorithms are not available. We also check
|
||||
* and enforce this right before the actual operation. */
|
||||
/* FIXME: We also need to check the AEAD algo. */
|
||||
if (opt.def_cipher_algo
|
||||
&& ! gnupg_cipher_is_allowed (opt.compliance,
|
||||
cmd == aEncr
|
||||
|
@ -415,13 +415,14 @@ dump_kbnode (KBNODE node)
|
||||
{
|
||||
PKT_public_key *pk = node->pkt->pkt.public_key;
|
||||
|
||||
log_printf (" keyid=%08lX a=%d u=%d %c%c%c%c\n",
|
||||
log_printf (" keyid=%08lX a=%d u=%d %c%c%c%c%c\n",
|
||||
(ulong)keyid_from_pk( pk, NULL ),
|
||||
pk->pubkey_algo, pk->pubkey_usage,
|
||||
pk->has_expired? 'e':'.',
|
||||
pk->flags.revoked? 'r':'.',
|
||||
pk->flags.valid? 'v':'.',
|
||||
pk->flags.mdc? 'm':'.');
|
||||
pk->flags.mdc? 'm':'.',
|
||||
pk->flags.aead? 'a':'.');
|
||||
}
|
||||
else
|
||||
log_printf ("\n");
|
||||
|
@ -3118,7 +3118,7 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
|
||||
}
|
||||
tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_NONE));
|
||||
}
|
||||
if (uid->flags.mdc || !uid->flags.ks_modify)
|
||||
if (uid->flags.mdc || uid->flags.aead || !uid->flags.ks_modify)
|
||||
{
|
||||
tty_printf ("\n ");
|
||||
tty_printf (_("Features: "));
|
||||
@ -3128,6 +3128,12 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
|
||||
tty_printf ("MDC");
|
||||
any = 1;
|
||||
}
|
||||
if (!uid->flags.aead)
|
||||
{
|
||||
if (any)
|
||||
tty_printf (", ");
|
||||
tty_printf ("AEAD");
|
||||
}
|
||||
if (!uid->flags.ks_modify)
|
||||
{
|
||||
if (any)
|
||||
@ -3172,6 +3178,8 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
|
||||
}
|
||||
if (uid->flags.mdc)
|
||||
tty_printf (" [mdc]");
|
||||
if (uid->flags.aead)
|
||||
tty_printf (" [aead]");
|
||||
if (!uid->flags.ks_modify)
|
||||
tty_printf (" [no-ks-modify]");
|
||||
tty_printf ("\n");
|
||||
@ -3317,6 +3325,8 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
|
||||
}
|
||||
if (uid->flags.mdc)
|
||||
es_fputs (",mdc", fp);
|
||||
if (uid->flags.aead)
|
||||
es_fputs (",aead", fp);
|
||||
if (!uid->flags.ks_modify)
|
||||
es_fputs (",no-ks-modify", fp);
|
||||
}
|
||||
|
120
g10/keygen.c
120
g10/keygen.c
@ -127,6 +127,9 @@ struct opaque_data_usage_and_pk {
|
||||
};
|
||||
|
||||
|
||||
/* FIXME: These globals vars are ugly. And using MAX_PREFS even for
|
||||
* aeads is useless, given that we don't expects more than a very few
|
||||
* algorithms. */
|
||||
static int prefs_initialized = 0;
|
||||
static byte sym_prefs[MAX_PREFS];
|
||||
static int nsym_prefs;
|
||||
@ -134,7 +137,11 @@ static byte hash_prefs[MAX_PREFS];
|
||||
static int nhash_prefs;
|
||||
static byte zip_prefs[MAX_PREFS];
|
||||
static int nzip_prefs;
|
||||
static int mdc_available,ks_modify;
|
||||
static byte aead_prefs[MAX_PREFS];
|
||||
static int naead_prefs;
|
||||
static int mdc_available;
|
||||
static int 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,
|
||||
@ -326,6 +333,8 @@ set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf)
|
||||
log_info(_("too many digest preferences\n"));
|
||||
else if(type==3)
|
||||
log_info(_("too many compression preferences\n"));
|
||||
else if(type==4)
|
||||
log_info(_("too many AEAD preferences\n"));
|
||||
else
|
||||
BUG();
|
||||
|
||||
@ -346,10 +355,10 @@ set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf)
|
||||
int
|
||||
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;
|
||||
byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS], aead[MAX_PREFS];
|
||||
int nsym=0, nhash=0, nzip=0, naead=0, val, rc=0;
|
||||
int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */
|
||||
char dummy_string[20*4+1]; /* Enough for 20 items. */
|
||||
char dummy_string[25*4+1]; /* Enough for 25 items. */
|
||||
|
||||
if (!string || !ascii_strcasecmp (string, "default"))
|
||||
{
|
||||
@ -383,6 +392,11 @@ keygen_set_std_prefs (const char *string,int personal)
|
||||
strcat(dummy_string,"S7 ");
|
||||
strcat(dummy_string,"S2 "); /* 3DES */
|
||||
|
||||
if (opt.flags.rfc4880bis && !openpgp_aead_test_algo (AEAD_ALGO_OCB))
|
||||
strcat(dummy_string,"A2 ");
|
||||
if (opt.flags.rfc4880bis && !openpgp_aead_test_algo (AEAD_ALGO_EAX))
|
||||
strcat(dummy_string,"A1 ");
|
||||
|
||||
if (personal)
|
||||
{
|
||||
/* The default internal hash algo order is:
|
||||
@ -475,6 +489,11 @@ keygen_set_std_prefs (const char *string,int personal)
|
||||
if(set_one_pref(val,3,tok,zip,&nzip))
|
||||
rc=-1;
|
||||
}
|
||||
else if ((val=string_to_aead_algo (tok)))
|
||||
{
|
||||
if (set_one_pref (val, 4, tok, aead, &naead))
|
||||
rc = -1;
|
||||
}
|
||||
else if (ascii_strcasecmp(tok,"mdc")==0)
|
||||
mdc=1;
|
||||
else if (ascii_strcasecmp(tok,"no-mdc")==0)
|
||||
@ -520,6 +539,29 @@ keygen_set_std_prefs (const char *string,int personal)
|
||||
opt.personal_cipher_prefs[i].value = 0;
|
||||
}
|
||||
}
|
||||
else if (personal == PREFTYPE_AEAD)
|
||||
{
|
||||
xfree(opt.personal_aead_prefs);
|
||||
|
||||
if (!naead)
|
||||
opt.personal_aead_prefs = NULL;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
opt.personal_aead_prefs=
|
||||
xmalloc(sizeof(prefitem_t *)*(naead+1));
|
||||
|
||||
for (i=0; i<naead; i++)
|
||||
{
|
||||
opt.personal_aead_prefs[i].type = PREFTYPE_AEAD;
|
||||
opt.personal_aead_prefs[i].value = sym[i];
|
||||
}
|
||||
|
||||
opt.personal_aead_prefs[i].type = PREFTYPE_NONE;
|
||||
opt.personal_aead_prefs[i].value = 0;
|
||||
}
|
||||
}
|
||||
else if(personal==PREFTYPE_HASH)
|
||||
{
|
||||
xfree(opt.personal_digest_prefs);
|
||||
@ -572,7 +614,9 @@ keygen_set_std_prefs (const char *string,int personal)
|
||||
memcpy (sym_prefs, sym, (nsym_prefs=nsym));
|
||||
memcpy (hash_prefs, hash, (nhash_prefs=nhash));
|
||||
memcpy (zip_prefs, zip, (nzip_prefs=nzip));
|
||||
memcpy (aead_prefs, aead, (naead_prefs=naead));
|
||||
mdc_available = mdc;
|
||||
aead_available = !!naead;
|
||||
ks_modify = modify;
|
||||
prefs_initialized = 1;
|
||||
}
|
||||
@ -581,6 +625,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 *
|
||||
@ -594,8 +639,8 @@ keygen_get_std_prefs(void)
|
||||
|
||||
uid->ref=1;
|
||||
|
||||
uid->prefs=xmalloc((sizeof(prefitem_t *)*
|
||||
(nsym_prefs+nhash_prefs+nzip_prefs+1)));
|
||||
uid->prefs = xmalloc ((sizeof(prefitem_t *)*
|
||||
(nsym_prefs+naead_prefs+nhash_prefs+nzip_prefs+1)));
|
||||
|
||||
for(i=0;i<nsym_prefs;i++,j++)
|
||||
{
|
||||
@ -603,6 +648,12 @@ keygen_get_std_prefs(void)
|
||||
uid->prefs[j].value=sym_prefs[i];
|
||||
}
|
||||
|
||||
for (i=0; i < naead_prefs; i++, j++)
|
||||
{
|
||||
uid->prefs[j].type = PREFTYPE_AEAD;
|
||||
uid->prefs[j].value = aead_prefs[i];
|
||||
}
|
||||
|
||||
for(i=0;i<nhash_prefs;i++,j++)
|
||||
{
|
||||
uid->prefs[j].type=PREFTYPE_HASH;
|
||||
@ -618,8 +669,9 @@ keygen_get_std_prefs(void)
|
||||
uid->prefs[j].type=PREFTYPE_NONE;
|
||||
uid->prefs[j].value=0;
|
||||
|
||||
uid->flags.mdc=mdc_available;
|
||||
uid->flags.ks_modify=ks_modify;
|
||||
uid->flags.mdc = mdc_available;
|
||||
uid->flags.aead = aead_available;
|
||||
uid->flags.ks_modify = ks_modify;
|
||||
|
||||
return uid;
|
||||
}
|
||||
@ -665,6 +717,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)
|
||||
{
|
||||
@ -726,6 +821,14 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque)
|
||||
delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_SYM);
|
||||
}
|
||||
|
||||
if (naead_prefs)
|
||||
build_sig_subpkt (sig, SIGSUBPKT_PREF_AEAD, aead_prefs, naead_prefs);
|
||||
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
|
||||
@ -744,6 +847,7 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque)
|
||||
|
||||
/* Make sure that the MDC feature flag is set if 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);
|
||||
|
||||
|
@ -41,6 +41,8 @@
|
||||
# define DEFAULT_CIPHER_ALGO CIPHER_ALGO_3DES
|
||||
#endif
|
||||
|
||||
#define DEFAULT_AEAD_ALGO AEAD_ALGO_EAX
|
||||
|
||||
#define DEFAULT_DIGEST_ALGO ((GNUPG)? DIGEST_ALGO_SHA256:DIGEST_ALGO_SHA1)
|
||||
#define DEFAULT_S2K_DIGEST_ALGO DIGEST_ALGO_SHA1
|
||||
#ifdef HAVE_ZIP
|
||||
@ -123,6 +125,9 @@ int openpgp_cipher_blocklen (cipher_algo_t algo);
|
||||
int openpgp_cipher_test_algo(cipher_algo_t algo);
|
||||
const char *openpgp_cipher_algo_name (cipher_algo_t algo);
|
||||
|
||||
gpg_error_t openpgp_aead_test_algo (aead_algo_t algo);
|
||||
const char *openpgp_aead_algo_name (aead_algo_t algo);
|
||||
|
||||
pubkey_algo_t map_pk_gcry_to_openpgp (enum gcry_pk_algos algo);
|
||||
int openpgp_pk_test_algo (pubkey_algo_t algo);
|
||||
int openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use);
|
||||
@ -151,12 +156,14 @@ void obsolete_scdaemon_option (const char *configname,
|
||||
unsigned int configlineno, const char *name);
|
||||
|
||||
int string_to_cipher_algo (const char *string);
|
||||
aead_algo_t string_to_aead_algo (const char *string);
|
||||
int string_to_digest_algo (const char *string);
|
||||
|
||||
const char *compress_algo_to_string(int algo);
|
||||
int string_to_compress_algo(const char *string);
|
||||
int check_compress_algo(int algo);
|
||||
int default_cipher_algo(void);
|
||||
aead_algo_t default_aead_algo(void);
|
||||
int default_compress_algo(void);
|
||||
void compliance_failure(void);
|
||||
|
||||
|
80
g10/misc.c
80
g10/misc.c
@ -582,6 +582,41 @@ 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)
|
||||
{
|
||||
switch (algo)
|
||||
{
|
||||
case AEAD_ALGO_NONE:
|
||||
break;
|
||||
case AEAD_ALGO_EAX:
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
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 0 if ALGO is a supported OpenPGP public key algorithm. */
|
||||
int
|
||||
openpgp_pk_test_algo (pubkey_algo_t algo)
|
||||
@ -1112,6 +1147,39 @@ string_to_cipher_algo (const char *string)
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Map an AEAD mode string to a an AEAD algorithm number as defined by
|
||||
* rrc4880bis. Also support the "An" syntax as used by the preference
|
||||
* strings.
|
||||
*/
|
||||
aead_algo_t
|
||||
string_to_aead_algo (const char *string)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!string)
|
||||
result = 0;
|
||||
if (!ascii_strcasecmp (string, "EAX"))
|
||||
result = 1;
|
||||
else if (!ascii_strcasecmp (string, "OCB"))
|
||||
result = 2;
|
||||
else if ((string[0]=='A' || string[0]=='a'))
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
string++;
|
||||
result = strtol (string, &endptr, 10);
|
||||
if (!*string || *endptr || result < 1 || result > 2)
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrapper around gcry_md_map_name to provide a fallback using the
|
||||
* "Hn" syntax as used by the preference strings.
|
||||
@ -1228,6 +1296,18 @@ default_cipher_algo(void)
|
||||
return opt.s2k_cipher_algo;
|
||||
}
|
||||
|
||||
|
||||
aead_algo_t
|
||||
default_aead_algo(void)
|
||||
{
|
||||
if(opt.def_aead_algo)
|
||||
return opt.def_aead_algo;
|
||||
else if(opt.personal_aead_prefs)
|
||||
return opt.personal_aead_prefs[0].value;
|
||||
else
|
||||
return DEFAULT_AEAD_ALGO;
|
||||
}
|
||||
|
||||
/* There is no default_digest_algo function, but see
|
||||
sign.c:hash_for() */
|
||||
|
||||
|
@ -92,6 +92,7 @@ struct
|
||||
int no_armor;
|
||||
int list_packets; /* Option --list-packets active. */
|
||||
int def_cipher_algo;
|
||||
int def_aead_algo;
|
||||
int force_mdc;
|
||||
int disable_mdc;
|
||||
int def_digest_algo;
|
||||
@ -177,6 +178,7 @@ struct
|
||||
const char *def_preference_list;
|
||||
const char *def_keyserver_url;
|
||||
prefitem_t *personal_cipher_prefs;
|
||||
prefitem_t *personal_aead_prefs;
|
||||
prefitem_t *personal_digest_prefs;
|
||||
prefitem_t *personal_compress_prefs;
|
||||
struct weakhash *weak_digests;
|
||||
|
@ -72,7 +72,8 @@ typedef enum {
|
||||
PREFTYPE_NONE = 0,
|
||||
PREFTYPE_SYM = 1,
|
||||
PREFTYPE_HASH = 2,
|
||||
PREFTYPE_ZIP = 3
|
||||
PREFTYPE_ZIP = 3,
|
||||
PREFTYPE_AEAD = 4
|
||||
} preftype_t;
|
||||
|
||||
typedef struct {
|
||||
@ -290,6 +291,7 @@ typedef struct
|
||||
struct
|
||||
{
|
||||
unsigned int mdc:1;
|
||||
unsigned int aead:1;
|
||||
unsigned int ks_modify:1;
|
||||
unsigned int compacted:1;
|
||||
unsigned int primary:2; /* 2 if set via the primary flag, 1 if calculated */
|
||||
@ -386,6 +388,7 @@ typedef struct
|
||||
struct
|
||||
{
|
||||
unsigned int mdc:1; /* MDC feature set. */
|
||||
unsigned int aead:1; /* AEAD feature set. */
|
||||
unsigned int disabled_valid:1;/* The next flag is valid. */
|
||||
unsigned int disabled:1; /* The key has been disabled. */
|
||||
unsigned int primary:1; /* This is a primary key. */
|
||||
@ -471,7 +474,7 @@ typedef struct {
|
||||
Note: this is ignored when encrypting. */
|
||||
byte is_partial;
|
||||
/* If 0, MDC is disabled. Otherwise, the MDC method that was used
|
||||
(currently, only DIGEST_ALGO_SHA1 is supported). */
|
||||
(only DIGEST_ALGO_SHA1 has ever been defined). */
|
||||
byte mdc_method;
|
||||
/* An iobuf holding the data to be decrypted. (This is not used for
|
||||
encryption!) */
|
||||
|
@ -1468,9 +1468,12 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype,
|
||||
support. All this doesn't mean IDEA is actually
|
||||
available, of course. */
|
||||
implicit=CIPHER_ALGO_3DES;
|
||||
|
||||
break;
|
||||
|
||||
case PREFTYPE_AEAD:
|
||||
/* No implicit algo. */
|
||||
break;
|
||||
|
||||
case PREFTYPE_HASH:
|
||||
/* While I am including this code for completeness, note
|
||||
that currently --pgp2 mode locks the hash at MD5, so this
|
||||
@ -1553,6 +1556,8 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype,
|
||||
prefs=NULL;
|
||||
if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs)
|
||||
prefs=opt.personal_cipher_prefs;
|
||||
else if(preftype==PREFTYPE_AEAD && opt.personal_aead_prefs)
|
||||
prefs=opt.personal_aead_prefs;
|
||||
else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs)
|
||||
prefs=opt.personal_digest_prefs;
|
||||
else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs)
|
||||
|
Loading…
x
Reference in New Issue
Block a user