From cb739b0b7d766aabccdee4b0d3cc0a201e60f434 Mon Sep 17 00:00:00 2001 From: Boyuan Yang <byang@debian.org> Date: Sat, 7 Dec 2019 13:53:10 -0500 Subject: [PATCH] Import Upstream version 0.8.0 --- MANIFEST.in | 10 + PKG-INFO | 16 +- README.rst | 9 +- scrypt-1.1.6/lib/crypto/crypto_aesctr.h | 59 --- scrypt-1.1.6/lib/crypto/sha256.c | 412 ---------------- scrypt-1.1.6/lib/crypto/sha256.h | 62 --- scrypt-1.1.6/lib/util/readpass.h | 45 -- scrypt-1.1.6/lib/util/sysendian.h | 140 ------ scrypt-1.1.6/lib/util/warn.c | 75 --- scrypt-1.1.6/lib/util/warn.h | 13 - {scrypt-1.1.6 => scrypt-1.2.0}/config.h | 8 +- scrypt-1.2.0/lib/crypto/crypto_scrypt.c | 255 ++++++++++ .../lib/crypto/crypto_scrypt.h | 1 + .../lib/crypto/crypto_scrypt_smix.c | 166 +------ scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h | 14 + .../lib/crypto/crypto_scrypt_smix_sse2.c | 247 ++++++++++ .../lib/crypto/crypto_scrypt_smix_sse2.h | 16 + .../lib/scryptenc/scryptenc.c | 210 +++------ .../lib/scryptenc/scryptenc.h | 8 + .../lib/scryptenc/scryptenc_cpuperf.c | 11 +- .../lib/scryptenc/scryptenc_cpuperf.h | 0 .../lib/util/memlimit.c | 119 ++--- .../lib/util/memlimit.h | 0 scrypt-1.2.0/libcperciva/alg/sha256.c | 442 ++++++++++++++++++ scrypt-1.2.0/libcperciva/alg/sha256.h | 95 ++++ .../libcperciva/cpusupport/cpusupport.h | 64 +++ scrypt-1.2.0/libcperciva/crypto/crypto_aes.c | 166 +++++++ scrypt-1.2.0/libcperciva/crypto/crypto_aes.h | 31 ++ .../libcperciva/crypto/crypto_aes_aesni.c | 236 ++++++++++ .../libcperciva/crypto/crypto_aes_aesni.h | 31 ++ .../libcperciva}/crypto/crypto_aesctr.c | 70 +-- .../libcperciva/crypto/crypto_aesctr.h | 41 ++ .../libcperciva/crypto/crypto_entropy.c | 215 +++++++++ .../libcperciva/crypto/crypto_entropy.h | 14 + scrypt-1.2.0/libcperciva/util/entropy.c | 105 +++++ scrypt-1.2.0/libcperciva/util/entropy.h | 13 + .../libcperciva/util/insecure_memzero.c | 19 + .../libcperciva/util/insecure_memzero.h | 37 ++ scrypt-1.2.0/libcperciva/util/sysendian.h | 146 ++++++ scrypt-1.2.0/libcperciva/util/warnp.c | 76 +++ scrypt-1.2.0/libcperciva/util/warnp.h | 59 +++ .../scrypt_platform.h | 0 scrypt.egg-info/PKG-INFO | 141 ++++++ scrypt.egg-info/SOURCES.txt | 47 ++ scrypt.egg-info/dependency_links.txt | 1 + scrypt.egg-info/top_level.txt | 2 + scrypt.py | 2 +- setup.cfg | 5 + setup.py | 105 ++--- src/scrypt.c | 32 +- tests/__init__.py | 36 ++ tests/test_scrypt.py | 11 +- tests/test_scrypt_py2x.py | 9 +- tests/test_scrypt_py3x.py | 9 +- 54 files changed, 2877 insertions(+), 1279 deletions(-) create mode 100644 MANIFEST.in delete mode 100644 scrypt-1.1.6/lib/crypto/crypto_aesctr.h delete mode 100644 scrypt-1.1.6/lib/crypto/sha256.c delete mode 100644 scrypt-1.1.6/lib/crypto/sha256.h delete mode 100644 scrypt-1.1.6/lib/util/readpass.h delete mode 100644 scrypt-1.1.6/lib/util/sysendian.h delete mode 100644 scrypt-1.1.6/lib/util/warn.c delete mode 100644 scrypt-1.1.6/lib/util/warn.h rename {scrypt-1.1.6 => scrypt-1.2.0}/config.h (95%) create mode 100644 scrypt-1.2.0/lib/crypto/crypto_scrypt.c rename {scrypt-1.1.6 => scrypt-1.2.0}/lib/crypto/crypto_scrypt.h (99%) rename scrypt-1.1.6/lib/crypto/crypto_scrypt-nosse.c => scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c (59%) create mode 100644 scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h create mode 100644 scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c create mode 100644 scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h rename {scrypt-1.1.6 => scrypt-1.2.0}/lib/scryptenc/scryptenc.c (76%) rename {scrypt-1.1.6 => scrypt-1.2.0}/lib/scryptenc/scryptenc.h (93%) rename {scrypt-1.1.6 => scrypt-1.2.0}/lib/scryptenc/scryptenc_cpuperf.c (95%) rename {scrypt-1.1.6 => scrypt-1.2.0}/lib/scryptenc/scryptenc_cpuperf.h (100%) rename {scrypt-1.1.6 => scrypt-1.2.0}/lib/util/memlimit.c (74%) rename {scrypt-1.1.6 => scrypt-1.2.0}/lib/util/memlimit.h (100%) create mode 100644 scrypt-1.2.0/libcperciva/alg/sha256.c create mode 100644 scrypt-1.2.0/libcperciva/alg/sha256.h create mode 100644 scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h create mode 100644 scrypt-1.2.0/libcperciva/crypto/crypto_aes.c create mode 100644 scrypt-1.2.0/libcperciva/crypto/crypto_aes.h create mode 100644 scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c create mode 100644 scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h rename {scrypt-1.1.6/lib => scrypt-1.2.0/libcperciva}/crypto/crypto_aesctr.c (53%) create mode 100644 scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h create mode 100644 scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c create mode 100644 scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h create mode 100644 scrypt-1.2.0/libcperciva/util/entropy.c create mode 100644 scrypt-1.2.0/libcperciva/util/entropy.h create mode 100644 scrypt-1.2.0/libcperciva/util/insecure_memzero.c create mode 100644 scrypt-1.2.0/libcperciva/util/insecure_memzero.h create mode 100644 scrypt-1.2.0/libcperciva/util/sysendian.h create mode 100644 scrypt-1.2.0/libcperciva/util/warnp.c create mode 100644 scrypt-1.2.0/libcperciva/util/warnp.h rename {scrypt-1.1.6 => scrypt-1.2.0}/scrypt_platform.h (100%) create mode 100644 scrypt.egg-info/PKG-INFO create mode 100644 scrypt.egg-info/SOURCES.txt create mode 100644 scrypt.egg-info/dependency_links.txt create mode 100644 scrypt.egg-info/top_level.txt create mode 100644 setup.cfg diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..23fe106 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,10 @@ +recursive-include scrypt-1.2.0 *.h +include README.rst +include src/*.c + +include tests/__init__.py +include tests/ciphertexts.csv +include tests/hashvectors.csv +include tests/test_scrypt.py +include tests/test_scrypt_py2x.py +include tests/test_scrypt_py3x.py diff --git a/PKG-INFO b/PKG-INFO index 6d65038..fae8de3 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: scrypt -Version: 0.6.1 +Version: 0.8.0 Summary: Bindings for the scrypt key derivation function library Home-page: http://bitbucket.org/mhallin/py-scrypt Author: Magnus Hallin @@ -73,11 +73,8 @@ Description: ========================= From these, one can make a simple password verifier using the following functions:: - def randstr(length): - return ''.join(chr(random.randint(0,255)) for i in range(length)) - def hash_password(password, maxtime=0.5, datalength=64): - return scrypt.encrypt(randstr(datalength), password, maxtime=maxtime) + return scrypt.encrypt(os.urandom(datalength), password, maxtime=maxtime) def verify_password(hashed_password, guessed_password, maxtime=0.5): try: @@ -118,6 +115,9 @@ Description: ========================= Burstaholic_ on Bitbucket provided the necessary changes to make the library build on Windows. + The `python-appveyor-demo`_ repository for setting up automated Windows + builds for a multitude of Python versions. + License ======= @@ -127,13 +127,15 @@ Description: ========================= .. _Python: http://python.org .. _Burstaholic: https://bitbucket.org/Burstaholic .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca + .. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License -Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 Classifier: Topic :: Security :: Cryptography Classifier: Topic :: Software Development :: Libraries diff --git a/README.rst b/README.rst index f567b6c..c923b09 100644 --- a/README.rst +++ b/README.rst @@ -65,11 +65,8 @@ Fore encryption/decryption, the library exports two functions From these, one can make a simple password verifier using the following functions:: - def randstr(length): - return ''.join(chr(random.randint(0,255)) for i in range(length)) - def hash_password(password, maxtime=0.5, datalength=64): - return scrypt.encrypt(randstr(datalength), password, maxtime=maxtime) + return scrypt.encrypt(os.urandom(datalength), password, maxtime=maxtime) def verify_password(hashed_password, guessed_password, maxtime=0.5): try: @@ -110,6 +107,9 @@ platform testing and work on the ``hash`` function. Burstaholic_ on Bitbucket provided the necessary changes to make the library build on Windows. +The `python-appveyor-demo`_ repository for setting up automated Windows +builds for a multitude of Python versions. + License ======= @@ -119,3 +119,4 @@ This library is licensed under the same license as scrypt; 2-clause BSD. .. _Python: http://python.org .. _Burstaholic: https://bitbucket.org/Burstaholic .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca +.. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo diff --git a/scrypt-1.1.6/lib/crypto/crypto_aesctr.h b/scrypt-1.1.6/lib/crypto/crypto_aesctr.h deleted file mode 100644 index b50398f..0000000 --- a/scrypt-1.1.6/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/scrypt-1.1.6/lib/crypto/sha256.c b/scrypt-1.1.6/lib/crypto/sha256.c deleted file mode 100644 index 2812cf5..0000000 --- a/scrypt-1.1.6/lib/crypto/sha256.c +++ /dev/null @@ -1,412 +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 "scrypt_platform.h" - -#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 scrypt_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)) - -/* scrypt_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) - -/* - * scrypt_SHA256 block compression function. The 256-bit state is transformed via - * the 512-bit input block to produce a new state. - */ -static void -scrypt_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 -scrypt_SHA256_Pad(scrypt_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); - scrypt_SHA256_Update(ctx, PAD, (size_t)plen); - - /* Add the terminating bit-count */ - scrypt_SHA256_Update(ctx, len, 8); -} - -/* SHA-256 initialization. Begins a SHA-256 operation. */ -void -scrypt_SHA256_Init(scrypt_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 -scrypt_SHA256_Update(scrypt_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); - scrypt_SHA256_Transform(ctx->state, ctx->buf); - src += 64 - r; - len -= 64 - r; - - /* Perform complete blocks */ - while (len >= 64) { - scrypt_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 -scrypt_SHA256_Final(unsigned char digest[32], scrypt_SHA256_CTX * ctx) -{ - - /* Add padding */ - scrypt_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-scrypt_SHA256 operation with the given key. */ -void -HMAC_scrypt_SHA256_Init(HMAC_scrypt_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 scrypt_SHA256(K). */ - if (Klen > 64) { - scrypt_SHA256_Init(&ctx->ictx); - scrypt_SHA256_Update(&ctx->ictx, K, Klen); - scrypt_SHA256_Final(khash, &ctx->ictx); - K = khash; - Klen = 32; - } - - /* Inner scrypt_SHA256 operation is scrypt_SHA256(K xor [block of 0x36] || data). */ - scrypt_SHA256_Init(&ctx->ictx); - memset(pad, 0x36, 64); - for (i = 0; i < Klen; i++) - pad[i] ^= K[i]; - scrypt_SHA256_Update(&ctx->ictx, pad, 64); - - /* Outer scrypt_SHA256 operation is scrypt_SHA256(K xor [block of 0x5c] || hash). */ - scrypt_SHA256_Init(&ctx->octx); - memset(pad, 0x5c, 64); - for (i = 0; i < Klen; i++) - pad[i] ^= K[i]; - scrypt_SHA256_Update(&ctx->octx, pad, 64); - - /* Clean the stack. */ - memset(khash, 0, 32); -} - -/* Add bytes to the HMAC-scrypt_SHA256 operation. */ -void -HMAC_scrypt_SHA256_Update(HMAC_scrypt_SHA256_CTX * ctx, const void *in, size_t len) -{ - - /* Feed data to the inner scrypt_SHA256 operation. */ - scrypt_SHA256_Update(&ctx->ictx, in, len); -} - -/* Finish an HMAC-scrypt_SHA256 operation. */ -void -HMAC_scrypt_SHA256_Final(unsigned char digest[32], HMAC_scrypt_SHA256_CTX * ctx) -{ - unsigned char ihash[32]; - - /* Finish the inner scrypt_SHA256 operation. */ - scrypt_SHA256_Final(ihash, &ctx->ictx); - - /* Feed the inner hash to the outer scrypt_SHA256 operation. */ - scrypt_SHA256_Update(&ctx->octx, ihash, 32); - - /* Finish the outer scrypt_SHA256 operation. */ - scrypt_SHA256_Final(digest, &ctx->octx); - - /* Clean the stack. */ - memset(ihash, 0, 32); -} - -/** - * PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): - * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-scrypt_SHA256 as the PRF, and - * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). - */ -void -PBKDF2_scrypt_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_scrypt_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_scrypt_SHA256_Init(&PShctx, passwd, passwdlen); - HMAC_scrypt_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_scrypt_SHA256_CTX)); - HMAC_scrypt_SHA256_Update(&hctx, ivec, 4); - HMAC_scrypt_SHA256_Final(U, &hctx); - - /* T_i = U_1 ... */ - memcpy(T, U, 32); - - for (j = 2; j <= c; j++) { - /* Compute U_j. */ - HMAC_scrypt_SHA256_Init(&hctx, passwd, passwdlen); - HMAC_scrypt_SHA256_Update(&hctx, U, 32); - HMAC_scrypt_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_scrypt_SHA256_CTX)); -} diff --git a/scrypt-1.1.6/lib/crypto/sha256.h b/scrypt-1.1.6/lib/crypto/sha256.h deleted file mode 100644 index 74ab0fd..0000000 --- a/scrypt-1.1.6/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 _scrypt_SHA256_H_ -#define _scrypt_SHA256_H_ - -#include <sys/types.h> - -#include <stdint.h> - -typedef struct scrypt_SHA256Context { - uint32_t state[8]; - uint32_t count[2]; - unsigned char buf[64]; -} scrypt_SHA256_CTX; - -typedef struct HMAC_scrypt_SHA256Context { - scrypt_SHA256_CTX ictx; - scrypt_SHA256_CTX octx; -} HMAC_scrypt_SHA256_CTX; - -void scrypt_SHA256_Init(scrypt_SHA256_CTX *); -void scrypt_SHA256_Update(scrypt_SHA256_CTX *, const void *, size_t); -void scrypt_SHA256_Final(unsigned char [32], scrypt_SHA256_CTX *); -void HMAC_scrypt_SHA256_Init(HMAC_scrypt_SHA256_CTX *, const void *, size_t); -void HMAC_scrypt_SHA256_Update(HMAC_scrypt_SHA256_CTX *, const void *, size_t); -void HMAC_scrypt_SHA256_Final(unsigned char [32], HMAC_scrypt_SHA256_CTX *); - -/** - * PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): - * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-scrypt_SHA256 as the PRF, and - * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). - */ -void PBKDF2_scrypt_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, - uint64_t, uint8_t *, size_t); - -#endif /* !_scrypt_SHA256_H_ */ diff --git a/scrypt-1.1.6/lib/util/readpass.h b/scrypt-1.1.6/lib/util/readpass.h deleted file mode 100644 index da57278..0000000 --- a/scrypt-1.1.6/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/scrypt-1.1.6/lib/util/sysendian.h b/scrypt-1.1.6/lib/util/sysendian.h deleted file mode 100644 index 62ef31a..0000000 --- a/scrypt-1.1.6/lib/util/sysendian.h +++ /dev/null @@ -1,140 +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_ - -#include "scrypt_platform.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/scrypt-1.1.6/lib/util/warn.c b/scrypt-1.1.6/lib/util/warn.c deleted file mode 100644 index 504f935..0000000 --- a/scrypt-1.1.6/lib/util/warn.c +++ /dev/null @@ -1,75 +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 "scrypt_platform.h" - -#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/scrypt-1.1.6/lib/util/warn.h b/scrypt-1.1.6/lib/util/warn.h deleted file mode 100644 index 262d24b..0000000 --- a/scrypt-1.1.6/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/scrypt-1.1.6/config.h b/scrypt-1.2.0/config.h similarity index 95% rename from scrypt-1.1.6/config.h rename to scrypt-1.2.0/config.h index f1e6fd6..9c17aa9 100644 --- a/scrypt-1.1.6/config.h +++ b/scrypt-1.2.0/config.h @@ -54,7 +54,7 @@ /* #undef HAVE_SYS_ENDIAN_H */ /* Define to 1 if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H 1 +/* #define HAVE_SYS_PARAM_H */ /* Define to 1 if you have the <sys/stat.h> header file. */ #define HAVE_SYS_STAT_H 1 @@ -78,19 +78,19 @@ #define PACKAGE_NAME "scrypt" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "scrypt 1.1.6" +#define PACKAGE_STRING "scrypt 1.2.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "scrypt" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.1.6" +#define PACKAGE_VERSION "1.2.0" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "1.1.6" +#define VERSION "1.2.0" /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ diff --git a/scrypt-1.2.0/lib/crypto/crypto_scrypt.c b/scrypt-1.2.0/lib/crypto/crypto_scrypt.c new file mode 100644 index 0000000..b082086 --- /dev/null +++ b/scrypt-1.2.0/lib/crypto/crypto_scrypt.c @@ -0,0 +1,255 @@ +/*- + * 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 "scrypt_platform.h" + +#include <sys/types.h> + +#ifndef _WIN32 +#include <sys/mman.h> +#endif + +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "cpusupport.h" +#include "sha256.h" +#include "warnp.h" + +#include "crypto_scrypt_smix.h" +#include "crypto_scrypt_smix_sse2.h" + +#include "crypto_scrypt.h" + +static void (*smix_func)(uint8_t *, size_t, uint64_t, void *, void *) = NULL; + +/** + * _crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen, smix): + * Perform the requested scrypt computation, using ${smix} as the smix routine. + */ +static 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 (*smix)(uint8_t *, size_t, uint64_t, void *, void *)) +{ + void * B0, * V0, * XY0; + uint8_t * B; + uint32_t * V; + uint32_t * XY; + size_t r = _r, p = _p; + 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 < 2)) { + 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); +#if !defined(MAP_ANON) || !defined(HAVE_MMAP) + 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)); +#if !defined(MAP_ANON) || !defined(HAVE_MMAP) + if ((V0 = malloc(128 * r * N + 63)) == NULL) + goto err2; + V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63)); +#endif +#endif +#if defined(MAP_ANON) && defined(HAVE_MMAP) + 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. */ +#if defined(MAP_ANON) && defined(HAVE_MMAP) + 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); +} + +#define TESTLEN 64 +static struct scrypt_test { + const char * passwd; + const char * salt; + uint64_t N; + uint32_t r; + uint32_t p; + uint8_t result[TESTLEN]; +} testcase = { + "pleaseletmein", + "SodiumChloride", + 16, + 8, + 1, + { + 0x25, 0xa9, 0xfa, 0x20, 0x7f, 0x87, 0xca, 0x09, + 0xa4, 0xef, 0x8b, 0x9f, 0x77, 0x7a, 0xca, 0x16, + 0xbe, 0xb7, 0x84, 0xae, 0x18, 0x30, 0xbf, 0xbf, + 0xd3, 0x83, 0x25, 0xaa, 0xbb, 0x93, 0x77, 0xdf, + 0x1b, 0xa7, 0x84, 0xd7, 0x46, 0xea, 0x27, 0x3b, + 0xf5, 0x16, 0xa4, 0x6f, 0xbf, 0xac, 0xf5, 0x11, + 0xc5, 0xbe, 0xba, 0x4c, 0x4a, 0xb3, 0xac, 0xc7, + 0xfa, 0x6f, 0x46, 0x0b, 0x6c, 0x0f, 0x47, 0x7b, + } +}; + +static int +testsmix(void (*smix)(uint8_t *, size_t, uint64_t, void *, void *)) +{ + uint8_t hbuf[TESTLEN]; + + /* Perform the computation. */ + if (_crypto_scrypt( + (const uint8_t *)testcase.passwd, strlen(testcase.passwd), + (const uint8_t *)testcase.salt, strlen(testcase.salt), + testcase.N, testcase.r, testcase.p, hbuf, TESTLEN, smix)) + return (-1); + + /* Does it match? */ + return (memcmp(testcase.result, hbuf, TESTLEN)); +} + +static void +selectsmix(void) +{ + +#ifdef CPUSUPPORT_X86_SSE2 + /* If we're running on an SSE2-capable CPU, try that code. */ + if (cpusupport_x86_sse2()) { + /* If SSE2ized smix works, use it. */ + if (!testsmix(crypto_scrypt_smix_sse2)) { + smix_func = crypto_scrypt_smix_sse2; + return; + } + warn0("Disabling broken SSE2 scrypt support - please report bug!"); + } +#endif + + /* If generic smix works, use it. */ + if (!testsmix(crypto_scrypt_smix)) { + smix_func = crypto_scrypt_smix; + return; + } + warn0("Generic scrypt code is broken - please report bug!"); + + /* If we get here, something really bad happened. */ + abort(); +} + +/** + * 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) +{ + + if (smix_func == NULL) + selectsmix(); + + return (_crypto_scrypt(passwd, passwdlen, salt, saltlen, N, _r, _p, + buf, buflen, smix_func)); +} diff --git a/scrypt-1.1.6/lib/crypto/crypto_scrypt.h b/scrypt-1.2.0/lib/crypto/crypto_scrypt.h similarity index 99% rename from scrypt-1.1.6/lib/crypto/crypto_scrypt.h rename to scrypt-1.2.0/lib/crypto/crypto_scrypt.h index f72e1f4..e7e0082 100644 --- a/scrypt-1.1.6/lib/crypto/crypto_scrypt.h +++ b/scrypt-1.2.0/lib/crypto/crypto_scrypt.h @@ -30,6 +30,7 @@ #define _CRYPTO_SCRYPT_H_ #include <stdint.h> +#include <unistd.h> /** * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): diff --git a/scrypt-1.1.6/lib/crypto/crypto_scrypt-nosse.c b/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c similarity index 59% rename from scrypt-1.1.6/lib/crypto/crypto_scrypt-nosse.c rename to scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c index a253379..ec3ec29 100644 --- a/scrypt-1.1.6/lib/crypto/crypto_scrypt-nosse.c +++ b/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c @@ -26,36 +26,25 @@ * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ -#include "scrypt_platform.h" - -#include <sys/types.h> - -#ifndef _WIN32 -#include <sys/mman.h> -#endif - -#include <errno.h> #include <stdint.h> -#include <stdlib.h> #include <string.h> #include "sha256.h" #include "sysendian.h" -#include "crypto_scrypt.h" +#include "crypto_scrypt_smix.h" -static void blkcpy(void *, void *, size_t); -static void blkxor(void *, void *, size_t); +static void blkcpy(void *, const void *, size_t); +static void blkxor(void *, const 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 blockmix_salsa8(const uint32_t *, uint32_t *, uint32_t *, size_t); +static uint64_t integerify(const void *, size_t); static void -blkcpy(void * dest, void * src, size_t len) +blkcpy(void * dest, const void * src, size_t len) { size_t * D = dest; - size_t * S = src; + const size_t * S = src; size_t L = len / sizeof(size_t); size_t i; @@ -64,10 +53,10 @@ blkcpy(void * dest, void * src, size_t len) } static void -blkxor(void * dest, void * src, size_t len) +blkxor(void * dest, const void * src, size_t len) { size_t * D = dest; - size_t * S = src; + const size_t * S = src; size_t L = len / sizeof(size_t); size_t i; @@ -126,7 +115,7 @@ salsa20_8(uint32_t B[16]) * temporary space X must be 64 bytes. */ static void -blockmix_salsa8(uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r) +blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r) { size_t i; @@ -158,27 +147,28 @@ blockmix_salsa8(uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r) * Return the result of parsing B_{2r-1} as a little-endian integer. */ static uint64_t -integerify(void * B, size_t r) +integerify(const void * B, size_t r) { - uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64); + const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64); return (((uint64_t)(X[1]) << 32) + X[0]); } /** - * smix(B, r, N, V, XY): + * crypto_scrypt_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) +void +crypto_scrypt_smix(uint8_t * B, size_t r, uint64_t N, void * _V, void * XY) { uint32_t * X = XY; - uint32_t * Y = &XY[32 * r]; - uint32_t * Z = &XY[64 * r]; + uint32_t * Y = (void *)((uint8_t *)(XY) + 128 * r); + uint32_t * Z = (void *)((uint8_t *)(XY) + 256 * r); + uint32_t * V = _V; uint64_t i; uint64_t j; size_t k; @@ -223,123 +213,3 @@ smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY) 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 _WIN32 -#undef HAVE_POSIX_MEMALIGN -#endif - -#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_scrypt_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_scrypt_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/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h b/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h new file mode 100644 index 0000000..b52067f --- /dev/null +++ b/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h @@ -0,0 +1,14 @@ +#ifndef _CRYPTO_SCRYPT_SMIX_H_ +#define _CRYPTO_SCRYPT_SMIX_H_ + +/** + * crypto_scrypt_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. + */ +void crypto_scrypt_smix(uint8_t *, size_t, uint64_t, void *, void *); + +#endif /* !_CRYPTO_SCRYPT_SMIX_H_ */ diff --git a/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c b/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c new file mode 100644 index 0000000..9fd0308 --- /dev/null +++ b/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c @@ -0,0 +1,247 @@ +/*- + * 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 "cpusupport.h" +#ifdef CPUSUPPORT_X86_SSE2 + +#include <emmintrin.h> +#include <stdint.h> + +#include "sysendian.h" + +#include "crypto_scrypt_smix_sse2.h" + +static void blkcpy(void *, const void *, size_t); +static void blkxor(void *, const void *, size_t); +static void salsa20_8(__m128i *); +static void blockmix_salsa8(const __m128i *, __m128i *, __m128i *, size_t); +static uint64_t integerify(const void *, size_t); + +static void +blkcpy(void * dest, const void * src, size_t len) +{ + __m128i * D = dest; + const __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, const void * src, size_t len) +{ + __m128i * D = dest; + const __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(const __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(const void * B, size_t r) +{ + const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64); + + return (((uint64_t)(X[13]) << 32) + X[0]); +} + +/** + * crypto_scrypt_smix_sse2(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. + * + * Use SSE2 instructions. + */ +void +crypto_scrypt_smix_sse2(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]); + } + } +} + +#endif /* CPUSUPPORT_X86_SSE2 */ diff --git a/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h b/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h new file mode 100644 index 0000000..eda43a4 --- /dev/null +++ b/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h @@ -0,0 +1,16 @@ +#ifndef _CRYPTO_SCRYPT_SMIX_SSE2_H_ +#define _CRYPTO_SCRYPT_SMIX_SSE2_H_ + +/** + * crypto_scrypt_smix_sse2(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. + * + * Use SSE2 instructions. + */ +void crypto_scrypt_smix_sse2(uint8_t *, size_t, uint64_t, void *, void *); + +#endif /* !_CRYPTO_SCRYPT_SMIX_SSE2_H_ */ diff --git a/scrypt-1.1.6/lib/scryptenc/scryptenc.c b/scrypt-1.2.0/lib/scryptenc/scryptenc.c similarity index 76% rename from scrypt-1.1.6/lib/scryptenc/scryptenc.c rename to scrypt-1.2.0/lib/scryptenc/scryptenc.c index c16a82c..fc58c48 100644 --- a/scrypt-1.1.6/lib/scryptenc/scryptenc.c +++ b/scrypt-1.2.0/lib/scryptenc/scryptenc.c @@ -35,28 +35,24 @@ #include <string.h> #include <unistd.h> -#include <openssl/aes.h> - +#include "crypto_aes.h" #include "crypto_aesctr.h" +#include "crypto_entropy.h" +#include "insecure_memzero.h" +#include "sha256.h" +#include "sysendian.h" + #include "crypto_scrypt.h" #include "memlimit.h" #include "scryptenc_cpuperf.h" -#include "sha256.h" -#include "sysendian.h" #include "scryptenc.h" -#ifdef _WIN32 -#include <windows.h> -#include <Wincrypt.h> -#endif - #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, @@ -90,7 +86,7 @@ pickparams(size_t maxmem, double maxmemfrac, double maxtime, * opslimit imposes the stronger limit on N. */ #ifdef DEBUG - fprintf(stderr, "Requiring 128Nr <= %u, 4Nrp <= %f\n", + fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n", memlimit, opslimit); #endif if (opslimit < memlimit/32) { @@ -117,7 +113,7 @@ pickparams(size_t maxmem, double maxmemfrac, double maxtime, } #ifdef DEBUG - fprintf(stderr, "N = %u r = %d p = %d\n", + fprintf(stderr, "N = %zu r = %d p = %d\n", (size_t)(1) << *logN, (int)(*r), (int)(*p)); #endif @@ -161,70 +157,6 @@ checkparams(size_t maxmem, double maxmemfrac, double maxtime, return (0); } -static int -getsalt(uint8_t salt[32]) -{ - int fd; - ssize_t lenread; - uint8_t * buf = salt; - size_t buflen = 32; - -#ifndef _WIN32 - /* 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); -#else - HCRYPTPROV context; - DWORD error; - - if(CryptAcquireContext(&context, NULL, NULL, PROV_RSA_AES, 0) == NTE_BAD_KEYSET) - { - if(!CryptAcquireContext(&context, NULL, NULL, PROV_RSA_AES, CRYPT_NEWKEYSET)) - { - error = GetLastError(); - printf("%x", error); - return (14); - } - } - - if(CryptGenRandom(context, 32, buf)) - { - buf += 32; - return (0); - } - else{return(15);} -#endif -} - static int scryptenc_setup(uint8_t header[96], uint8_t dk[64], const uint8_t * passwd, size_t passwdlen, @@ -236,9 +168,9 @@ scryptenc_setup(uint8_t header[96], uint8_t dk[64], uint64_t N; uint32_t r; uint32_t p; - scrypt_SHA256_CTX ctx; + SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; - HMAC_scrypt_SHA256_CTX hctx; + HMAC_SHA256_CTX hctx; int rc; /* Pick values for N, r, p. */ @@ -248,8 +180,8 @@ scryptenc_setup(uint8_t header[96], uint8_t dk[64], N = (uint64_t)(1) << logN; /* Get some salt. */ - if ((rc = getsalt(salt)) != 0) - return (rc); + if (crypto_entropy_read(salt, 32)) + return (4); /* Generate the derived keys. */ if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64)) @@ -264,15 +196,15 @@ scryptenc_setup(uint8_t header[96], uint8_t dk[64], memcpy(&header[16], salt, 32); /* Add header checksum. */ - scrypt_SHA256_Init(&ctx); - scrypt_SHA256_Update(&ctx, header, 48); - scrypt_SHA256_Final(hbuf, &ctx); + 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_scrypt_SHA256_Init(&hctx, key_hmac, 32); - HMAC_scrypt_SHA256_Update(&hctx, header, 64); - HMAC_scrypt_SHA256_Final(hbuf, &hctx); + HMAC_SHA256_Init(&hctx, key_hmac, 32); + HMAC_SHA256_Update(&hctx, header, 64); + HMAC_SHA256_Final(hbuf, &hctx); memcpy(&header[64], hbuf, 32); /* Success! */ @@ -290,9 +222,9 @@ scryptdec_setup(const uint8_t header[96], uint8_t dk[64], uint32_t r; uint32_t p; uint64_t N; - scrypt_SHA256_CTX ctx; + SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; - HMAC_scrypt_SHA256_CTX hctx; + HMAC_SHA256_CTX hctx; int rc; /* Parse N, r, p, salt. */ @@ -302,9 +234,9 @@ scryptdec_setup(const uint8_t header[96], uint8_t dk[64], memcpy(salt, &header[16], 32); /* Verify header checksum. */ - scrypt_SHA256_Init(&ctx); - scrypt_SHA256_Update(&ctx, header, 48); - scrypt_SHA256_Final(hbuf, &ctx); + SHA256_Init(&ctx); + SHA256_Update(&ctx, header, 48); + SHA256_Final(hbuf, &ctx); if (memcmp(&header[48], hbuf, 16)) return (7); @@ -322,9 +254,9 @@ scryptdec_setup(const uint8_t header[96], uint8_t dk[64], return (3); /* Check header signature (i.e., verify password). */ - HMAC_scrypt_SHA256_Init(&hctx, key_hmac, 32); - HMAC_scrypt_SHA256_Update(&hctx, header, 64); - HMAC_scrypt_SHA256_Final(hbuf, &hctx); + 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); @@ -349,8 +281,8 @@ scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; int rc; - HMAC_scrypt_SHA256_CTX hctx; - AES_KEY key_enc_exp; + HMAC_SHA256_CTX hctx; + struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; /* Generate the header and derived key. */ @@ -362,22 +294,22 @@ scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, memcpy(outbuf, header, 96); /* Encrypt data. */ - if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp)) + if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); - if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL) + if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); crypto_aesctr_stream(AES, inbuf, &outbuf[96], inbuflen); crypto_aesctr_free(AES); + crypto_aes_key_free(key_enc_exp); /* Add signature. */ - HMAC_scrypt_SHA256_Init(&hctx, key_hmac, 32); - HMAC_scrypt_SHA256_Update(&hctx, outbuf, 96 + inbuflen); - HMAC_scrypt_SHA256_Final(hbuf, &hctx); + 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)); + insecure_memzero(dk, 64); /* Success! */ return (0); @@ -386,7 +318,7 @@ scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, /** * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): - * Decrypt inbuflen bytes fro inbuf, writing the result into outbuf and the + * 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. */ @@ -400,8 +332,8 @@ scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; int rc; - HMAC_scrypt_SHA256_CTX hctx; - AES_KEY key_enc_exp; + HMAC_SHA256_CTX hctx; + struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; /* @@ -425,24 +357,24 @@ scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, return (rc); /* Decrypt data. */ - if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp)) + if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); - if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL) + 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); + crypto_aes_key_free(key_enc_exp); *outlen = inbuflen - 128; /* Verify signature. */ - HMAC_scrypt_SHA256_Init(&hctx, key_hmac, 32); - HMAC_scrypt_SHA256_Update(&hctx, inbuf, inbuflen - 32); - HMAC_scrypt_SHA256_Final(hbuf, &hctx); + 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)); + insecure_memzero(dk, 64); /* Success! */ return (0); @@ -466,8 +398,8 @@ scryptenc_file(FILE * infile, FILE * outfile, uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; size_t readlen; - HMAC_scrypt_SHA256_CTX hctx; - AES_KEY key_enc_exp; + HMAC_SHA256_CTX hctx; + struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; int rc; @@ -477,8 +409,8 @@ scryptenc_file(FILE * infile, FILE * outfile, return (rc); /* Hash and write the header. */ - HMAC_scrypt_SHA256_Init(&hctx, key_hmac, 32); - HMAC_scrypt_SHA256_Update(&hctx, header, 96); + HMAC_SHA256_Init(&hctx, key_hmac, 32); + HMAC_SHA256_Update(&hctx, header, 96); if (fwrite(header, 96, 1, outfile) != 1) return (12); @@ -486,32 +418,34 @@ scryptenc_file(FILE * infile, FILE * outfile, * 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)) + if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); - if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL) + 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_scrypt_SHA256_Update(&hctx, buf, readlen); - if (fwrite(buf, 1, readlen, outfile) < readlen) + HMAC_SHA256_Update(&hctx, buf, readlen); + if (fwrite(buf, 1, readlen, outfile) < readlen) { + crypto_aesctr_free(AES); return (12); + } } while (1); crypto_aesctr_free(AES); + crypto_aes_key_free(key_enc_exp); /* Did we exit the loop due to a read error? */ if (ferror(infile)) return (13); /* Compute the final HMAC and output it. */ - HMAC_scrypt_SHA256_Final(hbuf, &hctx); + 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)); + insecure_memzero(dk, 64); /* Success! */ return (0); @@ -536,13 +470,13 @@ scryptdec_file(FILE * infile, FILE * outfile, uint8_t * key_hmac = &dk[32]; size_t buflen = 0; size_t readlen; - HMAC_scrypt_SHA256_CTX hctx; - AES_KEY key_enc_exp; + HMAC_SHA256_CTX hctx; + struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; int rc; /* - * Read the first 7 bytes of the file; all future version of scrypt + * Read the first 7 bytes of the file; all future versions of scrypt * are guaranteed to have at least 7 bytes of header. */ if (fread(header, 7, 1, infile) < 1) { @@ -559,7 +493,7 @@ scryptdec_file(FILE * infile, FILE * outfile, return (8); /* - * Read another 89 bytes of the file; version 0 of the srypt file + * Read another 89 bytes of the file; version 0 of the scrypt file * format has a 96-byte header. */ if (fread(&header[7], 89, 1, infile) < 1) { @@ -575,8 +509,8 @@ scryptdec_file(FILE * infile, FILE * outfile, return (rc); /* Start hashing with the header. */ - HMAC_scrypt_SHA256_Init(&hctx, key_hmac, 32); - HMAC_scrypt_SHA256_Update(&hctx, header, 96); + 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, @@ -584,9 +518,9 @@ scryptdec_file(FILE * infile, FILE * outfile, * 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)) + if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); - if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL) + if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); do { /* Read data until we have more than 32 bytes of it. */ @@ -601,16 +535,19 @@ scryptdec_file(FILE * infile, FILE * outfile, * Decrypt, hash, and output everything except the last 32 * bytes out of what we have in our buffer. */ - HMAC_scrypt_SHA256_Update(&hctx, buf, buflen - 32); + HMAC_SHA256_Update(&hctx, buf, buflen - 32); crypto_aesctr_stream(AES, buf, buf, buflen - 32); - if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32) + if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32) { + crypto_aesctr_free(AES); 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); + crypto_aes_key_free(key_enc_exp); /* Did we exit the loop due to a read error? */ if (ferror(infile)) @@ -621,13 +558,12 @@ scryptdec_file(FILE * infile, FILE * outfile, return (7); /* Verify signature. */ - HMAC_scrypt_SHA256_Final(hbuf, &hctx); + 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)); + insecure_memzero(dk, 64); return (0); } diff --git a/scrypt-1.1.6/lib/scryptenc/scryptenc.h b/scrypt-1.2.0/lib/scryptenc/scryptenc.h similarity index 93% rename from scrypt-1.1.6/lib/scryptenc/scryptenc.h rename to scrypt-1.2.0/lib/scryptenc/scryptenc.h index 7dc3dd3..99090d4 100644 --- a/scrypt-1.1.6/lib/scryptenc/scryptenc.h +++ b/scrypt-1.2.0/lib/scryptenc/scryptenc.h @@ -32,6 +32,14 @@ #include <stdint.h> #include <stdio.h> +/** + * NOTE: This file provides prototypes for routines which encrypt/decrypt data + * using a key derived from a password by using the scrypt key derivation + * function. If you are just trying to "hash" a password for user logins, + * this is not the code you are looking for. You want to use the crypt_scrypt + * function directly. + */ + /** * The parameters maxmem, maxmemfrac, and maxtime used by all of these * functions are defined as follows: diff --git a/scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.c b/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c similarity index 95% rename from scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.c rename to scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c index 14d0d0a..1e69e75 100644 --- a/scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.c +++ b/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c @@ -38,13 +38,6 @@ #include "scryptenc_cpuperf.h" -#ifdef _WIN32 -struct timespec { - time_t tv_sec; - long tv_nsec; -}; -#endif - #ifdef HAVE_CLOCK_GETTIME static clock_t clocktouse; @@ -163,7 +156,7 @@ scryptenc_cpuperf(double * opps) break; } while (1); - /* Could how many scryps we can do before the next tick. */ + /* Count how many scrypts we can do before the next tick. */ if (getclocktime(&st)) return (2); do { @@ -182,7 +175,7 @@ scryptenc_cpuperf(double * opps) } while (1); #ifdef DEBUG - fprintf(stderr, "%u salsa20/8 cores performed in %f seconds\n", + fprintf(stderr, "%ju salsa20/8 cores performed in %f seconds\n", (uintmax_t)i, diffd); #endif diff --git a/scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.h b/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h similarity index 100% rename from scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.h rename to scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h diff --git a/scrypt-1.1.6/lib/util/memlimit.c b/scrypt-1.2.0/lib/util/memlimit.c similarity index 74% rename from scrypt-1.1.6/lib/util/memlimit.c rename to scrypt-1.2.0/lib/util/memlimit.c index 6268163..85c0607 100644 --- a/scrypt-1.1.6/lib/util/memlimit.c +++ b/scrypt-1.2.0/lib/util/memlimit.c @@ -32,9 +32,7 @@ #ifndef _WIN32 #include <sys/resource.h> -#endif - -#ifdef _WIN32 +#else #define _WIN32_WINNT 0x0502 #include <Windows.h> #include <tchar.h> @@ -43,7 +41,7 @@ #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> #endif -#ifdef HAVE_SYSCTL_HW_USERMEM +#ifdef HAVE_SYS_SYSCTL_H #include <sys/sysctl.h> #endif #ifdef HAVE_SYS_SYSINFO_H @@ -53,6 +51,7 @@ #include <errno.h> #include <stddef.h> #include <stdint.h> +#include <string.h> #include <unistd.h> #ifdef DEBUG @@ -61,43 +60,48 @@ #include "memlimit.h" -#ifdef HAVE_SYSCTL_HW_USERMEM +/* If we don't have CTL_HW, we can't use HW_USERMEM. */ +#ifndef CTL_HW +#undef HW_USERMEM +#endif + +#ifdef CTL_HW static int -memlimit_sysctl_hw_usermem(size_t * memlimit) +memlimit_sysctl_hw(size_t * memlimit, int mibleaf) { int mib[2]; - uint8_t usermembuf[8]; - size_t usermemlen = 8; - uint64_t usermem; + uint8_t sysctlbuf[8]; + size_t sysctlbuflen = 8; + uint64_t sysctlval; /* Ask the kernel how much RAM we have. */ mib[0] = CTL_HW; - mib[1] = HW_USERMEM; - if (sysctl(mib, 2, usermembuf, &usermemlen, NULL, 0)) + mib[1] = mibleaf; + if (sysctl(mib, 2, sysctlbuf, &sysctlbuflen, 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 we read 8 bytes out, assume this is a system-endian uint64_t. + * If we only read 4 bytes out, the OS is trying to give us a + * uint32_t answer -- but given how many systems now have 4GB+ of RAM, + * it's probably truncating, and we really can't trust the value we + * have returned to us. */ - if (usermemlen == sizeof(uint64_t)) - usermem = *(uint64_t *)usermembuf; - else if (usermemlen == sizeof(uint32_t)) - usermem = *(uint32_t *)usermembuf; + if (sysctlbuflen == sizeof(uint64_t)) + memcpy(&sysctlval, sysctlbuf, sizeof(uint64_t)); + else if (sysctlbuflen == sizeof(uint32_t)) + sysctlval = SIZE_MAX; else return (1); /* Return the sysctl value, but clamp to SIZE_MAX if necessary. */ #if UINT64_MAX > SIZE_MAX - if (usermem > SIZE_MAX) + if (sysctlval > SIZE_MAX) *memlimit = SIZE_MAX; else - *memlimit = usermem; + *memlimit = sysctlval; #else - *memlimit = usermem; + *memlimit = sysctlval; #endif /* Success! */ @@ -162,7 +166,7 @@ memlimit_rlimit(size_t * memlimit) if (getrlimit(RLIMIT_AS, &rl)) return (1); if ((rl.rlim_cur != RLIM_INFINITY) && - ((uint64_t)rl.rlim_cur < memrlimit)) + ((uint64_t)rl.rlim_cur < memrlimit)) memrlimit = rl.rlim_cur; #endif @@ -170,7 +174,7 @@ memlimit_rlimit(size_t * memlimit) if (getrlimit(RLIMIT_DATA, &rl)) return (1); if ((rl.rlim_cur != RLIM_INFINITY) && - ((uint64_t)rl.rlim_cur < memrlimit)) + ((uint64_t)rl.rlim_cur < memrlimit)) memrlimit = rl.rlim_cur; /* ... and RLIMIT_RSS. */ @@ -178,7 +182,7 @@ memlimit_rlimit(size_t * memlimit) if (getrlimit(RLIMIT_RSS, &rl)) return (1); if ((rl.rlim_cur != RLIM_INFINITY) && - ((uint64_t)rl.rlim_cur < memrlimit)) + ((uint64_t)rl.rlim_cur < memrlimit)) memrlimit = rl.rlim_cur; #endif @@ -216,7 +220,7 @@ memlimit_sysconf(size_t * memlimit) /* Read the two limits. */ if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) || - ((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) { + ((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) { /* Did an error occur? */ if (errno != 0) return (1); @@ -247,15 +251,15 @@ memlimit_sysconf(size_t * memlimit) static int memlimit_windows(size_t * memlimit) { - MEMORYSTATUSEX state; - state.dwLength = sizeof(state); + MEMORYSTATUSEX state; + state.dwLength = sizeof(state); - if(!GlobalMemoryStatusEx (&state)) - return (1); + if(!GlobalMemoryStatusEx (&state)) + return (1); - - *memlimit = state.ullTotalPhys; - return (0); + + *memlimit = state.ullTotalPhys; + return (0); } #endif @@ -263,54 +267,63 @@ memlimit_windows(size_t * memlimit) int memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit) { - size_t sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit; - size_t sysconf_memlimit; + size_t usermem_memlimit, memsize_memlimit; + size_t sysinfo_memlimit, rlimit_memlimit; + size_t sysconf_memlimit, windows_memlimit; size_t memlimit_min; size_t memavail; - size_t windows_memlimit; /* Get memory limits. */ -#ifdef HAVE_SYSCTL_HW_USERMEM - if (memlimit_sysctl_hw_usermem(&sysctl_memlimit)) +#ifdef HW_USERMEM + if (memlimit_sysctl_hw(&usermem_memlimit, HW_USERMEM)) + return (1); +#else + usermem_memlimit = SIZE_MAX; +#endif +#ifdef HW_MEMSIZE + if (memlimit_sysctl_hw(&memsize_memlimit, HW_MEMSIZE)) return (1); #else - sysctl_memlimit = (size_t)(-1); + memsize_memlimit = SIZE_MAX; #endif #ifdef HAVE_SYSINFO if (memlimit_sysinfo(&sysinfo_memlimit)) return (1); #else - sysinfo_memlimit = (size_t)(-1); + sysinfo_memlimit = SIZE_MAX; #endif #ifndef _WIN32 if (memlimit_rlimit(&rlimit_memlimit)) return (1); #else - rlimit_memlimit=(size_t)(-1); + rlimit_memlimit = SIZE_MAX; #endif #ifdef _SC_PHYS_PAGES if (memlimit_sysconf(&sysconf_memlimit)) return (1); #else - sysconf_memlimit = (size_t)(-1); + sysconf_memlimit = SIZE_MAX; #endif #ifdef _WIN32 - if (memlimit_windows(&windows_memlimit)) - return (1); + if (memlimit_windows(&windows_memlimit)) + return (1); #else - windows_memlimit=(size_t)(-1); + windows_memlimit = SIZE_MAX; #endif #ifdef DEBUG - fprintf(stderr, "Memory limits are %u %u %u %u %u\n", - sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit, - sysconf_memlimit, windows_memlimit); + fprintf(stderr, "Memory limits are %zu %zu %zu %zu %zu\n", + usermem_memlimit, memsize_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; + memlimit_min = SIZE_MAX; + if (memlimit_min > usermem_memlimit) + memlimit_min = usermem_memlimit; + if (memlimit_min > memsize_memlimit) + memlimit_min = memsize_memlimit; if (memlimit_min > sysinfo_memlimit) memlimit_min = sysinfo_memlimit; if (memlimit_min > rlimit_memlimit) @@ -334,7 +347,7 @@ memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit) memavail = 1048576; #ifdef DEBUG - fprintf(stderr, "Allowing up to %u memory to be used\n", memavail); + fprintf(stderr, "Allowing up to %zu memory to be used\n", memavail); #endif /* Return limit via the provided pointer. */ diff --git a/scrypt-1.1.6/lib/util/memlimit.h b/scrypt-1.2.0/lib/util/memlimit.h similarity index 100% rename from scrypt-1.1.6/lib/util/memlimit.h rename to scrypt-1.2.0/lib/util/memlimit.h diff --git a/scrypt-1.2.0/libcperciva/alg/sha256.c b/scrypt-1.2.0/libcperciva/alg/sha256.c new file mode 100644 index 0000000..e204501 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/alg/sha256.c @@ -0,0 +1,442 @@ +#include <assert.h> +#include <stdint.h> +#include <string.h> + +#include "insecure_memzero.h" +#include "sysendian.h" + +#include "sha256.h" + +/* + * Encode a length len/4 vector of (uint32_t) into a length len vector of + * (uint8_t) in big-endian form. Assumes len is a multiple of 4. + */ +static void +be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len) +{ + size_t i; + + /* Sanity-check. */ + assert(len % 4 == 0); + + /* Encode vector, one word at a time. */ + for (i = 0; i < len / 4; i++) + be32enc(dst + i * 4, src[i]); +} + +/* + * Decode a big-endian length len vector of (uint8_t) into a length + * len/4 vector of (uint32_t). Assumes len is a multiple of 4. + */ +static void +be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len) +{ + size_t i; + + /* Sanity-check. */ + assert(len % 4 == 0); + + /* Decode vector, one word at a time. */ + 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 uint8_t 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. */ + insecure_memzero(W, 256); + insecure_memzero(S, 32); + insecure_memzero(&t0, sizeof(uint32_t)); + insecure_memzero(&t1, sizeof(uint32_t)); +} + +static uint8_t 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) +{ + uint8_t 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. + */ + be64enc(len, ctx->count); + + /* Add 1--64 bytes so that the resulting length is 56 mod 64. */ + r = (ctx->count >> 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); +} + +/* Magic initialization constants. */ +static const uint32_t initstate[8] = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 +}; + +/** + * SHA256_Init(ctx): + * Initialize the SHA256 context ${ctx}. + */ +void +SHA256_Init(SHA256_CTX * ctx) +{ + + /* Zero bits processed so far. */ + ctx->count = 0; + + /* Initialize state. */ + memcpy(ctx->state, initstate, sizeof(initstate)); +} + +/** + * SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. + */ +void +SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len) +{ + uint32_t r; + const uint8_t * src = in; + + /* Return immediately if we have nothing to do. */ + if (len == 0) + return; + + /* Number of bytes left in the buffer from previous updates. */ + r = (ctx->count >> 3) & 0x3f; + + /* Update number of bits. */ + ctx->count += (uint64_t)(len) << 3; + + /* 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); +} + +/** + * SHA256_Final(digest, ctx): + * Output the SHA256 hash of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +void +SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx) +{ + + /* Add padding. */ + SHA256_Pad(ctx); + + /* Write the hash. */ + be32enc_vect(digest, ctx->state, 32); + + /* Clear the context state. */ + insecure_memzero(ctx, sizeof(SHA256_CTX)); +} + +/** + * SHA256_Buf(in, len, digest): + * Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}. + */ +void +SHA256_Buf(const void * in, size_t len, uint8_t digest[32]) +{ + SHA256_CTX ctx; + + SHA256_Init(&ctx); + SHA256_Update(&ctx, in, len); + SHA256_Final(digest, &ctx); +} + +/** + * HMAC_SHA256_Init(ctx, K, Klen): + * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from + * ${K}. + */ +void +HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) +{ + uint8_t pad[64]; + uint8_t khash[32]; + const uint8_t * 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. */ + insecure_memzero(khash, 32); + insecure_memzero(pad, 64); +} + +/** + * HMAC_SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. + */ +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); +} + +/** + * HMAC_SHA256_Final(digest, ctx): + * Output the HMAC-SHA256 of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +void +HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx) +{ + uint8_t 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. */ + insecure_memzero(ihash, 32); +} + +/** + * HMAC_SHA256_Buf(K, Klen, in, len, digest): + * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of + * length ${Klen}, and write the result to ${digest}. + */ +void +HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len, + uint8_t digest[32]) +{ + HMAC_SHA256_CTX ctx; + + HMAC_SHA256_Init(&ctx, K, Klen); + HMAC_SHA256_Update(&ctx, in, len); + HMAC_SHA256_Final(digest, &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 * 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; + + /* Sanity-check. */ + assert(dkLen <= 32 * (size_t)(UINT32_MAX)); + + /* 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. */ + insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX)); +} diff --git a/scrypt-1.2.0/libcperciva/alg/sha256.h b/scrypt-1.2.0/libcperciva/alg/sha256.h new file mode 100644 index 0000000..5cd824b --- /dev/null +++ b/scrypt-1.2.0/libcperciva/alg/sha256.h @@ -0,0 +1,95 @@ +#ifndef _SHA256_H_ +#define _SHA256_H_ + +#include <stddef.h> +#include <stdint.h> + +/* + * Use #defines in order to avoid namespace collisions with anyone else's + * SHA256 code (e.g., the code in OpenSSL). + */ +#define SHA256_Init libcperciva_SHA256_Init +#define SHA256_Update libcperciva_SHA256_Update +#define SHA256_Final libcperciva_SHA256_Final +#define SHA256_Buf libcperciva_SHA256_Buf +#define SHA256_CTX libcperciva_SHA256_CTX +#define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init +#define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update +#define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final +#define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf +#define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX + +/* Context structure for SHA256 operations. */ +typedef struct { + uint32_t state[8]; + uint64_t count; + uint8_t buf[64]; +} SHA256_CTX; + +/** + * SHA256_Init(ctx): + * Initialize the SHA256 context ${ctx}. + */ +void SHA256_Init(SHA256_CTX *); + +/** + * SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. + */ +void SHA256_Update(SHA256_CTX *, const void *, size_t); + +/** + * SHA256_Final(digest, ctx): + * Output the SHA256 hash of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +void SHA256_Final(uint8_t[32], SHA256_CTX *); + +/** + * SHA256_Buf(in, len, digest): + * Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}. + */ +void SHA256_Buf(const void *, size_t, uint8_t[32]); + +/* Context structure for HMAC-SHA256 operations. */ +typedef struct { + SHA256_CTX ictx; + SHA256_CTX octx; +} HMAC_SHA256_CTX; + +/** + * HMAC_SHA256_Init(ctx, K, Klen): + * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from + * ${K}. + */ +void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t); + +/** + * HMAC_SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. + */ +void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t); + +/** + * HMAC_SHA256_Final(digest, ctx): + * Output the HMAC-SHA256 of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *); + +/** + * HMAC_SHA256_Buf(K, Klen, in, len, digest): + * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of + * length ${Klen}, and write the result to ${digest}. + */ +void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[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 *, size_t, const uint8_t *, size_t, + uint64_t, uint8_t *, size_t); + +#endif /* !_SHA256_H_ */ diff --git a/scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h b/scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h new file mode 100644 index 0000000..36d3a07 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h @@ -0,0 +1,64 @@ +#ifndef _CPUSUPPORT_H_ +#define _CPUSUPPORT_H_ + +/* + * To enable support for non-portable CPU features at compile time, one or + * more CPUSUPPORT_ARCH_FEATURE macros should be defined. This can be done + * directly on the compiler command line; or a file can be created with the + * necessary #define lines and then -D CPUSUPPORT_CONFIG_FILE=cpuconfig.h + * (or similar) can be provided to include that file here. + */ +#ifdef CPUSUPPORT_CONFIG_FILE +#include CPUSUPPORT_CONFIG_FILE +#endif + +/* + * The CPUSUPPORT_FEATURE macro declares the necessary variables and + * functions for detecting CPU feature support at run time. The function + * defined in the macro acts to cache the result of the ..._detect function + * using the ..._present and ..._init variables. + */ +#define CPUSUPPORT_FEATURE(arch, feature) \ + extern int cpusupport_ ## arch ## _ ## feature ## _present; \ + extern int cpusupport_ ## arch ## _ ## feature ## _init; \ + int cpusupport_ ## arch ## _ ## feature ## _detect(void); \ + \ + static inline int \ + cpusupport_ ## arch ## _ ## feature(void) \ + { \ + \ + if (cpusupport_ ## arch ## _ ## feature ## _present) \ + return (1); \ + else if (cpusupport_ ## arch ## _ ## feature ## _init) \ + return (0); \ + cpusupport_ ## arch ## _ ## feature ## _present = \ + cpusupport_ ## arch ##_ ## feature ## _detect(); \ + cpusupport_ ## arch ## _ ## feature ## _init = 1; \ + return (cpusupport_ ## arch ## _ ## feature ## _present); \ + } \ + struct cpusupport_ ## arch ## _ ## feature ## _dummy + +/* + * CPUSUPPORT_FEATURE_DECL(arch, feature): + * Macro which defines variables and provides a function declaration for + * detecting the presence of "feature" on the "arch" architecture. The + * function body following this macro expansion must return nonzero if the + * feature is present, or zero if the feature is not present or the detection + * fails for any reason. + */ +#define CPUSUPPORT_FEATURE_DECL(arch, feature) \ + int cpusupport_ ## arch ## _ ## feature ## _present = 0; \ + int cpusupport_ ## arch ## _ ## feature ## _init = 0; \ + int \ + cpusupport_ ## arch ## _ ## feature ## _detect(void) + +/* + * Any features listed here must have associated C files compiled and linked + * in, since the macro references symbols which must be defined. Projects + * which do not need to detect certain CPU features may wish to remove lines + * from this list so that the associated C files can be omitted. + */ +CPUSUPPORT_FEATURE(x86, aesni); +CPUSUPPORT_FEATURE(x86, sse2); + +#endif /* !_CPUSUPPORT_H_ */ diff --git a/scrypt-1.2.0/libcperciva/crypto/crypto_aes.c b/scrypt-1.2.0/libcperciva/crypto/crypto_aes.c new file mode 100644 index 0000000..41d5e12 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/crypto/crypto_aes.c @@ -0,0 +1,166 @@ +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <openssl/aes.h> + +#include "cpusupport.h" +#include "crypto_aes_aesni.h" +#include "insecure_memzero.h" +#include "warnp.h" + +#include "crypto_aes.h" + +/** + * This represents either an AES_KEY or a struct crypto_aes_key_aesni; we + * know which it is based on whether we're using AESNI code or not. As such, + * it's just an opaque pointer; but declaring it as a named structure type + * prevents type-mismatch bugs in upstream code. + */ +struct crypto_aes_key; + +#ifdef CPUSUPPORT_X86_AESNI +/* Test whether OpenSSL and AESNI code produce the same AES ciphertext. */ +static int +aesnitest(uint8_t ptext[16], uint8_t * key, size_t keylen) +{ + AES_KEY kexp_openssl; + void * kexp_aesni; + uint8_t ctext_openssl[16]; + uint8_t ctext_aesni[16]; + + /* Expand the key. */ + AES_set_encrypt_key(key, keylen * 8, &kexp_openssl); + if ((kexp_aesni = crypto_aes_key_expand_aesni(key, keylen)) == NULL) + goto err0; + + /* Encrypt the block. */ + AES_encrypt(ptext, ctext_openssl, &kexp_openssl); + crypto_aes_encrypt_block_aesni(ptext, ctext_aesni, kexp_aesni); + + /* Free the AESNI expanded key. */ + crypto_aes_key_free_aesni(kexp_aesni); + + /* Do the outputs match? */ + return (memcmp(ctext_openssl, ctext_aesni, 16)); + +err0: + /* Failure! */ + return (-1); +} + +/* Should we use AESNI? */ +static int +useaesni(void) +{ + static int aesnigood = -1; + uint8_t key[32]; + uint8_t ptext[16]; + size_t i; + + /* If we haven't decided which code to use yet, decide now. */ + while (aesnigood == -1) { + /* Default to OpenSSL. */ + aesnigood = 0; + + /* If the CPU doesn't claim to support AESNI, stop here. */ + if (!cpusupport_x86_aesni()) + break; + + /* Test cases: key is 0x00010203..., ptext is 0x00112233... */ + for (i = 0; i < 16; i++) + ptext[i] = 0x11 * i; + for (i = 0; i < 32; i++) + key[i] = i; + + /* Test that AESNI and OpenSSL produce the same results. */ + if (aesnitest(ptext, key, 16) || aesnitest(ptext, key, 32)) { + warn0("Disabling AESNI due to failed self-test"); + break; + } + + /* AESNI works; use it. */ + aesnigood = 1; + } + + return (aesnigood); +} +#endif /* CPUSUPPORT_X86_AESNI */ + +/** + * crypto_aes_key_expand(key, len): + * Expand the ${len}-byte AES key ${key} into a structure which can be passed + * to crypto_aes_encrypt_block. The length must be 16 or 32. + */ +struct crypto_aes_key * +crypto_aes_key_expand(const uint8_t * key, size_t len) +{ + AES_KEY * kexp; + + /* Sanity-check. */ + assert((len == 16) || (len == 32)); + +#ifdef CPUSUPPORT_X86_AESNI + /* Use AESNI if we can. */ + if (useaesni()) + return (crypto_aes_key_expand_aesni(key, len)); +#endif + + /* Allocate structure. */ + if ((kexp = malloc(sizeof(AES_KEY))) == NULL) + goto err0; + + /* Expand the key. */ + AES_set_encrypt_key(key, len * 8, kexp); + + /* Success! */ + return ((void *)kexp); + +err0: + /* Failure! */ + return (NULL); +} + +/** + * crypto_aes_encrypt_block(in, out, key): + * Using the expanded AES key ${key}, encrypt the block ${in} and write the + * resulting ciphertext to ${out}. + */ +void +crypto_aes_encrypt_block(const uint8_t * in, uint8_t * out, + const struct crypto_aes_key * key) +{ + +#ifdef CPUSUPPORT_X86_AESNI + if (useaesni()) { + crypto_aes_encrypt_block_aesni(in, out, (const void *)key); + return; + } +#endif + + /* Get AES to do the work. */ + AES_encrypt(in, out, (const void *)key); +} + +/** + * crypto_aes_key_free(key): + * Free the expanded AES key ${key}. + */ +void +crypto_aes_key_free(struct crypto_aes_key * key) +{ + +#ifdef CPUSUPPORT_X86_AESNI + if (useaesni()) { + crypto_aes_key_free_aesni((void *)key); + return; + } +#endif + + /* Attempt to zero the expanded key. */ + insecure_memzero(key, sizeof(AES_KEY)); + + /* Free the key. */ + free(key); +} diff --git a/scrypt-1.2.0/libcperciva/crypto/crypto_aes.h b/scrypt-1.2.0/libcperciva/crypto/crypto_aes.h new file mode 100644 index 0000000..beaac65 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/crypto/crypto_aes.h @@ -0,0 +1,31 @@ +#ifndef _CRYPTO_AES_H_ +#define _CRYPTO_AES_H_ + +#include <stddef.h> +#include <stdint.h> + +/* Opaque structure. */ +struct crypto_aes_key; + +/** + * crypto_aes_key_expand(key, len): + * Expand the ${len}-byte AES key ${key} into a structure which can be passed + * to crypto_aes_encrypt_block. The length must be 16 or 32. + */ +struct crypto_aes_key * crypto_aes_key_expand(const uint8_t *, size_t); + +/** + * crypto_aes_encrypt_block(in, out, key): + * Using the expanded AES key ${key}, encrypt the block ${in} and write the + * resulting ciphertext to ${out}. + */ +void crypto_aes_encrypt_block(const uint8_t *, uint8_t *, + const struct crypto_aes_key *); + +/** + * crypto_aes_key_free(key): + * Free the expanded AES key ${key}. + */ +void crypto_aes_key_free(struct crypto_aes_key *); + +#endif /* !_CRYPTO_AES_H_ */ diff --git a/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c b/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c new file mode 100644 index 0000000..4559c1a --- /dev/null +++ b/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c @@ -0,0 +1,236 @@ +#include "cpusupport.h" +#ifdef CPUSUPPORT_X86_AESNI + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <wmmintrin.h> + +#include "insecure_memzero.h" +#include "warnp.h" + +#include "crypto_aes_aesni.h" + +/* Expanded-key structure. */ +struct crypto_aes_key_aesni { + uint8_t rkeys_buf[15 * sizeof(__m128i) + (sizeof(__m128i) - 1)]; + __m128i * rkeys; + size_t nr; +}; + +/* Compute an AES-128 round key. */ +#define MKRKEY128(rkeys, i, rcon) do { \ + __m128i _s = rkeys[i - 1]; \ + __m128i _t = rkeys[i - 1]; \ + _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \ + _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \ + _t = _mm_aeskeygenassist_si128(_t, rcon); \ + _t = _mm_shuffle_epi32(_t, 0xff); \ + rkeys[i] = _mm_xor_si128(_s, _t); \ +} while (0) + +/** + * crypto_aes_key_expand_128_aesni(key, rkeys): + * Expand the 128-bit AES key ${key} into the 11 round keys ${rkeys}. This + * implementation uses x86 AESNI instructions, and should only be used if + * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero. + */ +static void +crypto_aes_key_expand_128_aesni(const uint8_t key[16], __m128i rkeys[11]) +{ + + /* The first round key is just the key. */ + /** + * XXX Compiler breakage: + * The intrinsic defined by Intel for _mm_loadu_si128 defines it as + * taking a (const __m128i *) parameter. This forces us to write a + * bug: The cast to (const __m128i *) is invalid since it increases + * the alignment requirement of the pointer. Alas, until compilers + * get fixed intrinsics, all we can do is code the bug and require + * that alignment-requirement-increasing compiler warnings get + * disabled. + */ + rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]); + + /* + * Each of the remaining round keys are computed from the preceding + * round key: rotword+subword+rcon (provided as aeskeygenassist) to + * compute the 'temp' value, then xor with 1, 2, 3, or all 4 of the + * 32-bit words from the preceding round key. Unfortunately, 'rcon' + * is encoded as an immediate value, so we need to write the loop out + * ourselves rather than allowing the compiler to expand it. + */ + MKRKEY128(rkeys, 1, 0x01); + MKRKEY128(rkeys, 2, 0x02); + MKRKEY128(rkeys, 3, 0x04); + MKRKEY128(rkeys, 4, 0x08); + MKRKEY128(rkeys, 5, 0x10); + MKRKEY128(rkeys, 6, 0x20); + MKRKEY128(rkeys, 7, 0x40); + MKRKEY128(rkeys, 8, 0x80); + MKRKEY128(rkeys, 9, 0x1b); + MKRKEY128(rkeys, 10, 0x36); +} + +/* Compute an AES-256 round key. */ +#define MKRKEY256(rkeys, i, shuffle, rcon) do { \ + __m128i _s = rkeys[i - 2]; \ + __m128i _t = rkeys[i - 1]; \ + _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \ + _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \ + _t = _mm_aeskeygenassist_si128(_t, rcon); \ + _t = _mm_shuffle_epi32(_t, shuffle); \ + rkeys[i] = _mm_xor_si128(_s, _t); \ +} while (0) + +/** + * crypto_aes_key_expand_256_aesni(key, rkeys): + * Expand the 256-bit AES key ${key} into the 15 round keys ${rkeys}. This + * implementation uses x86 AESNI instructions, and should only be used if + * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero. + */ +static void +crypto_aes_key_expand_256_aesni(const uint8_t key[32], __m128i rkeys[15]) +{ + + /* The first two round keys are just the key. */ + /** + * XXX Compiler breakage: + * The intrinsic defined by Intel for _mm_loadu_si128 defines it as + * taking a (const __m128i *) parameter. This forces us to write a + * bug: The cast to (const __m128i *) is invalid since it increases + * the alignment requirement of the pointer. Alas, until compilers + * get fixed intrinsics, all we can do is code the bug and require + * that alignment-requirement-increasing compiler warnings get + * disabled. + */ + rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]); + rkeys[1] = _mm_loadu_si128((const __m128i *)&key[16]); + + /* + * Each of the remaining round keys are computed from the preceding + * pair of keys. Even rounds use rotword+subword+rcon, while odd + * rounds just use subword; the aeskeygenassist instruction computes + * both, and we use 0xff or 0xaa to select the one we need. The rcon + * value used is irrelevant for odd rounds since we ignore the value + * which it feeds into. Unfortunately, the 'shuffle' and 'rcon' + * values are encoded into the instructions as immediates, so we need + * to write the loop out ourselves rather than allowing the compiler + * to expand it. + */ + MKRKEY256(rkeys, 2, 0xff, 0x01); + MKRKEY256(rkeys, 3, 0xaa, 0x00); + MKRKEY256(rkeys, 4, 0xff, 0x02); + MKRKEY256(rkeys, 5, 0xaa, 0x00); + MKRKEY256(rkeys, 6, 0xff, 0x04); + MKRKEY256(rkeys, 7, 0xaa, 0x00); + MKRKEY256(rkeys, 8, 0xff, 0x08); + MKRKEY256(rkeys, 9, 0xaa, 0x00); + MKRKEY256(rkeys, 10, 0xff, 0x10); + MKRKEY256(rkeys, 11, 0xaa, 0x00); + MKRKEY256(rkeys, 12, 0xff, 0x20); + MKRKEY256(rkeys, 13, 0xaa, 0x00); + MKRKEY256(rkeys, 14, 0xff, 0x40); +} + +/** + * crypto_aes_key_expand_aesni(key, len): + * Expand the ${len}-byte AES key ${key} into a structure which can be passed + * to crypto_aes_encrypt_block_aesni. The length must be 16 or 32. This + * implementation uses x86 AESNI instructions, and should only be used if + * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero. + */ +void * +crypto_aes_key_expand_aesni(const uint8_t * key, size_t len) +{ + struct crypto_aes_key_aesni * kexp; + size_t rkey_offset; + + /* Allocate structure. */ + if ((kexp = malloc(sizeof(struct crypto_aes_key_aesni))) == NULL) + goto err0; + + /* Figure out where to put the round keys. */ + rkey_offset = (uintptr_t)(&kexp->rkeys_buf[0]) % sizeof(__m128i); + rkey_offset = (sizeof(__m128i) - rkey_offset) % sizeof(__m128i); + kexp->rkeys = (void *)&kexp->rkeys_buf[rkey_offset]; + + /* Compute round keys. */ + if (len == 16) { + kexp->nr = 10; + crypto_aes_key_expand_128_aesni(key, kexp->rkeys); + } else if (len == 32) { + kexp->nr = 14; + crypto_aes_key_expand_256_aesni(key, kexp->rkeys); + } else { + warn0("Unsupported AES key length: %zu bytes", len); + goto err1; + } + + /* Success! */ + return (kexp); + +err1: + free(kexp); +err0: + /* Failure! */ + return (NULL); +} + +/** + * crypto_aes_encrypt_block_aesni(in, out, key): + * Using the expanded AES key ${key}, encrypt the block ${in} and write the + * resulting ciphertext to ${out}. This implementation uses x86 AESNI + * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined + * and cpusupport_x86_aesni() returns nonzero. + */ +void +crypto_aes_encrypt_block_aesni(const uint8_t * in, uint8_t * out, + const void * key) +{ + const struct crypto_aes_key_aesni * _key = key; + const __m128i * aes_key = _key->rkeys; + __m128i aes_state; + size_t nr = _key->nr; + + aes_state = _mm_loadu_si128((const __m128i *)in); + aes_state = _mm_xor_si128(aes_state, aes_key[0]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[1]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[2]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[3]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[4]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[5]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[6]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[7]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[8]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[9]); + if (nr > 10) { + aes_state = _mm_aesenc_si128(aes_state, aes_key[10]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[11]); + + if (nr > 12) { + aes_state = _mm_aesenc_si128(aes_state, aes_key[12]); + aes_state = _mm_aesenc_si128(aes_state, aes_key[13]); + } + } + + aes_state = _mm_aesenclast_si128(aes_state, aes_key[nr]); + _mm_storeu_si128((__m128i *)out, aes_state); +} + +/** + * crypto_aes_key_free_aesni(key): + * Free the expanded AES key ${key}. + */ +void +crypto_aes_key_free_aesni(void * key) +{ + + /* Attempt to zero the expanded key. */ + insecure_memzero(key, sizeof(struct crypto_aes_key_aesni)); + + /* Free the key. */ + free(key); +} + +#endif /* CPUSUPPORT_X86_AESNI */ diff --git a/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h b/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h new file mode 100644 index 0000000..af5a55a --- /dev/null +++ b/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h @@ -0,0 +1,31 @@ +#ifndef _CRYPTO_AES_AESNI_H_ +#define _CRYPTO_AES_AESNI_H_ + +#include <stddef.h> +#include <stdint.h> + +/** + * crypto_aes_key_expand_aesni(key, len): + * Expand the ${len}-byte AES key ${key} into a structure which can be passed + * to crypto_aes_encrypt_block_aesni. The length must be 16 or 32. This + * implementation uses x86 AESNI instructions, and should only be used if + * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero. + */ +void * crypto_aes_key_expand_aesni(const uint8_t *, size_t); + +/** + * crypto_aes_encrypt_block_aesni(in, out, key): + * Using the expanded AES key ${key}, encrypt the block ${in} and write the + * resulting ciphertext to ${out}. This implementation uses x86 AESNI + * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined + * and cpusupport_x86_aesni() returns nonzero. + */ +void crypto_aes_encrypt_block_aesni(const uint8_t *, uint8_t *, const void *); + +/** + * crypto_aes_key_free_aesni(key): + * Free the expanded AES key ${key}. + */ +void crypto_aes_key_free_aesni(void *); + +#endif /* !_CRYPTO_AES_AESNI_H_ */ diff --git a/scrypt-1.1.6/lib/crypto/crypto_aesctr.c b/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c similarity index 53% rename from scrypt-1.1.6/lib/crypto/crypto_aesctr.c rename to scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c index 00db8f0..a8900f0 100644 --- a/scrypt-1.1.6/lib/crypto/crypto_aesctr.c +++ b/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c @@ -1,44 +1,13 @@ -/*- - * 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 "scrypt_platform.h" - #include <stdint.h> #include <stdlib.h> -#include <openssl/aes.h> - +#include "crypto_aes.h" #include "sysendian.h" #include "crypto_aesctr.h" struct crypto_aesctr { - AES_KEY * key; + const struct crypto_aes_key * key; uint64_t nonce; uint64_t bytectr; uint8_t buf[16]; @@ -51,7 +20,7 @@ struct crypto_aesctr { * lifetime of the stream. */ struct crypto_aesctr * -crypto_aesctr_init(AES_KEY * key, uint64_t nonce) +crypto_aesctr_init(const struct crypto_aes_key * key, uint64_t nonce) { struct crypto_aesctr * stream; @@ -94,7 +63,8 @@ crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf, if (bytemod == 0) { be64enc(pblk, stream->nonce); be64enc(pblk + 8, stream->bytectr / 16); - AES_encrypt(pblk, stream->buf, stream->key); + crypto_aes_encrypt_block(pblk, stream->buf, + stream->key); } /* Encrypt a byte. */ @@ -114,6 +84,10 @@ crypto_aesctr_free(struct crypto_aesctr * stream) { int i; + /* Be compatible with free(NULL). */ + if (stream == NULL) + return; + /* Zero potentially sensitive information. */ for (i = 0; i < 16; i++) stream->buf[i] = 0; @@ -122,3 +96,29 @@ crypto_aesctr_free(struct crypto_aesctr * stream) /* Free the stream. */ free(stream); } + +/** + * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen): + * Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free. + */ +void +crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce, + const uint8_t * inbuf, uint8_t * outbuf, size_t buflen) +{ + struct crypto_aesctr stream_rec; + struct crypto_aesctr * stream = &stream_rec; + int i; + + /* Initialize values. */ + stream->key = key; + stream->nonce = nonce; + stream->bytectr = 0; + + /* Perform the encryption. */ + crypto_aesctr_stream(stream, inbuf, outbuf, buflen); + + /* Zero potentially sensitive information. */ + for (i = 0; i < 16; i++) + stream->buf[i] = 0; + stream->bytectr = stream->nonce = 0; +} diff --git a/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h b/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h new file mode 100644 index 0000000..7ab9839 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h @@ -0,0 +1,41 @@ +#ifndef _CRYPTO_AESCTR_H_ +#define _CRYPTO_AESCTR_H_ + +#include <stddef.h> +#include <stdint.h> + +/* Opaque type. */ +struct crypto_aes_key; + +/** + * 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(const struct crypto_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 *); + +/** + * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen): + * Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free. + */ +void crypto_aesctr_buf(const struct crypto_aes_key *, uint64_t, + const uint8_t *, uint8_t *, size_t); + +#endif /* !_CRYPTO_AESCTR_H_ */ diff --git a/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c b/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c new file mode 100644 index 0000000..d9a3fba --- /dev/null +++ b/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c @@ -0,0 +1,215 @@ +#include <assert.h> +#include <stdint.h> +#include <string.h> + +#include "entropy.h" +#include "insecure_memzero.h" + +#include "sha256.h" + +#include "crypto_entropy.h" + +/** + * This system implements the HMAC_DRBG pseudo-random number generator as + * specified in section 10.1.2 of the NIST SP 800-90 standard. In this + * implementation, the optional personalization_string and additional_input + * specified in the standard are not implemented. + */ + +/* Internal HMAC_DRBG state. */ +static struct { + uint8_t Key[32]; + uint8_t V[32]; + uint32_t reseed_counter; +} drbg; + +/* Set to non-zero once the PRNG has been instantiated. */ +static int instantiated = 0; + +/* Could be as high as 2^48 if we wanted... */ +#define RESEED_INTERVAL 256 + +/* Limited to 2^16 by specification. */ +#define GENERATE_MAXLEN 65536 + +static int instantiate(void); +static void update(uint8_t *, size_t); +static int reseed(void); +static void generate(uint8_t *, size_t); + +/** + * instantiate(void): + * Initialize the DRBG state. (Section 10.1.2.3) + */ +static int +instantiate(void) +{ + uint8_t seed_material[48]; + + /* Obtain random seed_material = (entropy_input || nonce). */ + if (entropy_read(seed_material, 48)) + return (-1); + + /* Initialize Key, V, and reseed_counter. */ + memset(drbg.Key, 0x00, 32); + memset(drbg.V, 0x01, 32); + drbg.reseed_counter = 1; + + /* Mix the random seed into the state. */ + update(seed_material, 48); + + /* Clean the stack. */ + insecure_memzero(seed_material, 48); + + /* Success! */ + return (0); +} + +/** + * update(data, datalen): + * Update the DRBG state using the provided data. (Section 10.1.2.2) + */ +static void +update(uint8_t * data, size_t datalen) +{ + HMAC_SHA256_CTX ctx; + uint8_t K[32]; + uint8_t Vx[33]; + + /* Load (Key, V) into (K, Vx). */ + memcpy(K, drbg.Key, 32); + memcpy(Vx, drbg.V, 32); + + /* K <- HMAC(K, V || 0x00 || data). */ + Vx[32] = 0x00; + HMAC_SHA256_Init(&ctx, K, 32); + HMAC_SHA256_Update(&ctx, Vx, 33); + HMAC_SHA256_Update(&ctx, data, datalen); + HMAC_SHA256_Final(K, &ctx); + + /* V <- HMAC(K, V). */ + HMAC_SHA256_Buf(K, 32, Vx, 32, Vx); + + /* If the provided data is non-Null, perform another mixing stage. */ + if (datalen != 0) { + /* K <- HMAC(K, V || 0x01 || data). */ + Vx[32] = 0x01; + HMAC_SHA256_Init(&ctx, K, 32); + HMAC_SHA256_Update(&ctx, Vx, 33); + HMAC_SHA256_Update(&ctx, data, datalen); + HMAC_SHA256_Final(K, &ctx); + + /* V <- HMAC(K, V). */ + HMAC_SHA256_Buf(K, 32, Vx, 32, Vx); + } + + /* Copy (K, Vx) back to (Key, V). */ + memcpy(drbg.Key, K, 32); + memcpy(drbg.V, Vx, 32); + + /* Clean the stack. */ + insecure_memzero(K, 32); + insecure_memzero(Vx, 33); +} + +/** + * reseed(void): + * Reseed the DRBG state (mix in new entropy). (Section 10.1.2.4) + */ +static int +reseed(void) +{ + uint8_t seed_material[32]; + + /* Obtain random seed_material = entropy_input. */ + if (entropy_read(seed_material, 32)) + return (-1); + + /* Mix the random seed into the state. */ + update(seed_material, 32); + + /* Reset the reseed_counter. */ + drbg.reseed_counter = 1; + + /* Clean the stack. */ + insecure_memzero(seed_material, 32); + + /* Success! */ + return (0); +} + +/** + * generate(buf, buflen): + * Fill the provided buffer with random bits, assuming that reseed_counter + * is less than RESEED_INTERVAL (the caller is responsible for calling + * reseed() as needed) and ${buflen} is less than 2^16 (the caller is + * responsible for splitting up larger requests). (Section 10.1.2.5) + */ +static void +generate(uint8_t * buf, size_t buflen) +{ + size_t bufpos; + + assert(buflen <= GENERATE_MAXLEN); + assert(drbg.reseed_counter <= RESEED_INTERVAL); + + /* Iterate until we've filled the buffer. */ + for (bufpos = 0; bufpos < buflen; bufpos += 32) { + HMAC_SHA256_Buf(drbg.Key, 32, drbg.V, 32, drbg.V); + if (buflen - bufpos >= 32) + memcpy(&buf[bufpos], drbg.V, 32); + else + memcpy(&buf[bufpos], drbg.V, buflen - bufpos); + } + + /* Mix up state. */ + update(NULL, 0); + + /* We're one data-generation step closer to needing a reseed. */ + drbg.reseed_counter += 1; +} + +/** + * crypto_entropy_read(buf, buflen): + * Fill the buffer with unpredictable bits. + */ +int +crypto_entropy_read(uint8_t * buf, size_t buflen) +{ + size_t bytes_to_provide; + + /* Instantiate if needed. */ + if (instantiated == 0) { + /* Try to instantiate the PRNG. */ + if (instantiate()) + return (-1); + + /* We have instantiated the PRNG. */ + instantiated = 1; + } + + /* Loop until we've filled the buffer. */ + while (buflen > 0) { + /* Do we need to reseed? */ + if (drbg.reseed_counter > RESEED_INTERVAL) { + if (reseed()) + return (-1); + } + + /* How much data are we generating in this step? */ + if (buflen > GENERATE_MAXLEN) + bytes_to_provide = GENERATE_MAXLEN; + else + bytes_to_provide = buflen; + + /* Generate bytes. */ + generate(buf, bytes_to_provide); + + /* We've done part of the buffer. */ + buf += bytes_to_provide; + buflen -= bytes_to_provide; + } + + /* Success! */ + return (0); +} diff --git a/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h b/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h new file mode 100644 index 0000000..1137710 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h @@ -0,0 +1,14 @@ +#ifndef _CRYPTO_ENTROPY_H_ +#define _CRYPTO_ENTROPY_H_ + +#include <stddef.h> +#include <stdint.h> + +/** + * crypto_entropy_read(buf, buflen): + * Fill the buffer with unpredictable bits. The value ${buflen} must be + * less than 2^16. + */ +int crypto_entropy_read(uint8_t *, size_t); + +#endif /* !_CRYPTO_ENTROPY_H_ */ diff --git a/scrypt-1.2.0/libcperciva/util/entropy.c b/scrypt-1.2.0/libcperciva/util/entropy.c new file mode 100644 index 0000000..2195be1 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/util/entropy.c @@ -0,0 +1,105 @@ +#include <fcntl.h> +#include <limits.h> +#include <stdint.h> +#include <unistd.h> + +#include "warnp.h" + +#include "entropy.h" + +#ifdef _WIN32 +#include <windows.h> +#include <Wincrypt.h> +#endif + +/** + * XXX Portability + * XXX We obtain random bytes from the operating system by opening + * XXX /dev/urandom and reading them from that device; this works on + * XXX modern UNIX-like operating systems but not on systems like + * XXX win32 where there is no concept of /dev/urandom. + */ + +/** + * entropy_read(buf, buflen): + * Fill the given buffer with random bytes provided by the operating system. + */ +int +entropy_read(uint8_t * buf, size_t buflen) +{ + int fd; + ssize_t lenread; + +#ifndef _WIN32 + /* Sanity-check the buffer size. */ + if (buflen > SSIZE_MAX) { + warn0("Programmer error: " + "Trying to read insane amount of random data: %zu", + buflen); + goto err0; + } + + /* Open /dev/urandom. */ + if ((fd = open("/dev/urandom", O_RDONLY)) == -1) { + warnp("open(/dev/urandom)"); + goto err0; + } + + /* Read bytes until we have filled the buffer. */ + while (buflen > 0) { + if ((lenread = read(fd, buf, buflen)) == -1) { + warnp("read(/dev/urandom)"); + goto err1; + } + + /* The random device should never EOF. */ + if (lenread == 0) { + warn0("EOF on /dev/urandom?"); + goto err1; + } + + /* We've filled a portion of the buffer. */ + buf += lenread; + buflen -= lenread; + } + + /* Close the device. */ + while (close(fd) == -1) { + if (errno != EINTR) { + warnp("close(/dev/urandom)"); + goto err0; + } + } + + /* Success! */ + return (0); + +err1: + close(fd); +err0: + /* Failure! */ + return (-1); + +#else // _WIN32 + + HCRYPTPROV context; + DWORD error; + + if(CryptAcquireContext(&context, NULL, NULL, PROV_RSA_AES, 0) == NTE_BAD_KEYSET) + { + if(!CryptAcquireContext(&context, NULL, NULL, PROV_RSA_AES, CRYPT_NEWKEYSET)) + { + error = GetLastError(); + return (-1); + } + } + + if(CryptGenRandom(context, 32, buf)) + { + buf += 32; + return (0); + } + else{return(-1);} + +#endif // _WIN32 +} diff --git a/scrypt-1.2.0/libcperciva/util/entropy.h b/scrypt-1.2.0/libcperciva/util/entropy.h new file mode 100644 index 0000000..fa6f1cf --- /dev/null +++ b/scrypt-1.2.0/libcperciva/util/entropy.h @@ -0,0 +1,13 @@ +#ifndef _ENTROPY_H_ +#define _ENTROPY_H_ + +#include <stddef.h> +#include <stdint.h> + +/** + * entropy_read(buf, buflen): + * Fill the given buffer with random bytes provided by the operating system. + */ +int entropy_read(uint8_t *, size_t); + +#endif /* !_ENTROPY_H_ */ diff --git a/scrypt-1.2.0/libcperciva/util/insecure_memzero.c b/scrypt-1.2.0/libcperciva/util/insecure_memzero.c new file mode 100644 index 0000000..bd26bac --- /dev/null +++ b/scrypt-1.2.0/libcperciva/util/insecure_memzero.c @@ -0,0 +1,19 @@ +#include <stddef.h> +#include <stdint.h> + +#include "insecure_memzero.h" + +/* Function which does the zeroing. */ +static void +insecure_memzero_func(volatile void * buf, size_t len) +{ + volatile uint8_t * _buf = buf; + size_t i; + + for (i = 0; i < len; i++) + _buf[i] = 0; +} + +/* Pointer to memory-zeroing function. */ +void (* volatile insecure_memzero_ptr)(volatile void *, size_t) = + insecure_memzero_func; diff --git a/scrypt-1.2.0/libcperciva/util/insecure_memzero.h b/scrypt-1.2.0/libcperciva/util/insecure_memzero.h new file mode 100644 index 0000000..1c3f06b --- /dev/null +++ b/scrypt-1.2.0/libcperciva/util/insecure_memzero.h @@ -0,0 +1,37 @@ +#ifndef _INSECURE_MEMZERO_H_ +#define _INSECURE_MEMZERO_H_ + +#include <stddef.h> + +/* Pointer to memory-zeroing function. */ +extern void (* volatile insecure_memzero_ptr)(volatile void *, size_t); + +/** + * insecure_memzero(buf, len): + * Attempt to zero ${len} bytes at ${buf} in spite of optimizing compilers' + * best (standards-compliant) attempts to remove the buffer-zeroing. In + * particular, to avoid performing the zeroing, a compiler would need to + * use optimistic devirtualization; recognize that non-volatile objects do not + * need to be treated as volatile, even if they are accessed via volatile + * qualified pointers; and perform link-time optimization; in addition to the + * dead-code elimination which often causes buffer-zeroing to be elided. + * + * Note however that zeroing a buffer does not guarantee that the data held + * in the buffer is not stored elsewhere; in particular, there may be copies + * held in CPU registers or in anonymous allocations on the stack, even if + * every named variable is successfully sanitized. Solving the "wipe data + * from the system" problem will require a C language extension which does not + * yet exist. + * + * For more information, see: + * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html + * http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html + */ +static inline void +insecure_memzero(volatile void * buf, size_t len) +{ + + (insecure_memzero_ptr)(buf, len); +} + +#endif /* !_INSECURE_MEMZERO_H_ */ diff --git a/scrypt-1.2.0/libcperciva/util/sysendian.h b/scrypt-1.2.0/libcperciva/util/sysendian.h new file mode 100644 index 0000000..7bed2f5 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/util/sysendian.h @@ -0,0 +1,146 @@ +#ifndef _SYSENDIAN_H_ +#define _SYSENDIAN_H_ + +#include <stdint.h> + +/* Avoid namespace collisions with BSD <sys/endian.h>. */ +#define be16dec libcperciva_be16dec +#define be16enc libcperciva_be16enc +#define be32dec libcperciva_be32dec +#define be32enc libcperciva_be32enc +#define be64dec libcperciva_be64dec +#define be64enc libcperciva_be64enc +#define le16dec libcperciva_le16dec +#define le16enc libcperciva_le16enc +#define le32dec libcperciva_le32dec +#define le32enc libcperciva_le32enc +#define le64dec libcperciva_le64dec +#define le64enc libcperciva_le64enc + +static inline uint16_t +be16dec(const void * pp) +{ + const uint8_t * p = (uint8_t const *)pp; + + return ((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8)); +} + +static inline void +be16enc(void * pp, uint16_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[1] = x & 0xff; + p[0] = (x >> 8) & 0xff; +} + +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 uint16_t +le16dec(const void * pp) +{ + const uint8_t * p = (uint8_t const *)pp; + + return ((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8)); +} + +static inline void +le16enc(void * pp, uint16_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[0] = x & 0xff; + p[1] = (x >> 8) & 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 /* !_SYSENDIAN_H_ */ diff --git a/scrypt-1.2.0/libcperciva/util/warnp.c b/scrypt-1.2.0/libcperciva/util/warnp.c new file mode 100644 index 0000000..2ec5a57 --- /dev/null +++ b/scrypt-1.2.0/libcperciva/util/warnp.c @@ -0,0 +1,76 @@ +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "warnp.h" + +static int initialized = 0; +static char * name = NULL; + +/* Free the name string. */ +static void +done(void) +{ + + free(name); + name = NULL; +} + +/** + * warnp_setprogname(progname): + * Set the program name to be used by warn() and warnx() to ${progname}. + */ +void +warnp_setprogname(const char * progname) +{ + const char * p; + + /* Free the name if we already have one. */ + free(name); + + /* Find the last segment of the program name. */ + for (p = progname; progname[0] != '\0'; progname++) + if (progname[0] == '/') + p = progname + 1; + + /* Copy the name string. */ + name = strdup(p); + + /* If we haven't already done so, register our exit handler. */ + if (initialized == 0) { + atexit(done); + initialized = 1; + } +} + +void +warn(const char * fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)"); + 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", (name != NULL) ? name : "(unknown)"); + if (fmt != NULL) { + fprintf(stderr, ": "); + vfprintf(stderr, fmt, ap); + } + fprintf(stderr, "\n"); + va_end(ap); +} diff --git a/scrypt-1.2.0/libcperciva/util/warnp.h b/scrypt-1.2.0/libcperciva/util/warnp.h new file mode 100644 index 0000000..2dadbdf --- /dev/null +++ b/scrypt-1.2.0/libcperciva/util/warnp.h @@ -0,0 +1,59 @@ +#ifndef _WARNP_H_ +#define _WARNP_H_ + +#include <errno.h> + +/* Avoid namespace collisions with BSD <err.h>. */ +#define warn libcperciva_warn +#define warnx libcperciva_warnx + +/** + * warnp_setprogname(progname): + * Set the program name to be used by warn() and warnx() to ${progname}. + */ +void warnp_setprogname(const char *); +#define WARNP_INIT do { \ + if (argv[0] != NULL) \ + warnp_setprogname(argv[0]); \ +} while (0) + +/* As in BSD <err.h>. */ +void warn(const char *, ...); +void warnx(const char *, ...); + +/* + * If compiled with DEBUG defined, print __FILE__ and __LINE__. + */ +#ifdef DEBUG +#define warnline do { \ + warnx("%s, %d", __FILE__, __LINE__); \ +} while (0) +#else +#define warnline +#endif + +/* + * Call warn(3) or warnx(3) depending upon whether errno == 0; and clear + * errno (so that the standard error message isn't repeated later). + */ +#define warnp(...) do { \ + warnline; \ + if (errno != 0) { \ + warn(__VA_ARGS__); \ + errno = 0; \ + } else \ + warnx(__VA_ARGS__); \ +} while (0) + +/* + * Call warnx(3) and set errno == 0. Unlike warnp, this should be used + * in cases where we're reporting a problem which we discover ourselves + * rather than one which is reported to us from a library or the kernel. + */ +#define warn0(...) do { \ + warnline; \ + warnx(__VA_ARGS__); \ + errno = 0; \ +} while (0) + +#endif /* !_WARNP_H_ */ diff --git a/scrypt-1.1.6/scrypt_platform.h b/scrypt-1.2.0/scrypt_platform.h similarity index 100% rename from scrypt-1.1.6/scrypt_platform.h rename to scrypt-1.2.0/scrypt_platform.h diff --git a/scrypt.egg-info/PKG-INFO b/scrypt.egg-info/PKG-INFO new file mode 100644 index 0000000..fae8de3 --- /dev/null +++ b/scrypt.egg-info/PKG-INFO @@ -0,0 +1,141 @@ +Metadata-Version: 1.1 +Name: scrypt +Version: 0.8.0 +Summary: Bindings for the scrypt key derivation function library +Home-page: http://bitbucket.org/mhallin/py-scrypt +Author: Magnus Hallin +Author-email: mhallin@gmail.com +License: 2-clause BSD +Description: ========================= + Python scrypt_ bindings + ========================= + + This is a set of Python_ bindings for the scrypt_ key derivation + function. + + Scrypt is useful when encrypting password as it is possible to specify + a *minimum* amount of time to use when encrypting and decrypting. If, + for example, a password takes 0.05 seconds to verify, a user won't + notice the slight delay when signing in, but doing a brute force + search of several billion passwords will take a considerable amount of + time. This is in contrast to more traditional hash functions such as + MD5 or the SHA family which can be implemented extremely fast on cheap + hardware. + + Installation + ============ + + You can install py-scrypt from this repository if you want the latest + but possibly non-compiling version:: + + $ hg clone http://bitbucket.org/mhallin/py-scrypt + $ cd py-scrypt + $ python setup.py build + + Become superuser (or use virtualenv): + # python setup.py install + + Run tests after install: + $ python setup.py test + + Or you can install the latest release from PyPi:: + + $ pip install scrypt + + If you want py-scrypt for your Python 3 environment, just run the + above commands with your Python 3 interpreter. Py-scrypt supports both + Python 2 and 3. + + From version 0.6.0 (not available on PyPi yet), py-scrypt supports + PyPy as well. + + Usage + ===== + + Fore encryption/decryption, the library exports two functions + ``encrypt`` and ``decrypt``:: + + >>> import scrypt + >>> data = scrypt.encrypt('a secret message', 'password', maxtime=0.1) # This will take at least 0.1 seconds + >>> data[:20] + 'scrypt\x00\r\x00\x00\x00\x08\x00\x00\x00\x01RX9H' + >>> scrypt.decrypt(data, 'password', maxtime=0.1) # This will also take at least 0.1 seconds + 'a secret message' + >>> scrypt.decrypt(data, 'password', maxtime=0.05) # scrypt won't be able to decrypt this data fast enough + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + scrypt.error: decrypting file would take too long + >>> scrypt.decrypt(data, 'wrong password', maxtime=0.1) # scrypt will throw an exception if the password is incorrect + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + scrypt.error: password is incorrect + + From these, one can make a simple password verifier using the following + functions:: + + def hash_password(password, maxtime=0.5, datalength=64): + return scrypt.encrypt(os.urandom(datalength), password, maxtime=maxtime) + + def verify_password(hashed_password, guessed_password, maxtime=0.5): + try: + scrypt.decrypt(hashed_password, guessed_password, maxtime) + return True + except scrypt.error: + return False + + + But, if you want output that is deterministic and constant in size, + you can use the ``hash`` function:: + + >>> import scrypt + >>> h1 = scrypt.hash('password', 'random salt') + >>> len(h1) # The hash will be 64 bytes by default, but is overridable. + 64 + >>> h1[:10] + '\xfe\x87\xf3hS\tUo\xcd\xc8' + >>> h2 = scrypt.hash('password', 'random salt') + >>> h1 == h2 # The hash function is deterministic + True + + + Acknowledgements + ================ + + Scrypt_ was created by Colin Percival and is licensed as 2-clause BSD. + Since scrypt does not normally build as a shared library, I have included + the source for the currently latest version of the library in this + repository. When a new version arrives, I will update these sources. + + `Kelvin Wong`_ on Bitbucket provided changes to make the library + available on Mac OS X 10.6 and earlier, as well as changes to make the + library work more like the command-line version of scrypt by + default. Kelvin also contributed with the unit tests, lots of cross + platform testing and work on the ``hash`` function. + + Burstaholic_ on Bitbucket provided the necessary changes to make + the library build on Windows. + + The `python-appveyor-demo`_ repository for setting up automated Windows + builds for a multitude of Python versions. + + License + ======= + + This library is licensed under the same license as scrypt; 2-clause BSD. + + .. _scrypt: http://www.tarsnap.com/scrypt.html + .. _Python: http://python.org + .. _Burstaholic: https://bitbucket.org/Burstaholic + .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca + .. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo + +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Topic :: Security :: Cryptography +Classifier: Topic :: Software Development :: Libraries diff --git a/scrypt.egg-info/SOURCES.txt b/scrypt.egg-info/SOURCES.txt new file mode 100644 index 0000000..f5f190d --- /dev/null +++ b/scrypt.egg-info/SOURCES.txt @@ -0,0 +1,47 @@ +MANIFEST.in +README.rst +scrypt.py +setup.py +scrypt-1.2.0/config.h +scrypt-1.2.0/scrypt_platform.h +scrypt-1.2.0/lib/crypto/crypto_scrypt.c +scrypt-1.2.0/lib/crypto/crypto_scrypt.h +scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c +scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h +scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c +scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h +scrypt-1.2.0/lib/scryptenc/scryptenc.c +scrypt-1.2.0/lib/scryptenc/scryptenc.h +scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c +scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h +scrypt-1.2.0/lib/util/memlimit.c +scrypt-1.2.0/lib/util/memlimit.h +scrypt-1.2.0/libcperciva/alg/sha256.c +scrypt-1.2.0/libcperciva/alg/sha256.h +scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h +scrypt-1.2.0/libcperciva/crypto/crypto_aes.c +scrypt-1.2.0/libcperciva/crypto/crypto_aes.h +scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c +scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h +scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c +scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h +scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c +scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h +scrypt-1.2.0/libcperciva/util/entropy.c +scrypt-1.2.0/libcperciva/util/entropy.h +scrypt-1.2.0/libcperciva/util/insecure_memzero.c +scrypt-1.2.0/libcperciva/util/insecure_memzero.h +scrypt-1.2.0/libcperciva/util/sysendian.h +scrypt-1.2.0/libcperciva/util/warnp.c +scrypt-1.2.0/libcperciva/util/warnp.h +scrypt.egg-info/PKG-INFO +scrypt.egg-info/SOURCES.txt +scrypt.egg-info/dependency_links.txt +scrypt.egg-info/top_level.txt +src/scrypt.c +tests/__init__.py +tests/ciphertexts.csv +tests/hashvectors.csv +tests/test_scrypt.py +tests/test_scrypt_py2x.py +tests/test_scrypt_py3x.py \ No newline at end of file diff --git a/scrypt.egg-info/dependency_links.txt b/scrypt.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/scrypt.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/scrypt.egg-info/top_level.txt b/scrypt.egg-info/top_level.txt new file mode 100644 index 0000000..b2329f8 --- /dev/null +++ b/scrypt.egg-info/top_level.txt @@ -0,0 +1,2 @@ +_scrypt +scrypt diff --git a/scrypt.py b/scrypt.py index d504400..cda17ff 100644 --- a/scrypt.py +++ b/scrypt.py @@ -89,7 +89,7 @@ def _ensure_bytes(data): return bytes(data, 'utf-8') return data - + def encrypt(input, password, maxtime=MAXTIME_DEFAULT_ENC, diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..861a9f5 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[egg_info] +tag_build = +tag_date = 0 +tag_svn_revision = 0 + diff --git a/setup.py b/setup.py index 0190808..32ccbe9 100644 --- a/setup.py +++ b/setup.py @@ -1,45 +1,16 @@ #!/usr/bin/env python -from distutils.core import setup, Extension, Command +from setuptools import setup, Extension import sys import platform +import struct includes = [] library_dirs = [] -cmdclasses = dict() +extra_sources = [] CFLAGS = [] -class Tester(Command): - """Runs unit tests""" - - user_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - if ((sys.version_info > (3, 2, 0, 'final', 0)) or - (sys.version_info > (2, 7, 0, 'final', 0) and sys.version_info < (3, 0, 0, 'final', 0))): - from unittest import TextTestRunner, defaultTestLoader - else: - try: - from unittest2 import TextTestRunner, defaultTestLoader - except ImportError: - print("Please install unittest2 to run the test suite") - exit(-1) - from tests import test_scrypt, test_scrypt_py2x, test_scrypt_py3x - suite = defaultTestLoader.loadTestsFromModule(test_scrypt) - suite.addTests(defaultTestLoader.loadTestsFromModule(test_scrypt_py2x)) - suite.addTests(defaultTestLoader.loadTestsFromModule(test_scrypt_py3x)) - runner = TextTestRunner() - result = runner.run(suite) - -cmdclasses['test'] = Tester - if sys.platform.startswith('linux'): define_macros = [('HAVE_CLOCK_GETTIME', '1'), ('HAVE_LIBRT', '1'), @@ -53,10 +24,17 @@ if sys.platform.startswith('linux'): libraries = ['crypto', 'rt'] CFLAGS.append('-O2') elif sys.platform.startswith('win32'): - define_macros = [] - library_dirs = ['c:\OpenSSL-Win32\lib\MinGW'] - libraries = ['eay32'] - includes = ['c:\OpenSSL-Win32\include'] + define_macros = [('inline', '__inline')] + libraries = ['libeay32', 'advapi32'] + extra_sources = ['scrypt-windows-stubs/gettimeofday.c'] + + if struct.calcsize('P') == 8: + library_dirs = ['c:\OpenSSL-Win64\lib'] + includes = ['c:\OpenSSL-Win64\include', 'scrypt-windows-stubs/include'] + else: + library_dirs = ['c:\OpenSSL-Win32\lib'] + includes = ['c:\OpenSSL-Win32\include', 'scrypt-windows-stubs/include'] + elif sys.platform.startswith('darwin') and platform.mac_ver()[0] < '10.6': define_macros = [('HAVE_SYSCTL_HW_USERMEM', '1')] libraries = ['crypto'] @@ -65,27 +43,39 @@ else: ('HAVE_SYSCTL_HW_USERMEM', '1')] libraries = ['crypto'] -scrypt_module = Extension('_scrypt', - sources=['src/scrypt.c', - 'scrypt-1.1.6/lib/crypto/crypto_aesctr.c', - 'scrypt-1.1.6/lib/crypto/crypto_scrypt-nosse.c', - 'scrypt-1.1.6/lib/crypto/sha256.c', - 'scrypt-1.1.6/lib/scryptenc/scryptenc.c', - 'scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.c', - 'scrypt-1.1.6/lib/util/memlimit.c', - 'scrypt-1.1.6/lib/util/warn.c'], - include_dirs=['scrypt-1.1.6', - 'scrypt-1.1.6/lib', - 'scrypt-1.1.6/lib/scryptenc', - 'scrypt-1.1.6/lib/crypto', - 'scrypt-1.1.6/lib/util'] + includes, - define_macros=[('HAVE_CONFIG_H', None)] + define_macros, - extra_compile_args=CFLAGS, - library_dirs=library_dirs, - libraries=libraries) +scrypt_module = Extension( + '_scrypt', + sources=['src/scrypt.c', + 'scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c', + 'scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c', + 'scrypt-1.2.0/lib/crypto/crypto_scrypt.c', + 'scrypt-1.2.0/lib/scryptenc/scryptenc.c', + 'scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c', + 'scrypt-1.2.0/lib/util/memlimit.c', + 'scrypt-1.2.0/libcperciva/alg/sha256.c', + 'scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c', + 'scrypt-1.2.0/libcperciva/crypto/crypto_aes.c', + 'scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c', + 'scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c', + 'scrypt-1.2.0/libcperciva/util/entropy.c', + 'scrypt-1.2.0/libcperciva/util/insecure_memzero.c', + 'scrypt-1.2.0/libcperciva/util/warnp.c'] + extra_sources, + include_dirs=['scrypt-1.2.0', + 'scrypt-1.2.0/lib', + 'scrypt-1.2.0/lib/scryptenc', + 'scrypt-1.2.0/lib/crypto', + 'scrypt-1.2.0/lib/util', + 'scrypt-1.2.0/libcperciva/cpusupport', + 'scrypt-1.2.0/libcperciva/alg', + 'scrypt-1.2.0/libcperciva/util', + 'scrypt-1.2.0/libcperciva/crypto'] + includes, + define_macros=[('HAVE_CONFIG_H', None)] + define_macros, + extra_compile_args=CFLAGS, + library_dirs=library_dirs, + libraries=libraries) setup(name='scrypt', - version='0.6.1', + version='0.8.0', description='Bindings for the scrypt key derivation function library', author='Magnus Hallin', author_email='mhallin@gmail.com', @@ -95,11 +85,12 @@ setup(name='scrypt', classifiers=['Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', 'Topic :: Security :: Cryptography', 'Topic :: Software Development :: Libraries'], license='2-clause BSD', long_description=open('README.rst').read(), - cmdclass=cmdclasses) + test_suite='tests.all_tests') diff --git a/src/scrypt.c b/src/scrypt.c index 69d6816..0ffad2e 100644 --- a/src/scrypt.c +++ b/src/scrypt.c @@ -67,8 +67,32 @@ DL_EXPORT(int) exp_crypto_scrypt(const uint8_t *passwd, size_t passwdlen, /* We need a stub init_scrypt function so the module will link as a proper module. - - Do not import _scrypt from python; it will not work since _scrypt is not a *real* module */ -PyMODINIT_FUNC init_scrypt(void) { } -PyMODINIT_FUNC PyInit__scrypt(void) { } + +static PyMethodDef scrypt_methods[] = { + {NULL, NULL, 0, NULL}, +}; + +#if PY_MAJOR_VERSION == 2 + +PyMODINIT_FUNC init_scrypt(void) { + Py_InitModule("_scrypt", scrypt_methods); +} + +#endif + +#if PY_MAJOR_VERSION == 3 + +static struct PyModuleDef scrypt_module = { + PyModuleDef_HEAD_INIT, + "_scrypt", + NULL, + -1, + scrypt_methods +}; + +PyMODINIT_FUNC PyInit__scrypt(void) { + return PyModule_Create(&scrypt_module); +} + +#endif diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..720e56b 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,36 @@ +from sys import version_info, exit + +from .test_scrypt import TestScrypt, TestScryptHash +from .test_scrypt_c_module import TestScryptCModule +from .test_scrypt_py2x import TestScryptForPython2 +from .test_scrypt_py3x import TestScryptForPy3 + +if ((version_info > (3, 2, 0, 'final', 0)) or + (version_info > (2, 7, 0, 'final', 0) and + version_info < (3, 0, 0, 'final', 0))): + import unittest as testm +else: + try: + import unittest2 as testm + except ImportError: + print("Please install unittest2 to run the test suite") + exit(-1) + + +def all_tests(): + suite = testm.TestSuite() + loader = testm.TestLoader() + + test_classes = [ + TestScrypt, + TestScryptCModule, + TestScryptHash, + TestScryptForPython2, + TestScryptForPy3, + ] + + for cls in test_classes: + tests = loader.loadTestsFromTestCase(cls) + suite.addTests(tests) + + return suite diff --git a/tests/test_scrypt.py b/tests/test_scrypt.py index 4c5a207..47a46b9 100644 --- a/tests/test_scrypt.py +++ b/tests/test_scrypt.py @@ -2,14 +2,15 @@ from os import urandom from os.path import dirname, abspath, sep -from sys import version_info +from sys import version_info, exit from csv import reader from binascii import a2b_hex, b2a_hex -import base64 -import json + +import scrypt if ((version_info > (3, 2, 0, 'final', 0)) or - (version_info > (2, 7, 0, 'final', 0) and version_info < (3, 0, 0, 'final', 0))): + (version_info > (2, 7, 0, 'final', 0) and + version_info < (3, 0, 0, 'final', 0))): import unittest as testm else: try: @@ -18,8 +19,6 @@ else: print("Please install unittest2 to run the test suite") exit(-1) -import scrypt - class TestScrypt(testm.TestCase): diff --git a/tests/test_scrypt_py2x.py b/tests/test_scrypt_py2x.py index 811cf37..73fddca 100644 --- a/tests/test_scrypt_py2x.py +++ b/tests/test_scrypt_py2x.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- -from sys import version_info +from sys import version_info, exit + +import scrypt if ((version_info > (3, 2, 0, 'final', 0)) or - (version_info > (2, 7, 0, 'final', 0) and version_info < (3, 0, 0, 'final', 0))): + (version_info > (2, 7, 0, 'final', 0) and + version_info < (3, 0, 0, 'final', 0))): import unittest as testm else: try: @@ -12,8 +15,6 @@ else: print("Please install unittest2 to run the test suite") exit(-1) -import scrypt - @testm.skipIf(version_info > (3, 0, 0, 'final', 0), "Tests for Python 2 only") class TestScryptForPython2(testm.TestCase): diff --git a/tests/test_scrypt_py3x.py b/tests/test_scrypt_py3x.py index e03e098..ec05f06 100644 --- a/tests/test_scrypt_py3x.py +++ b/tests/test_scrypt_py3x.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- -from sys import version_info +from sys import version_info, exit + +import scrypt if ((version_info > (3, 2, 0, 'final', 0)) or - (version_info > (2, 7, 0, 'final', 0) and version_info < (3, 0, 0, 'final', 0))): + (version_info > (2, 7, 0, 'final', 0) and + version_info < (3, 0, 0, 'final', 0))): import unittest as testm else: try: @@ -12,8 +15,6 @@ else: print("Please install unittest2 to run the test suite") exit(-1) -import scrypt - @testm.skipIf(version_info < (3, 0, 0, 'final', 0), "Tests for Python 3 only") class TestScryptForPy3(testm.TestCase): -- GitLab