From 6cabb7a2a18f871b8c3d5de58bcdc5aaa5b201af Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Thu, 9 Oct 2014 16:54:15 -0400 Subject: [PATCH] gpg: Add build and runtime support for larger RSA keys * configure.ac: Added --enable-large-secmem option. * g10/options.h: Add opt.flags.large_rsa. * g10/gpg.c: Contingent on configure option: adjust secmem size, add gpg --enable-large-rsa, bound to opt.flags.large_rsa. * g10/keygen.c: Adjust max RSA size based on opt.flags.large_rsa * doc/gpg.texi: Document --enable-large-rsa. -- This is a cherry-pick of 534e2876acc05f9f8d9b54c18511fe768d77dfb5 from STABLE-BRANCH-1-4 against master Some older implementations built and used RSA keys up to 16Kib, but the larger secret keys now fail when used by more recent GnuPG, due to secure memory limitations. Building with ./configure --enable-large-secmem will make gpg capable of working with those secret keys, as well as permitting the use of a new gpg option --enable-large-rsa, which let gpg generate RSA keys up to 8Kib when used with --batch --gen-key. Debian-bug-id: 739424 Minor edits by wk. GnuPG-bug-id: 1732 --- configure.ac | 15 +++++++++++++++ doc/gpg.texi | 9 +++++++++ g10/gpg.c | 22 +++++++++++++++++++++- g10/keygen.c | 5 +++-- g10/options.h | 1 + 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 28268f11c..7ce8c097b 100644 --- a/configure.ac +++ b/configure.ac @@ -107,6 +107,7 @@ card_support=yes use_ccid_driver=yes dirmngr_auto_start=yes use_tls_library=no +large_secmem=no GNUPG_BUILD_PROGRAM(gpg, yes) GNUPG_BUILD_PROGRAM(gpgsm, yes) @@ -223,6 +224,20 @@ AC_ARG_ENABLE(selinux-support, AC_MSG_RESULT($selinux_support) +AC_MSG_CHECKING([whether to allocate extra secure memory]) +AC_ARG_ENABLE(large-secmem, + AC_HELP_STRING([--enable-large-secmem], + [allocate extra secure memory]), + large_secmem=$enableval, large_secmem=no) +AC_MSG_RESULT($large_secmem) +if test "$large_secmem" = yes ; then + SECMEM_BUFFER_SIZE=65536 +else + SECMEM_BUFFER_SIZE=32768 +fi +AC_DEFINE_UNQUOTED(SECMEM_BUFFER_SIZE,$SECMEM_BUFFER_SIZE, + [Size of secure memory buffer]) + AC_MSG_CHECKING([whether to enable trust models]) AC_ARG_ENABLE(trust-models, AC_HELP_STRING([--disable-trust-models], diff --git a/doc/gpg.texi b/doc/gpg.texi index 002e888ce..e7360e913 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1181,6 +1181,15 @@ the opposite meaning. The options are: validation. This option is only meaningful if pka-lookups is set. @end table +@item --enable-large-rsa +@itemx --disable-large-rsa +@opindex enable-large-rsa +@opindex disable-large-rsa +With --gen-key and --batch, enable the creation of larger RSA secret +keys than is generally recommended (up to 8192 bits). These large +keys are more expensive to use, and their signatures and +certifications are also larger. + @item --enable-dsa2 @itemx --disable-dsa2 @opindex enable-dsa2 diff --git a/g10/gpg.c b/g10/gpg.c index f5860428a..e7d6d00a8 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -376,6 +376,8 @@ enum cmd_and_opt_values oAutoKeyLocate, oNoAutoKeyLocate, oAllowMultisigVerification, + oEnableLargeRSA, + oDisableLargeRSA, oEnableDSA2, oDisableDSA2, oAllowMultipleMessages, @@ -770,6 +772,8 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oAllowMultisigVerification, "allow-multisig-verification", "@"), + ARGPARSE_s_n (oEnableLargeRSA, "enable-large-rsa", "@"), + ARGPARSE_s_n (oDisableLargeRSA, "disable-large-rsa", "@"), ARGPARSE_s_n (oEnableDSA2, "enable-dsa2", "@"), ARGPARSE_s_n (oDisableDSA2, "disable-dsa2", "@"), ARGPARSE_s_n (oAllowMultipleMessages, "allow-multiple-messages", "@"), @@ -2181,7 +2185,7 @@ main (int argc, char **argv) #endif /* Initialize the secure memory. */ - if (!gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0)) + if (!gcry_control (GCRYCTL_INIT_SECMEM, SECMEM_BUFFER_SIZE, 0)) got_secmem = 1; #if defined(HAVE_GETUID) && defined(HAVE_GETEUID) /* There should be no way to get to this spot while still carrying @@ -3099,6 +3103,22 @@ main (int argc, char **argv) release_akl(); break; + case oEnableLargeRSA: +#if SECMEM_BUFFER_SIZE >= 65536 + opt.flags.large_rsa=1; +#else + if (configname) + log_info("%s:%d: WARNING: gpg not built with large secure " + "memory buffer. Ignoring enable-large-rsa\n", + configname,configlineno); + else + log_info("WARNING: gpg not built with large secure " + "memory buffer. Ignoring --enable-large-rsa\n"); +#endif /* SECMEM_BUFFER_SIZE >= 65536 */ + break; + case oDisableLargeRSA: opt.flags.large_rsa=0; + break; + case oEnableDSA2: opt.flags.dsa2=1; break; case oDisableDSA2: opt.flags.dsa2=0; break; diff --git a/g10/keygen.c b/g10/keygen.c index 229f2bfed..1c8d70e98 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1555,6 +1555,7 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, int err; char *keyparms; char nbitsstr[35]; + const unsigned maxsize = (opt.flags.large_rsa ? 8192 : 4096); assert (is_RSA(algo)); @@ -1566,9 +1567,9 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, nbits = 2048; log_info (_("keysize invalid; using %u bits\n"), nbits ); } - else if (nbits > 4096) + else if (nbits > maxsize) { - nbits = 4096; + nbits = maxsize; log_info (_("keysize invalid; using %u bits\n"), nbits ); } diff --git a/g10/options.h b/g10/options.h index 7efb3d6e6..edd31a9c2 100644 --- a/g10/options.h +++ b/g10/options.h @@ -229,6 +229,7 @@ struct unsigned int dsa2:1; unsigned int allow_multiple_messages:1; unsigned int allow_weak_digest_algos:1; + unsigned int large_rsa:1; } flags; /* Linked list of ways to find a key if the key isn't on the local