summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2015-07-08 19:54:40 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2015-07-08 19:54:40 +0100
commit9affdc735bc5731580619057405d16cf588afe9b (patch)
treee813c32a03abc78201f005361238d976b0ca0773
parentb2378b42f08b6582ae891e8d8599dde474e032ba (diff)
downloadlua-scrypt-git-9affdc735bc5731580619057405d16cf588afe9b.tar.gz
Change to using libscrypt even though it has known failure modes
-rw-r--r--COPYING28
-rw-r--r--Makefile37
-rw-r--r--example.lua5
-rw-r--r--lib/README6
-rw-r--r--lib/crypto/crypto_aesctr.c123
-rw-r--r--lib/crypto/crypto_aesctr.h59
-rw-r--r--lib/crypto/crypto_scrypt-nosse.c337
-rw-r--r--lib/crypto/crypto_scrypt-ref.c283
-rw-r--r--lib/crypto/crypto_scrypt-sse.c365
-rw-r--r--lib/crypto/crypto_scrypt.h46
-rw-r--r--lib/crypto/sha256.c411
-rw-r--r--lib/crypto/sha256.h62
-rw-r--r--lib/scryptenc/scryptenc.c605
-rw-r--r--lib/scryptenc/scryptenc.h112
-rw-r--r--lib/scryptenc/scryptenc_cpuperf.c184
-rw-r--r--lib/scryptenc/scryptenc_cpuperf.h39
-rw-r--r--lib/util/memlimit.c301
-rw-r--r--lib/util/memlimit.h42
-rw-r--r--lib/util/readpass.c142
-rw-r--r--lib/util/readpass.h45
-rw-r--r--lib/util/sysendian.h138
-rw-r--r--lib/util/warn.c74
-rw-r--r--lib/util/warn.h13
-rw-r--r--luascrypt.c271
24 files changed, 144 insertions, 3584 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..80ff910
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,28 @@
+Copyright 2015 Daniel Silverstone <dsilvers@digital-scurf.org>
+All rights reserved.
+
+Based on code by Rob Kendrick <rjek@rjek.com>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of their contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/Makefile b/Makefile
index 46171fc..070b1b2 100644
--- a/Makefile
+++ b/Makefile
@@ -100,43 +100,18 @@ LIBCRYPT_C := lib/crypto/crypto_aesctr.c \
lib/crypto/crypto_scrypt-ref.c \
lib/crypto/sha256.c
-ifneq ($(USE_SSE),)
- LIBCRYPT_C := $(subst -nosse.c$,-sse.c,$(LIBCRYPT_C))
-endif
-
-LIBCRYPT_O := $(subst .c$,.o,$(LIBCRYPT_C))
-
-LIBSCRYPTENC_C := lib/scryptenc/scryptenc.c lib/scryptenc/scryptenc_cpuperf.c
-LIBSCRYPTENC_O := $(subst .c$,.o,$(LIBSCRYPTENC_C))
-
-LIBUTIL_C := lib/util/memlimit.c lib/util/readpass.c lib/util/warn.c
-LIBUTIL_O := $(subst .c$,.o,$(LIBUTIL_C))
-
-SCRYPT_LIBS := libcrypt.a libscryptenc.a libutil.a
-
CFLAGS ?= -O2 -Wall
INSTALL := /usr/bin/install
+SCRYPT_LIBS := -lscrypt
all: lua-5.1-try lua-5.2-try
clean:
- $(RM) scrypt-5.1.so scrypt-5.2.so scrypt.so
- $(RM) $(SCRYPT_LIBS)
- $(RM) $(LIBCRYPT_O)
- $(RM) $(LIBSCRYPTENC_O)
- $(RM) $(LIBUTIL_O)
+ $(RM) scrypt-5.1.so scrypt-5.2.so scrypt.so
+ $(RM) luascrypt.o
%.o: %.c
- $(CC) $(CFLAGS) -fPIC $(LUA51_INC) -I lib/util -I lib/crypto -I lib/scryptenc -c $< -o $@
-
-libcrypt.a: $(LIBCRYPT_O)
- $(AR) q libcrypt.a $(LIBCRYPT_O)
-
-libscryptenc.a: $(LIBSCRYPTENC_O)
- $(AR) q libscryptenc.a $(LIBSCRYPTENC_O)
-
-libutil.a: $(LIBUTIL_O)
- $(AR) q libutil.a $(LIBUTIL_O)
+ $(CC) $(CFLAGS) -fPIC $(LUA51_INC) -c $< -o $@
lua-5.1: scrypt-5.1.so
ln -s -f scrypt-5.1.so scrypt.so
@@ -145,7 +120,7 @@ lua-5.1-install: lua-5.1
$(INSTALL) -d $(DESTDIR)$(LUA51_CMOD_INST)
$(INSTALL) -m 755 scrypt-5.1.so $(DESTDIR)$(LUA51_CMOD_INST)/scrypt.so
-scrypt-5.1.so: luascrypt.o $(SCRYPT_LIBS)
+scrypt-5.1.so: luascrypt.o
$(CC) $(CFLAGS) -shared -o $@ $^ $(LUA51_LIB) $(SCRYPT_LIBS)
lua-5.2: scrypt-5.2.so
@@ -155,7 +130,7 @@ lua-5.2-install: lua-5.2
$(INSTALL) -d $(DESTDIR)$(LUA52_CMOD_INST)
$(INSTALL) -m 755 scrypt-5.2.so $(DESTDIR)$(LUA52_CMOD_INST)/scrypt.so
-scrypt-5.2.so: luascrypt.o $(SCRYPT_LIBS)
+scrypt-5.2.so: luascrypt.o
$(CC) $(CFLAGS) -shared -o $@ $^ $(LUA51_LIB) $(SCRYPT_LIBS)
diff --git a/example.lua b/example.lua
index a38f811..a600ad7 100644
--- a/example.lua
+++ b/example.lua
@@ -14,7 +14,7 @@ time "Generate hash2"
assert(hash1 ~= hash2) -- hashes are salted
-local hash3 = scrypt.hash_password("Hello", 2^16, 8, 1)
+local hash3 = scrypt.hash_password("Hello", 2^15, 8, 1)
time "Generate hash3"
assert(scrypt.verify_password(hash1, "Hello"))
@@ -28,3 +28,6 @@ time "Verify hash3 with correct password"
assert(scrypt.verify_password(hash3, "World") == false)
time "Verify hash3 with incorrect password"
+
+local hash4 = scrypt.hash_password("Hello")
+time "Generate hash 4, default N/r/p"
diff --git a/lib/README b/lib/README
deleted file mode 100644
index 3bb211e..0000000
--- a/lib/README
+++ /dev/null
@@ -1,6 +0,0 @@
-The source code under this directory is taken from the client for the
-Tarsnap online backup system (and released under the 2-clause BSD license
-with permission of the author); keeping this code in sync with the Tarsnap
-code is highly desirable and explains why there is some functionality
-included here which is not actually used by the scrypt file encryption
-utility.
diff --git a/lib/crypto/crypto_aesctr.c b/lib/crypto/crypto_aesctr.c
deleted file mode 100644
index bc7479c..0000000
--- a/lib/crypto/crypto_aesctr.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*-
- * Copyright 2007-2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <openssl/aes.h>
-
-#include "sysendian.h"
-
-#include "crypto_aesctr.h"
-
-struct crypto_aesctr {
- AES_KEY * key;
- uint64_t nonce;
- uint64_t bytectr;
- uint8_t buf[16];
-};
-
-/**
- * crypto_aesctr_init(key, nonce):
- * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
- * expanded key and nonce. The key provided must remain valid for the
- * lifetime of the stream.
- */
-struct crypto_aesctr *
-crypto_aesctr_init(AES_KEY * key, uint64_t nonce)
-{
- struct crypto_aesctr * stream;
-
- /* Allocate memory. */
- if ((stream = malloc(sizeof(struct crypto_aesctr))) == NULL)
- goto err0;
-
- /* Initialize values. */
- stream->key = key;
- stream->nonce = nonce;
- stream->bytectr = 0;
-
- /* Success! */
- return (stream);
-
-err0:
- /* Failure! */
- return (NULL);
-}
-
-/**
- * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
- * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
- * bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers
- * ${inbuf} and ${outbuf} overlap, they must be identical.
- */
-void
-crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf,
- uint8_t * outbuf, size_t buflen)
-{
- uint8_t pblk[16];
- size_t pos;
- int bytemod;
-
- for (pos = 0; pos < buflen; pos++) {
- /* How far through the buffer are we? */
- bytemod = stream->bytectr % 16;
-
- /* Generate a block of cipherstream if needed. */
- if (bytemod == 0) {
- be64enc(pblk, stream->nonce);
- be64enc(pblk + 8, stream->bytectr / 16);
- AES_encrypt(pblk, stream->buf, stream->key);
- }
-
- /* Encrypt a byte. */
- outbuf[pos] = inbuf[pos] ^ stream->buf[bytemod];
-
- /* Move to the next byte of cipherstream. */
- stream->bytectr += 1;
- }
-}
-
-/**
- * crypto_aesctr_free(stream):
- * Free the provided stream object.
- */
-void
-crypto_aesctr_free(struct crypto_aesctr * stream)
-{
- int i;
-
- /* Zero potentially sensitive information. */
- for (i = 0; i < 16; i++)
- stream->buf[i] = 0;
- stream->bytectr = stream->nonce = 0;
-
- /* Free the stream. */
- free(stream);
-}
diff --git a/lib/crypto/crypto_aesctr.h b/lib/crypto/crypto_aesctr.h
deleted file mode 100644
index b50398f..0000000
--- a/lib/crypto/crypto_aesctr.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _CRYPTO_AESCTR_H_
-#define _CRYPTO_AESCTR_H_
-
-#include <stdint.h>
-
-#include <openssl/aes.h>
-
-/**
- * crypto_aesctr_init(key, nonce):
- * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
- * expanded key and nonce. The key provided must remain valid for the
- * lifetime of the stream.
- */
-struct crypto_aesctr * crypto_aesctr_init(AES_KEY *, uint64_t);
-
-/**
- * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
- * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
- * bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers
- * ${inbuf} and ${outbuf} overlap, they must be identical.
- */
-void crypto_aesctr_stream(struct crypto_aesctr *, const uint8_t *,
- uint8_t *, size_t);
-
-/**
- * crypto_aesctr_free(stream):
- * Free the provided stream object.
- */
-void crypto_aesctr_free(struct crypto_aesctr *);
-
-#endif /* !_CRYPTO_AESCTR_H_ */
diff --git a/lib/crypto/crypto_scrypt-nosse.c b/lib/crypto/crypto_scrypt-nosse.c
deleted file mode 100644
index 9389029..0000000
--- a/lib/crypto/crypto_scrypt-nosse.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "sha256.h"
-#include "sysendian.h"
-
-#include "crypto_scrypt.h"
-
-static void blkcpy(void *, void *, size_t);
-static void blkxor(void *, void *, size_t);
-static void salsa20_8(uint32_t[16]);
-static void blockmix_salsa8(uint32_t *, uint32_t *, uint32_t *, size_t);
-static uint64_t integerify(void *, size_t);
-static void smix(uint8_t *, size_t, uint64_t, uint32_t *, uint32_t *);
-
-static void
-blkcpy(void * dest, void * src, size_t len)
-{
- size_t * D = dest;
- size_t * S = src;
- size_t L = len / sizeof(size_t);
- size_t i;
-
- for (i = 0; i < L; i++)
- D[i] = S[i];
-}
-
-static void
-blkxor(void * dest, void * src, size_t len)
-{
- size_t * D = dest;
- size_t * S = src;
- size_t L = len / sizeof(size_t);
- size_t i;
-
- for (i = 0; i < L; i++)
- D[i] ^= S[i];
-}
-
-/**
- * salsa20_8(B):
- * Apply the salsa20/8 core to the provided block.
- */
-static void
-salsa20_8(uint32_t B[16])
-{
- uint32_t x[16];
- size_t i;
-
- blkcpy(x, B, 64);
- for (i = 0; i < 8; i += 2) {
-#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
- /* Operate on columns. */
- x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
- x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
-
- x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
- x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
-
- x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
- x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
-
- x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
- x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
-
- /* Operate on rows. */
- x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
- x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
-
- x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
- x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
-
- x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
- x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
-
- x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
- x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
-#undef R
- }
- for (i = 0; i < 16; i++)
- B[i] += x[i];
-}
-
-/**
- * blockmix_salsa8(Bin, Bout, X, r):
- * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
- * bytes in length; the output Bout must also be the same size. The
- * temporary space X must be 64 bytes.
- */
-static void
-blockmix_salsa8(uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r)
-{
- size_t i;
-
- /* 1: X <-- B_{2r - 1} */
- blkcpy(X, &Bin[(2 * r - 1) * 16], 64);
-
- /* 2: for i = 0 to 2r - 1 do */
- for (i = 0; i < 2 * r; i += 2) {
- /* 3: X <-- H(X \xor B_i) */
- blkxor(X, &Bin[i * 16], 64);
- salsa20_8(X);
-
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- blkcpy(&Bout[i * 8], X, 64);
-
- /* 3: X <-- H(X \xor B_i) */
- blkxor(X, &Bin[i * 16 + 16], 64);
- salsa20_8(X);
-
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- blkcpy(&Bout[i * 8 + r * 16], X, 64);
- }
-}
-
-/**
- * integerify(B, r):
- * Return the result of parsing B_{2r-1} as a little-endian integer.
- */
-static uint64_t
-integerify(void * B, size_t r)
-{
- uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64);
-
- return (((uint64_t)(X[1]) << 32) + X[0]);
-}
-
-/**
- * smix(B, r, N, V, XY):
- * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
- * the temporary storage V must be 128rN bytes in length; the temporary
- * storage XY must be 256r + 64 bytes in length. The value N must be a
- * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
- * multiple of 64 bytes.
- */
-static void
-smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY)
-{
- uint32_t * X = XY;
- uint32_t * Y = &XY[32 * r];
- uint32_t * Z = &XY[64 * r];
- uint64_t i;
- uint64_t j;
- size_t k;
-
- /* 1: X <-- B */
- for (k = 0; k < 32 * r; k++)
- X[k] = le32dec(&B[4 * k]);
-
- /* 2: for i = 0 to N - 1 do */
- for (i = 0; i < N; i += 2) {
- /* 3: V_i <-- X */
- blkcpy(&V[i * (32 * r)], X, 128 * r);
-
- /* 4: X <-- H(X) */
- blockmix_salsa8(X, Y, Z, r);
-
- /* 3: V_i <-- X */
- blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r);
-
- /* 4: X <-- H(X) */
- blockmix_salsa8(Y, X, Z, r);
- }
-
- /* 6: for i = 0 to N - 1 do */
- for (i = 0; i < N; i += 2) {
- /* 7: j <-- Integerify(X) mod N */
- j = integerify(X, r) & (N - 1);
-
- /* 8: X <-- H(X \xor V_j) */
- blkxor(X, &V[j * (32 * r)], 128 * r);
- blockmix_salsa8(X, Y, Z, r);
-
- /* 7: j <-- Integerify(X) mod N */
- j = integerify(Y, r) & (N - 1);
-
- /* 8: X <-- H(X \xor V_j) */
- blkxor(Y, &V[j * (32 * r)], 128 * r);
- blockmix_salsa8(Y, X, Z, r);
- }
-
- /* 10: B' <-- X */
- for (k = 0; k < 32 * r; k++)
- le32enc(&B[4 * k], X[k]);
-}
-
-/**
- * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
- * p, buflen) and write the result into buf. The parameters r, p, and buflen
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
- * must be a power of 2 greater than 1.
- *
- * Return 0 on success; or -1 on error.
- */
-int
-crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
- const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
- uint8_t * buf, size_t buflen)
-{
- void * B0, * V0, * XY0;
- uint8_t * B;
- uint32_t * V;
- uint32_t * XY;
- uint32_t i;
-
- /* Sanity-check parameters. */
-#if SIZE_MAX > UINT32_MAX
- if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
- errno = EFBIG;
- goto err0;
- }
-#endif
- if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
- errno = EFBIG;
- goto err0;
- }
- if (((N & (N - 1)) != 0) || (N == 0)) {
- errno = EINVAL;
- goto err0;
- }
- if ((r > SIZE_MAX / 128 / p) ||
-#if SIZE_MAX / 256 <= UINT32_MAX
- (r > SIZE_MAX / 256) ||
-#endif
- (N > SIZE_MAX / 128 / r)) {
- errno = ENOMEM;
- goto err0;
- }
-
- /* Allocate memory. */
-#ifdef HAVE_POSIX_MEMALIGN
- if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
- goto err0;
- B = (uint8_t *)(B0);
- if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
- goto err1;
- XY = (uint32_t *)(XY0);
-#ifndef MAP_ANON
- if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
- goto err2;
- V = (uint32_t *)(V0);
-#endif
-#else
- if ((B0 = malloc(128 * r * p + 63)) == NULL)
- goto err0;
- B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
- if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
- goto err1;
- XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
-#ifndef MAP_ANON
- if ((V0 = malloc(128 * r * N + 63)) == NULL)
- goto err2;
- V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
-#endif
-#endif
-#ifdef MAP_ANON
- if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
-#ifdef MAP_NOCORE
- MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
-#else
- MAP_ANON | MAP_PRIVATE,
-#endif
- -1, 0)) == MAP_FAILED)
- goto err2;
- V = (uint32_t *)(V0);
-#endif
-
- /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
- PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
-
- /* 2: for i = 0 to p - 1 do */
- for (i = 0; i < p; i++) {
- /* 3: B_i <-- MF(B_i, N) */
- smix(&B[i * 128 * r], r, N, V, XY);
- }
-
- /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
- PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
-
- /* Free memory. */
-#ifdef MAP_ANON
- if (munmap(V0, 128 * r * N))
- goto err2;
-#else
- free(V0);
-#endif
- free(XY0);
- free(B0);
-
- /* Success! */
- return (0);
-
-err2:
- free(XY0);
-err1:
- free(B0);
-err0:
- /* Failure! */
- return (-1);
-}
diff --git a/lib/crypto/crypto_scrypt-ref.c b/lib/crypto/crypto_scrypt-ref.c
deleted file mode 100644
index 1b0d514..0000000
--- a/lib/crypto/crypto_scrypt-ref.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "sha256.h"
-#include "sysendian.h"
-
-#include "crypto_scrypt.h"
-
-static void blkcpy(uint8_t *, uint8_t *, size_t);
-static void blkxor(uint8_t *, uint8_t *, size_t);
-static void salsa20_8(uint8_t[64]);
-static void blockmix_salsa8(uint8_t *, uint8_t *, size_t);
-static uint64_t integerify(uint8_t *, size_t);
-static void smix(uint8_t *, size_t, uint64_t, uint8_t *, uint8_t *);
-
-static void
-blkcpy(uint8_t * dest, uint8_t * src, size_t len)
-{
- size_t i;
-
- for (i = 0; i < len; i++)
- dest[i] = src[i];
-}
-
-static void
-blkxor(uint8_t * dest, uint8_t * src, size_t len)
-{
- size_t i;
-
- for (i = 0; i < len; i++)
- dest[i] ^= src[i];
-}
-
-/**
- * salsa20_8(B):
- * Apply the salsa20/8 core to the provided block.
- */
-static void
-salsa20_8(uint8_t B[64])
-{
- uint32_t B32[16];
- uint32_t x[16];
- size_t i;
-
- /* Convert little-endian values in. */
- for (i = 0; i < 16; i++)
- B32[i] = le32dec(&B[i * 4]);
-
- /* Compute x = doubleround^4(B32). */
- for (i = 0; i < 16; i++)
- x[i] = B32[i];
- for (i = 0; i < 8; i += 2) {
-#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
- /* Operate on columns. */
- x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
- x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
-
- x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
- x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
-
- x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
- x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
-
- x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
- x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
-
- /* Operate on rows. */
- x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
- x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
-
- x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
- x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
-
- x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
- x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
-
- x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
- x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
-#undef R
- }
-
- /* Compute B32 = B32 + x. */
- for (i = 0; i < 16; i++)
- B32[i] += x[i];
-
- /* Convert little-endian values out. */
- for (i = 0; i < 16; i++)
- le32enc(&B[4 * i], B32[i]);
-}
-
-/**
- * blockmix_salsa8(B, Y, r):
- * Compute B = BlockMix_{salsa20/8, r}(B). The input B must be 128r bytes in
- * length; the temporary space Y must also be the same size.
- */
-static void
-blockmix_salsa8(uint8_t * B, uint8_t * Y, size_t r)
-{
- uint8_t X[64];
- size_t i;
-
- /* 1: X <-- B_{2r - 1} */
- blkcpy(X, &B[(2 * r - 1) * 64], 64);
-
- /* 2: for i = 0 to 2r - 1 do */
- for (i = 0; i < 2 * r; i++) {
- /* 3: X <-- H(X \xor B_i) */
- blkxor(X, &B[i * 64], 64);
- salsa20_8(X);
-
- /* 4: Y_i <-- X */
- blkcpy(&Y[i * 64], X, 64);
- }
-
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- for (i = 0; i < r; i++)
- blkcpy(&B[i * 64], &Y[(i * 2) * 64], 64);
- for (i = 0; i < r; i++)
- blkcpy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);
-}
-
-/**
- * integerify(B, r):
- * Return the result of parsing B_{2r-1} as a little-endian integer.
- */
-static uint64_t
-integerify(uint8_t * B, size_t r)
-{
- uint8_t * X = &B[(2 * r - 1) * 64];
-
- return (le64dec(X));
-}
-
-/**
- * smix(B, r, N, V, XY):
- * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; the
- * temporary storage V must be 128rN bytes in length; the temporary storage
- * XY must be 256r bytes in length. The value N must be a power of 2.
- */
-static void
-smix(uint8_t * B, size_t r, uint64_t N, uint8_t * V, uint8_t * XY)
-{
- uint8_t * X = XY;
- uint8_t * Y = &XY[128 * r];
- uint64_t i;
- uint64_t j;
-
- /* 1: X <-- B */
- blkcpy(X, B, 128 * r);
-
- /* 2: for i = 0 to N - 1 do */
- for (i = 0; i < N; i++) {
- /* 3: V_i <-- X */
- blkcpy(&V[i * (128 * r)], X, 128 * r);
-
- /* 4: X <-- H(X) */
- blockmix_salsa8(X, Y, r);
- }
-
- /* 6: for i = 0 to N - 1 do */
- for (i = 0; i < N; i++) {
- /* 7: j <-- Integerify(X) mod N */
- j = integerify(X, r) & (N - 1);
-
- /* 8: X <-- H(X \xor V_j) */
- blkxor(X, &V[j * (128 * r)], 128 * r);
- blockmix_salsa8(X, Y, r);
- }
-
- /* 10: B' <-- X */
- blkcpy(B, X, 128 * r);
-}
-
-/**
- * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
- * p, buflen) and write the result into buf. The parameters r, p, and buflen
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
- * must be a power of 2.
- *
- * Return 0 on success; or -1 on error.
- */
-int
-crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
- const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
- uint8_t * buf, size_t buflen)
-{
- uint8_t * B;
- uint8_t * V;
- uint8_t * XY;
- uint32_t i;
-
- /* Sanity-check parameters. */
-#if SIZE_MAX > UINT32_MAX
- if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
- errno = EFBIG;
- goto err0;
- }
-#endif
- if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
- errno = EFBIG;
- goto err0;
- }
- if (((N & (N - 1)) != 0) || (N == 0)) {
- errno = EINVAL;
- goto err0;
- }
- if ((r > SIZE_MAX / 128 / p) ||
-#if SIZE_MAX / 256 <= UINT32_MAX
- (r > SIZE_MAX / 256) ||
-#endif
- (N > SIZE_MAX / 128 / r)) {
- errno = ENOMEM;
- goto err0;
- }
-
- /* Allocate memory. */
- if ((B = malloc(128 * r * p)) == NULL)
- goto err0;
- if ((XY = malloc(256 * r)) == NULL)
- goto err1;
- if ((V = malloc(128 * r * N)) == NULL)
- goto err2;
-
- /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
- PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
-
- /* 2: for i = 0 to p - 1 do */
- for (i = 0; i < p; i++) {
- /* 3: B_i <-- MF(B_i, N) */
- smix(&B[i * 128 * r], r, N, V, XY);
- }
-
- /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
- PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
-
- /* Free memory. */
- free(V);
- free(XY);
- free(B);
-
- /* Success! */
- return (0);
-
-err2:
- free(XY);
-err1:
- free(B);
-err0:
- /* Failure! */
- return (-1);
-}
diff --git a/lib/crypto/crypto_scrypt-sse.c b/lib/crypto/crypto_scrypt-sse.c
deleted file mode 100644
index 0e6ff33..0000000
--- a/lib/crypto/crypto_scrypt-sse.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <emmintrin.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "sha256.h"
-#include "sysendian.h"
-
-#include "crypto_scrypt.h"
-
-static void blkcpy(void *, void *, size_t);
-static void blkxor(void *, void *, size_t);
-static void salsa20_8(__m128i *);
-static void blockmix_salsa8(__m128i *, __m128i *, __m128i *, size_t);
-static uint64_t integerify(void *, size_t);
-static void smix(uint8_t *, size_t, uint64_t, void *, void *);
-
-static void
-blkcpy(void * dest, void * src, size_t len)
-{
- __m128i * D = dest;
- __m128i * S = src;
- size_t L = len / 16;
- size_t i;
-
- for (i = 0; i < L; i++)
- D[i] = S[i];
-}
-
-static void
-blkxor(void * dest, void * src, size_t len)
-{
- __m128i * D = dest;
- __m128i * S = src;
- size_t L = len / 16;
- size_t i;
-
- for (i = 0; i < L; i++)
- D[i] = _mm_xor_si128(D[i], S[i]);
-}
-
-/**
- * salsa20_8(B):
- * Apply the salsa20/8 core to the provided block.
- */
-static void
-salsa20_8(__m128i B[4])
-{
- __m128i X0, X1, X2, X3;
- __m128i T;
- size_t i;
-
- X0 = B[0];
- X1 = B[1];
- X2 = B[2];
- X3 = B[3];
-
- for (i = 0; i < 8; i += 2) {
- /* Operate on "columns". */
- T = _mm_add_epi32(X0, X3);
- X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7));
- X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25));
- T = _mm_add_epi32(X1, X0);
- X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
- X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
- T = _mm_add_epi32(X2, X1);
- X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13));
- X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19));
- T = _mm_add_epi32(X3, X2);
- X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
- X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
-
- /* Rearrange data. */
- X1 = _mm_shuffle_epi32(X1, 0x93);
- X2 = _mm_shuffle_epi32(X2, 0x4E);
- X3 = _mm_shuffle_epi32(X3, 0x39);
-
- /* Operate on "rows". */
- T = _mm_add_epi32(X0, X1);
- X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7));
- X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25));
- T = _mm_add_epi32(X3, X0);
- X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
- X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
- T = _mm_add_epi32(X2, X3);
- X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13));
- X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19));
- T = _mm_add_epi32(X1, X2);
- X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
- X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
-
- /* Rearrange data. */
- X1 = _mm_shuffle_epi32(X1, 0x39);
- X2 = _mm_shuffle_epi32(X2, 0x4E);
- X3 = _mm_shuffle_epi32(X3, 0x93);
- }
-
- B[0] = _mm_add_epi32(B[0], X0);
- B[1] = _mm_add_epi32(B[1], X1);
- B[2] = _mm_add_epi32(B[2], X2);
- B[3] = _mm_add_epi32(B[3], X3);
-}
-
-/**
- * blockmix_salsa8(Bin, Bout, X, r):
- * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
- * bytes in length; the output Bout must also be the same size. The
- * temporary space X must be 64 bytes.
- */
-static void
-blockmix_salsa8(__m128i * Bin, __m128i * Bout, __m128i * X, size_t r)
-{
- size_t i;
-
- /* 1: X <-- B_{2r - 1} */
- blkcpy(X, &Bin[8 * r - 4], 64);
-
- /* 2: for i = 0 to 2r - 1 do */
- for (i = 0; i < r; i++) {
- /* 3: X <-- H(X \xor B_i) */
- blkxor(X, &Bin[i * 8], 64);
- salsa20_8(X);
-
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- blkcpy(&Bout[i * 4], X, 64);
-
- /* 3: X <-- H(X \xor B_i) */
- blkxor(X, &Bin[i * 8 + 4], 64);
- salsa20_8(X);
-
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- blkcpy(&Bout[(r + i) * 4], X, 64);
- }
-}
-
-/**
- * integerify(B, r):
- * Return the result of parsing B_{2r-1} as a little-endian integer.
- */
-static uint64_t
-integerify(void * B, size_t r)
-{
- uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64);
-
- return (((uint64_t)(X[13]) << 32) + X[0]);
-}
-
-/**
- * smix(B, r, N, V, XY):
- * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
- * the temporary storage V must be 128rN bytes in length; the temporary
- * storage XY must be 256r + 64 bytes in length. The value N must be a
- * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
- * multiple of 64 bytes.
- */
-static void
-smix(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)
-{
- __m128i * X = XY;
- __m128i * Y = (void *)((uintptr_t)(XY) + 128 * r);
- __m128i * Z = (void *)((uintptr_t)(XY) + 256 * r);
- uint32_t * X32 = (void *)X;
- uint64_t i, j;
- size_t k;
-
- /* 1: X <-- B */
- for (k = 0; k < 2 * r; k++) {
- for (i = 0; i < 16; i++) {
- X32[k * 16 + i] =
- le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
- }
- }
-
- /* 2: for i = 0 to N - 1 do */
- for (i = 0; i < N; i += 2) {
- /* 3: V_i <-- X */
- blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r);
-
- /* 4: X <-- H(X) */
- blockmix_salsa8(X, Y, Z, r);
-
- /* 3: V_i <-- X */
- blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r),
- Y, 128 * r);
-
- /* 4: X <-- H(X) */
- blockmix_salsa8(Y, X, Z, r);
- }
-
- /* 6: for i = 0 to N - 1 do */
- for (i = 0; i < N; i += 2) {
- /* 7: j <-- Integerify(X) mod N */
- j = integerify(X, r) & (N - 1);
-
- /* 8: X <-- H(X \xor V_j) */
- blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
- blockmix_salsa8(X, Y, Z, r);
-
- /* 7: j <-- Integerify(X) mod N */
- j = integerify(Y, r) & (N - 1);
-
- /* 8: X <-- H(X \xor V_j) */
- blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
- blockmix_salsa8(Y, X, Z, r);
- }
-
- /* 10: B' <-- X */
- for (k = 0; k < 2 * r; k++) {
- for (i = 0; i < 16; i++) {
- le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],
- X32[k * 16 + i]);
- }
- }
-}
-
-/**
- * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
- * p, buflen) and write the result into buf. The parameters r, p, and buflen
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
- * must be a power of 2 greater than 1.
- *
- * Return 0 on success; or -1 on error.
- */
-int
-crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
- const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
- uint8_t * buf, size_t buflen)
-{
- void * B0, * V0, * XY0;
- uint8_t * B;
- uint32_t * V;
- uint32_t * XY;
- uint32_t i;
-
- /* Sanity-check parameters. */
-#if SIZE_MAX > UINT32_MAX
- if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
- errno = EFBIG;
- goto err0;
- }
-#endif
- if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
- errno = EFBIG;
- goto err0;
- }
- if (((N & (N - 1)) != 0) || (N == 0)) {
- errno = EINVAL;
- goto err0;
- }
- if ((r > SIZE_MAX / 128 / p) ||
-#if SIZE_MAX / 256 <= UINT32_MAX
- (r > (SIZE_MAX - 64) / 256) ||
-#endif
- (N > SIZE_MAX / 128 / r)) {
- errno = ENOMEM;
- goto err0;
- }
-
- /* Allocate memory. */
-#ifdef HAVE_POSIX_MEMALIGN
- if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
- goto err0;
- B = (uint8_t *)(B0);
- if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
- goto err1;
- XY = (uint32_t *)(XY0);
-#ifndef MAP_ANON
- if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
- goto err2;
- V = (uint32_t *)(V0);
-#endif
-#else
- if ((B0 = malloc(128 * r * p + 63)) == NULL)
- goto err0;
- B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
- if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
- goto err1;
- XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
-#ifndef MAP_ANON
- if ((V0 = malloc(128 * r * N + 63)) == NULL)
- goto err2;
- V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
-#endif
-#endif
-#ifdef MAP_ANON
- if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
-#ifdef MAP_NOCORE
- MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
-#else
- MAP_ANON | MAP_PRIVATE,
-#endif
- -1, 0)) == MAP_FAILED)
- goto err2;
- V = (uint32_t *)(V0);
-#endif
-
- /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
- PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
-
- /* 2: for i = 0 to p - 1 do */
- for (i = 0; i < p; i++) {
- /* 3: B_i <-- MF(B_i, N) */
- smix(&B[i * 128 * r], r, N, V, XY);
- }
-
- /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
- PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
-
- /* Free memory. */
-#ifdef MAP_ANON
- if (munmap(V0, 128 * r * N))
- goto err2;
-#else
- free(V0);
-#endif
- free(XY0);
- free(B0);
-
- /* Success! */
- return (0);
-
-err2:
- free(XY0);
-err1:
- free(B0);
-err0:
- /* Failure! */
- return (-1);
-}
diff --git a/lib/crypto/crypto_scrypt.h b/lib/crypto/crypto_scrypt.h
deleted file mode 100644
index f72e1f4..0000000
--- a/lib/crypto/crypto_scrypt.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _CRYPTO_SCRYPT_H_
-#define _CRYPTO_SCRYPT_H_
-
-#include <stdint.h>
-
-/**
- * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
- * p, buflen) and write the result into buf. The parameters r, p, and buflen
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
- * must be a power of 2 greater than 1.
- *
- * Return 0 on success; or -1 on error.
- */
-int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
- uint32_t, uint32_t, uint8_t *, size_t);
-
-#endif /* !_CRYPTO_SCRYPT_H_ */
diff --git a/lib/crypto/sha256.c b/lib/crypto/sha256.c
deleted file mode 100644
index d2f915f..0000000
--- a/lib/crypto/sha256.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*-
- * Copyright 2005,2007,2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <string.h>
-
-#include "sysendian.h"
-
-#include "sha256.h"
-
-/*
- * Encode a length len/4 vector of (uint32_t) into a length len vector of
- * (unsigned char) in big-endian form. Assumes len is a multiple of 4.
- */
-static void
-be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
-{
- size_t i;
-
- for (i = 0; i < len / 4; i++)
- be32enc(dst + i * 4, src[i]);
-}
-
-/*
- * Decode a big-endian length len vector of (unsigned char) into a length
- * len/4 vector of (uint32_t). Assumes len is a multiple of 4.
- */
-static void
-be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
-{
- size_t i;
-
- for (i = 0; i < len / 4; i++)
- dst[i] = be32dec(src + i * 4);
-}
-
-/* Elementary functions used by SHA256 */
-#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
-#define Maj(x, y, z) ((x & (y | z)) | (y & z))
-#define SHR(x, n) (x >> n)
-#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
-#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
-#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
-#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
-#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
-
-/* SHA256 round function */
-#define RND(a, b, c, d, e, f, g, h, k) \
- t0 = h + S1(e) + Ch(e, f, g) + k; \
- t1 = S0(a) + Maj(a, b, c); \
- d += t0; \
- h = t0 + t1;
-
-/* Adjusted round function for rotating state */
-#define RNDr(S, W, i, k) \
- RND(S[(64 - i) % 8], S[(65 - i) % 8], \
- S[(66 - i) % 8], S[(67 - i) % 8], \
- S[(68 - i) % 8], S[(69 - i) % 8], \
- S[(70 - i) % 8], S[(71 - i) % 8], \
- W[i] + k)
-
-/*
- * SHA256 block compression function. The 256-bit state is transformed via
- * the 512-bit input block to produce a new state.
- */
-static void
-SHA256_Transform(uint32_t * state, const unsigned char block[64])
-{
- uint32_t W[64];
- uint32_t S[8];
- uint32_t t0, t1;
- int i;
-
- /* 1. Prepare message schedule W. */
- be32dec_vect(W, block, 64);
- for (i = 16; i < 64; i++)
- W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
-
- /* 2. Initialize working variables. */
- memcpy(S, state, 32);
-
- /* 3. Mix. */
- RNDr(S, W, 0, 0x428a2f98);
- RNDr(S, W, 1, 0x71374491);
- RNDr(S, W, 2, 0xb5c0fbcf);
- RNDr(S, W, 3, 0xe9b5dba5);
- RNDr(S, W, 4, 0x3956c25b);
- RNDr(S, W, 5, 0x59f111f1);
- RNDr(S, W, 6, 0x923f82a4);
- RNDr(S, W, 7, 0xab1c5ed5);
- RNDr(S, W, 8, 0xd807aa98);
- RNDr(S, W, 9, 0x12835b01);
- RNDr(S, W, 10, 0x243185be);
- RNDr(S, W, 11, 0x550c7dc3);
- RNDr(S, W, 12, 0x72be5d74);
- RNDr(S, W, 13, 0x80deb1fe);
- RNDr(S, W, 14, 0x9bdc06a7);
- RNDr(S, W, 15, 0xc19bf174);
- RNDr(S, W, 16, 0xe49b69c1);
- RNDr(S, W, 17, 0xefbe4786);
- RNDr(S, W, 18, 0x0fc19dc6);
- RNDr(S, W, 19, 0x240ca1cc);
- RNDr(S, W, 20, 0x2de92c6f);
- RNDr(S, W, 21, 0x4a7484aa);
- RNDr(S, W, 22, 0x5cb0a9dc);
- RNDr(S, W, 23, 0x76f988da);
- RNDr(S, W, 24, 0x983e5152);
- RNDr(S, W, 25, 0xa831c66d);
- RNDr(S, W, 26, 0xb00327c8);
- RNDr(S, W, 27, 0xbf597fc7);
- RNDr(S, W, 28, 0xc6e00bf3);
- RNDr(S, W, 29, 0xd5a79147);
- RNDr(S, W, 30, 0x06ca6351);
- RNDr(S, W, 31, 0x14292967);
- RNDr(S, W, 32, 0x27b70a85);
- RNDr(S, W, 33, 0x2e1b2138);
- RNDr(S, W, 34, 0x4d2c6dfc);
- RNDr(S, W, 35, 0x53380d13);
- RNDr(S, W, 36, 0x650a7354);
- RNDr(S, W, 37, 0x766a0abb);
- RNDr(S, W, 38, 0x81c2c92e);
- RNDr(S, W, 39, 0x92722c85);
- RNDr(S, W, 40, 0xa2bfe8a1);
- RNDr(S, W, 41, 0xa81a664b);
- RNDr(S, W, 42, 0xc24b8b70);
- RNDr(S, W, 43, 0xc76c51a3);
- RNDr(S, W, 44, 0xd192e819);
- RNDr(S, W, 45, 0xd6990624);
- RNDr(S, W, 46, 0xf40e3585);
- RNDr(S, W, 47, 0x106aa070);
- RNDr(S, W, 48, 0x19a4c116);
- RNDr(S, W, 49, 0x1e376c08);
- RNDr(S, W, 50, 0x2748774c);
- RNDr(S, W, 51, 0x34b0bcb5);
- RNDr(S, W, 52, 0x391c0cb3);
- RNDr(S, W, 53, 0x4ed8aa4a);
- RNDr(S, W, 54, 0x5b9cca4f);
- RNDr(S, W, 55, 0x682e6ff3);
- RNDr(S, W, 56, 0x748f82ee);
- RNDr(S, W, 57, 0x78a5636f);
- RNDr(S, W, 58, 0x84c87814);
- RNDr(S, W, 59, 0x8cc70208);
- RNDr(S, W, 60, 0x90befffa);
- RNDr(S, W, 61, 0xa4506ceb);
- RNDr(S, W, 62, 0xbef9a3f7);
- RNDr(S, W, 63, 0xc67178f2);
-
- /* 4. Mix local working variables into global state */
- for (i = 0; i < 8; i++)
- state[i] += S[i];
-
- /* Clean the stack. */
- memset(W, 0, 256);
- memset(S, 0, 32);
- t0 = t1 = 0;
-}
-
-static unsigned char PAD[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* Add padding and terminating bit-count. */
-static void
-SHA256_Pad(SHA256_CTX * ctx)
-{
- unsigned char len[8];
- uint32_t r, plen;
-
- /*
- * Convert length to a vector of bytes -- we do this now rather
- * than later because the length will change after we pad.
- */
- be32enc_vect(len, ctx->count, 8);
-
- /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
- r = (ctx->count[1] >> 3) & 0x3f;
- plen = (r < 56) ? (56 - r) : (120 - r);
- SHA256_Update(ctx, PAD, (size_t)plen);
-
- /* Add the terminating bit-count */
- SHA256_Update(ctx, len, 8);
-}
-
-/* SHA-256 initialization. Begins a SHA-256 operation. */
-void
-SHA256_Init(SHA256_CTX * ctx)
-{
-
- /* Zero bits processed so far */
- ctx->count[0] = ctx->count[1] = 0;
-
- /* Magic initialization constants */
- ctx->state[0] = 0x6A09E667;
- ctx->state[1] = 0xBB67AE85;
- ctx->state[2] = 0x3C6EF372;
- ctx->state[3] = 0xA54FF53A;
- ctx->state[4] = 0x510E527F;
- ctx->state[5] = 0x9B05688C;
- ctx->state[6] = 0x1F83D9AB;
- ctx->state[7] = 0x5BE0CD19;
-}
-
-/* Add bytes into the hash */
-void
-SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
-{
- uint32_t bitlen[2];
- uint32_t r;
- const unsigned char *src = in;
-
- /* Number of bytes left in the buffer from previous updates */
- r = (ctx->count[1] >> 3) & 0x3f;
-
- /* Convert the length into a number of bits */
- bitlen[1] = ((uint32_t)len) << 3;
- bitlen[0] = (uint32_t)(len >> 29);
-
- /* Update number of bits */
- if ((ctx->count[1] += bitlen[1]) < bitlen[1])
- ctx->count[0]++;
- ctx->count[0] += bitlen[0];
-
- /* Handle the case where we don't need to perform any transforms */
- if (len < 64 - r) {
- memcpy(&ctx->buf[r], src, len);
- return;
- }
-
- /* Finish the current block */
- memcpy(&ctx->buf[r], src, 64 - r);
- SHA256_Transform(ctx->state, ctx->buf);
- src += 64 - r;
- len -= 64 - r;
-
- /* Perform complete blocks */
- while (len >= 64) {
- SHA256_Transform(ctx->state, src);
- src += 64;
- len -= 64;
- }
-
- /* Copy left over data into buffer */
- memcpy(ctx->buf, src, len);
-}
-
-/*
- * SHA-256 finalization. Pads the input data, exports the hash value,
- * and clears the context state.
- */
-void
-SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
-{
-
- /* Add padding */
- SHA256_Pad(ctx);
-
- /* Write the hash */
- be32enc_vect(digest, ctx->state, 32);
-
- /* Clear the context state */
- memset((void *)ctx, 0, sizeof(*ctx));
-}
-
-/* Initialize an HMAC-SHA256 operation with the given key. */
-void
-HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
-{
- unsigned char pad[64];
- unsigned char khash[32];
- const unsigned char * K = _K;
- size_t i;
-
- /* If Klen > 64, the key is really SHA256(K). */
- if (Klen > 64) {
- SHA256_Init(&ctx->ictx);
- SHA256_Update(&ctx->ictx, K, Klen);
- SHA256_Final(khash, &ctx->ictx);
- K = khash;
- Klen = 32;
- }
-
- /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
- SHA256_Init(&ctx->ictx);
- memset(pad, 0x36, 64);
- for (i = 0; i < Klen; i++)
- pad[i] ^= K[i];
- SHA256_Update(&ctx->ictx, pad, 64);
-
- /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
- SHA256_Init(&ctx->octx);
- memset(pad, 0x5c, 64);
- for (i = 0; i < Klen; i++)
- pad[i] ^= K[i];
- SHA256_Update(&ctx->octx, pad, 64);
-
- /* Clean the stack. */
- memset(khash, 0, 32);
-}
-
-/* Add bytes to the HMAC-SHA256 operation. */
-void
-HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
-{
-
- /* Feed data to the inner SHA256 operation. */
- SHA256_Update(&ctx->ictx, in, len);
-}
-
-/* Finish an HMAC-SHA256 operation. */
-void
-HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
-{
- unsigned char ihash[32];
-
- /* Finish the inner SHA256 operation. */
- SHA256_Final(ihash, &ctx->ictx);
-
- /* Feed the inner hash to the outer SHA256 operation. */
- SHA256_Update(&ctx->octx, ihash, 32);
-
- /* Finish the outer SHA256 operation. */
- SHA256_Final(digest, &ctx->octx);
-
- /* Clean the stack. */
- memset(ihash, 0, 32);
-}
-
-/**
- * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
- * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
- * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
- */
-void
-PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
- size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
-{
- HMAC_SHA256_CTX PShctx, hctx;
- size_t i;
- uint8_t ivec[4];
- uint8_t U[32];
- uint8_t T[32];
- uint64_t j;
- int k;
- size_t clen;
-
- /* Compute HMAC state after processing P and S. */
- HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
- HMAC_SHA256_Update(&PShctx, salt, saltlen);
-
- /* Iterate through the blocks. */
- for (i = 0; i * 32 < dkLen; i++) {
- /* Generate INT(i + 1). */
- be32enc(ivec, (uint32_t)(i + 1));
-
- /* Compute U_1 = PRF(P, S || INT(i)). */
- memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
- HMAC_SHA256_Update(&hctx, ivec, 4);
- HMAC_SHA256_Final(U, &hctx);
-
- /* T_i = U_1 ... */
- memcpy(T, U, 32);
-
- for (j = 2; j <= c; j++) {
- /* Compute U_j. */
- HMAC_SHA256_Init(&hctx, passwd, passwdlen);
- HMAC_SHA256_Update(&hctx, U, 32);
- HMAC_SHA256_Final(U, &hctx);
-
- /* ... xor U_j ... */
- for (k = 0; k < 32; k++)
- T[k] ^= U[k];
- }
-
- /* Copy as many bytes as necessary into buf. */
- clen = dkLen - i * 32;
- if (clen > 32)
- clen = 32;
- memcpy(&buf[i * 32], T, clen);
- }
-
- /* Clean PShctx, since we never called _Final on it. */
- memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
-}
diff --git a/lib/crypto/sha256.h b/lib/crypto/sha256.h
deleted file mode 100644
index 289a523..0000000
--- a/lib/crypto/sha256.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * Copyright 2005,2007,2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $
- */
-
-#ifndef _SHA256_H_
-#define _SHA256_H_
-
-#include <sys/types.h>
-
-#include <stdint.h>
-
-typedef struct SHA256Context {
- uint32_t state[8];
- uint32_t count[2];
- unsigned char buf[64];
-} SHA256_CTX;
-
-typedef struct HMAC_SHA256Context {
- SHA256_CTX ictx;
- SHA256_CTX octx;
-} HMAC_SHA256_CTX;
-
-void SHA256_Init(SHA256_CTX *);
-void SHA256_Update(SHA256_CTX *, const void *, size_t);
-void SHA256_Final(unsigned char [32], SHA256_CTX *);
-void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
-void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
-void HMAC_SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *);
-
-/**
- * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
- * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
- * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
- */
-void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
- uint64_t, uint8_t *, size_t);
-
-#endif /* !_SHA256_H_ */
diff --git a/lib/scryptenc/scryptenc.c b/lib/scryptenc/scryptenc.c
deleted file mode 100644
index cf091bf..0000000
--- a/lib/scryptenc/scryptenc.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <openssl/aes.h>
-
-#include "crypto_aesctr.h"
-#include "crypto_scrypt.h"
-#include "memlimit.h"
-#include "scryptenc_cpuperf.h"
-#include "sha256.h"
-#include "sysendian.h"
-
-#include "scryptenc.h"
-
-#define ENCBLOCK 65536
-
-static int pickparams(size_t, double, double,
- int *, uint32_t *, uint32_t *);
-static int checkparams(size_t, double, double, int, uint32_t, uint32_t);
-static int getsalt(uint8_t[32]);
-
-static int
-pickparams(size_t maxmem, double maxmemfrac, double maxtime,
- int * logN, uint32_t * r, uint32_t * p)
-{
- size_t memlimit;
- double opps;
- double opslimit;
- double maxN, maxrp;
- int rc;
-
- /* Figure out how much memory to use. */
- if (memtouse(maxmem, maxmemfrac, &memlimit))
- return (1);
-
- /* Figure out how fast the CPU is. */
- if ((rc = scryptenc_cpuperf(&opps)) != 0)
- return (rc);
- opslimit = opps * maxtime;
-
- /* Allow a minimum of 2^15 salsa20/8 cores. */
- if (opslimit < 32768)
- opslimit = 32768;
-
- /* Fix r = 8 for now. */
- *r = 8;
-
- /*
- * The memory limit requires that 128Nr <= memlimit, while the CPU
- * limit requires that 4Nrp <= opslimit. If opslimit < memlimit/32,
- * opslimit imposes the stronger limit on N.
- */
-#ifdef DEBUG
- fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n",
- memlimit, opslimit);
-#endif
- if (opslimit < memlimit/32) {
- /* Set p = 1 and choose N based on the CPU limit. */
- *p = 1;
- maxN = opslimit / (*r * 4);
- for (*logN = 1; *logN < 63; *logN += 1) {
- if ((uint64_t)(1) << *logN > maxN / 2)
- break;
- }
- } else {
- /* Set N based on the memory limit. */
- maxN = memlimit / (*r * 128);
- for (*logN = 1; *logN < 63; *logN += 1) {
- if ((uint64_t)(1) << *logN > maxN / 2)
- break;
- }
-
- /* Choose p based on the CPU limit. */
- maxrp = (opslimit / 4) / ((uint64_t)(1) << *logN);
- if (maxrp > 0x3fffffff)
- maxrp = 0x3fffffff;
- *p = (uint32_t)(maxrp) / *r;
- }
-
-#ifdef DEBUG
- fprintf(stderr, "N = %zu r = %d p = %d\n",
- (size_t)(1) << *logN, (int)(*r), (int)(*p));
-#endif
-
- /* Success! */
- return (0);
-}
-
-static int
-checkparams(size_t maxmem, double maxmemfrac, double maxtime,
- int logN, uint32_t r, uint32_t p)
-{
- size_t memlimit;
- double opps;
- double opslimit;
- uint64_t N;
- int rc;
-
- /* Figure out the maximum amount of memory we can use. */
- if (memtouse(maxmem, maxmemfrac, &memlimit))
- return (1);
-
- /* Figure out how fast the CPU is. */
- if ((rc = scryptenc_cpuperf(&opps)) != 0)
- return (rc);
- opslimit = opps * maxtime;
-
- /* Sanity-check values. */
- if ((logN < 1) || (logN > 63))
- return (7);
- if ((uint64_t)(r) * (uint64_t)(p) >= 0x40000000)
- return (7);
-
- /* Check limits. */
- N = (uint64_t)(1) << logN;
- if ((memlimit / N) / r < 128)
- return (9);
- if ((opslimit / N) / (r * p) < 4)
- return (10);
-
- /* Success! */
- return (0);
-}
-
-static int
-getsalt(uint8_t salt[32])
-{
- int fd;
- ssize_t lenread;
- uint8_t * buf = salt;
- size_t buflen = 32;
-
- /* Open /dev/urandom. */
- if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
- goto err0;
-
- /* Read bytes until we have filled the buffer. */
- while (buflen > 0) {
- if ((lenread = read(fd, buf, buflen)) == -1)
- goto err1;
-
- /* The random device should never EOF. */
- if (lenread == 0)
- goto err1;
-
- /* We're partly done. */
- buf += lenread;
- buflen -= lenread;
- }
-
- /* Close the device. */
- while (close(fd) == -1) {
- if (errno != EINTR)
- goto err0;
- }
-
- /* Success! */
- return (0);
-
-err1:
- close(fd);
-err0:
- /* Failure! */
- return (4);
-}
-
-static int
-scryptenc_setup(uint8_t header[96], uint8_t dk[64],
- const uint8_t * passwd, size_t passwdlen,
- size_t maxmem, double maxmemfrac, double maxtime)
-{
- uint8_t salt[32];
- uint8_t hbuf[32];
- int logN;
- uint64_t N;
- uint32_t r;
- uint32_t p;
- SHA256_CTX ctx;
- uint8_t * key_hmac = &dk[32];
- HMAC_SHA256_CTX hctx;
- int rc;
-
- /* Pick values for N, r, p. */
- if ((rc = pickparams(maxmem, maxmemfrac, maxtime,
- &logN, &r, &p)) != 0)
- return (rc);
- N = (uint64_t)(1) << logN;
-
- /* Get some salt. */
- if ((rc = getsalt(salt)) != 0)
- return (rc);
-
- /* Generate the derived keys. */
- if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
- return (3);
-
- /* Construct the file header. */
- memcpy(header, "scrypt", 6);
- header[6] = 0;
- header[7] = logN;
- be32enc(&header[8], r);
- be32enc(&header[12], p);
- memcpy(&header[16], salt, 32);
-
- /* Add header checksum. */
- SHA256_Init(&ctx);
- SHA256_Update(&ctx, header, 48);
- SHA256_Final(hbuf, &ctx);
- memcpy(&header[48], hbuf, 16);
-
- /* Add header signature (used for verifying password). */
- HMAC_SHA256_Init(&hctx, key_hmac, 32);
- HMAC_SHA256_Update(&hctx, header, 64);
- HMAC_SHA256_Final(hbuf, &hctx);
- memcpy(&header[64], hbuf, 32);
-
- /* Success! */
- return (0);
-}
-
-static int
-scryptdec_setup(const uint8_t header[96], uint8_t dk[64],
- const uint8_t * passwd, size_t passwdlen,
- size_t maxmem, double maxmemfrac, double maxtime)
-{
- uint8_t salt[32];
- uint8_t hbuf[32];
- int logN;
- uint32_t r;
- uint32_t p;
- uint64_t N;
- SHA256_CTX ctx;
- uint8_t * key_hmac = &dk[32];
- HMAC_SHA256_CTX hctx;
- int rc;
-
- /* Parse N, r, p, salt. */
- logN = header[7];
- r = be32dec(&header[8]);
- p = be32dec(&header[12]);
- memcpy(salt, &header[16], 32);
-
- /* Verify header checksum. */
- SHA256_Init(&ctx);
- SHA256_Update(&ctx, header, 48);
- SHA256_Final(hbuf, &ctx);
- if (memcmp(&header[48], hbuf, 16))
- return (7);
-
- /*
- * Check whether the provided parameters are valid and whether the
- * key derivation function can be computed within the allowed memory
- * and CPU time.
- */
- if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p)) != 0)
- return (rc);
-
- /* Compute the derived keys. */
- N = (uint64_t)(1) << logN;
- if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
- return (3);
-
- /* Check header signature (i.e., verify password). */
- HMAC_SHA256_Init(&hctx, key_hmac, 32);
- HMAC_SHA256_Update(&hctx, header, 64);
- HMAC_SHA256_Final(hbuf, &hctx);
- if (memcmp(hbuf, &header[64], 32))
- return (11);
-
- /* Success! */
- return (0);
-}
-
-/**
- * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
- * maxmem, maxmemfrac, maxtime):
- * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
- * bytes to outbuf.
- */
-int
-scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
- const uint8_t * passwd, size_t passwdlen,
- size_t maxmem, double maxmemfrac, double maxtime)
-{
- uint8_t dk[64];
- uint8_t hbuf[32];
- uint8_t header[96];
- uint8_t * key_enc = dk;
- uint8_t * key_hmac = &dk[32];
- int rc;
- HMAC_SHA256_CTX hctx;
- AES_KEY key_enc_exp;
- struct crypto_aesctr * AES;
-
- /* Generate the header and derived key. */
- if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
- maxmem, maxmemfrac, maxtime)) != 0)
- return (rc);
-
- /* Copy header into output buffer. */
- memcpy(outbuf, header, 96);
-
- /* Encrypt data. */
- if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp))
- return (5);
- if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL)
- return (6);
- crypto_aesctr_stream(AES, inbuf, &outbuf[96], inbuflen);
- crypto_aesctr_free(AES);
-
- /* Add signature. */
- HMAC_SHA256_Init(&hctx, key_hmac, 32);
- HMAC_SHA256_Update(&hctx, outbuf, 96 + inbuflen);
- HMAC_SHA256_Final(hbuf, &hctx);
- memcpy(&outbuf[96 + inbuflen], hbuf, 32);
-
- /* Zero sensitive data. */
- memset(dk, 0, 64);
- memset(&key_enc_exp, 0, sizeof(AES_KEY));
-
- /* Success! */
- return (0);
-}
-
-/**
- * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
- * maxmem, maxmemfrac, maxtime):
- * Decrypt inbuflen bytes fro inbuf, writing the result into outbuf and the
- * decrypted data length to outlen. The allocated length of outbuf must
- * be at least inbuflen.
- */
-int
-scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
- size_t * outlen, const uint8_t * passwd, size_t passwdlen,
- size_t maxmem, double maxmemfrac, double maxtime)
-{
- uint8_t hbuf[32];
- uint8_t dk[64];
- uint8_t * key_enc = dk;
- uint8_t * key_hmac = &dk[32];
- int rc;
- HMAC_SHA256_CTX hctx;
- AES_KEY key_enc_exp;
- struct crypto_aesctr * AES;
-
- /*
- * All versions of the scrypt format will start with "scrypt" and
- * have at least 7 bytes of header.
- */
- if ((inbuflen < 7) || (memcmp(inbuf, "scrypt", 6) != 0))
- return (7);
-
- /* Check the format. */
- if (inbuf[6] != 0)
- return (8);
-
- /* We must have at least 128 bytes. */
- if (inbuflen < 128)
- return (7);
-
- /* Parse the header and generate derived keys. */
- if ((rc = scryptdec_setup(inbuf, dk, passwd, passwdlen,
- maxmem, maxmemfrac, maxtime)) != 0)
- return (rc);
-
- /* Decrypt data. */
- if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp))
- return (5);
- if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL)
- return (6);
- crypto_aesctr_stream(AES, &inbuf[96], outbuf, inbuflen - 128);
- crypto_aesctr_free(AES);
- *outlen = inbuflen - 128;
-
- /* Verify signature. */
- HMAC_SHA256_Init(&hctx, key_hmac, 32);
- HMAC_SHA256_Update(&hctx, inbuf, inbuflen - 32);
- HMAC_SHA256_Final(hbuf, &hctx);
- if (memcmp(hbuf, &inbuf[inbuflen - 32], 32))
- return (7);
-
- /* Zero sensitive data. */
- memset(dk, 0, 64);
- memset(&key_enc_exp, 0, sizeof(AES_KEY));
-
- /* Success! */
- return (0);
-}
-
-/**
- * scryptenc_file(infile, outfile, passwd, passwdlen,
- * maxmem, maxmemfrac, maxtime):
- * Read a stream from infile and encrypt it, writing the resulting stream to
- * outfile.
- */
-int
-scryptenc_file(FILE * infile, FILE * outfile,
- const uint8_t * passwd, size_t passwdlen,
- size_t maxmem, double maxmemfrac, double maxtime)
-{
- uint8_t buf[ENCBLOCK];
- uint8_t dk[64];
- uint8_t hbuf[32];
- uint8_t header[96];
- uint8_t * key_enc = dk;
- uint8_t * key_hmac = &dk[32];
- size_t readlen;
- HMAC_SHA256_CTX hctx;
- AES_KEY key_enc_exp;
- struct crypto_aesctr * AES;
- int rc;
-
- /* Generate the header and derived key. */
- if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
- maxmem, maxmemfrac, maxtime)) != 0)
- return (rc);
-
- /* Hash and write the header. */
- HMAC_SHA256_Init(&hctx, key_hmac, 32);
- HMAC_SHA256_Update(&hctx, header, 96);
- if (fwrite(header, 96, 1, outfile) != 1)
- return (12);
-
- /*
- * Read blocks of data, encrypt them, and write them out; hash the
- * data as it is produced.
- */
- if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp))
- return (5);
- if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL)
- return (6);
- do {
- if ((readlen = fread(buf, 1, ENCBLOCK, infile)) == 0)
- break;
- crypto_aesctr_stream(AES, buf, buf, readlen);
- HMAC_SHA256_Update(&hctx, buf, readlen);
- if (fwrite(buf, 1, readlen, outfile) < readlen)
- return (12);
- } while (1);
- crypto_aesctr_free(AES);
-
- /* Did we exit the loop due to a read error? */
- if (ferror(infile))
- return (13);
-
- /* Compute the final HMAC and output it. */
- HMAC_SHA256_Final(hbuf, &hctx);
- if (fwrite(hbuf, 32, 1, outfile) != 1)
- return (12);
-
- /* Zero sensitive data. */
- memset(dk, 0, 64);
- memset(&key_enc_exp, 0, sizeof(AES_KEY));
-
- /* Success! */
- return (0);
-}
-
-/**
- * scryptdec_file(infile, outfile, passwd, passwdlen,
- * maxmem, maxmemfrac, maxtime):
- * Read a stream from infile and decrypt it, writing the resulting stream to
- * outfile.
- */
-int
-scryptdec_file(FILE * infile, FILE * outfile,
- const uint8_t * passwd, size_t passwdlen,
- size_t maxmem, double maxmemfrac, double maxtime)
-{
- uint8_t buf[ENCBLOCK + 32];
- uint8_t header[96];
- uint8_t hbuf[32];
- uint8_t dk[64];
- uint8_t * key_enc = dk;
- uint8_t * key_hmac = &dk[32];
- size_t buflen = 0;
- size_t readlen;
- HMAC_SHA256_CTX hctx;
- AES_KEY key_enc_exp;
- struct crypto_aesctr * AES;
- int rc;
-
- /*
- * Read the first 7 bytes of the file; all future version of scrypt
- * are guaranteed to have at least 7 bytes of header.
- */
- if (fread(header, 7, 1, infile) < 1) {
- if (ferror(infile))
- return (13);
- else
- return (7);
- }
-
- /* Do we have the right magic? */
- if (memcmp(header, "scrypt", 6))
- return (7);
- if (header[6] != 0)
- return (8);
-
- /*
- * Read another 89 bytes of the file; version 0 of the srypt file
- * format has a 96-byte header.
- */
- if (fread(&header[7], 89, 1, infile) < 1) {
- if (ferror(infile))
- return (13);
- else
- return (7);
- }
-
- /* Parse the header and generate derived keys. */
- if ((rc = scryptdec_setup(header, dk, passwd, passwdlen,
- maxmem, maxmemfrac, maxtime)) != 0)
- return (rc);
-
- /* Start hashing with the header. */
- HMAC_SHA256_Init(&hctx, key_hmac, 32);
- HMAC_SHA256_Update(&hctx, header, 96);
-
- /*
- * We don't know how long the encrypted data block is (we can't know,
- * since data can be streamed into 'scrypt enc') so we need to read
- * data and decrypt all of it except the final 32 bytes, then check
- * if that final 32 bytes is the correct signature.
- */
- if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp))
- return (5);
- if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL)
- return (6);
- do {
- /* Read data until we have more than 32 bytes of it. */
- if ((readlen = fread(&buf[buflen], 1,
- ENCBLOCK + 32 - buflen, infile)) == 0)
- break;
- buflen += readlen;
- if (buflen <= 32)
- continue;
-
- /*
- * Decrypt, hash, and output everything except the last 32
- * bytes out of what we have in our buffer.
- */
- HMAC_SHA256_Update(&hctx, buf, buflen - 32);
- crypto_aesctr_stream(AES, buf, buf, buflen - 32);
- if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32)
- return (12);
-
- /* Move the last 32 bytes to the start of the buffer. */
- memmove(buf, &buf[buflen - 32], 32);
- buflen = 32;
- } while (1);
- crypto_aesctr_free(AES);
-
- /* Did we exit the loop due to a read error? */
- if (ferror(infile))
- return (13);
-
- /* Did we read enough data that we *might* have a valid signature? */
- if (buflen < 32)
- return (7);
-
- /* Verify signature. */
- HMAC_SHA256_Final(hbuf, &hctx);
- if (memcmp(hbuf, buf, 32))
- return (7);
-
- /* Zero sensitive data. */
- memset(dk, 0, 64);
- memset(&key_enc_exp, 0, sizeof(AES_KEY));
-
- return (0);
-}
diff --git a/lib/scryptenc/scryptenc.h b/lib/scryptenc/scryptenc.h
deleted file mode 100644
index 7dc3dd3..0000000
--- a/lib/scryptenc/scryptenc.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _SCRYPTENC_H_
-#define _SCRYPTENC_H_
-
-#include <stdint.h>
-#include <stdio.h>
-
-/**
- * The parameters maxmem, maxmemfrac, and maxtime used by all of these
- * functions are defined as follows:
- * maxmem - maximum number of bytes of storage to use for V array (which is
- * by far the largest consumer of memory). If this value is set to 0, no
- * maximum will be enforced; any other value less than 1 MiB will be
- * treated as 1 MiB.
- * maxmemfrac - maximum fraction of available storage to use for the V array,
- * where "available storage" is defined as the minimum out of the
- * RLIMIT_AS, RLIMIT_DATA. and RLIMIT_RSS resource limits (if any are
- * set). If this value is set to 0 or more than 0.5 it will be treated
- * as 0.5; and this value will never cause a limit of less than 1 MiB to
- * be enforced.
- * maxtime - maximum amount of CPU time to spend computing the derived keys,
- * in seconds. This limit is only approximately enforced; the CPU
- * performance is estimated and parameter limits are chosen accordingly.
- * For the encryption functions, the parameters to the scrypt key derivation
- * function are chosen to make the key as strong as possible subject to the
- * specified limits; for the decryption functions, the parameters used are
- * compared to the computed limits and an error is returned if decrypting
- * the data would take too much memory or CPU time.
- */
-/**
- * Return codes from scrypt(enc|dec)_(buf|file):
- * 0 success
- * 1 getrlimit or sysctl(hw.usermem) failed
- * 2 clock_getres or clock_gettime failed
- * 3 error computing derived key
- * 4 could not read salt from /dev/urandom
- * 5 error in OpenSSL
- * 6 malloc failed
- * 7 data is not a valid scrypt-encrypted block
- * 8 unrecognized scrypt format
- * 9 decrypting file would take too much memory
- * 10 decrypting file would take too long
- * 11 password is incorrect
- * 12 error writing output file
- * 13 error reading input file
- */
-
-/**
- * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
- * maxmem, maxmemfrac, maxtime):
- * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
- * bytes to outbuf.
- */
-int scryptenc_buf(const uint8_t *, size_t, uint8_t *,
- const uint8_t *, size_t, size_t, double, double);
-
-/**
- * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
- * maxmem, maxmemfrac, maxtime):
- * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
- * decrypted data length to outlen. The allocated length of outbuf must
- * be at least inbuflen.
- */
-int scryptdec_buf(const uint8_t *, size_t, uint8_t *, size_t *,
- const uint8_t *, size_t, size_t, double, double);
-
-/**
- * scryptenc_file(infile, outfile, passwd, passwdlen,
- * maxmem, maxmemfrac, maxtime):
- * Read a stream from infile and encrypt it, writing the resulting stream to
- * outfile.
- */
-int scryptenc_file(FILE *, FILE *, const uint8_t *, size_t,
- size_t, double, double);
-
-/**
- * scryptdec_file(infile, outfile, passwd, passwdlen,
- * maxmem, maxmemfrac, maxtime):
- * Read a stream from infile and decrypt it, writing the resulting stream to
- * outfile.
- */
-int scryptdec_file(FILE *, FILE *, const uint8_t *, size_t,
- size_t, double, double);
-
-#endif /* !_SCRYPTENC_H_ */
diff --git a/lib/scryptenc/scryptenc_cpuperf.c b/lib/scryptenc/scryptenc_cpuperf.c
deleted file mode 100644
index 27b7915..0000000
--- a/lib/scryptenc/scryptenc_cpuperf.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#include <sys/time.h>
-
-#include <stdint.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "crypto_scrypt.h"
-
-#include "scryptenc_cpuperf.h"
-
-#ifdef HAVE_CLOCK_GETTIME
-
-static clock_t clocktouse;
-
-static int
-getclockres(double * resd)
-{
- struct timespec res;
-
- /*
- * Try clocks in order of preference until we find one which works.
- * (We assume that if clock_getres works, clock_gettime will, too.)
- * The use of if/else/if/else/if/else rather than if/elif/elif/else
- * is ugly but legal, and allows us to #ifdef things appropriately.
- */
-#ifdef CLOCK_VIRTUAL
- if (clock_getres(CLOCK_VIRTUAL, &res) == 0)
- clocktouse = CLOCK_VIRTUAL;
- else
-#endif
-#ifdef CLOCK_MONOTONIC
- if (clock_getres(CLOCK_MONOTONIC, &res) == 0)
- clocktouse = CLOCK_MONOTONIC;
- else
-#endif
- if (clock_getres(CLOCK_REALTIME, &res) == 0)
- clocktouse = CLOCK_REALTIME;
- else
- return (-1);
-
- /* Convert clock resolution to a double. */
- *resd = res.tv_sec + res.tv_nsec * 0.000000001;
-
- return (0);
-}
-
-static int
-getclocktime(struct timespec * ts)
-{
-
- if (clock_gettime(clocktouse, ts))
- return (-1);
-
- return (0);
-}
-
-#else
-static int
-getclockres(double * resd)
-{
-
- *resd = 1.0 / CLOCKS_PER_SEC;
-
- return (0);
-}
-
-static int
-getclocktime(struct timespec * ts)
-{
- struct timeval tv;
-
- if (gettimeofday(&tv, NULL))
- return (-1);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec * 1000;
-
- return (0);
-}
-#endif
-
-static int
-getclockdiff(struct timespec * st, double * diffd)
-{
- struct timespec en;
-
- if (getclocktime(&en))
- return (1);
- *diffd = (en.tv_nsec - st->tv_nsec) * 0.000000001 +
- (en.tv_sec - st->tv_sec);
-
- return (0);
-}
-
-/**
- * scryptenc_cpuperf(opps):
- * Estimate the number of salsa20/8 cores which can be executed per second,
- * and return the value via opps.
- */
-int
-scryptenc_cpuperf(double * opps)
-{
- struct timespec st;
- double resd, diffd;
- uint64_t i = 0;
-
- /* Get the clock resolution. */
- if (getclockres(&resd))
- return (2);
-
-#ifdef DEBUG
- fprintf(stderr, "Clock resolution is %f\n", resd);
-#endif
-
- /* Loop until the clock ticks. */
- if (getclocktime(&st))
- return (2);
- do {
- /* Do an scrypt. */
- if (crypto_scrypt(NULL, 0, NULL, 0, 16, 1, 1, NULL, 0))
- return (3);
-
- /* Has the clock ticked? */
- if (getclockdiff(&st, &diffd))
- return (2);
- if (diffd > 0)
- break;
- } while (1);
-
- /* Could how many scryps we can do before the next tick. */
- if (getclocktime(&st))
- return (2);
- do {
- /* Do an scrypt. */
- if (crypto_scrypt(NULL, 0, NULL, 0, 128, 1, 1, NULL, 0))
- return (3);
-
- /* We invoked the salsa20/8 core 512 times. */
- i += 512;
-
- /* Check if we have looped for long enough. */
- if (getclockdiff(&st, &diffd))
- return (2);
- if (diffd > resd)
- break;
- } while (1);
-
-#ifdef DEBUG
- fprintf(stderr, "%ju salsa20/8 cores performed in %f seconds\n",
- (uintmax_t)i, diffd);
-#endif
-
- /* We can do approximately i salsa20/8 cores per diffd seconds. */
- *opps = i / diffd;
- return (0);
-}
diff --git a/lib/scryptenc/scryptenc_cpuperf.h b/lib/scryptenc/scryptenc_cpuperf.h
deleted file mode 100644
index e236fff..0000000
--- a/lib/scryptenc/scryptenc_cpuperf.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _SCRYPTENC_CPUPERF_H_
-#define _SCRYPTENC_CPUPERF_H_
-
-/**
- * scryptenc_cpuperf(opps):
- * Estimate the number of salsa20/8 cores which can be executed per second,
- * and return the value via opps.
- */
-int scryptenc_cpuperf(double *);
-
-#endif /* !_SCRYPTENC_CPUPERF_H_ */
diff --git a/lib/util/memlimit.c b/lib/util/memlimit.c
deleted file mode 100644
index f1f10bf..0000000
--- a/lib/util/memlimit.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#include <sys/types.h>
-#include <sys/resource.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYSCTL_HW_USERMEM
-#include <sys/sysctl.h>
-#endif
-#ifdef HAVE_SYS_SYSINFO_H
-#include <sys/sysinfo.h>
-#endif
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-#include "memlimit.h"
-
-#ifdef HAVE_SYSCTL_HW_USERMEM
-static int
-memlimit_sysctl_hw_usermem(size_t * memlimit)
-{
- int mib[2];
- uint8_t usermembuf[8];
- size_t usermemlen = 8;
- uint64_t usermem;
-
- /* Ask the kernel how much RAM we have. */
- mib[0] = CTL_HW;
- mib[1] = HW_USERMEM;
- if (sysctl(mib, 2, usermembuf, &usermemlen, NULL, 0))
- return (1);
-
- /*
- * Parse as either a uint64_t or a uint32_t based on the length of
- * output the kernel reports having copied out. It appears that all
- * systems providing a sysctl interface for reading integers copy
- * them out as system-endian values, so we don't need to worry about
- * parsing them.
- */
- if (usermemlen == sizeof(uint64_t))
- usermem = *(uint64_t *)usermembuf;
- else if (usermemlen == sizeof(uint32_t))
- usermem = *(uint32_t *)usermembuf;
- else
- return (1);
-
- /* Return the sysctl value, but clamp to SIZE_MAX if necessary. */
-#if UINT64_MAX > SIZE_MAX
- if (usermem > SIZE_MAX)
- *memlimit = SIZE_MAX;
- else
- *memlimit = usermem;
-#else
- *memlimit = usermem;
-#endif
-
- /* Success! */
- return (0);
-}
-#endif
-
-/* If we don't HAVE_STRUCT_SYSINFO, we can't use sysinfo. */
-#ifndef HAVE_STRUCT_SYSINFO
-#undef HAVE_SYSINFO
-#endif
-
-/* If we don't HAVE_STRUCT_SYSINFO_TOTALRAM, we can't use sysinfo. */
-#ifndef HAVE_STRUCT_SYSINFO_TOTALRAM
-#undef HAVE_SYSINFO
-#endif
-
-#ifdef HAVE_SYSINFO
-static int
-memlimit_sysinfo(size_t * memlimit)
-{
- struct sysinfo info;
- uint64_t totalmem;
-
- /* Get information from the kernel. */
- if (sysinfo(&info))
- return (1);
- totalmem = info.totalram;
-
- /* If we're on a modern kernel, adjust based on mem_unit. */
-#ifdef HAVE_STRUCT_SYSINFO_MEM_UNIT
- totalmem = totalmem * info.mem_unit;
-#endif
-
- /* Return the value, but clamp to SIZE_MAX if necessary. */
-#if UINT64_MAX > SIZE_MAX
- if (totalmem > SIZE_MAX)
- *memlimit = SIZE_MAX;
- else
- *memlimit = totalmem;
-#else
- *memlimit = totalmem;
-#endif
-
- /* Success! */
- return (0);
-}
-#endif /* HAVE_SYSINFO */
-
-static int
-memlimit_rlimit(size_t * memlimit)
-{
- struct rlimit rl;
- uint64_t memrlimit;
-
- /* Find the least of... */
- memrlimit = (uint64_t)(-1);
-
- /* ... RLIMIT_AS... */
-#ifdef RLIMIT_AS
- if (getrlimit(RLIMIT_AS, &rl))
- return (1);
- if ((rl.rlim_cur != RLIM_INFINITY) &&
- ((uint64_t)rl.rlim_cur < memrlimit))
- memrlimit = rl.rlim_cur;
-#endif
-
- /* ... RLIMIT_DATA... */
- if (getrlimit(RLIMIT_DATA, &rl))
- return (1);
- if ((rl.rlim_cur != RLIM_INFINITY) &&
- ((uint64_t)rl.rlim_cur < memrlimit))
- memrlimit = rl.rlim_cur;
-
- /* ... and RLIMIT_RSS. */
-#ifdef RLIMIT_RSS
- if (getrlimit(RLIMIT_RSS, &rl))
- return (1);
- if ((rl.rlim_cur != RLIM_INFINITY) &&
- ((uint64_t)rl.rlim_cur < memrlimit))
- memrlimit = rl.rlim_cur;
-#endif
-
- /* Return the value, but clamp to SIZE_MAX if necessary. */
-#if UINT64_MAX > SIZE_MAX
- if (memrlimit > SIZE_MAX)
- *memlimit = SIZE_MAX;
- else
- *memlimit = memrlimit;
-#else
- *memlimit = memrlimit;
-#endif
-
- /* Success! */
- return (0);
-}
-
-#ifdef _SC_PHYS_PAGES
-
-/* Some systems define _SC_PAGESIZE instead of _SC_PAGE_SIZE. */
-#ifndef _SC_PAGE_SIZE
-#define _SC_PAGE_SIZE _SC_PAGESIZE
-#endif
-
-static int
-memlimit_sysconf(size_t * memlimit)
-{
- long pagesize;
- long physpages;
- uint64_t totalmem;
-
- /* Set errno to 0 in order to distinguish "no limit" from "error". */
- errno = 0;
-
- /* Read the two limits. */
- if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) ||
- ((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) {
- /* Did an error occur? */
- if (errno != 0)
- return (1);
-
- /* If not, there is no limit. */
- totalmem = (uint64_t)(-1);
- } else {
- /* Compute the limit. */
- totalmem = (uint64_t)(pagesize) * (uint64_t)(physpages);
- }
-
- /* Return the value, but clamp to SIZE_MAX if necessary. */
-#if UINT64_MAX > SIZE_MAX
- if (totalmem > SIZE_MAX)
- *memlimit = SIZE_MAX;
- else
- *memlimit = totalmem;
-#else
- *memlimit = totalmem;
-#endif
-
- /* Success! */
- return (0);
-}
-#endif
-
-int
-memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit)
-{
- size_t sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit;
- size_t sysconf_memlimit;
- size_t memlimit_min;
- size_t memavail;
-
- /* Get memory limits. */
-#ifdef HAVE_SYSCTL_HW_USERMEM
- if (memlimit_sysctl_hw_usermem(&sysctl_memlimit))
- return (1);
-#else
- sysctl_memlimit = (size_t)(-1);
-#endif
-#ifdef HAVE_SYSINFO
- if (memlimit_sysinfo(&sysinfo_memlimit))
- return (1);
-#else
- sysinfo_memlimit = (size_t)(-1);
-#endif
- if (memlimit_rlimit(&rlimit_memlimit))
- return (1);
-#ifdef _SC_PHYS_PAGES
- if (memlimit_sysconf(&sysconf_memlimit))
- return (1);
-#else
- sysconf_memlimit = (size_t)(-1);
-#endif
-
-#ifdef DEBUG
- fprintf(stderr, "Memory limits are %zu %zu %zu %zu\n",
- sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit,
- sysconf_memlimit);
-#endif
-
- /* Find the smallest of them. */
- memlimit_min = (size_t)(-1);
- if (memlimit_min > sysctl_memlimit)
- memlimit_min = sysctl_memlimit;
- if (memlimit_min > sysinfo_memlimit)
- memlimit_min = sysinfo_memlimit;
- if (memlimit_min > rlimit_memlimit)
- memlimit_min = rlimit_memlimit;
- if (memlimit_min > sysconf_memlimit)
- memlimit_min = sysconf_memlimit;
-
- /* Only use the specified fraction of the available memory. */
- if ((maxmemfrac > 0.5) || (maxmemfrac == 0.0))
- maxmemfrac = 0.5;
- memavail = maxmemfrac * memlimit_min;
-
- /* Don't use more than the specified maximum. */
- if ((maxmem > 0) && (memavail > maxmem))
- memavail = maxmem;
-
- /* But always allow at least 1 MiB. */
- if (memavail < 1048576)
- memavail = 1048576;
-
-#ifdef DEBUG
- fprintf(stderr, "Allowing up to %zu memory to be used\n", memavail);
-#endif
-
- /* Return limit via the provided pointer. */
- *memlimit = memavail;
- return (0);
-}
diff --git a/lib/util/memlimit.h b/lib/util/memlimit.h
deleted file mode 100644
index d3b4891..0000000
--- a/lib/util/memlimit.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _MEMLIMIT_H_
-#define _MEMLIMIT_H_
-
-#include <stddef.h>
-
-/**
- * memtouse(maxmem, maxmemfrac, memlimit):
- * Examine the system and return via memlimit the amount of RAM which should
- * be used -- the specified fraction of the available RAM, but no more than
- * maxmem, and no less than 1MiB.
- */
-int memtouse(size_t, double, size_t *);
-
-#endif /* !_MEMLIMIT_H_ */
diff --git a/lib/util/readpass.c b/lib/util/readpass.c
deleted file mode 100644
index f76fb46..0000000
--- a/lib/util/readpass.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "warn.h"
-
-#include "readpass.h"
-
-#define MAXPASSLEN 2048
-
-/**
- * tarsnap_getpass(passwd, prompt, confirmprompt, devtty)
- * If ${devtty} is non-zero, read a password from /dev/tty if possible; if
- * not, read from stdin. If reading from a tty (either /dev/tty or stdin),
- * disable echo and prompt the user by printing ${prompt} to stderr. If
- * ${confirmprompt} is non-NULL, read a second password (prompting if a
- * terminal is being used) and repeat until the user enters the same password
- * twice. Return the password as a malloced NUL-terminated string via
- * ${passwd}. The obscure name is to avoid namespace collisions due to the
- * getpass / readpass / readpassphrase / etc. functions in various libraries.
- */
-int
-tarsnap_readpass(char ** passwd, const char * prompt,
- const char * confirmprompt, int devtty)
-{
- FILE * readfrom;
- char passbuf[MAXPASSLEN];
- char confpassbuf[MAXPASSLEN];
- struct termios term, term_old;
- int usingtty;
-
- /*
- * If devtty != 0, try to open /dev/tty; if that fails, or if devtty
- * is zero, we'll read the password from stdin instead.
- */
- if ((devtty == 0) || ((readfrom = fopen("/dev/tty", "r")) == NULL))
- readfrom = stdin;
-
- /* If we're reading from a terminal, try to disable echo. */
- if ((usingtty = isatty(fileno(readfrom))) != 0) {
- if (tcgetattr(fileno(readfrom), &term_old)) {
- warn("Cannot read terminal settings");
- goto err1;
- }
- memcpy(&term, &term_old, sizeof(struct termios));
- term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL;
- if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
- warn("Cannot set terminal settings");
- goto err1;
- }
- }
-
-retry:
- /* If we have a terminal, prompt the user to enter the password. */
- if (usingtty)
- fprintf(stderr, "%s: ", prompt);
-
- /* Read the password. */
- if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
- warn("Cannot read password");
- goto err2;
- }
-
- /* Confirm the password if necessary. */
- if (confirmprompt != NULL) {
- if (usingtty)
- fprintf(stderr, "%s: ", confirmprompt);
- if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
- warn("Cannot read password");
- goto err2;
- }
- if (strcmp(passbuf, confpassbuf)) {
- fprintf(stderr,
- "Passwords mismatch, please try again\n");
- goto retry;
- }
- }
-
- /* Terminate the string at the first "\r" or "\n" (if any). */
- passbuf[strcspn(passbuf, "\r\n")] = '\0';
-
- /* If we changed terminal settings, reset them. */
- if (usingtty)
- tcsetattr(fileno(readfrom), TCSANOW, &term_old);
-
- /* Close /dev/tty if we opened it. */
- if (readfrom != stdin)
- fclose(readfrom);
-
- /* Copy the password out. */
- if ((*passwd = strdup(passbuf)) == NULL) {
- warn("Cannot allocate memory");
- goto err1;
- }
-
- /* Zero any stored passwords. */
- memset(passbuf, 0, MAXPASSLEN);
- memset(confpassbuf, 0, MAXPASSLEN);
-
- /* Success! */
- return (0);
-
-err2:
- /* Reset terminal settings if necessary. */
- if (usingtty)
- tcsetattr(fileno(readfrom), TCSAFLUSH, &term_old);
-err1:
- /* Close /dev/tty if we opened it. */
- if (readfrom != stdin)
- fclose(readfrom);
-
- /* Failure! */
- return (-1);
-}
diff --git a/lib/util/readpass.h b/lib/util/readpass.h
deleted file mode 100644
index da57278..0000000
--- a/lib/util/readpass.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _READPASS_H_
-#define _READPASS_H_
-
-/**
- * tarsnap_getpass(passwd, prompt, confirmprompt, devtty)
- * If ${devtty} is non-zero, read a password from /dev/tty if possible; if
- * not, read from stdin. If reading from a tty (either /dev/tty or stdin),
- * disable echo and prompt the user by printing ${prompt} to stderr. If
- * ${confirmprompt} is non-NULL, read a second password (prompting if a
- * terminal is being used) and repeat until the user enters the same password
- * twice. Return the password as a malloced NUL-terminated string via
- * ${passwd}. The obscure name is to avoid namespace collisions due to the
- * getpass / readpass / readpassphrase / etc. functions in various libraries.
- */
-int tarsnap_readpass(char **, const char *, const char *, int);
-
-#endif /* !_READPASS_H_ */
diff --git a/lib/util/sysendian.h b/lib/util/sysendian.h
deleted file mode 100644
index 0495194..0000000
--- a/lib/util/sysendian.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*-
- * Copyright 2007-2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _SYSENDIAN_H_
-#define _SYSENDIAN_H_
-
-/* If we don't have be64enc, the <sys/endian.h> we have isn't usable. */
-#if !HAVE_DECL_BE64ENC
-#undef HAVE_SYS_ENDIAN_H
-#endif
-
-#ifdef HAVE_SYS_ENDIAN_H
-
-#include <sys/endian.h>
-
-#else
-
-#include <stdint.h>
-
-static inline uint32_t
-be32dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
- ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
-}
-
-static inline void
-be32enc(void *pp, uint32_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[3] = x & 0xff;
- p[2] = (x >> 8) & 0xff;
- p[1] = (x >> 16) & 0xff;
- p[0] = (x >> 24) & 0xff;
-}
-
-static inline uint64_t
-be64dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
- ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
- ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
- ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
-}
-
-static inline void
-be64enc(void *pp, uint64_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[7] = x & 0xff;
- p[6] = (x >> 8) & 0xff;
- p[5] = (x >> 16) & 0xff;
- p[4] = (x >> 24) & 0xff;
- p[3] = (x >> 32) & 0xff;
- p[2] = (x >> 40) & 0xff;
- p[1] = (x >> 48) & 0xff;
- p[0] = (x >> 56) & 0xff;
-}
-
-static inline uint32_t
-le32dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
- ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
-}
-
-static inline void
-le32enc(void *pp, uint32_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[0] = x & 0xff;
- p[1] = (x >> 8) & 0xff;
- p[2] = (x >> 16) & 0xff;
- p[3] = (x >> 24) & 0xff;
-}
-
-static inline uint64_t
-le64dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
- ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
- ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
- ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
-}
-
-static inline void
-le64enc(void *pp, uint64_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[0] = x & 0xff;
- p[1] = (x >> 8) & 0xff;
- p[2] = (x >> 16) & 0xff;
- p[3] = (x >> 24) & 0xff;
- p[4] = (x >> 32) & 0xff;
- p[5] = (x >> 40) & 0xff;
- p[6] = (x >> 48) & 0xff;
- p[7] = (x >> 56) & 0xff;
-}
-#endif /* !HAVE_SYS_ENDIAN_H */
-
-#endif /* !_SYSENDIAN_H_ */
diff --git a/lib/util/warn.c b/lib/util/warn.c
deleted file mode 100644
index 69f7b2d..0000000
--- a/lib/util/warn.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#ifdef HAVE_ERR_H
-/*
- * Everything is provided through err.h and the associated library, so we
- * don't need to do anything here.
- */
-#else
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "warn.h"
-
-const char * warn_progname = "(null)";
-
-void
-warn(const char * fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "%s", warn_progname);
- if (fmt != NULL) {
- fprintf(stderr, ": ");
- vfprintf(stderr, fmt, ap);
- }
- fprintf(stderr, ": %s\n", strerror(errno));
- va_end(ap);
-}
-
-void
-warnx(const char * fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "%s", warn_progname);
- if (fmt != NULL) {
- fprintf(stderr, ": ");
- vfprintf(stderr, fmt, ap);
- }
- fprintf(stderr, "\n");
- va_end(ap);
-}
-#endif
diff --git a/lib/util/warn.h b/lib/util/warn.h
deleted file mode 100644
index 262d24b..0000000
--- a/lib/util/warn.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _WARN_H_
-#define _WARN_H_
-
-#ifdef HAVE_ERR_H
-#include <err.h>
-#else
-#define NEED_WARN_PROGNAME
-const char * warn_progname;
-void warn(const char *, ...);
-void warnx(const char *, ...);
-#endif
-
-#endif /* !_WARN_H_ */
diff --git a/luascrypt.c b/luascrypt.c
index f863381..2492cf7 100644
--- a/luascrypt.c
+++ b/luascrypt.c
@@ -1,208 +1,149 @@
-/* scrypt for Lua
- * Copyright 2013 Rob Kendrick <rjek+luascrypt@rjek.com>
- *
- * Heavy based on Barry Steyn's code, and distributed under the same licence:
- *
- * Copyright (C) 2012 Barry Steyn (http://doctrina.org/Scrypt-Authentication-For-Node.html)
- *
- * This source code is provided 'as-is', without any express or implied
- * warranty. In no event will the author be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this source code must not be misrepresented; you must not
- * claim that you wrote the original source code. If you use this source code
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- *
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original source code.
+/*
+ * luascrypt - Lua binding to libscrypt
*
- * 3. This notice may not be removed or altered from any source distribution.
+ * Copyright 2015 Daniel Silverstone <dsilvers@digital-scurf.org>
*
- * Barry Steyn barry.steyn@gmail.com
+ * Please see the file COPYING for licence details.
*/
-#include <stdlib.h>
-#include <string.h>
+#include <stdint.h>
#include <errno.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
-#include <stdint.h>
-#include <math.h>
-#include <lua.h>
-#include <lauxlib.h>
+#include "lua.h"
+#include "lauxlib.h"
-#include "sha256.h"
-#include "sysendian.h"
-#include "crypto_scrypt.h"
-#include "memlimit.h"
-#include "scryptenc_cpuperf.h"
+#include "libscrypt.h"
-/*
- * Obtains salt for password hash. This function is copied from Colin Percival's scrypt reference code
- */
-static int
-getsalt(uint8_t salt[32]) {
+static void
+luascrypt_salt_gen(char *salt, int saltlen)
+{
int fd;
- ssize_t lenread;
- uint8_t * buf = salt;
- size_t buflen = 32;
-
- /* Open /dev/urandom. */
- if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
- goto err0;
-
- /* Read bytes until we have filled the buffer. */
- while (buflen > 0) {
- if ((lenread = read(fd, buf, buflen)) == -1)
- goto err1;
-
- /* The random device should never EOF. */
- if (lenread == 0)
- goto err1;
-
- /* We're partly done. */
- buf += lenread;
- buflen -= lenread;
- }
-
- /* Close the device. */
- while (close(fd) == -1) {
- if (errno != EINTR)
- goto err0;
+ /* 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
+ * libscrypt implementation is fast, call it, and then overwrite it
+ * 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 */
+ close(fd); /* Since we have our fallback. */
}
-
- /* Success! */
- return (0);
-
-err1:
- close(fd);
-err0:
- /* Failure! */
- return (4);
}
static int
-ls_hash_password(lua_State *L)
+luascrypt_hash_password(lua_State *L)
{
- const uint8_t *passwd = (const uint8_t *)luaL_checkstring(L, 1);
- size_t passwdlen = lua_objlen(L, 1);
- uint64_t N = luaL_checknumber(L, 2);
- uint32_t r = luaL_checknumber(L, 3);
- uint32_t p = luaL_checknumber(L, 4);
-
- uint8_t dk[64], salt[32], hbuf[32], header[96];
- uint8_t *key_hmac = &dk[32];
-
- SHA256_CTX ctx;
- HMAC_SHA256_CTX hctx;
-
- int result;
-
- errno = 0;
- if ((result = getsalt(salt)) != 0) {
- lua_pushstring(L, strerror(errno));
- lua_error(L);
+ // password {N, r, p} -> crypted
+ size_t passwd_len;
+ const char *passwd = luaL_checklstring(L, 1, &passwd_len);
+ char buffer[256]; /* This value is nasty here, but */
+ char salt[16]; /* while I am not normally into magic */
+ uint8_t hashbuf[64]; /* numbers, these are taken from the */
+ char saltbuf[256]; /* libscrypt_hash() source. */
+ char outbuf[256]; /* Icky, I know, but what can I do? */
+ uint32_t N = SCRYPT_N;
+ uint32_t r = SCRYPT_r;
+ uint32_t p = SCRYPT_p;
+ if (lua_gettop(L) > 1) {
+ N = (uint32_t)luaL_checknumber(L, 2);
+ r = (uint32_t)luaL_checknumber(L, 3);
+ p = (uint32_t)luaL_checknumber(L, 4);
}
- errno = 0;
- if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64) != 0) {
- lua_pushstring(L, strerror(errno));
- lua_error(L);
+ /* We know that libscrypt is limited to N of 2^15 or less
+ * so raise an error if N is too large
+ */
+ if (N > 32768) {
+ return luaL_error(L, "Unable to generate password hash: %s",
+ "N is too large (limited to 2^15)");
}
- memcpy(header, "scrypt", 6);
- header[6] = 0;
- header[7] = (int)log2(N);
- be32enc(&header[8], r);
- be32enc(&header[12], p);
- memcpy(&header[16], salt, 32);
+ luascrypt_salt_gen(salt, sizeof(salt));
+
+ if (libscrypt_scrypt((uint8_t*)passwd, passwd_len,
+ (uint8_t*)salt, sizeof(salt),
+ N, r, p,
+ hashbuf, sizeof(hashbuf)) < 0) {
+ return luaL_error(L, "Unable to generate password hash: %s",
+ (errno == EFBIG) ? "r and p are too large" :
+ (errno == EINVAL) ? "N is not a power of 2" :
+ (errno == ENOMEM) ? "Buffer sizes are bad" :
+ "Unknown error");
+ }
- SHA256_Init(&ctx);
- SHA256_Update(&ctx, header, 48);
- SHA256_Final(hbuf, &ctx);
- memcpy(&header[48], hbuf, 16);
+ if (libscrypt_b64_encode(outbuf, (char *)hashbuf, sizeof(hashbuf)) < 0) {
+ return luaL_error(L, "Unable to encode password hash.");
+ }
- HMAC_SHA256_Init(&hctx, key_hmac, 32);
- HMAC_SHA256_Update(&hctx, header, 64);
- HMAC_SHA256_Final(hbuf, &hctx);
- memcpy(&header[64], hbuf, 32);
+ if (libscrypt_b64_encode(saltbuf, salt, sizeof(salt)) < 0) {
+ return luaL_error(L, "Unable to encode salt.");
+ }
- lua_pushlstring(L, (const char *)header, 96);
+ if (libscrypt_mcf(N, r, p, saltbuf, outbuf, buffer) < 1) {
+ return luaL_error(L, "Unable to mcf encode password.");
+ }
+
+
+ /* some versions of libscrypt fail to include the final equals
+ * after mcf encoding -- check and if it's missing, add it back
+ */
+ {
+ int oblen = strlen(outbuf);
+ int bulen = strlen(buffer);
+ if (outbuf[oblen-1] == outbuf[oblen-2] &&
+ outbuf[oblen-1] == '=' &&
+ buffer[bulen-1] == '=' && buffer[bulen-2] != '=') {
+ strcat(buffer, "=");
+ }
+ }
+
+ lua_pushstring(L, buffer);
return 1;
}
static int
-ls_verify_password(lua_State *L) {
- const uint8_t *header = (uint8_t *)luaL_checkstring(L, 1);
- const uint8_t *passwd = (uint8_t *)luaL_checkstring(L, 2);
- size_t headerlen = lua_objlen(L, 1);
- size_t passwdlen = lua_objlen(L, 2);
-
- int N;
- uint32_t r, p;
- uint8_t dk[64], salt[32], hbuf[32];
- uint8_t *key_hmac = &dk[32];
-
- HMAC_SHA256_CTX hctx;
- SHA256_CTX ctx;
-
- if (headerlen != 96) {
- lua_pushliteral(L, "password hash must be 96 bytes");
- lua_error(L);
- }
-
- N = (uint64_t) 1 << header[7];
- r = be32dec(&header[8]);
- p = be32dec(&header[12]);
- memcpy(salt, &header[16], 32);
-
- SHA256_Init(&ctx);
- SHA256_Update(&ctx, header, 48);
- SHA256_Final(hbuf, &ctx);
-
- if (memcmp(&header[48], hbuf, 16)) {
- lua_pushnil(L);
- lua_pushliteral(L, "header SHA does not verify; hash corrupt");
- return 2;
- }
+luascrypt_verify_password(lua_State *L)
+{
+ // crypted password -> okbool
+ const char *crypted = luaL_checkstring(L, 1);
+ const char *passwd = luaL_checkstring(L, 2);
- errno = 0;
- if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64) != 0) {
- lua_pushstring(L, strerror(errno));
- lua_error(L);
- }
+ /* libscrypt_check() mutates the provided crypted data, so copy it
+ * otherwise we damage the memory Lua holds.
+ */
+ char *crypted_copy = (char *)lua_newuserdata(L, strlen(crypted)+1);
+ strcpy(crypted_copy, crypted);
- HMAC_SHA256_Init(&hctx, key_hmac, 32);
- HMAC_SHA256_Update(&hctx, header, 64);
- HMAC_SHA256_Final(hbuf, &hctx);
+ int r = libscrypt_check(crypted_copy, (char *)passwd);
- if (memcmp(hbuf, &header[64], 32)) {
- lua_pushboolean(L, 0);
- } else {
- lua_pushboolean(L, 1);
+ if (r < 0) {
+ return luaL_error(L, "Unable to verify password. Bad crypt.");
}
+ lua_pushboolean(L, r);
return 1;
}
-static const struct luaL_Reg
-ls_functions[] = {
- { "hash_password", ls_hash_password },
- { "verify_password", ls_verify_password },
-
+static const struct luaL_Reg
+luascrypt_functions[] = {
+ { "hash_password", luascrypt_hash_password },
+ { "verify_password", luascrypt_verify_password },
{ NULL, NULL }
};
int
luaopen_scrypt(lua_State *L)
{
-
- luaL_register(L, "scrypt", ls_functions);
+ luaL_register(L, "scrypt", luascrypt_functions);
return 1;
}