diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index 85a4251de..aeb3389a7 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -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, diff --git a/g10/getkey.c b/g10/getkey.c index dabd052e0..497dace3a 100644 --- a/g10/getkey.c +++ b/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; } } } diff --git a/g10/gpg.c b/g10/gpg.c index 61e39b8e4..fadd2f096 100644 --- a/g10/gpg.c +++ b/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 diff --git a/g10/kbnode.c b/g10/kbnode.c index c2aaacd76..64def0509 100644 --- a/g10/kbnode.c +++ b/g10/kbnode.c @@ -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"); diff --git a/g10/keyedit.c b/g10/keyedit.c index 8d8625371..81344eb79 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -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); } diff --git a/g10/keygen.c b/g10/keygen.c index 912fa390c..d5f778262 100644 --- a/g10/keygen.c +++ b/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; iref=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;iprefs[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;iprefs[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); diff --git a/g10/main.h b/g10/main.h index 4a8f8c32a..6abc5985f 100644 --- a/g10/main.h +++ b/g10/main.h @@ -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); diff --git a/g10/misc.c b/g10/misc.c index 9016d2770..2da0d270c 100644 --- a/g10/misc.c +++ b/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() */ diff --git a/g10/options.h b/g10/options.h index 61f7403be..6ad103709 100644 --- a/g10/options.h +++ b/g10/options.h @@ -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; diff --git a/g10/packet.h b/g10/packet.h index 8dca88b75..894b38946 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -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!) */ diff --git a/g10/pkclist.c b/g10/pkclist.c index 581cae407..a759672ab 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -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)