diff options
author | Werner Koch <[email protected]> | 2018-01-10 16:07:11 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2018-01-10 16:07:11 +0000 |
commit | 4e2ba546cdccbbc6d3e29867ee5671fd44d74e67 (patch) | |
tree | ed822c35d3c88ba22a4754e2765a02a928e1a6ef | |
parent | gpg: Add option and preference framework for AEAD. (diff) | |
download | gnupg-4e2ba546cdccbbc6d3e29867ee5671fd44d74e67.tar.gz gnupg-4e2ba546cdccbbc6d3e29867ee5671fd44d74e67.zip |
gpg: New option --force-aead
* g10/dek.h (DEK): Turn fields use_mdc, algo_printed and symmetric
into single bit vars. Make sure they are always set to 1 or 0.
(DEK): New field use_aead.
* g10/options.h (struct opt): New field force_aead.
* g10/pkclist.c (select_aead_from_pklist): New.
* g10/gpg.c (oForceAEAD): New const.
(opts): New options "--force-aead".
(main): Set new option.
* g10/encrypt.c (use_aead): New.
(encrypt_simple): Implement new flags DEK.use_aead.
(encrypt_crypt): Ditto.
(encrypt_filter): Ditto.
* g10/sign.c (sign_symencrypt_file): Ditto.
--
This patch should be enough to detect whether AEAD can be used.
Not tested.
Signed-off-by: Werner Koch <[email protected]>
-rw-r--r-- | g10/dek.h | 25 | ||||
-rw-r--r-- | g10/encrypt.c | 75 | ||||
-rw-r--r-- | g10/gpg.c | 5 | ||||
-rw-r--r-- | g10/keydb.h | 1 | ||||
-rw-r--r-- | g10/main.h | 1 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/pkclist.c | 25 | ||||
-rw-r--r-- | g10/sign.c | 7 |
8 files changed, 120 insertions, 20 deletions
@@ -1,5 +1,5 @@ /* dek.h - The data encryption key structure. - * Copyright (C) 2014 Werner Koch + * Copyright (C) 2014, 2017 Werner Koch * * This file is part of GnuPG. * @@ -26,14 +26,25 @@ typedef struct int algo; /* The length of the key (in bytes). */ int keylen; + /* Whether we've already printed information about this key. This - is currently only used in decrypt_data() and only if we are in - verbose mode. */ - int algo_info_printed; - int use_mdc; + * is currently only used in decrypt_data() and only if we are in + * verbose mode. */ + int algo_info_printed : 1; + + /* AEAD shall be used. */ + int use_aead : 1; + + /* MDC shall be used. */ + int use_mdc : 1; + /* This key was read from a SK-ESK packet (see proc_symkey_enc). */ - int symmetric; - byte key[32]; /* This is the largest used keylen (256 bit). */ + int symmetric : 1; + + /* This is the largest used keylen (256 bit). */ + byte key[32]; + + /* The cacheid for the S2K. */ char s2k_cacheid[1+16+1]; } DEK; diff --git a/g10/encrypt.c b/g10/encrypt.c index 263226ad5..2951a45ff 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -109,6 +109,47 @@ encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey) } +/* Return true if we shall use AEAD mode. */ +int +use_aead (pk_list_t pk_list, int algo) +{ + int can_use; + + if (!opt.flags.rfc4880bis) + { + if (opt.force_aead) + log_info ("Warning: Option %s currently requires option '%s'\n", + "--force-aead", "--rfc4880bis"); + return 0; + } + + can_use = openpgp_cipher_get_algo_blklen (algo) != 16; + + /* With --force-mdc we clearly do not want AEAD. */ + if (opt.force_mdc) + return 0; + + /* However with --force-aead we want AEAD. */ + if (opt.force_aead) + { + if (!can_use) + log_info ("Warning: request to use AEAD ignored for cipher '%s'\n", + openpgp_cipher_algo_name (algo)); + return 1; + } + + /* AEAD does noly work with 128 bit cipher blocklength. */ + if (!can_use) + return 0; + + /* If all keys support AEAD we can use it. */ + if (select_aead_from_pklist (pk_list)) + return 1; + + return 0; /* No AEAD. */ +} + + /* We try very hard to use a MDC */ int use_mdc (pk_list_t pk_list,int algo) @@ -265,10 +306,15 @@ encrypt_simple (const char *filename, int mode, int use_seskey) log_info(_("using cipher %s\n"), openpgp_cipher_algo_name (cfx.dek->algo)); - cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo); + if (use_aead (NULL, cfx.dek->algo)) + cfx.dek->use_aead = 1; + else + cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); } - if (do_compress && cfx.dek && cfx.dek->use_mdc + if (do_compress + && cfx.dek + && (cfx.dek->use_mdc || cfx.dek->use_aead) && is_file_compressed(filename, &rc)) { if (opt.verbose) @@ -368,7 +414,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) /* Register the compress filter. */ if ( do_compress ) { - if (cfx.dek && cfx.dek->use_mdc) + if (cfx.dek && (cfx.dek->use_mdc || cfx.dek->use_aead)) zfx.new_ctb = 1; push_compress_filter (out, &zfx, default_compress_algo()); } @@ -676,14 +722,18 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, gnupg_status_compliance_flag (CO_DE_VS), NULL); - cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo); + if (use_aead (pk_list, cfx.dek->algo)) + cfx.dek->use_aead = 1; + else + cfx.dek->use_mdc = !!use_mdc (pk_list, cfx.dek->algo); /* Only do the is-file-already-compressed check if we are using a - MDC. This forces compressed files to be re-compressed if we do - not have a MDC to give some protection against chosen ciphertext - attacks. */ - - if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2)) + * MDC or AEAD. This forces compressed files to be re-compressed if + * we do not have a MDC to give some protection against chosen + * ciphertext attacks. */ + if (do_compress + && (cfx.dek->use_mdc || cfx.dek->use_aead) + && is_file_compressed (filename, &rc2)) { if (opt.verbose) log_info(_("'%s' already compressed\n"), filename); @@ -777,7 +827,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, /* Algo 0 means no compression. */ if (compr_algo) { - if (cfx.dek && cfx.dek->use_mdc) + if (cfx.dek && (cfx.dek->use_mdc || cfx.dek->use_aead)) zfx.new_ctb = 1; push_compress_filter (out,&zfx,compr_algo); } @@ -887,7 +937,10 @@ encrypt_filter (void *opaque, int control, efx->cfx.dek->algo = opt.def_cipher_algo; } - efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo); + if (use_aead (efx->pk_list, efx->cfx.dek->algo)) + efx->cfx.dek->use_aead = 1; + else + efx->cfx.dek->use_mdc = !!use_mdc (efx->pk_list,efx->cfx.dek->algo); make_session_key ( efx->cfx.dek ); if (DBG_CRYPTO) @@ -304,6 +304,7 @@ enum cmd_and_opt_values oNoForceMDC, oDisableMDC, oNoDisableMDC, + oForceAEAD, oS2KMode, oS2KDigest, oS2KCipher, @@ -605,6 +606,8 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oDisableMDC, "disable-mdc", "@"), ARGPARSE_s_n (oNoDisableMDC, "no-disable-mdc", "@"), + ARGPARSE_s_n (oForceAEAD, "force-aead", "@"), + ARGPARSE_s_n (oDisableSignerUID, "disable-signer-uid", "@"), ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), @@ -2977,6 +2980,8 @@ main (int argc, char **argv) case oDisableMDC: opt.disable_mdc = 1; break; case oNoDisableMDC: opt.disable_mdc = 0; break; + case oForceAEAD: opt.force_aead = 1; break; + case oDisableSignerUID: opt.flags.disable_signer_uid = 1; break; case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break; diff --git a/g10/keydb.h b/g10/keydb.h index 739376838..9f6064b41 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -232,6 +232,7 @@ int algo_available( preftype_t preftype, int algo, int select_algo_from_prefs( PK_LIST pk_list, int preftype, int request, const union pref_hint *hint); int select_mdc_from_pklist (PK_LIST pk_list); +int select_aead_from_pklist (pk_list_t pk_list); void warn_missing_mdc_from_pklist (PK_LIST pk_list); void warn_missing_aes_from_pklist (PK_LIST pk_list); diff --git a/g10/main.h b/g10/main.h index 6abc5985f..393a1b09e 100644 --- a/g10/main.h +++ b/g10/main.h @@ -233,6 +233,7 @@ void display_online_help( const char *keyword ); /*-- encode.c --*/ int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek); void encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey); +int use_aead (pk_list_t pk_list, int algo); int use_mdc (pk_list_t pk_list,int algo); int encrypt_symmetric (const char *filename ); int encrypt_store (const char *filename ); diff --git a/g10/options.h b/g10/options.h index 6ad103709..36bea694d 100644 --- a/g10/options.h +++ b/g10/options.h @@ -95,6 +95,7 @@ struct int def_aead_algo; int force_mdc; int disable_mdc; + int force_aead; int def_digest_algo; int cert_digest_algo; int compress_algo; diff --git a/g10/pkclist.c b/g10/pkclist.c index a759672ab..b85efa4cd 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -1651,6 +1651,31 @@ select_mdc_from_pklist (PK_LIST pk_list) } +/* Select the AEAD flag from the pk_list. We can only use AEAD if all + * recipients support this feature. Returns true if AEAD can be used. */ +int +select_aead_from_pklist (PK_LIST pk_list) +{ + pk_list_t pkr; + int aead; + + if (!pk_list) + return 0; + + for (pkr = pk_list; pkr; pkr = pkr->next) + { + if (pkr->pk->user_id) /* selected by user ID */ + aead = pkr->pk->user_id->flags.aead; + else + aead = pkr->pk->flags.aead; + if (!aead) + return 0; /* At least one recipient does not support it. */ + } + + return 1; /* Can be used. */ +} + + /* Print a warning for all keys in PK_LIST missing the MDC feature. */ void warn_missing_mdc_from_pklist (PK_LIST pk_list) diff --git a/g10/sign.c b/g10/sign.c index 4cf0cd39a..f8a1241a6 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1337,7 +1337,10 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) goto leave; } - cfx.dek->use_mdc = use_mdc (NULL, cfx.dek->algo); + if (use_aead (NULL, cfx.dek->algo)) + cfx.dek->use_aead = 1; + else + cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); /* now create the outfile */ rc = open_outfile (-1, fname, opt.armor? 1:0, 0, &out); @@ -1381,7 +1384,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) /* Push the compress filter */ if (default_compress_algo()) { - if (cfx.dek && cfx.dek->use_mdc) + if (cfx.dek && (cfx.dek->use_mdc || cfx.dek->use_aead)) zfx.new_ctb = 1; push_compress_filter (out, &zfx,default_compress_algo() ); } |