summaryrefslogtreecommitdiff
path: root/cipher/kdf.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-04-05 12:23:41 +0200
committerWerner Koch <wk@gnupg.org>2013-04-05 12:24:06 +0200
commitf23a068bcb6ec9788710698578d8be0a2a006dbc (patch)
tree16640fd3ce5f8fd358752ce4ed57667f0519ea0d /cipher/kdf.c
parent855b1a8f81b5a3b5b31d0c3c303675425f58a5af (diff)
downloadlibgcrypt-f23a068bcb6ec9788710698578d8be0a2a006dbc.tar.gz
Add test case for SCRYPT and rework the code.
* tests/t-kdf.c (check_scrypt): New. (main): Call new test. * configure.ac: Support disabling of the scrypt algorithm. Make KDF enabling similar to the other algorithm classes. Disable scrypt if we don't have a 64 bit type. * cipher/memxor.c, cipher/memxor.h: Remove. * cipher/scrypt.h: Remove. * cipher/kdf-internal.h: New. * cipher/Makefile.am: Remove files. Add new file. Move scrypt.c to EXTRA_libcipher_la_SOURCES. (GCRYPT_MODULES): Add GCRYPT_KDFS. * src/gcrypt.h.in (GCRY_KDF_SCRYPT): Change value. * cipher/kdf.c (pkdf2): Rename to _gcry_kdf_pkdf2. (_gcry_kdf_pkdf2): Don't bail out for SALTLEN==0. (gcry_kdf_derive): Allow for a passwordlen of zero for scrypt. Check for SALTLEN > 0 for GCRY_KDF_PBKDF2. Pass algo to _gcry_kdf_scrypt. (gcry_kdf_derive) [!USE_SCRYPT]: Return an error. * cipher/scrypt.c: Replace memxor.h by bufhelp.h. Replace scrypt.h by kdf-internal.h. Enable code only if HAVE_U64_TYPEDEF is defined. Replace C99 types uint64_t, uint32_t, and uint8_t by libgcrypt types. (_SALSA20_INPUT_LENGTH): Remove underscore from identifier. (_scryptBlockMix): Replace memxor by buf_xor. (_gcry_kdf_scrypt): Use gcry_malloc and gcry_free. Check for integer overflow. Add hack to support blocksize of 1 for tests. Return errors from calls to _gcry_kdf_pkdf2. * cipher/kdf.c (openpgp_s2k): Make static. -- This patch prepares the addition of more KDF functions, brings the code into Libgcrypt shape, adds a test case and makes the code more robust. For example, scrypt would have fail silently if Libgcrypt was not build with SHA256 support. Also fixed symbol naming for systems without a visibility support. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/kdf.c')
-rw-r--r--cipher/kdf.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/cipher/kdf.c b/cipher/kdf.c
index 4ea0fb29..da63574f 100644
--- a/cipher/kdf.c
+++ b/cipher/kdf.c
@@ -1,5 +1,6 @@
/* kdf.c - Key Derivation Functions
* Copyright (C) 1998, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -26,7 +27,7 @@
#include "g10lib.h"
#include "cipher.h"
#include "ath.h"
-#include "scrypt.h"
+#include "kdf-internal.h"
/* Transform a passphrase into a suitable key of length KEYSIZE and
@@ -34,7 +35,7 @@
must provide an HASHALGO, a valid ALGO and depending on that algo a
SALT of 8 bytes and the number of ITERATIONS. Code taken from
gnupg/agent/protect.c:hash_passphrase. */
-gpg_err_code_t
+static gpg_err_code_t
openpgp_s2k (const void *passphrase, size_t passphraselen,
int algo, int hashalgo,
const void *salt, size_t saltlen,
@@ -117,11 +118,11 @@ openpgp_s2k (const void *passphrase, size_t passphraselen,
used in HMAC mode. SALT is a salt of length SALTLEN and ITERATIONS
gives the number of iterations. */
gpg_err_code_t
-pkdf2 (const void *passphrase, size_t passphraselen,
- int hashalgo,
- const void *salt, size_t saltlen,
- unsigned long iterations,
- size_t keysize, void *keybuffer)
+_gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
+ int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
{
gpg_err_code_t ec;
gcry_md_hd_t md;
@@ -139,7 +140,10 @@ pkdf2 (const void *passphrase, size_t passphraselen,
unsigned long iter; /* Current iteration number. */
unsigned int i;
- if (!salt || !saltlen || !iterations || !dklen)
+ /* NWe allow for a saltlen of 0 here to support scrypt. It is not
+ clear whether rfc2898 allows for this this, thus we do a test on
+ saltlen > 0 only in gcry_kdf_derive. */
+ if (!salt || !iterations || !dklen)
return GPG_ERR_INV_VALUE;
hlen = gcry_md_get_algo_dlen (hashalgo);
@@ -239,11 +243,12 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen,
{
gpg_err_code_t ec;
- if (!passphrase || (!passphraselen && algo != GCRY_KDF_PBKDF2))
+ if (!passphrase)
{
ec = GPG_ERR_INV_DATA;
goto leave;
}
+
if (!keybuffer || !keysize)
{
ec = GPG_ERR_INV_VALUE;
@@ -256,8 +261,11 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen,
case GCRY_KDF_SIMPLE_S2K:
case GCRY_KDF_SALTED_S2K:
case GCRY_KDF_ITERSALTED_S2K:
- ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo,
- salt, saltlen, iterations, keysize, keybuffer);
+ if (!passphraselen)
+ ec = GPG_ERR_INV_DATA;
+ else
+ ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
break;
case GCRY_KDF_PBKDF1:
@@ -265,12 +273,22 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen,
break;
case GCRY_KDF_PBKDF2:
- ec = pkdf2 (passphrase, passphraselen, subalgo,
- salt, saltlen, iterations, keysize, keybuffer);
+ if (!saltlen)
+ ec = GPG_ERR_INV_VALUE;
+ else
+ ec = _gcry_kdf_pkdf2 (passphrase, passphraselen, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
break;
+
+ case 41:
case GCRY_KDF_SCRYPT:
- ec = scrypt (passphrase, passphraselen, subalgo,
- salt, saltlen, iterations, keysize, keybuffer);
+#if USE_SCRYPT
+ ec = _gcry_kdf_scrypt (passphrase, passphraselen, algo, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+#else
+ ec = GPG_ERR_UNSUPPORTED_ALGORITHM;
+#endif /*USE_SCRYPT*/
+ break;
default:
ec = GPG_ERR_UNKNOWN_ALGORITHM;