[PATCH] gpg 2.0.x: Add build and runtime support for larger RSA keys

Daniel Kahn Gillmor dkg at fifthhorseman.net
Fri Oct 3 19:59:34 CEST 2014


* 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 STABLE-BRANCH-2-0

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  | 17 +++++++++++++++++
 doc/gpg.texi  |  9 +++++++++
 g10/gpg.c     | 22 +++++++++++++++++++++-
 g10/keygen.c  |  5 +++--
 g10/options.h |  1 +
 5 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index 7137e3f..3f83bdc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -83,6 +83,7 @@ use_exec=yes
 disable_keyserver_path=no
 use_ccid_driver=yes
 use_standard_socket=no
+large_secmem=no
 
 GNUPG_BUILD_PROGRAM(gpg, yes)
 GNUPG_BUILD_PROGRAM(gpgsm, yes)
@@ -174,6 +175,22 @@ AC_ARG_ENABLE(selinux-support,
               selinux_support=$enableval, selinux_support=no)
 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])
+
+
 # Allow disabling of bzib2 support.
 # It is defined only after we confirm the library is available later
 AC_MSG_CHECKING([whether to enable the BZIP2 compression algorithm])
diff --git a/doc/gpg.texi b/doc/gpg.texi
index d66259e..b2c956e 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -1192,6 +1192,15 @@ the opposite meaning. The options are:
   validation. This option is only meaningful if pka-lookups is set.
 @end table
 
+ at item --enable-large-rsa
+ at itemx --disable-large-rsa
+ at opindex enable-large-rsa
+ at 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 a995796..576b88e 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -367,6 +367,8 @@ enum cmd_and_opt_values
     oAutoKeyLocate,
     oNoAutoKeyLocate,
     oAllowMultisigVerification,
+    oEnableLargeRSA,
+    oDisableLargeRSA,
     oEnableDSA2,
     oDisableDSA2,
     oAllowMultipleMessages,
@@ -736,6 +738,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", "@"),
@@ -2069,7 +2073,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
@@ -2964,6 +2968,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 5841ad8..17fde7f 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -1431,6 +1431,7 @@ gen_rsa (int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
   PKT_secret_key *sk;
   PKT_public_key *pk;
   gcry_sexp_t s_parms, s_key;
+  const unsigned maxsize = (opt.flags.large_rsa ? 8192 : 4096);
 
   assert (is_RSA(algo));
 
@@ -1442,9 +1443,9 @@ gen_rsa (int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
       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 1a13841..e9c540d 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -232,6 +232,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
-- 
2.1.0




More information about the Gnupg-devel mailing list