aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2021-02-10 14:31:34 +0100
committerWerner Koch <wk@gnupg.org>2021-02-10 14:40:02 +0100
commit825dd7220ff6079cbe2d0df7fde93526c077fb6d (patch)
tree8326478d78d1c32eebe440eaa99298dca77e11e4
parent6e730c18816fbb3e074d93840396ed18f00ab7e2 (diff)
downloadgnupg-825dd7220ff6079cbe2d0df7fde93526c077fb6d.tar.gz
gpg: Do not allow old cipher algorithms for encryption.
* g10/gpg.c: New option --allow-old-cipher-algos. (set_compliance_option): Set --rfc4880bis explictly to SHA256 and AES256. Allow old cipher algos for OpenPGP, rfc4880, and rfc2440. * g10/options.h (opt): Add flags.allow_old_cipher_algos. * g10/misc.c (print_sha1_keysig_rejected_note): Always print the note unless in --quiet mode. * g10/encrypt.c (setup_symkey): Disallow by default algos with a blocklengt < 128. (encrypt_crypt): Ditto. Fallback by default to AES instead of 3DES. * g10/pkclist.c (algo_available): Take care of old cipher also. (select_algo_from_prefs): Use AES as implicit algorithm by default. * tests/openpgp/defs.scm (create-gpghome): Set allow-old-cipher-algos. -- GnuPG-bug-id: 3415
-rw-r--r--doc/gpg.texi21
-rw-r--r--g10/encrypt.c35
-rw-r--r--g10/gpg.c26
-rw-r--r--g10/misc.c5
-rw-r--r--g10/options.h1
-rw-r--r--g10/pkclist.c19
-rw-r--r--tests/openpgp/defs.scm1
7 files changed, 92 insertions, 16 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi
index d44a9a211..8975cf9cd 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -2848,16 +2848,17 @@ different compliance option in the gpg.conf file.
@item --openpgp
@opindex openpgp
Reset all packet, cipher and digest options to strict OpenPGP
-behavior. Use this option to reset all previous options like
-@option{--s2k-*}, @option{--cipher-algo}, @option{--digest-algo} and
+behavior. This option implies @option{--allow-old-cipher-algos}. Use
+this option to reset all previous options like @option{--s2k-*},
+@option{--cipher-algo}, @option{--digest-algo} and
@option{--compress-algo} to OpenPGP compliant values. All PGP
workarounds are disabled.
@item --rfc4880
@opindex rfc4880
Reset all packet, cipher and digest options to strict RFC-4880
-behavior. Note that this is currently the same thing as
-@option{--openpgp}.
+behavior. This option implies @option{--allow-old-cipher-algos}.
+Note that this is currently the same thing as @option{--openpgp}.
@item --rfc4880bis
@opindex rfc4880bis
@@ -2869,7 +2870,8 @@ proposed updates of RFC-4880.
Reset all packet, cipher and digest options to strict RFC-2440
behavior. Note that by using this option encryption packets are
created in a legacy mode without MDC protection. This is dangerous
-and should thus only be used for experiments. See also option
+and should thus only be used for experiments. This option implies
+@option{--allow-old-cipher-algos}. See also option
@option{--ignore-mdc-error}.
@item --pgp6
@@ -3391,6 +3393,15 @@ necessary to get as much data as possible out of that garbled message.
Be aware that a missing or failed MDC can be an indication of an
attack. Use with great caution; see also option @option{--rfc2440}.
+@item --allow-old-cipher-algos
+@opindex allow-old-cipher-algos
+Old cipher algorithms like 3DES, IDEA, or CAST5 encrypt data using
+blocks of 64 bits; modern algorithms use blocks of 128 bit instead.
+To avoid certain attack on these old algorithms it is suggested not to
+encrypt more than 150 MiByte using the same key. For this reason gpg
+does not allow the use of 64 bit block size algorithms for encryption
+unless this option is specified.
+
@item --allow-weak-digest-algos
@opindex allow-weak-digest-algos
Signatures made with known-weak digest algorithms are normally
diff --git a/g10/encrypt.c b/g10/encrypt.c
index a021c0e07..388c3db74 100644
--- a/g10/encrypt.c
+++ b/g10/encrypt.c
@@ -538,6 +538,17 @@ setup_symkey (STRING2KEY **symkey_s2k, DEK **symkey_dek)
int s2kdigest;
defcipher = default_cipher_algo ();
+ if (openpgp_cipher_blocklen (defcipher) < 16
+ && !opt.flags.allow_old_cipher_algos)
+ {
+ log_error (_("cipher algorithm '%s' may not be used for encryption\n"),
+ openpgp_cipher_algo_name (defcipher));
+ if (!opt.quiet)
+ log_info (_("(use option \"%s\" to override)\n"),
+ "--allow-old-cipher-algos");
+ return gpg_error (GPG_ERR_CIPHER_ALGO);
+ }
+
if (!gnupg_cipher_is_allowed (opt.compliance, 1, defcipher,
GCRY_CIPHER_MODE_CFB))
{
@@ -741,10 +752,18 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
entry for 3DES, and the pk_list cannot be empty. In this
case, use 3DES anyway as it's the safest choice - perhaps the
v3 key is being used in an OpenPGP implementation and we know
- that the implementation behind any v4 key can handle 3DES. */
+ that the implementation behind any v4 key can handle 3DES.
+ Note that we do not support v3 keys since version 2.2 so the
+ above description gives only historical background. */
if (cfx.dek->algo == -1)
{
- cfx.dek->algo = CIPHER_ALGO_3DES;
+ /* If does not make sense to fallback to the rfc4880
+ * required 3DES if we will reject that algo later. Thus we
+ * fallback to AES anticipating RFC4880bis rules. */
+ if (opt.flags.allow_old_cipher_algos)
+ cfx.dek->algo = CIPHER_ALGO_3DES;
+ else
+ cfx.dek->algo = CIPHER_ALGO_AES;
}
/* In case 3DES has been selected, print a warning if any key
@@ -770,6 +789,18 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
cfx.dek->algo = opt.def_cipher_algo;
}
+ if (openpgp_cipher_blocklen (cfx.dek->algo) < 16
+ && !opt.flags.allow_old_cipher_algos)
+ {
+ log_error (_("cipher algorithm '%s' may not be used for encryption\n"),
+ openpgp_cipher_algo_name (cfx.dek->algo));
+ if (!opt.quiet)
+ log_info (_("(use option \"%s\" to override)\n"),
+ "--allow-old-cipher-algos");
+ rc = gpg_error (GPG_ERR_CIPHER_ALGO);
+ goto leave;
+ }
+
/* Check compliance. */
if (! gnupg_cipher_is_allowed (opt.compliance, 1, cfx.dek->algo,
GCRY_CIPHER_MODE_CFB))
diff --git a/g10/gpg.c b/g10/gpg.c
index e795f744a..b4b802248 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -345,6 +345,7 @@ enum cmd_and_opt_values
oAllowFreeformUID,
oNoAllowFreeformUID,
oAllowSecretKeyImport,
+ oAllowOldCipherAlgos,
oEnableSpecialFilenames,
oNoLiteral,
oSetFilesize,
@@ -854,6 +855,7 @@ static gpgrt_opt_t opts[] = {
/* Options to override new security defaults. */
ARGPARSE_s_n (oAllowWeakKeySignatures, "allow-weak-key-signatures", "@"),
ARGPARSE_s_n (oAllowWeakDigestAlgos, "allow-weak-digest-algos", "@"),
+ ARGPARSE_s_n (oAllowOldCipherAlgos, "allow-old-cipher-algos", "@"),
ARGPARSE_s_s (oWeakDigest, "weak-digest","@"),
ARGPARSE_s_s (oVerifyOptions, "verify-options", "@"),
ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"),
@@ -2186,7 +2188,23 @@ set_compliance_option (enum cmd_and_opt_values option)
{
case oRFC4880bis:
opt.flags.rfc4880bis = 1;
- /* fall through. */
+ opt.compliance = CO_RFC4880;
+ opt.flags.dsa2 = 1;
+ opt.flags.require_cross_cert = 1;
+ opt.rfc2440_text = 0;
+ opt.allow_non_selfsigned_uid = 1;
+ opt.allow_freeform_uid = 1;
+ 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;
+ opt.s2k_mode = 3; /* iterated+salted */
+ opt.s2k_digest_algo = DIGEST_ALGO_SHA256;
+ opt.s2k_cipher_algo = CIPHER_ALGO_AES256;
+ break;
case oOpenPGP:
case oRFC4880:
/* This is effectively the same as RFC2440, but with
@@ -2208,6 +2226,7 @@ set_compliance_option (enum cmd_and_opt_values option)
opt.s2k_mode = 3; /* iterated+salted */
opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+ opt.flags.allow_old_cipher_algos = 1;
break;
case oRFC2440:
opt.compliance = CO_RFC2440;
@@ -2225,6 +2244,7 @@ set_compliance_option (enum cmd_and_opt_values option)
opt.s2k_mode = 3; /* iterated+salted */
opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+ opt.flags.allow_old_cipher_algos = 1;
break;
case oPGP7: opt.compliance = CO_PGP7; break;
case oPGP8: opt.compliance = CO_PGP8; break;
@@ -3604,6 +3624,10 @@ main (int argc, char **argv)
opt.flags.allow_weak_key_signatures = 1;
break;
+ case oAllowOldCipherAlgos:
+ opt.flags.allow_old_cipher_algos = 1;
+ break;
+
case oFakedSystemTime:
{
size_t len = strlen (pargs.r.ret_str);
diff --git a/g10/misc.c b/g10/misc.c
index cd5c1bd7a..2a431b137 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -396,8 +396,9 @@ print_sha1_keysig_rejected_note (void)
log_info (_("Note: third-party key signatures using"
" the %s algorithm are rejected\n"),
gcry_md_algo_name (GCRY_MD_SHA1));
- print_further_info ("use option \"%s\" to override",
- "--allow-weak-key-signatures");
+ if (!opt.quiet)
+ log_info (_("(use option \"%s\" to override)\n"),
+ "--allow-weak-key-signatures");
}
diff --git a/g10/options.h b/g10/options.h
index 5b0b12fd3..61118314e 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -237,6 +237,7 @@ struct
unsigned int use_embedded_filename:1;
unsigned int utf8_filename:1;
unsigned int dsa2:1;
+ unsigned int allow_old_cipher_algos:1;
unsigned int allow_weak_digest_algos:1;
unsigned int allow_weak_key_signatures:1;
unsigned int large_rsa:1;
diff --git a/g10/pkclist.c b/g10/pkclist.c
index d53af7223..392689352 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -1397,6 +1397,10 @@ algo_available( preftype_t preftype, int algo, const struct pref_hint *hint)
{
if( preftype == PREFTYPE_SYM )
{
+ if (!opt.flags.allow_old_cipher_algos
+ && openpgp_cipher_blocklen (algo) < 16)
+ return 0; /* We don't want this one. */
+
if(PGP7 && (algo != CIPHER_ALGO_IDEA
&& algo != CIPHER_ALGO_3DES
&& algo != CIPHER_ALGO_CAST5
@@ -1494,12 +1498,15 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype,
switch(preftype)
{
case PREFTYPE_SYM:
- /* IDEA is implicitly there for v3 keys with v3 selfsigs if
- --pgp2 mode is on. This was a 2440 thing that was
- dropped from 4880 but is still relevant to GPG's 1991
- support. All this doesn't mean IDEA is actually
- available, of course. */
- implicit=CIPHER_ALGO_3DES;
+ /* Historical note: IDEA is implicitly there for v3 keys
+ with v3 selfsigs if --pgp2 mode is on. This was a 2440
+ thing that was dropped from 4880 but is still relevant to
+ GPG's 1991 support. All this doesn't mean IDEA is
+ actually available, of course. */
+ if (opt.flags.allow_old_cipher_algos)
+ implicit = CIPHER_ALGO_3DES;
+ else
+ implicit = CIPHER_ALGO_AES;
break;
case PREFTYPE_AEAD:
diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm
index fab033659..3f6248f9e 100644
--- a/tests/openpgp/defs.scm
+++ b/tests/openpgp/defs.scm
@@ -345,6 +345,7 @@
"no-auto-key-retrieve"
"no-auto-key-locate"
"allow-weak-digest-algos"
+ "allow-old-cipher-algos"
"ignore-mdc-error"
(if have-opt-always-trust
"no-auto-check-trustdb" "#no-auto-check-trustdb")