aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2018-12-11 17:12:51 +0000
committerWerner Koch <[email protected]>2018-12-11 17:12:51 +0000
commitcbcc8c19541fe8407f3b6588fce1535c64cf6b25 (patch)
treecc02d83240034f6089e321f16b2a6d821be7bbe6
parentdirmngr: Retry another server from the pool on 502, 503, 504. (diff)
downloadgnupg-cbcc8c19541fe8407f3b6588fce1535c64cf6b25.tar.gz
gnupg-cbcc8c19541fe8407f3b6588fce1535c64cf6b25.zip
agent: Make the S2K calibration time runtime configurabe.
* 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 <[email protected]>
-rw-r--r--agent/agent.h1
-rw-r--r--agent/gpg-agent.c7
-rw-r--r--agent/protect.c33
-rw-r--r--doc/gpg-agent.texi11
4 files changed, 43 insertions, 9 deletions
diff --git a/agent/agent.h b/agent/agent.h
index 8a3e5c6b6..05080f1f2 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -488,6 +488,7 @@ gpg_error_t agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
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);
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index de6947d4e..e1c0e2b0b 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -135,6 +135,7 @@ enum cmd_and_opt_values
oDisableScdaemon,
oDisableCheckOwnSocket,
oS2KCount,
+ oS2KCalibration,
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_u (oS2KCalibration, "s2k-calibration", "@"),
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;
+ set_s2k_calibration_time (0); /* Set to default. */
return 1;
}
@@ -929,6 +932,10 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
opt.s2k_count = pargs->r.ret_ulong;
break;
+ case oS2KCalibration:
+ set_s2k_calibration_time (pargs->r.ret_ulong);
+ break;
+
default:
return 0; /* not handled */
}
diff --git a/agent/protect.c b/agent/protect.c
index c7bd30b68..f95527f78 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -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
{
@@ -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);
- if (ms > AGENT_S2K_CALIBRATION)
+ if (ms > s2k_calibration_time)
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)
@@ -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)
{
- static unsigned long count;
-
- if (!count)
- count = calibrate_s2k_count ();
+ if (!s2k_calibrated_count)
+ s2k_calibrated_count = calibrate_s2k_count ();
/* Enforce a lower limit. */
- return count < 65536 ? 65536 : count;
+ return s2k_calibrated_count < 65536 ? 65536 : s2k_calibrated_count;
}
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index bcce03329..3997d2046 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -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.
+@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.
-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: