From f848a19d352121a00b8526ed5c2ec60330e25ab2 Mon Sep 17 00:00:00 2001 From: Richard Ipsum Date: Sun, 28 May 2017 19:36:01 +0100 Subject: Add TRUST_LIBSCRYPT_SALT_GEN build option Modern versions of libscrypt now generate salt correctly, indeed using the very method currently used by lua-scrypt.[1] This patch adds a build option that is disabled by default, when enabled lua-scrypt will use libscrypt's salt generation code rather than its own. [1]: https://sources.debian.net/src/libscrypt/1.21-3/crypto-scrypt-saltgen.c/ --- Makefile | 3 +-- luascrypt.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 8e756c1..e32ab37 100644 --- a/Makefile +++ b/Makefile @@ -100,11 +100,10 @@ LIBCRYPT_C := lib/crypto/crypto_aesctr.c \ lib/crypto/crypto_scrypt-ref.c \ lib/crypto/sha256.c -CFLAGS ?= -O2 -Wall INSTALL := /usr/bin/install SCRYPT_LIBS := -lscrypt -CFLAGS := $(CFLAGS) -fPIC +override CFLAGS := $(CFLAGS) -O2 -Wall -fPIC all: lua-5.1-try lua-5.2-try diff --git a/luascrypt.c b/luascrypt.c index 181f1e8..9fad808 100644 --- a/luascrypt.c +++ b/luascrypt.c @@ -34,7 +34,7 @@ luascrypt_salt_gen(char *salt, int saltlen) * if we can... */ libscrypt_salt_gen(salt, saltlen); - + fd = open("/dev/urandom", O_RDONLY); if (fd >= 0) { read(fd, salt, saltlen); /* Ignore errors in these two calls */ @@ -70,8 +70,15 @@ luascrypt_hash_password(lua_State *L) return luaL_error(L, "Unable to generate password hash: %s", "N is too large (limited to 2^15)"); } - + +#ifdef TRUST_LIBSCRYPT_SALT_GEN + /* Modern versions of libscrypt generate sufficiently random salts + * and take a uint8_t * instead of char * + */ + libscrypt_salt_gen((uint8_t *) salt, sizeof(salt)); +#else luascrypt_salt_gen(salt, sizeof(salt)); +#endif if (libscrypt_scrypt((uint8_t*)passwd, passwd_len, (uint8_t*)salt, sizeof(salt), -- cgit v1.2.1 From 5fcf093b8a8880bda56e0b9afe0dee8e9927c4c5 Mon Sep 17 00:00:00 2001 From: Richard Ipsum Date: Sat, 3 Jun 2017 20:58:03 +0100 Subject: README: add build instructions --- README | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/README b/README index 9bed714..281956d 100644 --- a/README +++ b/README @@ -6,11 +6,26 @@ verification library. lua-scrypt uses the [libscrypt][] library and provides a simple interface for hashing and verifying passwords. local scrypt = require "scrypt" - + local hash = scrypt.hash_password("Hello world") assert(scrypt.verify_password(hash, "Hello world")) +Installation +============ + +To compile lua-scrypt, on platforms with libscrypt 1.21 or later run, + + $ make CFLAGS+=-DTRUST_LIBSCRYPT_SALT_GEN + +for platforms with older versions (earlier than 1.21) of libscrypt run, + + $ make + +To install lua-scrypt, run, + + $ make install + Thanks ====== -- cgit v1.2.1 From 9271157304dbd707f87343df0106c3465b50d6a1 Mon Sep 17 00:00:00 2001 From: Richard Ipsum Date: Mon, 5 Jun 2017 18:32:27 +0100 Subject: Harden reading from /dev/urandom Guard against short reads. --- luascrypt.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/luascrypt.c b/luascrypt.c index 9fad808..11ae799 100644 --- a/luascrypt.c +++ b/luascrypt.c @@ -26,7 +26,9 @@ static void luascrypt_salt_gen(char *salt, int saltlen) { int fd; - /* We'd go with libscrypt's implementation, but since libscrypt's salt + /* Following comment applies to libscrypt prior to 1.21: + * + * We'd go with libscrypt's implementation, but since libscrypt's salt * generation is time based, we cannot fully trust it to generate * unique salts so to improve our chances we assume we have urandom * and fall back to libscrypt's implementation if we don't. Since the @@ -37,8 +39,28 @@ luascrypt_salt_gen(char *salt, int saltlen) fd = open("/dev/urandom", O_RDONLY); if (fd >= 0) { - read(fd, salt, saltlen); /* Ignore errors in these two calls */ - close(fd); /* Since we have our fallback. */ + size_t total = 0; + ssize_t n; + + while (total < saltlen) { + n = read(fd, salt + total, saltlen - total); + if (n == 0) { + break; + } + + if (n == -1) { + if (errno == EINTR) { + continue; /* just try again */ + } + + /* Ignore all other errors, since we have our fallback. */ + break; + } + + total += n; + } + + close(fd); } } -- cgit v1.2.1