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
This commit is contained in:
Werner Koch 2021-02-10 14:31:34 +01:00
parent 6e730c1881
commit 825dd7220f
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
7 changed files with 92 additions and 16 deletions

View File

@ -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

View File

@ -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))

View File

@ -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);

View File

@ -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");
}

View File

@ -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;

View File

@ -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:

View File

@ -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")