summaryrefslogtreecommitdiff
path: root/cipher/kdf.c
diff options
context:
space:
mode:
authorMilan Broz <gmazyland@gmail.com>2014-01-13 21:30:42 +0100
committerWerner Koch <wk@gnupg.org>2014-01-14 16:34:50 +0100
commit04cda6b7cc16f3f52c12d9d3e46c56701003496e (patch)
treef9942a9058230400055ffc5976373ed6db9da65d /cipher/kdf.c
parentdfde161355b15b25b1d1214d5ee0338e50b33517 (diff)
downloadlibgcrypt-04cda6b7cc16f3f52c12d9d3e46c56701003496e.tar.gz
PBKDF2: Use gcry_md_reset to speed up calculation.
* cipher/kdf.c (_gcry_kdf_pkdf2): Use gcry_md_reset to speed up calculation. -- Current PBKDF2 implementation uses gcry_md_set_key in every iteration which is extremely slow (even in comparison with other implementations). Use gcry_md_reset instead and set key only once. With this test program: char input[32000], salt[8], key[16]; gcry_kdf_derive(input, sizeof(input), GCRY_KDF_PBKDF2, gcry_md_map_name("sha1"), salt, sizeof(salt), 100000, sizeof(key), key); running time without patch: real 0m11.165s user 0m11.136s sys 0m0.000s and with patch applied real 0m0.230s user 0m0.184s sys 0m0.024s (The problem was found when cryptsetup started to use gcrypt internal PBKDF2 and for very long keyfiles unlocking time increased drastically. See https://bugzilla.redhat.com/show_bug.cgi?id=1051733) Signed-off-by: Milan Broz <gmazyland@gmail.com>
Diffstat (limited to 'cipher/kdf.c')
-rw-r--r--cipher/kdf.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/cipher/kdf.c b/cipher/kdf.c
index 503f0683..af0dc480 100644
--- a/cipher/kdf.c
+++ b/cipher/kdf.c
@@ -175,19 +175,21 @@ _gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
return ec;
}
+ ec = _gcry_md_setkey (md, passphrase, passphraselen);
+ if (ec)
+ {
+ _gcry_md_close (md);
+ xfree (sbuf);
+ return ec;
+ }
+
/* Step 3 and 4. */
memcpy (sbuf, salt, saltlen);
for (lidx = 1; lidx <= l; lidx++)
{
for (iter = 0; iter < iterations; iter++)
{
- ec = _gcry_md_setkey (md, passphrase, passphraselen);
- if (ec)
- {
- _gcry_md_close (md);
- xfree (sbuf);
- return ec;
- }
+ _gcry_md_reset (md);
if (!iter) /* Compute U_1: */
{
sbuf[saltlen] = (lidx >> 24);