Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 30 Jun 2013 21:05:29 +0400
From: Solar Designer <solar@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: Re: scrypt

On Sun, Jun 30, 2013 at 08:37:25PM +0400, Solar Designer wrote:
> So I went ahead and implemented cleaner and better (but still far from
> perfect) scrypt support for John the Ripper.

I forgot to mention that it's faster than Rafael's due to preserving and
reusing of memory allocation(s) across scrypt computations.  My escrypt,
which I had shared with Rafael, readily had this functionality - it only
needed to be made use of in the format.

And indeed there's OpenMP support, which somehow was missing in Rafael's
format.

> I've attached patch against the core tree.

I've now attached a newer revision of it.  The only changes since the
revision I posted some minutes ago are to escrypt/crypto_scrypt-sse.c
(more complete removal of the experimental defeat_tmto feature, which we
don't need in JtR yet) and escrypt/Makefile.

Alexander

diff -urpN john-1.8.0.1/src/Makefile john-1.8.0.1-scrypt/src/Makefile
--- john-1.8.0.1/src/Makefile	2013-06-02 22:06:20.000000000 +0000
+++ john-1.8.0.1-scrypt/src/Makefile	2013-06-30 16:46:46.706959086 +0000
@@ -42,6 +42,9 @@ JOHN_OBJS = \
 	BSDI_fmt.o \
 	MD5_fmt.o MD5_std.o \
 	BF_fmt.o BF_std.o \
+	scrypt_fmt.o \
+	escrypt/crypto_scrypt-best.o escrypt/crypto_scrypt-common.o \
+	escrypt/sha256.o \
 	AFS_fmt.o \
 	LM_fmt.o \
 	trip_fmt.o \
@@ -909,7 +912,7 @@ john.o: john.c
 	$(CC) $(CFLAGS_MAIN) $(OPT_NORMAL) $*.c
 
 .c.o:
-	$(CC) $(CFLAGS) $(OPT_NORMAL) $*.c
+	$(CC) $(CFLAGS) $(OPT_NORMAL) $< -o $@
 
 .S.o:
 	$(AS) $(ASFLAGS) $*.S
@@ -926,7 +929,7 @@ depend:
 
 clean:
 	$(RM) $(PROJ) $(PROJ_DOS) $(PROJ_WIN32)
-	$(RM) ../run/john.exe john-macosx-* *.o *.bak core
+	$(RM) ../run/john.exe john-macosx-* *.o escrypt/*.o *.bak core
 	$(RM) detect bench generic.h arch.h tmp.s
 	$(CP) $(NULL) Makefile.dep
 
diff -urpN john-1.8.0.1/src/escrypt/Makefile john-1.8.0.1-scrypt/src/escrypt/Makefile
--- john-1.8.0.1/src/escrypt/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/Makefile	2013-06-30 16:43:32.495120134 +0000
@@ -0,0 +1,47 @@
+# Copyright 2013 Alexander Peslyak
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted.
+#
+# 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.
+
+CC = gcc
+LD = $(CC)
+RM = rm -f
+CFLAGS = -Wall -march=native -O2 -fomit-frame-pointer
+#CFLAGS = -Wall -O2 -fomit-frame-pointer
+LDFLAGS = -s
+
+PROJ = tests
+OBJS_TESTS = crypto_scrypt-best.o crypto_scrypt-common.o sha256.o tests.o
+OBJS_RM = crypto_scrypt-*.o
+
+all: $(PROJ)
+
+tests: $(OBJS_TESTS)
+	$(LD) $(LDFLAGS) $(OBJS_TESTS) -o $@
+
+check: tests
+	./tests
+
+.c.o:
+	$(CC) -c $(CFLAGS) $*.c
+
+crypto_scrypt-best.o: scrypt_platform.c \
+    crypto_scrypt-sse.c crypto_scrypt-nosse.c
+crypto_scrypt-sse.o: scrypt_platform.c
+crypto_scrypt-nosse.o: scrypt_platform.c
+
+clean:
+	$(RM) $(PROJ) $(OBJS_TESTS) $(OBJS_RM)
diff -urpN john-1.8.0.1/src/escrypt/crypto_scrypt-best.c john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-best.c
--- john-1.8.0.1/src/escrypt/crypto_scrypt-best.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-best.c	2013-06-30 12:11:32.807860982 +0000
@@ -0,0 +1,5 @@
+#ifdef __SSE2__
+#include "crypto_scrypt-sse.c"
+#else
+#include "crypto_scrypt-nosse.c"
+#endif
diff -urpN john-1.8.0.1/src/escrypt/crypto_scrypt-common.c john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-common.c
--- john-1.8.0.1/src/escrypt/crypto_scrypt-common.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-common.c	2013-06-30 12:06:14.779766386 +0000
@@ -0,0 +1,252 @@
+/*-
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * 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 <stdint.h>
+#include <string.h>
+
+#include "crypto_scrypt.h"
+
+#define BYTES2CHARS(bytes) \
+	((((bytes) * 8) + 5) / 6)
+
+#define HASH_SIZE 32 /* bytes */
+#define HASH_LEN BYTES2CHARS(HASH_SIZE) /* base-64 chars */
+
+static const char * const itoa64 =
+	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static uint8_t * encode64_uint32(uint8_t * dst, size_t dstlen,
+    uint32_t src, uint32_t srcbits)
+{
+	uint32_t bit;
+
+	for (bit = 0; bit < srcbits; bit += 6) {
+		if (dstlen < 1)
+			return NULL;
+		*dst++ = itoa64[src & 0x3f];
+		dstlen--;
+		src >>= 6;
+	}
+
+	return dst;
+}
+
+static uint8_t * encode64(uint8_t * dst, size_t dstlen,
+    const uint8_t * src, size_t srclen)
+{
+	size_t i;
+
+	for (i = 0; i < srclen; ) {
+		uint8_t * dnext;
+		uint32_t value = 0, bits = 0;
+		do {
+			value |= (uint32_t)src[i++] << bits;
+			bits += 8;
+		} while (bits < 24 && i < srclen);
+		dnext = encode64_uint32(dst, dstlen, value, bits);
+		if (!dnext)
+			return NULL;
+		dstlen -= dnext - dst;
+		dst = dnext;
+	}
+
+	return dst;
+}
+
+static int decode64_one(uint32_t * dst, uint8_t src)
+{
+	const char * ptr = strchr(itoa64, src);
+	if (ptr) {
+		*dst = ptr - itoa64;
+		return 0;
+	}
+	*dst = 0;
+	return -1;
+}
+
+static const uint8_t * decode64_uint32(uint32_t * dst, uint32_t dstbits,
+    const uint8_t * src)
+{
+	uint32_t bit;
+	uint32_t value;
+
+	value = 0;
+	for (bit = 0; bit < dstbits; bit += 6) {
+		uint32_t one;
+		if (decode64_one(&one, *src)) {
+			*dst = 0;
+			return NULL;
+		}
+		src++;
+		value |= one << bit;
+	}
+
+	*dst = value;
+	return src;
+}
+
+uint8_t *
+escrypt_r(escrypt_local_t * local,
+    const uint8_t * passwd, size_t passwdlen,
+    const uint8_t * setting,
+    uint8_t * buf, size_t buflen)
+{
+	uint8_t hash[HASH_SIZE];
+	const uint8_t * src, * salt;
+	uint8_t * dst;
+	size_t prefixlen, saltlen, need;
+	uint64_t N;
+	uint32_t r, p;
+
+	if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$')
+		return NULL;
+	src = setting + 3;
+
+	{
+		uint32_t N_log2;
+		if (decode64_one(&N_log2, *src))
+			return NULL;
+		src++;
+		N = (uint64_t)1 << N_log2;
+	}
+
+	src = decode64_uint32(&r, 30, src);
+	if (!src)
+		return NULL;
+
+	src = decode64_uint32(&p, 30, src);
+	if (!src)
+		return NULL;
+
+	prefixlen = src - setting;
+
+	salt = src;
+	src = (uint8_t *)strrchr((char *)salt, '$');
+	if (src)
+		saltlen = src - salt;
+	else
+		saltlen = strlen((char *)salt);
+
+	need = prefixlen + saltlen + 1 + HASH_LEN + 1;
+	if (need > buflen || need < saltlen)
+		return NULL;
+
+	if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
+	    N, r, p, hash, sizeof(hash)))
+		return NULL;
+
+	dst = buf;
+	memcpy(dst, setting, prefixlen + saltlen);
+	dst += prefixlen + saltlen;
+	*dst++ = '$';
+
+	dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash));
+	/* Could zeroize hash[] here, but escrypt_kdf() doesn't zeroize its
+	 * memory allocations yet anyway. */
+	if (!dst || dst >= buf + buflen) /* Can't happen */
+		return NULL;
+
+	*dst = 0; /* NUL termination */
+
+	return buf;
+}
+
+uint8_t *
+escrypt(const uint8_t * passwd, const uint8_t * setting)
+{
+	static uint8_t buf[4 + 1 + 5 + 5 + BYTES2CHARS(32) + 1 + HASH_LEN + 1];
+	escrypt_local_t local;
+	uint8_t * retval;
+
+	if (escrypt_init_local(&local))
+		return NULL;
+	retval = escrypt_r(&local,
+	    passwd, strlen((char *)passwd), setting, buf, sizeof(buf));
+	if (escrypt_free_local(&local))
+		return NULL;
+	return retval;
+}
+
+uint8_t *
+escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p,
+    const uint8_t * src, size_t srclen,
+    uint8_t * buf, size_t buflen)
+{
+	uint8_t * dst;
+	size_t prefixlen = 3 + 1 + 5 + 5;
+	size_t saltlen = BYTES2CHARS(srclen);
+	size_t need;
+
+	need = prefixlen + saltlen + 1;
+	if (need > buflen || need < saltlen || saltlen < srclen)
+		return NULL;
+
+	if (N_log2 > 63 || ((uint64_t)r * (uint64_t)p >= (1U << 30)))
+		return NULL;
+
+	dst = buf;
+	*dst++ = '$';
+	*dst++ = '7';
+	*dst++ = '$';
+
+	*dst++ = itoa64[N_log2];
+
+	dst = encode64_uint32(dst, buflen - (dst - buf), r, 30);
+	if (!dst) /* Can't happen */
+		return NULL;
+
+	dst = encode64_uint32(dst, buflen - (dst - buf), p, 30);
+	if (!dst) /* Can't happen */
+		return NULL;
+
+	dst = encode64(dst, buflen - (dst - buf), src, srclen);
+	if (!dst || dst >= buf + buflen) /* Can't happen */
+		return NULL;
+
+	*dst = 0; /* NUL termination */
+
+	return buf;
+}
+
+uint8_t *
+escrypt_gensalt(uint32_t N_log2, uint32_t r, uint32_t p,
+    const uint8_t * src, size_t srclen)
+{
+	static uint8_t buf[4 + 1 + 5 + 5 + BYTES2CHARS(32) + 1];
+	return escrypt_gensalt_r(N_log2, r, p, src, srclen,
+	    buf, sizeof(buf));
+}
+
+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)
+{
+	escrypt_local_t local;
+	int retval;
+
+	if (escrypt_init_local(&local))
+		return -1;
+	retval = escrypt_kdf(&local,
+	    passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen);
+	if (escrypt_free_local(&local))
+		return -1;
+	return retval;
+}
diff -urpN john-1.8.0.1/src/escrypt/crypto_scrypt-nosse.c john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-nosse.c
--- john-1.8.0.1/src/escrypt/crypto_scrypt-nosse.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-nosse.c	2013-06-30 11:59:43.607781819 +0000
@@ -0,0 +1,300 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha256.h"
+#include "sysendian.h"
+
+#include "crypto_scrypt.h"
+
+#include "scrypt_platform.c"
+
+static inline void
+blkcpy(void * dest, const void * src, size_t len)
+{
+	size_t * D = dest;
+	const size_t * S = src;
+	size_t L = len / sizeof(size_t);
+	size_t i;
+
+	for (i = 0; i < L; i++)
+		D[i] = S[i];
+}
+
+static inline void
+blkxor(void * dest, const void * src, size_t len)
+{
+	size_t * D = dest;
+	const size_t * S = src;
+	size_t L = len / sizeof(size_t);
+	size_t i;
+
+	for (i = 0; i < L; i++)
+		D[i] ^= S[i];
+}
+
+/**
+ * salsa20_8(B):
+ * Apply the salsa20/8 core to the provided block.
+ */
+static void
+salsa20_8(uint32_t B[16])
+{
+	uint32_t x[16];
+	size_t i;
+
+	blkcpy(x, B, 64);
+	for (i = 0; i < 8; i += 2) {
+#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+		/* Operate on columns. */
+		x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);
+		x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);
+
+		x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);
+		x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);
+
+		x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);
+		x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);
+
+		x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);
+		x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);
+
+		/* Operate on rows. */
+		x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);
+		x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);
+
+		x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);
+		x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);
+
+		x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);
+		x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);
+
+		x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);
+		x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);
+#undef R
+	}
+	for (i = 0; i < 16; i++)
+		B[i] += x[i];
+}
+
+/**
+ * blockmix_salsa8(Bin, Bout, X, r):
+ * Compute Bout = BlockMix_{salsa20/8, r}(Bin).  The input Bin must be 128r
+ * bytes in length; the output Bout must also be the same size.  The
+ * temporary space X must be 64 bytes.
+ */
+static void
+blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r)
+{
+	size_t i;
+
+	/* 1: X <-- B_{2r - 1} */
+	blkcpy(X, &Bin[(2 * r - 1) * 16], 64);
+
+	/* 2: for i = 0 to 2r - 1 do */
+	for (i = 0; i < 2 * r; i += 2) {
+		/* 3: X <-- H(X \xor B_i) */
+		blkxor(X, &Bin[i * 16], 64);
+		salsa20_8(X);
+
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		blkcpy(&Bout[i * 8], X, 64);
+
+		/* 3: X <-- H(X \xor B_i) */
+		blkxor(X, &Bin[i * 16 + 16], 64);
+		salsa20_8(X);
+
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		blkcpy(&Bout[i * 8 + r * 16], X, 64);
+	}
+}
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ */
+static inline 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[1]) << 32) + X[0]);
+}
+
+/**
+ * smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
+ * the temporary storage V must be 128rN bytes in length; the temporary
+ * storage XY must be 256r + 64 bytes in length.  The value N must be a
+ * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
+ * multiple of 64 bytes.
+ */
+static void
+smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY)
+{
+	uint32_t * X = XY;
+	uint32_t * Y = &XY[32 * r];
+	uint32_t * Z = &XY[64 * r];
+	uint64_t i;
+	uint64_t j;
+	size_t k;
+
+	/* 1: X <-- B */
+	for (k = 0; k < 32 * r; k++)
+		X[k] = le32dec(&B[4 * k]);
+
+	/* 2: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i += 2) {
+		/* 3: V_i <-- X */
+		blkcpy(&V[i * (32 * r)], X, 128 * r);
+
+		/* 4: X <-- H(X) */
+		blockmix_salsa8(X, Y, Z, r);
+
+		/* 3: V_i <-- X */
+		blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r);
+
+		/* 4: X <-- H(X) */
+		blockmix_salsa8(Y, X, Z, r);
+	}
+
+	/* 6: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i += 2) {
+		/* 7: j <-- Integerify(X) mod N */
+		j = integerify(X, r) & (N - 1);
+
+		/* 8: X <-- H(X \xor V_j) */
+		blkxor(X, &V[j * (32 * r)], 128 * r);
+		blockmix_salsa8(X, Y, Z, r);
+
+		/* 7: j <-- Integerify(X) mod N */
+		j = integerify(Y, r) & (N - 1);
+
+		/* 8: X <-- H(X \xor V_j) */
+		blkxor(Y, &V[j * (32 * r)], 128 * r);
+		blockmix_salsa8(Y, X, Z, r);
+	}
+
+	/* 10: B' <-- X */
+	for (k = 0; k < 32 * r; k++)
+		le32enc(&B[4 * k], X[k]);
+}
+
+/**
+ * escrypt_kdf(local, 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
+escrypt_kdf(escrypt_local_t * local,
+    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)
+{
+	size_t B_size, V_size, XY_size, need;
+	uint8_t * B;
+	uint32_t * V, * XY;
+	uint32_t i;
+
+	/* Sanity-check parameters. */
+#if SIZE_MAX > UINT32_MAX
+	if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
+		errno = EFBIG;
+		return -1;
+	}
+#endif
+	if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
+		errno = EFBIG;
+		return -1;
+	}
+	if (((N & (N - 1)) != 0) || (N == 0)) {
+		errno = EINVAL;
+		return -1;
+	}
+	if ((r > SIZE_MAX / 128 / p) ||
+#if SIZE_MAX / 256 <= UINT32_MAX
+	    (r > SIZE_MAX / 256) ||
+#endif
+	    (N > SIZE_MAX / 128 / r)) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	/* Allocate memory. */
+	B_size = (size_t)128 * r * p;
+	V_size = (size_t)128 * r * N;
+	need = B_size + V_size;
+	if (need < V_size) {
+		errno = ENOMEM;
+		return -1;
+	}
+	XY_size = (size_t)256 * r;
+	need += XY_size;
+	if (need < XY_size) {
+		errno = ENOMEM;
+		return -1;
+	}
+	if (local->size < need) {
+		if (free_region(local))
+			return -1;
+		if (!alloc_region(local, need))
+			return -1;
+	}
+	B = (uint8_t *)local->aligned;
+	V = (uint32_t *)((uint8_t *)B + B_size);
+	XY = (uint32_t *)((uint8_t *)V + V_size);
+
+	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+	PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size);
+
+	/* 2: for i = 0 to p - 1 do */
+	for (i = 0; i < p; i++) {
+		/* 3: B_i <-- MF(B_i, N) */
+		smix(&B[(size_t)128 * i * r], r, N, V, XY);
+	}
+
+	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+	PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen);
+
+	/* Success! */
+	return 0;
+}
diff -urpN john-1.8.0.1/src/escrypt/crypto_scrypt-ref.c john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-ref.c
--- john-1.8.0.1/src/escrypt/crypto_scrypt-ref.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-ref.c	2013-06-30 12:00:20.743773750 +0000
@@ -0,0 +1,299 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha256.h"
+#include "sysendian.h"
+
+#include "crypto_scrypt.h"
+
+static void
+blkcpy(uint8_t * dest, const uint8_t * src, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++)
+		dest[i] = src[i];
+}
+
+static void
+blkxor(uint8_t * dest, const uint8_t * src, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++)
+		dest[i] ^= src[i];
+}
+
+/**
+ * salsa20_8(B):
+ * Apply the salsa20/8 core to the provided block.
+ */
+static void
+salsa20_8(uint8_t B[64])
+{
+	uint32_t B32[16];
+	uint32_t x[16];
+	size_t i;
+
+	/* Convert little-endian values in. */
+	for (i = 0; i < 16; i++)
+		B32[i] = le32dec(&B[i * 4]);
+
+	/* Compute x = doubleround^4(B32). */
+	for (i = 0; i < 16; i++)
+		x[i] = B32[i];
+	for (i = 0; i < 8; i += 2) {
+#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+		/* Operate on columns. */
+		x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);
+		x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);
+
+		x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);
+		x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);
+
+		x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);
+		x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);
+
+		x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);
+		x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);
+
+		/* Operate on rows. */
+		x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);
+		x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);
+
+		x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);
+		x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);
+
+		x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);
+		x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);
+
+		x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);
+		x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);
+#undef R
+	}
+
+	/* Compute B32 = B32 + x. */
+	for (i = 0; i < 16; i++)
+		B32[i] += x[i];
+
+	/* Convert little-endian values out. */
+	for (i = 0; i < 16; i++)
+		le32enc(&B[4 * i], B32[i]);
+}
+
+/**
+ * blockmix_salsa8(B, Y, r):
+ * Compute B = BlockMix_{salsa20/8, r}(B).  The input B must be 128r bytes in
+ * length; the temporary space Y must also be the same size.
+ */
+static void
+blockmix_salsa8(uint8_t * B, uint8_t * Y, size_t r)
+{
+	uint8_t X[64];
+	size_t i;
+
+	/* 1: X <-- B_{2r - 1} */
+	blkcpy(X, &B[(2 * r - 1) * 64], 64);
+
+	/* 2: for i = 0 to 2r - 1 do */
+	for (i = 0; i < 2 * r; i++) {
+		/* 3: X <-- H(X \xor B_i) */
+		blkxor(X, &B[i * 64], 64);
+		salsa20_8(X);
+
+		/* 4: Y_i <-- X */
+		blkcpy(&Y[i * 64], X, 64);
+	}
+
+	/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+	for (i = 0; i < r; i++)
+		blkcpy(&B[i * 64], &Y[(i * 2) * 64], 64);
+	for (i = 0; i < r; i++)
+		blkcpy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);
+}
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ */
+static uint64_t
+integerify(const uint8_t * B, size_t r)
+{
+	const uint8_t * X = &B[(2 * r - 1) * 64];
+
+	return le64dec(X);
+}
+
+/**
+ * smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length; the
+ * temporary storage V must be 128rN bytes in length; the temporary storage
+ * XY must be 256r bytes in length.  The value N must be a power of 2.
+ */
+static void
+smix(uint8_t * B, size_t r, uint64_t N, uint8_t * V, uint8_t * XY)
+{
+	uint8_t * X = XY;
+	uint8_t * Y = &XY[128 * r];
+	uint64_t i;
+	uint64_t j;
+
+	/* 1: X <-- B */
+	blkcpy(X, B, 128 * r);
+
+	/* 2: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i++) {
+		/* 3: V_i <-- X */
+		blkcpy(&V[i * (128 * r)], X, 128 * r);
+
+		/* 4: X <-- H(X) */
+		blockmix_salsa8(X, Y, r);
+	}
+
+	/* 6: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i++) {
+		/* 7: j <-- Integerify(X) mod N */
+		j = integerify(X, r) & (N - 1);
+
+		/* 8: X <-- H(X \xor V_j) */
+		blkxor(X, &V[j * (128 * r)], 128 * r);
+		blockmix_salsa8(X, Y, r);
+	}
+
+	/* 10: B' <-- X */
+	blkcpy(B, X, 128 * r);
+}
+
+/**
+ * escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
+ *     N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf.  The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
+ * must be a power of 2.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int
+escrypt_kdf(escrypt_local_t * local,
+    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)
+{
+	size_t B_size, V_size;
+	uint8_t * B, * V, * 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. */
+	B_size = (size_t)128 * r * p;
+	if ((B = malloc(B_size)) == NULL)
+		goto err0;
+	if ((XY = malloc((size_t)256 * r)) == NULL)
+		goto err1;
+	V_size = (size_t)128 * r * N;
+	if ((V = malloc(V_size)) == NULL)
+		goto err2;
+
+	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+	PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size);
+
+	/* 2: for i = 0 to p - 1 do */
+	for (i = 0; i < p; i++) {
+		/* 3: B_i <-- MF(B_i, N) */
+		smix(&B[(size_t)128 * i * r], r, N, V, XY);
+	}
+
+	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+	PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen);
+
+	/* Free memory. */
+	if (local->size) {
+		local->base = local->aligned = V;
+		local->size = V_size;
+	} else
+		free(V);
+	free(XY);
+	free(B);
+
+	/* Success! */
+	return 0;
+
+err2:
+	free(XY);
+err1:
+	free(B);
+err0:
+	/* Failure! */
+	return -1;
+}
+
+int
+escrypt_init_local(escrypt_local_t * local)
+{
+/* Indicate to escrypt_kdf() that we don't use the local structure */
+	local->size = 0;
+	return 0;
+}
+
+int
+escrypt_free_local(escrypt_local_t * local)
+{
+/* The reference implementation frees its memory in escrypt_kdf() */
+	return 0;
+}
diff -urpN john-1.8.0.1/src/escrypt/crypto_scrypt-sse.c john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-sse.c
--- john-1.8.0.1/src/escrypt/crypto_scrypt-sse.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt-sse.c	2013-06-30 16:43:44.027110180 +0000
@@ -0,0 +1,383 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * Copyright 2012,2013 Alexander Peslyak
+ * 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 <emmintrin.h>
+#ifdef __XOP__
+#include <x86intrin.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 "scrypt_platform.c"
+
+#ifdef __XOP__
+#define ARX(out, in1, in2, s) \
+	out = _mm_xor_si128(out, _mm_roti_epi32(_mm_add_epi32(in1, in2), s));
+#else
+#define ARX(out, in1, in2, s) \
+	{ \
+		__m128i T = _mm_add_epi32(in1, in2); \
+		out = _mm_xor_si128(out, _mm_slli_epi32(T, s)); \
+		out = _mm_xor_si128(out, _mm_srli_epi32(T, 32-s)); \
+	}
+#endif
+
+#define SALSA20_2ROUNDS \
+	/* Operate on "columns". */ \
+	ARX(X1, X0, X3, 7) \
+	ARX(X2, X1, X0, 9) \
+	ARX(X3, X2, X1, 13) \
+	ARX(X0, X3, X2, 18) \
+\
+	/* Rearrange data. */ \
+	X1 = _mm_shuffle_epi32(X1, 0x93); \
+	X2 = _mm_shuffle_epi32(X2, 0x4E); \
+	X3 = _mm_shuffle_epi32(X3, 0x39); \
+\
+	/* Operate on "rows". */ \
+	ARX(X3, X0, X1, 7) \
+	ARX(X2, X3, X0, 9) \
+	ARX(X1, X2, X3, 13) \
+	ARX(X0, X1, X2, 18) \
+\
+	/* Rearrange data. */ \
+	X1 = _mm_shuffle_epi32(X1, 0x39); \
+	X2 = _mm_shuffle_epi32(X2, 0x4E); \
+	X3 = _mm_shuffle_epi32(X3, 0x93);
+
+/**
+ * Apply the salsa20/8 core to the block provided in (X0 ... X3) ^ (Z0 ... Z3).
+ */
+#define SALSA20_8_XOR(in, out) \
+	{ \
+		__m128i Y0 = X0 = _mm_xor_si128(X0, (in)[0]); \
+		__m128i Y1 = X1 = _mm_xor_si128(X1, (in)[1]); \
+		__m128i Y2 = X2 = _mm_xor_si128(X2, (in)[2]); \
+		__m128i Y3 = X3 = _mm_xor_si128(X3, (in)[3]); \
+		SALSA20_2ROUNDS \
+		SALSA20_2ROUNDS \
+		SALSA20_2ROUNDS \
+		SALSA20_2ROUNDS \
+		(out)[0] = X0 = _mm_add_epi32(X0, Y0); \
+		(out)[1] = X1 = _mm_add_epi32(X1, Y1); \
+		(out)[2] = X2 = _mm_add_epi32(X2, Y2); \
+		(out)[3] = X3 = _mm_add_epi32(X3, Y3); \
+	}
+
+/**
+ * blockmix_salsa8(Bin, Bout, 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.
+ */
+static inline void
+blockmix_salsa8(const __m128i * Bin, __m128i * Bout, size_t r)
+{
+	__m128i X0, X1, X2, X3;
+	size_t i;
+
+	/* 1: X <-- B_{2r - 1} */
+	X0 = Bin[8 * r - 4];
+	X1 = Bin[8 * r - 3];
+	X2 = Bin[8 * r - 2];
+	X3 = Bin[8 * r - 1];
+
+	/* 3: X <-- H(X \xor B_i) */
+	/* 4: Y_i <-- X */
+	/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+	SALSA20_8_XOR(Bin, Bout)
+
+	/* 2: for i = 0 to 2r - 1 do */
+	r--;
+	for (i = 0; i < r;) {
+		/* 3: X <-- H(X \xor B_i) */
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4])
+
+		i++;
+
+		/* 3: X <-- H(X \xor B_i) */
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		SALSA20_8_XOR(&Bin[i * 8], &Bout[i * 4])
+	}
+
+	/* 3: X <-- H(X \xor B_i) */
+	/* 4: Y_i <-- X */
+	/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+	SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4])
+}
+
+#define XOR4(in) \
+	X0 = _mm_xor_si128(X0, (in)[0]); \
+	X1 = _mm_xor_si128(X1, (in)[1]); \
+	X2 = _mm_xor_si128(X2, (in)[2]); \
+	X3 = _mm_xor_si128(X3, (in)[3]);
+
+#define XOR4_2(in1, in2) \
+	X0 = _mm_xor_si128((in1)[0], (in2)[0]); \
+	X1 = _mm_xor_si128((in1)[1], (in2)[1]); \
+	X2 = _mm_xor_si128((in1)[2], (in2)[2]); \
+	X3 = _mm_xor_si128((in1)[3], (in2)[3]);
+
+static inline uint32_t
+blockmix_salsa8_xor(const __m128i * Bin1, const __m128i * Bin2, __m128i * Bout,
+    size_t r)
+{
+	__m128i X0, X1, X2, X3;
+	size_t i;
+
+	/* 1: X <-- B_{2r - 1} */
+	XOR4_2(&Bin1[8 * r - 4], &Bin2[8 * r - 4])
+
+	/* 3: X <-- H(X \xor B_i) */
+	/* 4: Y_i <-- X */
+	/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+	XOR4(Bin1)
+	SALSA20_8_XOR(Bin2, Bout)
+
+	/* 2: for i = 0 to 2r - 1 do */
+	r--;
+	for (i = 0; i < r;) {
+		/* 3: X <-- H(X \xor B_i) */
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		XOR4(&Bin1[i * 8 + 4])
+		SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4])
+
+		i++;
+
+		/* 3: X <-- H(X \xor B_i) */
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		XOR4(&Bin1[i * 8])
+		SALSA20_8_XOR(&Bin2[i * 8], &Bout[i * 4])
+	}
+
+	/* 3: X <-- H(X \xor B_i) */
+	/* 4: Y_i <-- X */
+	/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+	XOR4(&Bin1[i * 8 + 4])
+	SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4])
+
+	return _mm_cvtsi128_si32(X0);
+}
+
+#undef ARX
+#undef SALSA20_2ROUNDS
+#undef SALSA20_8_XOR
+#undef XOR4
+#undef XOR4_2
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ */
+static inline uint32_t
+integerify(const void * B, size_t r)
+{
+	return *(const uint32_t *)((uintptr_t)(B) + (2 * r - 1) * 64);
+}
+
+/**
+ * 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, uint32_t N, void * V, void * XY)
+{
+	size_t s = 128 * r;
+	__m128i * X = V, * Y;
+	uint32_t * X32 = V;
+	uint32_t i, j;
+	size_t k;
+
+	/* 1: X <-- B */
+	/* 3: V_i <-- X */
+	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 = 1; i < N - 1; i += 2) {
+		/* 4: X <-- H(X) */
+		/* 3: V_i <-- X */
+		Y = (void *)((uintptr_t)(V) + i * s);
+		blockmix_salsa8(X, Y, r);
+
+		/* 4: X <-- H(X) */
+		/* 3: V_i <-- X */
+		X = (void *)((uintptr_t)(V) + (i + 1) * s);
+		blockmix_salsa8(Y, X, r);
+	}
+
+	/* 4: X <-- H(X) */
+	/* 3: V_i <-- X */
+	Y = (void *)((uintptr_t)(V) + i * s);
+	blockmix_salsa8(X, Y, r);
+
+	/* 4: X <-- H(X) */
+	/* 3: V_i <-- X */
+	X = XY;
+	blockmix_salsa8(Y, X, r);
+
+	X32 = XY;
+	Y = (void *)((uintptr_t)(XY) + s);
+
+	/* 7: j <-- Integerify(X) mod N */
+	j = integerify(X, r) & (N - 1);
+
+	/* 6: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i += 2) {
+		__m128i * V_j = (void *)((uintptr_t)(V) + j * s);
+
+		/* 8: X <-- H(X \xor V_j) */
+		/* 7: j <-- Integerify(X) mod N */
+		j = blockmix_salsa8_xor(X, V_j, Y, r) & (N - 1);
+		V_j = (void *)((uintptr_t)(V) + j * s);
+
+		/* 8: X <-- H(X \xor V_j) */
+		/* 7: j <-- Integerify(X) mod N */
+		j = blockmix_salsa8_xor(Y, V_j, X, r) & (N - 1);
+	}
+
+	/* 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]);
+		}
+	}
+}
+
+/**
+ * escrypt_kdf(local, 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
+escrypt_kdf(escrypt_local_t * local,
+    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)
+{
+	size_t B_size, V_size, XY_size, need;
+	uint8_t * B;
+	uint32_t * V, * XY;
+	uint32_t i;
+
+	/* Sanity-check parameters. */
+#if SIZE_MAX > UINT32_MAX
+	if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
+		errno = EFBIG;
+		return -1;
+	}
+#endif
+	if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
+		errno = EFBIG;
+		return -1;
+	}
+	if (N > UINT32_MAX) {
+		errno = EFBIG;
+		return -1;
+	}
+	if (((N & (N - 1)) != 0) || (N == 0)) {
+		errno = EINVAL;
+		return -1;
+	}
+	if ((r > SIZE_MAX / 128 / p) ||
+#if SIZE_MAX / 256 <= UINT32_MAX
+	    (r > SIZE_MAX / 256) ||
+#endif
+	    (N > SIZE_MAX / 128 / r)) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	/* Allocate memory. */
+	B_size = (size_t)128 * r * p;
+	V_size = (size_t)128 * r * N;
+	need = B_size + V_size;
+	if (need < V_size) {
+		errno = ENOMEM;
+		return -1;
+	}
+	XY_size = (size_t)256 * r;
+	need += XY_size;
+	if (need < XY_size) {
+		errno = ENOMEM;
+		return -1;
+	}
+	if (local->size < need) {
+		if (free_region(local))
+			return -1;
+		if (!alloc_region(local, need))
+			return -1;
+	}
+	B = (uint8_t *)local->aligned;
+	V = (uint32_t *)((uint8_t *)B + B_size);
+	XY = (uint32_t *)((uint8_t *)V + V_size);
+
+	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+	PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size);
+
+	/* 2: for i = 0 to p - 1 do */
+	for (i = 0; i < p; i++) {
+		/* 3: B_i <-- MF(B_i, N) */
+		smix(&B[(size_t)128 * i * r], r, N, V, XY);
+	}
+
+	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+	PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen);
+
+	/* Success! */
+	return 0;
+}
diff -urpN john-1.8.0.1/src/escrypt/crypto_scrypt.h john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt.h
--- john-1.8.0.1/src/escrypt/crypto_scrypt.h	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/crypto_scrypt.h	2013-06-30 11:50:02.045153878 +0000
@@ -0,0 +1,82 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#ifndef _CRYPTO_SCRYPT_H_
+#define _CRYPTO_SCRYPT_H_
+
+#include <stdint.h>
+
+/**
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf.  The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
+ * must be a power of 2 greater than 1.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+extern 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);
+
+typedef struct {
+	void * base, * aligned;
+	size_t size;
+} escrypt_region_t;
+
+typedef escrypt_region_t escrypt_local_t;
+
+extern int escrypt_init_local(escrypt_local_t * __local);
+
+extern int escrypt_free_local(escrypt_local_t * __local);
+
+extern int escrypt_kdf(escrypt_local_t * __local,
+    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);
+
+extern uint8_t * escrypt_r(escrypt_local_t * __local,
+    const uint8_t * __passwd, size_t __passwdlen,
+    const uint8_t * __setting,
+    uint8_t * __buf, size_t __buflen);
+
+extern uint8_t * escrypt(const uint8_t * __passwd, const uint8_t * __setting);
+
+extern uint8_t * escrypt_gensalt_r(
+    uint32_t __N_log2, uint32_t __r, uint32_t __p,
+    const uint8_t * __src, size_t __srclen,
+    uint8_t * __buf, size_t __buflen);
+
+extern uint8_t * escrypt_gensalt(
+    uint32_t __N_log2, uint32_t __r, uint32_t __p,
+    const uint8_t * __src, size_t __srclen);
+
+#endif /* !_CRYPTO_SCRYPT_H_ */
diff -urpN john-1.8.0.1/src/escrypt/scrypt_platform.c john-1.8.0.1-scrypt/src/escrypt/scrypt_platform.c
--- john-1.8.0.1/src/escrypt/scrypt_platform.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/scrypt_platform.c	2013-06-30 12:04:07.603755404 +0000
@@ -0,0 +1,91 @@
+/*-
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/mman.h>
+
+#include "scrypt_platform.h"
+
+static void *
+alloc_region(escrypt_region_t * region, size_t size)
+{
+	uint8_t * base, * aligned;
+#ifdef MAP_ANON
+	if ((base = mmap(NULL, size, PROT_READ | PROT_WRITE,
+#ifdef MAP_NOCORE
+	    MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
+#else
+	    MAP_ANON | MAP_PRIVATE,
+#endif
+	    -1, 0)) == MAP_FAILED)
+		base = NULL;
+	aligned = base;
+#elif defined(HAVE_POSIX_MEMALIGN)
+	if ((errno = posix_memalign(&base, 64, size)) != 0)
+		base = NULL;
+	aligned = base;
+#else
+	base = aligned = NULL;
+	if (size + 63 < size)
+		errno = ENOMEM;
+	else if ((base = malloc(size + 63)) != NULL) {
+		aligned = base + 63;
+		aligned -= (uintptr_t)aligned & 63;
+	}
+#endif
+	region->base = base;
+	region->aligned = aligned;
+	region->size = base ? size : 0;
+	return aligned;
+}
+
+static inline void
+init_region(escrypt_region_t * region)
+{
+	region->base = region->aligned = NULL;
+	region->size = 0;
+}
+
+static int
+free_region(escrypt_region_t * region)
+{
+	if (region->base) {
+#ifdef MAP_ANON
+		if (munmap(region->base, region->size))
+			return -1;
+#else
+		free(region->base);
+#endif
+	}
+	init_region(region);
+	return 0;
+}
+
+int
+escrypt_init_local(escrypt_local_t * local)
+{
+	init_region(local);
+	return 0;
+}
+
+int
+escrypt_free_local(escrypt_local_t * local)
+{
+	return free_region(local);
+}
diff -urpN john-1.8.0.1/src/escrypt/scrypt_platform.h john-1.8.0.1-scrypt/src/escrypt/scrypt_platform.h
--- john-1.8.0.1/src/escrypt/scrypt_platform.h	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/scrypt_platform.h	2013-04-06 02:24:18.736869458 +0000
@@ -0,0 +1,6 @@
+#ifndef _SCRYPT_PLATFORM_H_
+#define _SCRYPT_PLATFORM_H_
+
+#define HAVE_POSIX_MEMALIGN
+
+#endif
diff -urpN john-1.8.0.1/src/escrypt/sha256.c john-1.8.0.1-scrypt/src/escrypt/sha256.c
--- john-1.8.0.1/src/escrypt/sha256.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/sha256.c	2010-01-16 20:48:20.000000000 +0000
@@ -0,0 +1,412 @@
+/*-
+ * 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 SHA256 */
+#define Ch(x, y, z)	((x & (y ^ z)) ^ z)
+#define Maj(x, y, z)	((x & (y | z)) | (y & z))
+#define SHR(x, n)	(x >> n)
+#define ROTR(x, n)	((x >> n) | (x << (32 - n)))
+#define S0(x)		(ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define S1(x)		(ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define s0(x)		(ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
+#define s1(x)		(ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
+
+/* SHA256 round function */
+#define RND(a, b, c, d, e, f, g, h, k)			\
+	t0 = h + S1(e) + Ch(e, f, g) + k;		\
+	t1 = S0(a) + Maj(a, b, c);			\
+	d += t0;					\
+	h  = t0 + t1;
+
+/* Adjusted round function for rotating state */
+#define RNDr(S, W, i, k)			\
+	RND(S[(64 - i) % 8], S[(65 - i) % 8],	\
+	    S[(66 - i) % 8], S[(67 - i) % 8],	\
+	    S[(68 - i) % 8], S[(69 - i) % 8],	\
+	    S[(70 - i) % 8], S[(71 - i) % 8],	\
+	    W[i] + k)
+
+/*
+ * SHA256 block compression function.  The 256-bit state is transformed via
+ * the 512-bit input block to produce a new state.
+ */
+static void
+SHA256_Transform(uint32_t * state, const unsigned char block[64])
+{
+	uint32_t W[64];
+	uint32_t S[8];
+	uint32_t t0, t1;
+	int i;
+
+	/* 1. Prepare message schedule W. */
+	be32dec_vect(W, block, 64);
+	for (i = 16; i < 64; i++)
+		W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
+
+	/* 2. Initialize working variables. */
+	memcpy(S, state, 32);
+
+	/* 3. Mix. */
+	RNDr(S, W, 0, 0x428a2f98);
+	RNDr(S, W, 1, 0x71374491);
+	RNDr(S, W, 2, 0xb5c0fbcf);
+	RNDr(S, W, 3, 0xe9b5dba5);
+	RNDr(S, W, 4, 0x3956c25b);
+	RNDr(S, W, 5, 0x59f111f1);
+	RNDr(S, W, 6, 0x923f82a4);
+	RNDr(S, W, 7, 0xab1c5ed5);
+	RNDr(S, W, 8, 0xd807aa98);
+	RNDr(S, W, 9, 0x12835b01);
+	RNDr(S, W, 10, 0x243185be);
+	RNDr(S, W, 11, 0x550c7dc3);
+	RNDr(S, W, 12, 0x72be5d74);
+	RNDr(S, W, 13, 0x80deb1fe);
+	RNDr(S, W, 14, 0x9bdc06a7);
+	RNDr(S, W, 15, 0xc19bf174);
+	RNDr(S, W, 16, 0xe49b69c1);
+	RNDr(S, W, 17, 0xefbe4786);
+	RNDr(S, W, 18, 0x0fc19dc6);
+	RNDr(S, W, 19, 0x240ca1cc);
+	RNDr(S, W, 20, 0x2de92c6f);
+	RNDr(S, W, 21, 0x4a7484aa);
+	RNDr(S, W, 22, 0x5cb0a9dc);
+	RNDr(S, W, 23, 0x76f988da);
+	RNDr(S, W, 24, 0x983e5152);
+	RNDr(S, W, 25, 0xa831c66d);
+	RNDr(S, W, 26, 0xb00327c8);
+	RNDr(S, W, 27, 0xbf597fc7);
+	RNDr(S, W, 28, 0xc6e00bf3);
+	RNDr(S, W, 29, 0xd5a79147);
+	RNDr(S, W, 30, 0x06ca6351);
+	RNDr(S, W, 31, 0x14292967);
+	RNDr(S, W, 32, 0x27b70a85);
+	RNDr(S, W, 33, 0x2e1b2138);
+	RNDr(S, W, 34, 0x4d2c6dfc);
+	RNDr(S, W, 35, 0x53380d13);
+	RNDr(S, W, 36, 0x650a7354);
+	RNDr(S, W, 37, 0x766a0abb);
+	RNDr(S, W, 38, 0x81c2c92e);
+	RNDr(S, W, 39, 0x92722c85);
+	RNDr(S, W, 40, 0xa2bfe8a1);
+	RNDr(S, W, 41, 0xa81a664b);
+	RNDr(S, W, 42, 0xc24b8b70);
+	RNDr(S, W, 43, 0xc76c51a3);
+	RNDr(S, W, 44, 0xd192e819);
+	RNDr(S, W, 45, 0xd6990624);
+	RNDr(S, W, 46, 0xf40e3585);
+	RNDr(S, W, 47, 0x106aa070);
+	RNDr(S, W, 48, 0x19a4c116);
+	RNDr(S, W, 49, 0x1e376c08);
+	RNDr(S, W, 50, 0x2748774c);
+	RNDr(S, W, 51, 0x34b0bcb5);
+	RNDr(S, W, 52, 0x391c0cb3);
+	RNDr(S, W, 53, 0x4ed8aa4a);
+	RNDr(S, W, 54, 0x5b9cca4f);
+	RNDr(S, W, 55, 0x682e6ff3);
+	RNDr(S, W, 56, 0x748f82ee);
+	RNDr(S, W, 57, 0x78a5636f);
+	RNDr(S, W, 58, 0x84c87814);
+	RNDr(S, W, 59, 0x8cc70208);
+	RNDr(S, W, 60, 0x90befffa);
+	RNDr(S, W, 61, 0xa4506ceb);
+	RNDr(S, W, 62, 0xbef9a3f7);
+	RNDr(S, W, 63, 0xc67178f2);
+
+	/* 4. Mix local working variables into global state */
+	for (i = 0; i < 8; i++)
+		state[i] += S[i];
+
+	/* Clean the stack. */
+	memset(W, 0, 256);
+	memset(S, 0, 32);
+	t0 = t1 = 0;
+}
+
+static unsigned char PAD[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* Add padding and terminating bit-count. */
+static void
+SHA256_Pad(SHA256_CTX * ctx)
+{
+	unsigned char len[8];
+	uint32_t r, plen;
+
+	/*
+	 * Convert length to a vector of bytes -- we do this now rather
+	 * than later because the length will change after we pad.
+	 */
+	be32enc_vect(len, ctx->count, 8);
+
+	/* Add 1--64 bytes so that the resulting length is 56 mod 64 */
+	r = (ctx->count[1] >> 3) & 0x3f;
+	plen = (r < 56) ? (56 - r) : (120 - r);
+	SHA256_Update(ctx, PAD, (size_t)plen);
+
+	/* Add the terminating bit-count */
+	SHA256_Update(ctx, len, 8);
+}
+
+/* SHA-256 initialization.  Begins a SHA-256 operation. */
+void
+SHA256_Init(SHA256_CTX * ctx)
+{
+
+	/* Zero bits processed so far */
+	ctx->count[0] = ctx->count[1] = 0;
+
+	/* Magic initialization constants */
+	ctx->state[0] = 0x6A09E667;
+	ctx->state[1] = 0xBB67AE85;
+	ctx->state[2] = 0x3C6EF372;
+	ctx->state[3] = 0xA54FF53A;
+	ctx->state[4] = 0x510E527F;
+	ctx->state[5] = 0x9B05688C;
+	ctx->state[6] = 0x1F83D9AB;
+	ctx->state[7] = 0x5BE0CD19;
+}
+
+/* Add bytes into the hash */
+void
+SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
+{
+	uint32_t bitlen[2];
+	uint32_t r;
+	const unsigned char *src = in;
+
+	/* Number of bytes left in the buffer from previous updates */
+	r = (ctx->count[1] >> 3) & 0x3f;
+
+	/* Convert the length into a number of bits */
+	bitlen[1] = ((uint32_t)len) << 3;
+	bitlen[0] = (uint32_t)(len >> 29);
+
+	/* Update number of bits */
+	if ((ctx->count[1] += bitlen[1]) < bitlen[1])
+		ctx->count[0]++;
+	ctx->count[0] += bitlen[0];
+
+	/* Handle the case where we don't need to perform any transforms */
+	if (len < 64 - r) {
+		memcpy(&ctx->buf[r], src, len);
+		return;
+	}
+
+	/* Finish the current block */
+	memcpy(&ctx->buf[r], src, 64 - r);
+	SHA256_Transform(ctx->state, ctx->buf);
+	src += 64 - r;
+	len -= 64 - r;
+
+	/* Perform complete blocks */
+	while (len >= 64) {
+		SHA256_Transform(ctx->state, src);
+		src += 64;
+		len -= 64;
+	}
+
+	/* Copy left over data into buffer */
+	memcpy(ctx->buf, src, len);
+}
+
+/*
+ * SHA-256 finalization.  Pads the input data, exports the hash value,
+ * and clears the context state.
+ */
+void
+SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
+{
+
+	/* Add padding */
+	SHA256_Pad(ctx);
+
+	/* Write the hash */
+	be32enc_vect(digest, ctx->state, 32);
+
+	/* Clear the context state */
+	memset((void *)ctx, 0, sizeof(*ctx));
+}
+
+/* Initialize an HMAC-SHA256 operation with the given key. */
+void
+HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
+{
+	unsigned char pad[64];
+	unsigned char khash[32];
+	const unsigned char * K = _K;
+	size_t i;
+
+	/* If Klen > 64, the key is really SHA256(K). */
+	if (Klen > 64) {
+		SHA256_Init(&ctx->ictx);
+		SHA256_Update(&ctx->ictx, K, Klen);
+		SHA256_Final(khash, &ctx->ictx);
+		K = khash;
+		Klen = 32;
+	}
+
+	/* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
+	SHA256_Init(&ctx->ictx);
+	memset(pad, 0x36, 64);
+	for (i = 0; i < Klen; i++)
+		pad[i] ^= K[i];
+	SHA256_Update(&ctx->ictx, pad, 64);
+
+	/* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
+	SHA256_Init(&ctx->octx);
+	memset(pad, 0x5c, 64);
+	for (i = 0; i < Klen; i++)
+		pad[i] ^= K[i];
+	SHA256_Update(&ctx->octx, pad, 64);
+
+	/* Clean the stack. */
+	memset(khash, 0, 32);
+}
+
+/* Add bytes to the HMAC-SHA256 operation. */
+void
+HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
+{
+
+	/* Feed data to the inner SHA256 operation. */
+	SHA256_Update(&ctx->ictx, in, len);
+}
+
+/* Finish an HMAC-SHA256 operation. */
+void
+HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
+{
+	unsigned char ihash[32];
+
+	/* Finish the inner SHA256 operation. */
+	SHA256_Final(ihash, &ctx->ictx);
+
+	/* Feed the inner hash to the outer SHA256 operation. */
+	SHA256_Update(&ctx->octx, ihash, 32);
+
+	/* Finish the outer SHA256 operation. */
+	SHA256_Final(digest, &ctx->octx);
+
+	/* Clean the stack. */
+	memset(ihash, 0, 32);
+}
+
+/**
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
+ * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
+ */
+void
+PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
+    size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
+{
+	HMAC_SHA256_CTX PShctx, hctx;
+	size_t i;
+	uint8_t ivec[4];
+	uint8_t U[32];
+	uint8_t T[32];
+	uint64_t j;
+	int k;
+	size_t clen;
+
+	/* Compute HMAC state after processing P and S. */
+	HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
+	HMAC_SHA256_Update(&PShctx, salt, saltlen);
+
+	/* Iterate through the blocks. */
+	for (i = 0; i * 32 < dkLen; i++) {
+		/* Generate INT(i + 1). */
+		be32enc(ivec, (uint32_t)(i + 1));
+
+		/* Compute U_1 = PRF(P, S || INT(i)). */
+		memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
+		HMAC_SHA256_Update(&hctx, ivec, 4);
+		HMAC_SHA256_Final(U, &hctx);
+
+		/* T_i = U_1 ... */
+		memcpy(T, U, 32);
+
+		for (j = 2; j <= c; j++) {
+			/* Compute U_j. */
+			HMAC_SHA256_Init(&hctx, passwd, passwdlen);
+			HMAC_SHA256_Update(&hctx, U, 32);
+			HMAC_SHA256_Final(U, &hctx);
+
+			/* ... xor U_j ... */
+			for (k = 0; k < 32; k++)
+				T[k] ^= U[k];
+		}
+
+		/* Copy as many bytes as necessary into buf. */
+		clen = dkLen - i * 32;
+		if (clen > 32)
+			clen = 32;
+		memcpy(&buf[i * 32], T, clen);
+	}
+
+	/* Clean PShctx, since we never called _Final on it. */
+	memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
+}
diff -urpN john-1.8.0.1/src/escrypt/sha256.h john-1.8.0.1-scrypt/src/escrypt/sha256.h
--- john-1.8.0.1/src/escrypt/sha256.h	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/sha256.h	2010-01-16 20:48:20.000000000 +0000
@@ -0,0 +1,62 @@
+/*-
+ * Copyright 2005,2007,2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $
+ */
+
+#ifndef _SHA256_H_
+#define _SHA256_H_
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+typedef struct SHA256Context {
+	uint32_t state[8];
+	uint32_t count[2];
+	unsigned char buf[64];
+} SHA256_CTX;
+
+typedef struct HMAC_SHA256Context {
+	SHA256_CTX ictx;
+	SHA256_CTX octx;
+} HMAC_SHA256_CTX;
+
+void	SHA256_Init(SHA256_CTX *);
+void	SHA256_Update(SHA256_CTX *, const void *, size_t);
+void	SHA256_Final(unsigned char [32], SHA256_CTX *);
+void	HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
+void	HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
+void	HMAC_SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *);
+
+/**
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
+ * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
+ */
+void	PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
+    uint64_t, uint8_t *, size_t);
+
+#endif /* !_SHA256_H_ */
diff -urpN john-1.8.0.1/src/escrypt/sysendian.h john-1.8.0.1-scrypt/src/escrypt/sysendian.h
--- john-1.8.0.1/src/escrypt/sysendian.h	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/sysendian.h	2010-01-16 20:48:20.000000000 +0000
@@ -0,0 +1,140 @@
+/*-
+ * 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 -urpN john-1.8.0.1/src/escrypt/tests.c john-1.8.0.1-scrypt/src/escrypt/tests.c
--- john-1.8.0.1/src/escrypt/tests.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/escrypt/tests.c	2013-06-30 12:37:28.816419356 +0000
@@ -0,0 +1,145 @@
+/*-
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#undef TEST_PBKDF2_SHA256
+#define TEST_SCRYPT
+#define TEST_ESCRYPT_ENCODING
+
+#ifdef TEST_PBKDF2_SHA256
+#include <assert.h>
+
+#include "sha256.h"
+
+static void
+print_PBKDF2_SHA256_raw(const char * passwd, size_t passwdlen,
+    const char * salt, size_t saltlen, uint64_t c, size_t dkLen)
+{
+	uint8_t dk[64];
+	int i;
+
+	assert(dkLen <= sizeof(dk));
+
+	/* XXX This prints the strings truncated at first NUL */
+	printf("PBKDF2_SHA256(\"%s\", \"%s\", %llu, %lu) =",
+	    passwd, salt, (unsigned long long)c, dkLen);
+
+	PBKDF2_SHA256((const uint8_t *) passwd, passwdlen,
+	    (const uint8_t *) salt, saltlen, c, dk, dkLen);
+
+	for (i = 0; i < dkLen; i++)
+		printf(" %02x", dk[i]);
+	puts("");
+}
+
+static void
+print_PBKDF2_SHA256(const char * passwd, const char * salt, uint64_t c,
+    size_t dkLen)
+{
+	print_PBKDF2_SHA256_raw(passwd, strlen(passwd), salt, strlen(salt), c,
+	    dkLen);
+}
+#endif
+
+#if defined(TEST_SCRYPT) || defined(TEST_ESCRYPT_ENCODING)
+#include "crypto_scrypt.h"
+#endif
+
+#ifdef TEST_SCRYPT
+static void
+print_scrypt(const char * passwd, const char * salt,
+    uint64_t N, uint32_t r, uint32_t p)
+{
+	uint8_t dk[64];
+	int i;
+
+	printf("scrypt(\"%s\", \"%s\", %llu, %u, %u) =",
+	    passwd, salt, (unsigned long long)N, r, p);
+
+	if (crypto_scrypt((const uint8_t *) passwd, strlen(passwd),
+	    (const uint8_t *) salt, strlen(salt), N, r, p, dk, sizeof(dk))) {
+		puts(" FAILED");
+		return;
+	}
+
+	for (i = 0; i < sizeof(dk); i++)
+		printf(" %02x", dk[i]);
+	puts("");
+}
+#endif
+
+int
+main(int argc, char *argv[])
+{
+#ifdef TEST_PBKDF2_SHA256
+	print_PBKDF2_SHA256("password", "salt", 1, 20);
+	print_PBKDF2_SHA256("password", "salt", 2, 20);
+	print_PBKDF2_SHA256("password", "salt", 4096, 20);
+	print_PBKDF2_SHA256("password", "salt", 16777216, 20);
+	print_PBKDF2_SHA256("passwordPASSWORDpassword",
+	    "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25);
+	print_PBKDF2_SHA256_raw("pass\0word", 9, "sa\0lt", 5, 4096, 16);
+#if 0
+	print_PBKDF2_SHA256("password", "salt", 1, 32);
+	print_PBKDF2_SHA256("password", "salt", 2, 32);
+	print_PBKDF2_SHA256("password", "salt", 4096, 32);
+	print_PBKDF2_SHA256("password", "salt", 16777216, 32);
+	print_PBKDF2_SHA256("passwordPASSWORDpassword",
+	    "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 40);
+	print_PBKDF2_SHA256("password", "salt", 4096, 16);
+	print_PBKDF2_SHA256("password", "salt", 1, 20);
+	print_PBKDF2_SHA256("password", "salt", 2, 20);
+	print_PBKDF2_SHA256("password", "salt", 4096, 20);
+	print_PBKDF2_SHA256("password", "salt", 16777216, 20);
+	print_PBKDF2_SHA256("password", "salt", 4096, 25);
+	print_PBKDF2_SHA256("password", "salt", 4096, 16);
+#endif
+#endif
+
+#ifdef TEST_SCRYPT
+	print_scrypt("", "", 16, 1, 1);
+	print_scrypt("password", "NaCl", 1024, 8, 16);
+	print_scrypt("pleaseletmein", "SodiumChloride", 16384, 8, 1);
+	print_scrypt("pleaseletmein", "SodiumChloride", 1048576, 8, 1);
+#endif
+
+#ifdef TEST_ESCRYPT_ENCODING
+	{
+		uint8_t * setting = escrypt_gensalt(14, 8, 1,
+		    (const uint8_t *)"binary data", 12);
+		printf("'%s'\n", (char *)setting);
+		if (setting) {
+			uint8_t * hash = escrypt(
+			    (const uint8_t *)"pleaseletmein", setting);
+			printf("'%s'\n", (char *)hash);
+			if (hash)
+				printf("'%s'\n", (char *)escrypt(
+				    (const uint8_t *)"pleaseletmein", hash));
+		}
+		printf("'%s'\n", (char *)escrypt(
+		    (const uint8_t *)"pleaseletmein",
+		    (const uint8_t *)"$7$C6..../....SodiumChloride"));
+	}
+#endif
+
+	return 0;
+}
diff -urpN john-1.8.0.1/src/john.c john-1.8.0.1-scrypt/src/john.c
--- john-1.8.0.1/src/john.c	2013-05-29 23:27:25.000000000 +0000
+++ john-1.8.0.1-scrypt/src/john.c	2013-06-30 14:31:49.238570241 +0000
@@ -65,6 +65,7 @@ extern int CPU_detect(void);
 #endif
 
 extern struct fmt_main fmt_DES, fmt_BSDI, fmt_MD5, fmt_BF;
+extern struct fmt_main fmt_scrypt;
 extern struct fmt_main fmt_AFS, fmt_LM;
 #ifdef HAVE_CRYPT
 extern struct fmt_main fmt_crypt;
@@ -102,6 +103,7 @@ static void john_register_all(void)
 	john_register_one(&fmt_BSDI);
 	john_register_one(&fmt_MD5);
 	john_register_one(&fmt_BF);
+	john_register_one(&fmt_scrypt);
 	john_register_one(&fmt_LM);
 	john_register_one(&fmt_AFS);
 	john_register_one(&fmt_trip);
diff -urpN john-1.8.0.1/src/scrypt_fmt.c john-1.8.0.1-scrypt/src/scrypt_fmt.c
--- john-1.8.0.1/src/scrypt_fmt.c	1970-01-01 00:00:00.000000000 +0000
+++ john-1.8.0.1-scrypt/src/scrypt_fmt.c	2013-06-30 15:29:52.839386946 +0000
@@ -0,0 +1,380 @@
+/*
+ * This file is part of John the Ripper password cracker,
+ * Copyright (c) 2013 by Solar Designer
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+#include "escrypt/crypto_scrypt.h"
+
+#include "arch.h"
+#include "misc.h"
+#include "common.h"
+#include "formats.h"
+
+#define FORMAT_LABEL			"scrypt"
+#define FORMAT_NAME			""
+#ifdef __XOP__
+#define ALGORITHM_NAME			"Salsa20/8 128/128 XOP"
+#elif defined(__AVX__)
+#define ALGORITHM_NAME			"Salsa20/8 128/128 AVX"
+#elif defined(__SSE2__)
+#define ALGORITHM_NAME			"Salsa20/8 128/128 SSE2"
+#else
+#define ALGORITHM_NAME			"Salsa20/8 32/" ARCH_BITS_STR
+#endif
+
+#define BENCHMARK_COMMENT		" (16384, 8, 1)"
+#define BENCHMARK_LENGTH		-1
+
+#define PLAINTEXT_LENGTH		125
+
+#define BINARY_SIZE			128
+#define BINARY_ALIGN			1
+#define SALT_SIZE			BINARY_SIZE
+#define SALT_ALIGN			1
+
+#define MIN_KEYS_PER_CRYPT		1
+#define MAX_KEYS_PER_CRYPT		1
+
+static struct fmt_tests tests[] = {
+	{"$7$C6..../....SodiumChloride$"
+	    "kBGj9fHznVYFQMEn/qDCfrDevf9YDtcDdKvEqHJLV8D", "pleaseletmein"},
+	{"$7$C6..../....\x01\x09\x0a\x0d\x20\x7f\x80\xff$"
+	    "b7cKqzsQk7txdc9As1WZBHjUPNWQWJW8A.UUUTA5eD1",
+	    "\x01\x09\x0a\x0d\x20\x7f\x80\xff"},
+	{"$7$2/..../....$rNxJWVHNv/mCNcgE/f6/L4zO6Fos5c2uTzhyzoisI62", ""},
+	{"$7$86....E....NaCl$xffjQo7Bm/.SKRS4B2EuynbOLjAmXU5AbDbRXhoBl64",
+	    "password"},
+	{NULL}
+};
+
+static int max_threads;
+static escrypt_local_t *local;
+
+static char saved_salt[SALT_SIZE];
+static struct {
+	char key[PLAINTEXT_LENGTH + 1];
+	char out[BINARY_SIZE];
+} *buffer;
+
+static void init(struct fmt_main *self)
+{
+	int i;
+
+#ifdef _OPENMP
+	max_threads = omp_get_max_threads();
+	self->params.min_keys_per_crypt *= max_threads;
+	self->params.max_keys_per_crypt *= max_threads;
+#else
+	max_threads = 1;
+#endif
+
+	local = mem_alloc(sizeof(*local) * max_threads);
+	for (i = 0; i < max_threads; i++)
+		escrypt_init_local(&local[i]);
+
+	buffer = mem_alloc(sizeof(*buffer) * self->params.max_keys_per_crypt);
+}
+
+static void done(void)
+{
+	int i;
+
+	for (i = 0; i < max_threads; i++)
+		escrypt_free_local(&local[i]);
+
+	MEM_FREE(local);
+	MEM_FREE(buffer);
+}
+
+static int valid(char *ciphertext, struct fmt_main *self)
+{
+	char *p;
+	int length;
+
+	if (strncmp(ciphertext, "$7$", 3))
+		return 0;
+
+	for (p = ciphertext + 3; p < ciphertext + (3 + 1 + 5 + 5); p++)
+		if (atoi64[ARCH_INDEX(*p)] == 0x7F)
+			return 0;
+
+	p = strrchr(ciphertext, '$');
+	if (!p)
+		return 0;
+
+	if (p - ciphertext > BINARY_SIZE - (1 + 43))
+		return 0;
+
+	length = 0;
+	while (atoi64[ARCH_INDEX(*++p)] != 0x7F)
+		length++;
+
+	return !*p && length == 43;
+}
+
+static void *binary(char *ciphertext)
+{
+	static char out[BINARY_SIZE];
+	strncpy(out, ciphertext, sizeof(out)); /* NUL padding is required */
+	return out;
+}
+
+static void *salt(char *ciphertext)
+{
+	static char out[SALT_SIZE];
+	char *p = strrchr(ciphertext, '$');
+	/* NUL padding is required */
+	memset(out, 0, sizeof(out));
+	memcpy(out, ciphertext, p - ciphertext);
+	return out;
+}
+
+#define H(s, i) \
+	((int)(unsigned char)(atoi64[ARCH_INDEX((s)[(i)])] ^ (s)[(i) - 1]))
+
+#define H0(s) \
+	int i = strlen(s) - 2; \
+	return i > 0 ? H((s), i) & 0xF : 0
+#define H1(s) \
+	int i = strlen(s) - 2; \
+	return i > 2 ? (H((s), i) ^ (H((s), i - 2) << 4)) & 0xFF : 0
+#define H2(s) \
+	int i = strlen(s) - 2; \
+	return i > 2 ? (H((s), i) ^ (H((s), i - 2) << 6)) & 0xFFF : 0
+#define H3(s) \
+	int i = strlen(s) - 2; \
+	return i > 4 ? (H((s), i) ^ (H((s), i - 2) << 5) ^ \
+	    (H((s), i - 4) << 10)) & 0xFFFF : 0
+#define H4(s) \
+	int i = strlen(s) - 2; \
+	return i > 6 ? (H((s), i) ^ (H((s), i - 2) << 5) ^ \
+	    (H((s), i - 4) << 10) ^ (H((s), i - 6) << 15)) & 0xFFFFF : 0
+
+static int binary_hash_0(void *binary)
+{
+	H0((char *)binary);
+}
+
+static int binary_hash_1(void *binary)
+{
+	H1((char *)binary);
+}
+
+static int binary_hash_2(void *binary)
+{
+	H2((char *)binary);
+}
+
+static int binary_hash_3(void *binary)
+{
+	H3((char *)binary);
+}
+
+static int binary_hash_4(void *binary)
+{
+	H4((char *)binary);
+}
+
+static int get_hash_0(int index)
+{
+	H0(buffer[index].out);
+}
+
+static int get_hash_1(int index)
+{
+	H1(buffer[index].out);
+}
+
+static int get_hash_2(int index)
+{
+	H2(buffer[index].out);
+}
+
+static int get_hash_3(int index)
+{
+	H3(buffer[index].out);
+}
+
+static int get_hash_4(int index)
+{
+	H4(buffer[index].out);
+}
+
+static int salt_hash(void *salt)
+{
+	int i, h;
+
+	i = strlen((char *)salt) - 1;
+	if (i > 1) i--;
+
+	h = (unsigned char)atoi64[ARCH_INDEX(((char *)salt)[i])];
+	h ^= ((unsigned char *)salt)[i - 1];
+	h <<= 6;
+	h ^= (unsigned char)atoi64[ARCH_INDEX(((char *)salt)[i - 1])];
+	h ^= ((unsigned char *)salt)[i];
+
+	return h & (SALT_HASH_SIZE - 1);
+}
+
+static void set_salt(void *salt)
+{
+	strcpy(saved_salt, salt);
+}
+
+static void set_key(char *key, int index)
+{
+	strnzcpy(buffer[index].key, key, PLAINTEXT_LENGTH + 1);
+}
+
+static char *get_key(int index)
+{
+	return buffer[index].key;
+}
+
+static int crypt_all(int *pcount, struct db_salt *salt)
+{
+	int count = *pcount;
+	int index;
+
+#ifdef _OPENMP
+	int failed = 0;
+
+#pragma omp parallel for default(none) private(index) shared(count, failed, max_threads, local, saved_salt, buffer)
+#endif
+	for (index = 0; index < count; index++) {
+		uint8_t *hash;
+#ifdef _OPENMP
+		int t = omp_get_thread_num();
+#else
+		const int t = 0;
+#endif
+		if (t < max_threads) {
+			hash = escrypt_r(&local[t],
+			    (const uint8_t *)buffer[index].key,
+			    strlen(buffer[index].key),
+			    (const uint8_t *)saved_salt,
+			    (uint8_t *)&buffer[index].out,
+			    sizeof(buffer[index].out));
+		} else { /* should not happen */
+			escrypt_local_t local;
+			hash = NULL;
+			if (escrypt_init_local(&local) == 0) {
+				hash = escrypt_r(&local,
+				    (const uint8_t *)buffer[index].key,
+				    strlen(buffer[index].key),
+				    (const uint8_t *)saved_salt,
+				    (uint8_t *)&buffer[index].out,
+				    sizeof(buffer[index].out));
+				escrypt_free_local(&local);
+			}
+		}
+		if (!hash) {
+#ifdef _OPENMP
+#pragma omp critical
+			failed = 1;
+			buffer[index].out[0] = 0;
+#else
+			fprintf(stderr, "scrypt memory allocation failed\n");
+			error();
+#endif
+		}
+	}
+
+#ifdef _OPENMP
+	if (failed) {
+		fprintf(stderr, "scrypt memory allocation failed\n");
+		error();
+	}
+#endif
+
+	return count;
+}
+
+static int cmp_all(void *binary, int count)
+{
+	int index;
+
+	for (index = 0; index < count; index++)
+		if (!strcmp((char *)binary, buffer[index].out))
+			return 1;
+
+	return 0;
+}
+
+static int cmp_one(void *binary, int index)
+{
+	return !strcmp((char *)binary, buffer[index].out);
+}
+
+static int cmp_exact(char *source, int index)
+{
+	return 1;
+}
+
+struct fmt_main fmt_scrypt = {
+	{
+		FORMAT_LABEL,
+		FORMAT_NAME,
+		ALGORITHM_NAME,
+		BENCHMARK_COMMENT,
+		BENCHMARK_LENGTH,
+		PLAINTEXT_LENGTH,
+		BINARY_SIZE,
+		BINARY_ALIGN,
+		SALT_SIZE,
+		SALT_ALIGN,
+		MIN_KEYS_PER_CRYPT,
+		MAX_KEYS_PER_CRYPT,
+		FMT_CASE | FMT_8_BIT | FMT_OMP,
+		tests
+	}, {
+		init,
+		done,
+		fmt_default_reset,
+		fmt_default_prepare,
+		valid,
+		fmt_default_split,
+		binary,
+		salt,
+		fmt_default_source,
+		{
+			binary_hash_0,
+			binary_hash_1,
+			binary_hash_2,
+			binary_hash_3,
+			binary_hash_4,
+			NULL,
+			NULL
+		},
+		salt_hash,
+		set_salt,
+		set_key,
+		get_key,
+		fmt_default_clear_keys,
+		crypt_all,
+		{
+			get_hash_0,
+			get_hash_1,
+			get_hash_2,
+			get_hash_3,
+			get_hash_4,
+			NULL,
+			NULL
+		},
+		cmp_all,
+		cmp_one,
+		cmp_exact
+	}
+};

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux - Powered by OpenVZ