agent: Make the S2K calibration time runtime configurabe.
authorWerner Koch <wk@gnupg.org>
Tue, 11 Dec 2018 17:12:51 +0000 (18:12 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 11 Dec 2018 17:12:51 +0000 (18:12 +0100)
* agent/protect.c (s2k_calibration_time): New file global var.
(calibrate_s2k_count): Use it here.
(get_calibrated_s2k_count): Replace function static var by ...
(s2k_calibrated_count): new file global var.
(set_s2k_calibration_time): New function.
* agent/gpg-agent.c (oS2KCalibration): New const.
(opts): New option --s2k-calibration.
(parse_rereadable_options): Parse that option.
--

Note that using an unrelistic high value (like 60000) takes quite some
time for calibration.

GnuPG-bug-id: 3399
Signed-off-by: Werner Koch <wk@gnupg.org>
agent/agent.h
agent/gpg-agent.c
agent/protect.c
doc/gpg-agent.texi

index 8a3e5c6..05080f1 100644 (file)
@@ -488,6 +488,7 @@ gpg_error_t agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
                                      char **passphrase_addr);
 
 /*-- protect.c --*/
                                      char **passphrase_addr);
 
 /*-- protect.c --*/
+void set_s2k_calibration_time (unsigned int milliseconds);
 unsigned long get_calibrated_s2k_count (void);
 unsigned long get_standard_s2k_count (void);
 unsigned char get_standard_s2k_count_rfc4880 (void);
 unsigned long get_calibrated_s2k_count (void);
 unsigned long get_standard_s2k_count (void);
 unsigned char get_standard_s2k_count_rfc4880 (void);
index de6947d..e1c0e2b 100644 (file)
@@ -135,6 +135,7 @@ enum cmd_and_opt_values
   oDisableScdaemon,
   oDisableCheckOwnSocket,
   oS2KCount,
   oDisableScdaemon,
   oDisableCheckOwnSocket,
   oS2KCount,
+  oS2KCalibration,
   oAutoExpandSecmem,
   oListenBacklog,
 
   oAutoExpandSecmem,
   oListenBacklog,
 
@@ -253,6 +254,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oEnableExtendedKeyFormat, "enable-extended-key-format", "@"),
 
   ARGPARSE_s_u (oS2KCount, "s2k-count", "@"),
   ARGPARSE_s_n (oEnableExtendedKeyFormat, "enable-extended-key-format", "@"),
 
   ARGPARSE_s_u (oS2KCount, "s2k-count", "@"),
+  ARGPARSE_s_u (oS2KCalibration, "s2k-calibration", "@"),
 
   ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"),
 
 
   ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"),
 
@@ -834,6 +836,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
       /* Note: When changing the next line, change also gpgconf_list.  */
       opt.ssh_fingerprint_digest = GCRY_MD_MD5;
       opt.s2k_count = 0;
       /* Note: When changing the next line, change also gpgconf_list.  */
       opt.ssh_fingerprint_digest = GCRY_MD_MD5;
       opt.s2k_count = 0;
+      set_s2k_calibration_time (0);  /* Set to default.  */
       return 1;
     }
 
       return 1;
     }
 
@@ -929,6 +932,10 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
       opt.s2k_count = pargs->r.ret_ulong;
       break;
 
       opt.s2k_count = pargs->r.ret_ulong;
       break;
 
+    case oS2KCalibration:
+      set_s2k_calibration_time (pargs->r.ret_ulong);
+      break;
+
     default:
       return 0; /* not handled */
     }
     default:
       return 0; /* not handled */
     }
index c7bd30b..f95527f 100644 (file)
@@ -71,6 +71,13 @@ static const struct {
 };
 
 
 };
 
 
+/* The number of milliseconds we use in the S2K function and the
+ * calibrated count value.  A count value of zero indicates that the
+ * calibration has not yet been done or needs to be done again.  */
+static unsigned int s2k_calibration_time = AGENT_S2K_CALIBRATION;
+static unsigned long s2k_calibrated_count;
+
+
 /* A helper object for time measurement.  */
 struct calibrate_time_s
 {
 /* A helper object for time measurement.  */
 struct calibrate_time_s
 {
@@ -175,11 +182,11 @@ calibrate_s2k_count (void)
       ms = calibrate_s2k_count_one (count);
       if (opt.verbose > 1)
         log_info ("S2K calibration: %lu -> %lums\n", count, ms);
       ms = calibrate_s2k_count_one (count);
       if (opt.verbose > 1)
         log_info ("S2K calibration: %lu -> %lums\n", count, ms);
-      if (ms > AGENT_S2K_CALIBRATION)
+      if (ms > s2k_calibration_time)
         break;
     }
 
         break;
     }
 
-  count = (unsigned long)(((double)count / ms) * AGENT_S2K_CALIBRATION);
+  count = (unsigned long)(((double)count / ms) * s2k_calibration_time);
   count /= 1024;
   count *= 1024;
   if (count < 65536)
   count /= 1024;
   count *= 1024;
   if (count < 65536)
@@ -195,18 +202,30 @@ calibrate_s2k_count (void)
 }
 
 
 }
 
 
+/* Set the calibration time.  This may be called early at startup or
+ * at any time.  Thus it should one set variables.  */
+void
+set_s2k_calibration_time (unsigned int milliseconds)
+{
+  if (!milliseconds)
+    milliseconds = AGENT_S2K_CALIBRATION;
+  else if (milliseconds > 60 * 1000)
+    milliseconds = 60 * 1000;  /* Cap at 60 seconds.  */
+  s2k_calibration_time = milliseconds;
+  s2k_calibrated_count = 0;  /* Force re-calibration.  */
+}
+
+
 /* Return the calibrated S2K count.  This is only public for the use
  * of the Assuan getinfo s2k_count_cal command.  */
 unsigned long
 get_calibrated_s2k_count (void)
 {
 /* Return the calibrated S2K count.  This is only public for the use
  * of the Assuan getinfo s2k_count_cal command.  */
 unsigned long
 get_calibrated_s2k_count (void)
 {
-  static unsigned long count;
-
-  if (!count)
-    count = calibrate_s2k_count ();
+  if (!s2k_calibrated_count)
+    s2k_calibrated_count = calibrate_s2k_count ();
 
   /* Enforce a lower limit.  */
 
   /* Enforce a lower limit.  */
-  return count < 65536 ? 65536 : count;
+  return s2k_calibrated_count < 65536 ? 65536 : s2k_calibrated_count;
 }
 
 
 }
 
 
index bcce033..3997d20 100644 (file)
@@ -669,12 +669,19 @@ For an heavy loaded gpg-agent with many concurrent connection this
 option avoids sign or decrypt errors due to out of secure memory error
 returns.
 
 option avoids sign or decrypt errors due to out of secure memory error
 returns.
 
+@item --s2k-calibration @var{milliseconds}
+@opindex s2k-calibration
+Change the default calibration time to @var{milliseconds}.  The given
+value is capped at 60 seconds; a value of 0 resets to the compiled-in
+default.  This option is re-read on a SIGHUP (or @code{gpgconf
+--reload gpg-agent}) and the S2K count is then re-calibrated.
+
 @item --s2k-count @var{n}
 @opindex s2k-count
 Specify the iteration count used to protect the passphrase.  This
 option can be used to override the auto-calibration done by default.
 @item --s2k-count @var{n}
 @opindex s2k-count
 Specify the iteration count used to protect the passphrase.  This
 option can be used to override the auto-calibration done by default.
-The auto-calibration computes a count which requires 100ms to mangle
-a given passphrase.
+The auto-calibration computes a count which requires by default 100ms
+to mangle a given passphrase.  See also @option{--s2k-calibration}.
 
 To view the actually used iteration count and the milliseconds
 required for an S2K operation use:
 
 To view the actually used iteration count and the milliseconds
 required for an S2K operation use: