summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2013-06-11 16:36:54 -0700
committerKenny Root <kroot@google.com>2013-06-12 11:44:41 -0700
commit5fd6d3161cc7407718c7e230f94db421543273b8 (patch)
tree8571d4956103987a70096c55d1bf785c9b69d738
parent6647e7567bfbcccf0952ff79da8b2ab809f2ed0e (diff)
downloadscrypt-5fd6d3161cc7407718c7e230f94db421543273b8.tar.gz
Import initial version of scrypt library
Change-Id: Idcc14fed4878763ad26855cd99c5e6093ab5b3dd
-rw-r--r--Android.mk11
-rw-r--r--MODULE_LICENSE_BSD_LIKE0
-rw-r--r--NOTICE28
-rw-r--r--Scrypt-config.mk88
-rw-r--r--Scrypt.mk46
-rw-r--r--android-config.mk16
-rw-r--r--build-config.mk6
-rw-r--r--config.h99
-rwxr-xr-ximport_scrypt.sh486
-rw-r--r--lib/README6
-rw-r--r--lib/crypto/crypto_scrypt-ref.c285
-rw-r--r--lib/crypto/crypto_scrypt-sse.c366
-rw-r--r--lib/crypto/crypto_scrypt.h46
-rw-r--r--lib/crypto/sha256.c412
-rw-r--r--lib/crypto/sha256.h62
-rw-r--r--lib/util/sysendian.h140
-rw-r--r--patches/README3
-rw-r--r--patches/bionic.patch12
-rw-r--r--scrypt.config78
-rw-r--r--scrypt.version1
-rw-r--r--scrypt_platform.h12
21 files changed, 2203 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..4920d2d
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+
+# Enable to be able to use ALOG* with #include "cutils/log.h"
+#log_c_includes += system/core/include
+#log_shared_libraries := liblog
+
+# These makefiles are here instead of being Android.mk files in the
+# respective crypto, ssl, and apps directories so
+# that import_openssl.sh import won't remove them.
+include $(LOCAL_PATH)/build-config.mk
+include $(LOCAL_PATH)/Scrypt.mk
diff --git a/MODULE_LICENSE_BSD_LIKE b/MODULE_LICENSE_BSD_LIKE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD_LIKE
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..e88e916
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,28 @@
+/*-
+ * 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.
+ */
diff --git a/Scrypt-config.mk b/Scrypt-config.mk
new file mode 100644
index 0000000..b32f9bd
--- /dev/null
+++ b/Scrypt-config.mk
@@ -0,0 +1,88 @@
+# Auto-generated - DO NOT EDIT!
+# To regenerate, edit scrypt.config, then run:
+# ./import_scrypt.sh import /path/to/scrypt-1.1.6.tar.gz
+#
+# Before including this file, the local Android.mk must define the following
+# variables:
+#
+# local_c_flags
+# local_c_includes
+# local_additional_dependencies
+#
+# This script will define the following variables:
+#
+# target_c_flags
+# target_c_includes
+# target_src_files
+#
+# host_c_flags
+# host_c_includes
+# host_src_files
+#
+
+# Ensure these are empty.
+unknown_arch_c_flags :=
+unknown_arch_src_files :=
+unknown_arch_exclude_files :=
+
+
+common_c_flags :=
+
+common_src_files := \
+ lib/crypto/crypto_scrypt-ref.c \
+
+common_c_includes := \
+ lib/crypto \
+ lib/util \
+
+arm_c_flags :=
+
+arm_src_files :=
+
+arm_exclude_files :=
+
+x86_c_flags :=
+
+x86_src_files := \
+ lib/crypto/crypto_scrypt-sse.c \
+
+x86_exclude_files := \
+ lib/crypto/crypto_scrypt-ref.c \
+
+x86_64_c_flags :=
+
+x86_64_src_files := \
+ lib/crypto/crypto_scrypt-sse.c \
+
+x86_64_exclude_files := \
+ lib/crypto/crypto_scrypt-ref.c \
+
+mips_c_flags :=
+
+mips_src_files :=
+
+mips_exclude_files :=
+
+target_arch := $(TARGET_ARCH)
+ifeq ($(target_arch)-$(TARGET_HAS_BIGENDIAN),mips-true)
+target_arch := unknown_arch
+endif
+
+target_c_flags := $(common_c_flags) $($(target_arch)_c_flags) $(local_c_flags)
+target_c_includes := $(addprefix external/scrypt/,$(common_c_includes)) $(local_c_includes)
+target_src_files := $(common_src_files) $($(target_arch)_src_files)
+target_src_files := $(filter-out $($(target_arch)_exclude_files), $(target_src_files))
+
+ifeq ($(HOST_OS)-$(HOST_ARCH),linux-x86)
+host_arch := x86
+else
+host_arch := unknown_arch
+endif
+
+host_c_flags := $(common_c_flags) $($(host_arch)_c_flags) $(local_c_flags)
+host_c_includes := $(addprefix external/scrypt/,$(common_c_includes)) $(local_c_includes)
+host_src_files := $(common_src_files) $($(host_arch)_src_files)
+host_src_files := $(filter-out $($(host_arch)_exclude_files), $(host_src_files))
+
+local_additional_dependencies += $(LOCAL_PATH)/Scrypt-config.mk
+
diff --git a/Scrypt.mk b/Scrypt.mk
new file mode 100644
index 0000000..33268c9
--- /dev/null
+++ b/Scrypt.mk
@@ -0,0 +1,46 @@
+local_c_flags :=
+
+local_c_includes := $(log_c_includes)
+
+local_additional_dependencies := $(LOCAL_PATH)/android-config.mk $(LOCAL_PATH)/Scrypt.mk
+
+include $(LOCAL_PATH)/Scrypt-config.mk
+
+#######################################
+# target static library
+include $(CLEAR_VARS)
+include $(LOCAL_PATH)/android-config.mk
+
+LOCAL_SHARED_LIBRARIES := $(log_shared_libraries)
+
+# If we're building an unbundled build, don't try to use clang since it's not
+# in the NDK yet. This can be removed when a clang version that is fast enough
+# in the NDK.
+ifeq (,$(TARGET_BUILD_APPS))
+LOCAL_CLANG := true
+else
+LOCAL_SDK_VERSION := 9
+endif
+
+LOCAL_SRC_FILES += $(target_src_files)
+LOCAL_CFLAGS += $(target_c_flags)
+LOCAL_C_INCLUDES += $(target_c_includes)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE:= libscrypt_static
+LOCAL_ADDITIONAL_DEPENDENCIES := $(local_additional_dependencies)
+include $(BUILD_STATIC_LIBRARY)
+
+########################################
+# host static library
+
+include $(CLEAR_VARS)
+include $(LOCAL_PATH)/android-config.mk
+LOCAL_SHARED_LIBRARIES := $(log_shared_libraries)
+LOCAL_SRC_FILES += $(host_src_files)
+LOCAL_CFLAGS += $(host_c_flags)
+LOCAL_C_INCLUDES += $(host_c_includes)
+LOCAL_LDLIBS += -ldl
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE:= libscrypt_static
+LOCAL_ADDITIONAL_DEPENDENCIES := $(local_additional_dependencies)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/android-config.mk b/android-config.mk
new file mode 100644
index 0000000..326e113
--- /dev/null
+++ b/android-config.mk
@@ -0,0 +1,16 @@
+#
+# These flags represent the build-time configuration of scrypt for Android
+#
+# The value of $(scrypt_cflags) was pruned from the Makefile generated
+# by running ./configure from import_scrypt.sh.
+#
+# This script performs minor but required patching for the Android build.
+#
+
+LOCAL_CFLAGS += $(scrypt_cflags)
+
+# Add in flags to let config.h be read properly
+LOCAL_CFLAGS += "-DHAVE_CONFIG_H"
+
+# Add clang here when it works on host
+# LOCAL_CLANG := true
diff --git a/build-config.mk b/build-config.mk
new file mode 100644
index 0000000..3d2ab91
--- /dev/null
+++ b/build-config.mk
@@ -0,0 +1,6 @@
+# Auto-generated - DO NOT EDIT!
+# To regenerate, edit scrypt.config, then run:
+# ./import_scrypt.sh import /path/to/scrypt-1.1.6.tar.gz
+#
+scrypt_cflags := \
+
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..3514f39
--- /dev/null
+++ b/config.h
@@ -0,0 +1,99 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#define HAVE_CLOCK_GETTIME 1
+
+/* Define to 1 if you have the declaration of `be64enc', and to 0 if you
+ don't. */
+#define HAVE_DECL_BE64ENC 0
+
+/* Define to 1 if you have the <err.h> header file. */
+#define HAVE_ERR_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+#define HAVE_LIBRT 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `posix_memalign' function. */
+#define HAVE_POSIX_MEMALIGN 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if the system has the type `struct sysinfo'. */
+#define HAVE_STRUCT_SYSINFO 1
+
+/* Define to 1 if `mem_unit' is member of `struct sysinfo'. */
+#define HAVE_STRUCT_SYSINFO_MEM_UNIT 1
+
+/* Define to 1 if `totalram' is member of `struct sysinfo'. */
+#define HAVE_STRUCT_SYSINFO_TOTALRAM 1
+
+/* Define to 1 if the OS has a hw.usermem sysctl */
+/* #undef HAVE_SYSCTL_HW_USERMEM */
+
+/* Define to 1 if you have the `sysinfo' function. */
+#define HAVE_SYSINFO 1
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+/* #undef HAVE_SYS_ENDIAN_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/sysinfo.h> header file. */
+#define HAVE_SYS_SYSINFO_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "scrypt"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "scrypt"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "scrypt 1.1.6"
+
+/* 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 to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "1.1.6"
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
diff --git a/import_scrypt.sh b/import_scrypt.sh
new file mode 100755
index 0000000..2270206
--- /dev/null
+++ b/import_scrypt.sh
@@ -0,0 +1,486 @@
+#!/bin/bash
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# This script imports new versions of scrypt (http://www.tarsnap.com/scrypt/) into the
+# Android source tree. To run, (1) fetch the appropriate tarball from the scrypt repository,
+# (2) check the gpg/pgp signature, and then (3) run:
+# ./import_scrypt.sh import scrypt-*.tar.gz
+#
+# IMPORTANT: See README.android for additional details.
+
+# turn on exit on error as well as a warning when it happens
+set -e
+set -x
+trap "echo WARNING: Exiting on non-zero subprocess exit code" ERR;
+
+# Ensure consistent sorting order / tool output.
+export LANG=C
+export LC_ALL=C
+
+export DIRNAME=$(dirname $0)
+
+function die() {
+ declare -r message=$1
+
+ echo $message
+ exit 1
+}
+
+function usage() {
+ declare -r message=$1
+
+ if [ ! "$message" = "" ]; then
+ echo $message
+ fi
+ echo "Usage:"
+ echo " ./import_scrypt.sh import </path/to/scrypt-*.tar.gz>"
+ echo " ./import_scrypt.sh regenerate <patch/*.patch>"
+ echo " ./import_scrypt.sh generate <patch/*.patch> </path/to/scrypt-*.tar.gz>"
+ exit 1
+}
+
+function main() {
+ if [ ! -d patches ]; then
+ die "scrypt patch directory patches/ not found"
+ fi
+
+ if [ ! -f scrypt.version ]; then
+ die "scrypt.version not found"
+ fi
+
+ source $DIRNAME/scrypt.version
+ if [ "$SCRYPT_VERSION" == "" ]; then
+ die "Invalid scrypt.version; see README.android for more information"
+ fi
+
+ SCRYPT_DIR=scrypt-$SCRYPT_VERSION
+ SCRYPT_DIR_ORIG=$SCRYPT_DIR.orig
+
+ if [ ! -f scrypt.config ]; then
+ die "scrypt.config not found"
+ fi
+
+ source $DIRNAME/scrypt.config
+ if [ "$CONFIGURE_ARGS" == "" -o "$UNNEEDED_SOURCES" == "" -o "$NEEDED_SOURCES" == "" ]; then
+ die "Invalid scrypt.config; see README.android for more information"
+ fi
+
+ declare -r command=$1
+ shift || usage "No command specified. Try import, regenerate, or generate."
+ if [ "$command" = "import" ]; then
+ declare -r tar=$1
+ shift || usage "No tar file specified."
+ import $tar
+ elif [ "$command" = "regenerate" ]; then
+ declare -r patch=$1
+ shift || usage "No patch file specified."
+ [ -d $SCRYPT_DIR ] || usage "$SCRYPT_DIR not found, did you mean to use generate?"
+ [ -d $SCRYPT_DIR_ORIG_ORIG ] || usage "$SCRYPT_DIR_ORIG not found, did you mean to use generate?"
+ regenerate $patch
+ elif [ "$command" = "generate" ]; then
+ declare -r patch=$1
+ shift || usage "No patch file specified."
+ declare -r tar=$1
+ shift || usage "No tar file specified."
+ generate $patch $tar
+ else
+ usage "Unknown command specified $command. Try import, regenerate, or generate."
+ fi
+}
+
+# Compute the name of an assembly source file generated by one of the
+# gen_asm_xxxx() functions below. The logic is the following:
+# - if "$2" is not empty, output it directly
+# - otherwise, change the file extension of $1 from .pl to .S and output
+# it.
+# Usage: default_asm_file "$1" "$2"
+# or default_asm_file "$@"
+#
+# $1: generator path (perl script)
+# $2: optional output file name.
+function default_asm_file () {
+ if [ "$2" ]; then
+ echo "$2"
+ else
+ echo "${1%%.pl}.S"
+ fi
+}
+
+# Generate an ARM assembly file.
+# $1: generator (perl script)
+# $2: [optional] output file name
+function gen_asm_arm () {
+ local OUT
+ OUT=$(default_asm_file "$@")
+ perl "$1" > "$OUT"
+}
+
+function gen_asm_mips () {
+ local OUT
+ OUT=$(default_asm_file "$@")
+ # The perl scripts expect to run the target compiler as $CC to determine
+ # the endianess of the target. Setting CC to true is a hack that forces the scripts
+ # to generate little endian output
+ CC=true perl "$1" o32 > "$OUT"
+}
+
+function gen_asm_x86 () {
+ local OUT
+ OUT=$(default_asm_file "$@")
+ perl "$1" elf -fPIC > "$OUT"
+}
+
+function gen_asm_x86_64 () {
+ local OUT
+ OUT=$(default_asm_file "$@")
+ perl "$1" elf "$OUT" > "$OUT"
+}
+
+
+# Filter all items in a list that match a given pattern.
+# $1: space-separated list
+# $2: egrep pattern.
+# Out: items in $1 that match $2
+function filter_by_egrep() {
+ declare -r pattern=$1
+ shift
+ echo "$@" | tr ' ' '\n' | grep -e "$pattern" | tr '\n' ' '
+}
+
+# Sort and remove duplicates in a space-separated list
+# $1: space-separated list
+# Out: new space-separated list
+function uniq_sort () {
+ echo "$@" | tr ' ' '\n' | sort -u | tr '\n' ' '
+}
+
+function print_autogenerated_header() {
+ echo "# Auto-generated - DO NOT EDIT!"
+ echo "# To regenerate, edit scrypt.config, then run:"
+ echo "# ./import_scrypt.sh import /path/to/scrypt-$SCRYPT_VERSION.tar.gz"
+ echo "#"
+}
+
+function generate_build_config_mk() {
+ ./configure $CONFIGURE_ARGS
+ #rm -f apps/CA.pl.bak crypto/scryptconf.h.bak
+
+ declare -r tmpfile=$(mktemp)
+ (grep -e -D Makefile | grep -v CONFIGURE_ARGS= | grep -v OPTIONS=) > $tmpfile
+
+ declare -r cflags=$(filter_by_egrep "^-D" $(grep -e "^CFLAG=" $tmpfile))
+ declare -r depflags=$(filter_by_egrep "^-D" $(grep -e "^DEPFLAG=" $tmpfile))
+ rm -f $tmpfile
+
+ echo "Generating $(basename $1)"
+ (
+ print_autogenerated_header
+
+ echo "scrypt_cflags := \\"
+ for cflag in $cflags $depflags; do
+ echo " $cflag \\"
+ done
+ echo ""
+ ) > $1
+}
+
+# Return the value of a computed variable name.
+# E.g.:
+# FOO=foo
+# BAR=bar
+# echo $(var_value FOO_$BAR) -> prints the value of ${FOO_bar}
+# $1: Variable name
+# Out: variable value
+var_value() {
+ # Note: don't use 'echo' here, because it's sensitive to values
+ # that begin with an underscore (e.g. "-n")
+ eval printf \"%s\\n\" \$$1
+}
+
+# Same as var_value, but returns sorted output without duplicates.
+# $1: Variable name
+# Out: variable value (if space-separated list, sorted with no duplicates)
+var_sorted_value() {
+ uniq_sort $(var_value $1)
+}
+
+# Print the definition of a given variable in a GNU Make build file.
+# $1: Variable name (e.g. common_src_files)
+# $2+: Variable value (e.g. list of sources)
+print_vardef_in_mk() {
+ declare -r varname=$1
+ shift
+ if [ -z "$1" ]; then
+ echo "$varname :="
+ else
+ echo "$varname := \\"
+ for src; do
+ echo " $src \\"
+ done
+ fi
+ echo ""
+}
+
+# Same as print_vardef_in_mk, but print a CFLAGS definition from
+# a list of compiler defines.
+# $1: Variable name (e.g. common_c_flags)
+# $2: List of defines (e.g. SCRYPT_NO_DONKEYS ...)
+print_defines_in_mk() {
+ declare -r varname=$1
+ shift
+ if [ -z "$1" ]; then
+ echo "$varname :="
+ else
+ echo "$varname := \\"
+ for def; do
+ echo " -D$def \\"
+ done
+ fi
+ echo ""
+}
+
+# Generate a configuration file like Scrypt-config.mk
+# This uses variable definitions from scrypt.config to build a config
+# file that can compute the list of target- and host-specific sources /
+# compiler flags for a given component.
+#
+# $1: Target file name. (e.g. Scrypt-config.mk)
+function generate_config_mk() {
+ declare -r output="$1"
+ declare -r all_archs="arm x86 x86_64 mips"
+
+ echo "Generating $(basename $output)"
+ (
+ print_autogenerated_header
+ echo \
+"# Before including this file, the local Android.mk must define the following
+# variables:
+#
+# local_c_flags
+# local_c_includes
+# local_additional_dependencies
+#
+# This script will define the following variables:
+#
+# target_c_flags
+# target_c_includes
+# target_src_files
+#
+# host_c_flags
+# host_c_includes
+# host_src_files
+#
+
+# Ensure these are empty.
+unknown_arch_c_flags :=
+unknown_arch_src_files :=
+unknown_arch_exclude_files :=
+
+"
+ common_defines=$(var_sorted_value SCRYPT_DEFINES)
+ print_defines_in_mk common_c_flags $common_defines
+
+ common_sources=$(var_sorted_value SCRYPT_SOURCES)
+ print_vardef_in_mk common_src_files $common_sources
+
+ common_includes=$(var_sorted_value SCRYPT_INCLUDES)
+ print_vardef_in_mk common_c_includes $common_includes
+
+ for arch in $all_archs; do
+ arch_defines=$(var_sorted_value SCRYPT_DEFINES_${arch})
+ print_defines_in_mk ${arch}_c_flags $arch_defines
+
+ arch_sources=$(var_sorted_value SCRYPT_SOURCES_${arch})
+ print_vardef_in_mk ${arch}_src_files $arch_sources
+
+ arch_exclude_sources=$(var_sorted_value SCRYPT_SOURCES_EXCLUDES_${arch})
+ print_vardef_in_mk ${arch}_exclude_files $arch_exclude_sources
+
+ done
+
+ echo "\
+target_arch := \$(TARGET_ARCH)
+ifeq (\$(target_arch)-\$(TARGET_HAS_BIGENDIAN),mips-true)
+target_arch := unknown_arch
+endif
+
+target_c_flags := \$(common_c_flags) \$(\$(target_arch)_c_flags) \$(local_c_flags)
+target_c_includes := \$(addprefix external/scrypt/,\$(common_c_includes)) \$(local_c_includes)
+target_src_files := \$(common_src_files) \$(\$(target_arch)_src_files)
+target_src_files := \$(filter-out \$(\$(target_arch)_exclude_files), \$(target_src_files))
+
+ifeq (\$(HOST_OS)-\$(HOST_ARCH),linux-x86)
+host_arch := x86
+else
+host_arch := unknown_arch
+endif
+
+host_c_flags := \$(common_c_flags) \$(\$(host_arch)_c_flags) \$(local_c_flags)
+host_c_includes := \$(addprefix external/scrypt/,\$(common_c_includes)) \$(local_c_includes)
+host_src_files := \$(common_src_files) \$(\$(host_arch)_src_files)
+host_src_files := \$(filter-out \$(\$(host_arch)_exclude_files), \$(host_src_files))
+
+local_additional_dependencies += \$(LOCAL_PATH)/$(basename $output)
+"
+
+ ) > "$output"
+}
+
+function import() {
+ declare -r SCRYPT_SOURCE=$1
+
+ untar $SCRYPT_SOURCE readonly
+ applypatches $SCRYPT_DIR
+
+ cd $SCRYPT_DIR
+
+ generate_build_config_mk ../build-config.mk
+
+ # Extract license from source file
+ sed '/^\/\*-/,/^ \*\//!d' lib/crypto/crypto_scrypt.h > ../NOTICE
+ touch ../MODULE_LICENSE_BSD_LIKE
+
+ cd ..
+
+ generate_config_mk Scrypt-config.mk
+
+ # Prune unnecessary sources
+ prune
+
+ NEEDED_SOURCES="$NEEDED_SOURCES"
+ for i in $NEEDED_SOURCES; do
+ echo "Updating $i"
+ rm -r $i
+ mv $SCRYPT_DIR/$i .
+ done
+
+ cleantar
+}
+
+function regenerate() {
+ declare -r patch=$1
+
+ generatepatch $patch
+}
+
+function generate() {
+ declare -r patch=$1
+ declare -r SCRYPT_SOURCE=$2
+
+ untar $SCRYPT_SOURCE
+ applypatches $SCRYPT_DIR_ORIG $patch
+ prune
+
+ for i in $NEEDED_SOURCES; do
+ echo "Restoring $i"
+ rm -r $SCRYPT_DIR/$i
+ cp -rf $i $SCRYPT_DIR/$i
+ done
+
+ generatepatch $patch
+ cleantar
+}
+
+# Find all files in a sub-directory that are encoded in ISO-8859
+# $1: Directory.
+# Out: list of files in $1 that are encoded as ISO-8859.
+function find_iso8859_files() {
+ find $1 -type f -print0 | xargs -0 file | fgrep "ISO-8859" | cut -d: -f1
+}
+
+# Convert all ISO-8859 files in a given subdirectory to UTF-8
+# $1: Directory name
+function convert_iso8859_to_utf8() {
+ declare -r iso_files=$(find_iso8859_files "$1")
+ for iso_file in $iso_files; do
+ iconv --from-code iso-8859-1 --to-code utf-8 $iso_file > $iso_file.tmp
+ rm -f $iso_file
+ mv $iso_file.tmp $iso_file
+ done
+}
+
+function untar() {
+ declare -r SCRYPT_SOURCE=$1
+ declare -r readonly=$2
+
+ # Remove old source
+ cleantar
+
+ # Process new source
+ tar -zxf $SCRYPT_SOURCE
+ convert_iso8859_to_utf8 $SCRYPT_DIR
+ cp -rfP $SCRYPT_DIR $SCRYPT_DIR_ORIG
+ if [ ! -z $readonly ]; then
+ find $SCRYPT_DIR_ORIG -type f -print0 | xargs -0 chmod a-w
+ fi
+}
+
+function prune() {
+ echo "Removing $UNNEEDED_SOURCES"
+ (cd $SCRYPT_DIR_ORIG && rm -rf $UNNEEDED_SOURCES)
+ (cd $SCRYPT_DIR && rm -r $UNNEEDED_SOURCES)
+}
+
+function cleantar() {
+ rm -rf $SCRYPT_DIR_ORIG
+ rm -rf $SCRYPT_DIR
+}
+
+function applypatches () {
+ declare -r dir=$1
+ declare -r skip_patch=$2
+
+ cd $dir
+
+ # Apply appropriate patches
+ for i in $SCRYPT_PATCHES; do
+ if [ ! "$skip_patch" = "patches/$i" ]; then
+ echo "Applying patch $i"
+ patch -p1 --merge < ../patches/$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
+ else
+ echo "Skiping patch $i"
+ fi
+
+ done
+
+ # Cleanup patch output
+ find . \( -type f -o -type l \) -name "*.orig" -print0 | xargs -0 rm -f
+
+ cd ..
+}
+
+function generatepatch() {
+ declare -r patch=$1
+
+ # Cleanup stray files before generating patch
+ find $SCRYPT_DIR -type f -name "*.orig" -print0 | xargs -0 rm -f
+ find $SCRYPT_DIR -type f -name "*~" -print0 | xargs -0 rm -f
+
+ declare -r variable_name=SCRYPT_PATCHES_`basename $patch .patch | sed s/-/_/`_SOURCES
+ # http://tldp.org/LDP/abs/html/ivr.html
+ eval declare -r sources=\$$variable_name
+ rm -f $patch
+ touch $patch
+ for i in $sources; do
+ LC_ALL=C TZ=UTC0 diff -aup $SCRYPT_DIR_ORIG/$i $SCRYPT_DIR/$i >> $patch && die "ERROR: No diff for patch $path in file $i"
+ done
+ echo "Generated patch $patch"
+ echo "NOTE To make sure there are not unwanted changes from conflicting patches, be sure to review the generated patch."
+}
+
+main $@
diff --git a/lib/README b/lib/README
new file mode 100644
index 0000000..3bb211e
--- /dev/null
+++ b/lib/README
@@ -0,0 +1,6 @@
+The source code under this directory is taken from the client for the
+Tarsnap online backup system (and released under the 2-clause BSD license
+with permission of the author); keeping this code in sync with the Tarsnap
+code is highly desirable and explains why there is some functionality
+included here which is not actually used by the scrypt file encryption
+utility.
diff --git a/lib/crypto/crypto_scrypt-ref.c b/lib/crypto/crypto_scrypt-ref.c
new file mode 100644
index 0000000..79a6f8f
--- /dev/null
+++ b/lib/crypto/crypto_scrypt-ref.c
@@ -0,0 +1,285 @@
+/*-
+ * 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 <errno.h>
+#include <stdint.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha256.h"
+#include "sysendian.h"
+
+#include "crypto_scrypt.h"
+
+static void blkcpy(uint8_t *, uint8_t *, size_t);
+static void blkxor(uint8_t *, uint8_t *, size_t);
+static void salsa20_8(uint8_t[64]);
+static void blockmix_salsa8(uint8_t *, uint8_t *, size_t);
+static uint64_t integerify(uint8_t *, size_t);
+static void smix(uint8_t *, size_t, uint64_t, uint8_t *, uint8_t *);
+
+static void
+blkcpy(uint8_t * dest, uint8_t * src, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ dest[i] = src[i];
+}
+
+static void
+blkxor(uint8_t * dest, uint8_t * src, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ dest[i] ^= src[i];
+}
+
+/**
+ * salsa20_8(B):
+ * Apply the salsa20/8 core to the provided block.
+ */
+static void
+salsa20_8(uint8_t B[64])
+{
+ uint32_t B32[16];
+ uint32_t x[16];
+ size_t i;
+
+ /* Convert little-endian values in. */
+ for (i = 0; i < 16; i++)
+ B32[i] = le32dec(&B[i * 4]);
+
+ /* Compute x = doubleround^4(B32). */
+ for (i = 0; i < 16; i++)
+ x[i] = B32[i];
+ for (i = 0; i < 8; i += 2) {
+#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+ /* Operate on columns. */
+ x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
+ x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
+
+ x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
+ x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
+
+ x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
+ x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
+
+ x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
+ x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
+
+ /* Operate on rows. */
+ x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
+ x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
+
+ x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
+ x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
+
+ x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
+ x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
+
+ x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
+ x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
+#undef R
+ }
+
+ /* Compute B32 = B32 + x. */
+ for (i = 0; i < 16; i++)
+ B32[i] += x[i];
+
+ /* Convert little-endian values out. */
+ for (i = 0; i < 16; i++)
+ le32enc(&B[4 * i], B32[i]);
+}
+
+/**
+ * blockmix_salsa8(B, Y, r):
+ * Compute B = BlockMix_{salsa20/8, r}(B). The input B must be 128r bytes in
+ * length; the temporary space Y must also be the same size.
+ */
+static void
+blockmix_salsa8(uint8_t * B, uint8_t * Y, size_t r)
+{
+ uint8_t X[64];
+ size_t i;
+
+ /* 1: X <-- B_{2r - 1} */
+ blkcpy(X, &B[(2 * r - 1) * 64], 64);
+
+ /* 2: for i = 0 to 2r - 1 do */
+ for (i = 0; i < 2 * r; i++) {
+ /* 3: X <-- H(X \xor B_i) */
+ blkxor(X, &B[i * 64], 64);
+ salsa20_8(X);
+
+ /* 4: Y_i <-- X */
+ blkcpy(&Y[i * 64], X, 64);
+ }
+
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ for (i = 0; i < r; i++)
+ blkcpy(&B[i * 64], &Y[(i * 2) * 64], 64);
+ for (i = 0; i < r; i++)
+ blkcpy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);
+}
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ */
+static uint64_t
+integerify(uint8_t * B, size_t r)
+{
+ uint8_t * X = &B[(2 * r - 1) * 64];
+
+ return (le64dec(X));
+}
+
+/**
+ * smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; the
+ * temporary storage V must be 128rN bytes in length; the temporary storage
+ * XY must be 256r bytes in length. The value N must be a power of 2.
+ */
+static void
+smix(uint8_t * B, size_t r, uint64_t N, uint8_t * V, uint8_t * XY)
+{
+ uint8_t * X = XY;
+ uint8_t * Y = &XY[128 * r];
+ uint64_t i;
+ uint64_t j;
+
+ /* 1: X <-- B */
+ blkcpy(X, B, 128 * r);
+
+ /* 2: for i = 0 to N - 1 do */
+ for (i = 0; i < N; i++) {
+ /* 3: V_i <-- X */
+ blkcpy(&V[i * (128 * r)], X, 128 * r);
+
+ /* 4: X <-- H(X) */
+ blockmix_salsa8(X, Y, r);
+ }
+
+ /* 6: for i = 0 to N - 1 do */
+ for (i = 0; i < N; i++) {
+ /* 7: j <-- Integerify(X) mod N */
+ j = integerify(X, r) & (N - 1);
+
+ /* 8: X <-- H(X \xor V_j) */
+ blkxor(X, &V[j * (128 * r)], 128 * r);
+ blockmix_salsa8(X, Y, r);
+ }
+
+ /* 10: B' <-- X */
+ blkcpy(B, X, 128 * r);
+}
+
+/**
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf. The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
+ * must be a power of 2.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int
+crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
+ const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
+ uint8_t * buf, size_t buflen)
+{
+ uint8_t * B;
+ uint8_t * V;
+ uint8_t * XY;
+ uint32_t i;
+
+ /* Sanity-check parameters. */
+#if SIZE_MAX > UINT32_MAX
+ if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
+ errno = EFBIG;
+ goto err0;
+ }
+#endif
+ if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
+ errno = EFBIG;
+ goto err0;
+ }
+ if (((N & (N - 1)) != 0) || (N == 0)) {
+ errno = EINVAL;
+ goto err0;
+ }
+ if ((r > SIZE_MAX / 128 / p) ||
+#if SIZE_MAX / 256 <= UINT32_MAX
+ (r > SIZE_MAX / 256) ||
+#endif
+ (N > SIZE_MAX / 128 / r)) {
+ errno = ENOMEM;
+ goto err0;
+ }
+
+ /* Allocate memory. */
+ if ((B = malloc(128 * r * p)) == NULL)
+ goto err0;
+ if ((XY = malloc(256 * r)) == NULL)
+ goto err1;
+ if ((V = malloc(128 * r * N)) == NULL)
+ goto err2;
+
+ /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
+
+ /* 2: for i = 0 to p - 1 do */
+ for (i = 0; i < p; i++) {
+ /* 3: B_i <-- MF(B_i, N) */
+ smix(&B[i * 128 * r], r, N, V, XY);
+ }
+
+ /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+ PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
+
+ /* Free memory. */
+ free(V);
+ free(XY);
+ free(B);
+
+ /* Success! */
+ return (0);
+
+err2:
+ free(XY);
+err1:
+ free(B);
+err0:
+ /* Failure! */
+ return (-1);
+}
diff --git a/lib/crypto/crypto_scrypt-sse.c b/lib/crypto/crypto_scrypt-sse.c
new file mode 100644
index 0000000..875175e
--- /dev/null
+++ b/lib/crypto/crypto_scrypt-sse.c
@@ -0,0 +1,366 @@
+/*-
+ * 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>
+#include <sys/mman.h>
+
+#include <emmintrin.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha256.h"
+#include "sysendian.h"
+
+#include "crypto_scrypt.h"
+
+static void blkcpy(void *, void *, size_t);
+static void blkxor(void *, void *, size_t);
+static void salsa20_8(__m128i *);
+static void blockmix_salsa8(__m128i *, __m128i *, __m128i *, size_t);
+static uint64_t integerify(void *, size_t);
+static void smix(uint8_t *, size_t, uint64_t, void *, void *);
+
+static void
+blkcpy(void * dest, void * src, size_t len)
+{
+ __m128i * D = dest;
+ __m128i * S = src;
+ size_t L = len / 16;
+ size_t i;
+
+ for (i = 0; i < L; i++)
+ D[i] = S[i];
+}
+
+static void
+blkxor(void * dest, void * src, size_t len)
+{
+ __m128i * D = dest;
+ __m128i * S = src;
+ size_t L = len / 16;
+ size_t i;
+
+ for (i = 0; i < L; i++)
+ D[i] = _mm_xor_si128(D[i], S[i]);
+}
+
+/**
+ * salsa20_8(B):
+ * Apply the salsa20/8 core to the provided block.
+ */
+static void
+salsa20_8(__m128i B[4])
+{
+ __m128i X0, X1, X2, X3;
+ __m128i T;
+ size_t i;
+
+ X0 = B[0];
+ X1 = B[1];
+ X2 = B[2];
+ X3 = B[3];
+
+ for (i = 0; i < 8; i += 2) {
+ /* Operate on "columns". */
+ T = _mm_add_epi32(X0, X3);
+ X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7));
+ X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25));
+ T = _mm_add_epi32(X1, X0);
+ X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
+ X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
+ T = _mm_add_epi32(X2, X1);
+ X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13));
+ X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19));
+ T = _mm_add_epi32(X3, X2);
+ X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
+ X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
+
+ /* Rearrange data. */
+ X1 = _mm_shuffle_epi32(X1, 0x93);
+ X2 = _mm_shuffle_epi32(X2, 0x4E);
+ X3 = _mm_shuffle_epi32(X3, 0x39);
+
+ /* Operate on "rows". */
+ T = _mm_add_epi32(X0, X1);
+ X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7));
+ X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25));
+ T = _mm_add_epi32(X3, X0);
+ X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
+ X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
+ T = _mm_add_epi32(X2, X3);
+ X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13));
+ X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19));
+ T = _mm_add_epi32(X1, X2);
+ X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
+ X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
+
+ /* Rearrange data. */
+ X1 = _mm_shuffle_epi32(X1, 0x39);
+ X2 = _mm_shuffle_epi32(X2, 0x4E);
+ X3 = _mm_shuffle_epi32(X3, 0x93);
+ }
+
+ B[0] = _mm_add_epi32(B[0], X0);
+ B[1] = _mm_add_epi32(B[1], X1);
+ B[2] = _mm_add_epi32(B[2], X2);
+ B[3] = _mm_add_epi32(B[3], X3);
+}
+
+/**
+ * blockmix_salsa8(Bin, Bout, X, r):
+ * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
+ * bytes in length; the output Bout must also be the same size. The
+ * temporary space X must be 64 bytes.
+ */
+static void
+blockmix_salsa8(__m128i * Bin, __m128i * Bout, __m128i * X, size_t r)
+{
+ size_t i;
+
+ /* 1: X <-- B_{2r - 1} */
+ blkcpy(X, &Bin[8 * r - 4], 64);
+
+ /* 2: for i = 0 to 2r - 1 do */
+ for (i = 0; i < r; i++) {
+ /* 3: X <-- H(X \xor B_i) */
+ blkxor(X, &Bin[i * 8], 64);
+ salsa20_8(X);
+
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ blkcpy(&Bout[i * 4], X, 64);
+
+ /* 3: X <-- H(X \xor B_i) */
+ blkxor(X, &Bin[i * 8 + 4], 64);
+ salsa20_8(X);
+
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ blkcpy(&Bout[(r + i) * 4], X, 64);
+ }
+}
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ */
+static uint64_t
+integerify(void * B, size_t r)
+{
+ uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64);
+
+ return (((uint64_t)(X[13]) << 32) + X[0]);
+}
+
+/**
+ * smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
+ * the temporary storage V must be 128rN bytes in length; the temporary
+ * storage XY must be 256r + 64 bytes in length. The value N must be a
+ * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
+ * multiple of 64 bytes.
+ */
+static void
+smix(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)
+{
+ __m128i * X = XY;
+ __m128i * Y = (void *)((uintptr_t)(XY) + 128 * r);
+ __m128i * Z = (void *)((uintptr_t)(XY) + 256 * r);
+ uint32_t * X32 = (void *)X;
+ uint64_t i, j;
+ size_t k;
+
+ /* 1: X <-- B */
+ for (k = 0; k < 2 * r; k++) {
+ for (i = 0; i < 16; i++) {
+ X32[k * 16 + i] =
+ le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
+ }
+ }
+
+ /* 2: for i = 0 to N - 1 do */
+ for (i = 0; i < N; i += 2) {
+ /* 3: V_i <-- X */
+ blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r);
+
+ /* 4: X <-- H(X) */
+ blockmix_salsa8(X, Y, Z, r);
+
+ /* 3: V_i <-- X */
+ blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r),
+ Y, 128 * r);
+
+ /* 4: X <-- H(X) */
+ blockmix_salsa8(Y, X, Z, r);
+ }
+
+ /* 6: for i = 0 to N - 1 do */
+ for (i = 0; i < N; i += 2) {
+ /* 7: j <-- Integerify(X) mod N */
+ j = integerify(X, r) & (N - 1);
+
+ /* 8: X <-- H(X \xor V_j) */
+ blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
+ blockmix_salsa8(X, Y, Z, r);
+
+ /* 7: j <-- Integerify(X) mod N */
+ j = integerify(Y, r) & (N - 1);
+
+ /* 8: X <-- H(X \xor V_j) */
+ blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
+ blockmix_salsa8(Y, X, Z, r);
+ }
+
+ /* 10: B' <-- X */
+ for (k = 0; k < 2 * r; k++) {
+ for (i = 0; i < 16; i++) {
+ le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],
+ X32[k * 16 + i]);
+ }
+ }
+}
+
+/**
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf. The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
+ * must be a power of 2 greater than 1.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int
+crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
+ const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
+ uint8_t * buf, size_t buflen)
+{
+ void * B0, * V0, * XY0;
+ uint8_t * B;
+ uint32_t * V;
+ uint32_t * XY;
+ uint32_t i;
+
+ /* Sanity-check parameters. */
+#if SIZE_MAX > UINT32_MAX
+ if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
+ errno = EFBIG;
+ goto err0;
+ }
+#endif
+ if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
+ errno = EFBIG;
+ goto err0;
+ }
+ if (((N & (N - 1)) != 0) || (N == 0)) {
+ errno = EINVAL;
+ goto err0;
+ }
+ if ((r > SIZE_MAX / 128 / p) ||
+#if SIZE_MAX / 256 <= UINT32_MAX
+ (r > (SIZE_MAX - 64) / 256) ||
+#endif
+ (N > SIZE_MAX / 128 / r)) {
+ errno = ENOMEM;
+ goto err0;
+ }
+
+ /* Allocate memory. */
+#ifdef HAVE_POSIX_MEMALIGN
+ if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
+ goto err0;
+ B = (uint8_t *)(B0);
+ if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
+ goto err1;
+ XY = (uint32_t *)(XY0);
+#ifndef MAP_ANON
+ if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
+ goto err2;
+ V = (uint32_t *)(V0);
+#endif
+#else
+ if ((B0 = malloc(128 * r * p + 63)) == NULL)
+ goto err0;
+ B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
+ if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
+ goto err1;
+ XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
+#ifndef MAP_ANON
+ if ((V0 = malloc(128 * r * N + 63)) == NULL)
+ goto err2;
+ V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
+#endif
+#endif
+#ifdef MAP_ANON
+ if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
+#ifdef MAP_NOCORE
+ MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
+#else
+ MAP_ANON | MAP_PRIVATE,
+#endif
+ -1, 0)) == MAP_FAILED)
+ goto err2;
+ V = (uint32_t *)(V0);
+#endif
+
+ /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
+
+ /* 2: for i = 0 to p - 1 do */
+ for (i = 0; i < p; i++) {
+ /* 3: B_i <-- MF(B_i, N) */
+ smix(&B[i * 128 * r], r, N, V, XY);
+ }
+
+ /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+ PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
+
+ /* Free memory. */
+#ifdef MAP_ANON
+ if (munmap(V0, 128 * r * N))
+ goto err2;
+#else
+ free(V0);
+#endif
+ free(XY0);
+ free(B0);
+
+ /* Success! */
+ return (0);
+
+err2:
+ free(XY0);
+err1:
+ free(B0);
+err0:
+ /* Failure! */
+ return (-1);
+}
diff --git a/lib/crypto/crypto_scrypt.h b/lib/crypto/crypto_scrypt.h
new file mode 100644
index 0000000..f72e1f4
--- /dev/null
+++ b/lib/crypto/crypto_scrypt.h
@@ -0,0 +1,46 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#ifndef _CRYPTO_SCRYPT_H_
+#define _CRYPTO_SCRYPT_H_
+
+#include <stdint.h>
+
+/**
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf. The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
+ * must be a power of 2 greater than 1.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
+ uint32_t, uint32_t, uint8_t *, size_t);
+
+#endif /* !_CRYPTO_SCRYPT_H_ */
diff --git a/lib/crypto/sha256.c b/lib/crypto/sha256.c
new file mode 100644
index 0000000..52148a3
--- /dev/null
+++ b/lib/crypto/sha256.c
@@ -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 --git a/lib/crypto/sha256.h b/lib/crypto/sha256.h
new file mode 100644
index 0000000..289a523
--- /dev/null
+++ b/lib/crypto/sha256.h
@@ -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 --git a/lib/util/sysendian.h b/lib/util/sysendian.h
new file mode 100644
index 0000000..62ef31a
--- /dev/null
+++ b/lib/util/sysendian.h
@@ -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 --git a/patches/README b/patches/README
new file mode 100644
index 0000000..79d0366
--- /dev/null
+++ b/patches/README
@@ -0,0 +1,3 @@
+bionic.patch:
+
+Allows scrypt to compile against bionic.
diff --git a/patches/bionic.patch b/patches/bionic.patch
new file mode 100644
index 0000000..4564ca0
--- /dev/null
+++ b/patches/bionic.patch
@@ -0,0 +1,12 @@
+diff --git a/lib/crypto/crypto_scrypt-ref.c b/lib/crypto/crypto_scrypt-ref.c
+index b47ca45..79a6f8f 100644
+--- a/lib/crypto/crypto_scrypt-ref.c
++++ b/lib/crypto/crypto_scrypt-ref.c
+@@ -30,6 +30,7 @@
+
+ #include <errno.h>
+ #include <stdint.h>
++#include <limits.h>
+ #include <stdlib.h>
+ #include <string.h>
+
diff --git a/scrypt.config b/scrypt.config
new file mode 100644
index 0000000..9ac5d74
--- /dev/null
+++ b/scrypt.config
@@ -0,0 +1,78 @@
+CONFIGURE_ARGS="\
+ \
+"
+
+# unneeded directories
+UNNEEDED_SOURCES="\
+lib/scryptenc \
+"
+
+# unneeded files
+UNNEEDED_SOURCES+="\
+config.h.in \
+configure \
+FORMAT \
+main.c \
+Makefile.in \
+scrypt.1 \
+lib/crypto/crypto_aesctr.c \
+lib/crypto/crypto_aesctr.h \
+lib/crypto/crypto_scrypt-nosse.c \
+lib/util/memlimit.c \
+lib/util/memlimit.h \
+lib/util/readpass.c \
+lib/util/readpass.h \
+lib/util/warn.c \
+lib/util/warn.h \
+"
+
+NEEDED_SOURCES="\
+config.h \
+lib \
+scrypt_platform.h \
+"
+
+SCRYPT_INCLUDES="\
+lib/crypto \
+lib/util \
+"
+
+SCRYPT_SOURCES="\
+lib/crypto/crypto_scrypt-ref.c \
+"
+
+SCRYPT_SOURCES_arm="\
+"
+
+SCRYPT_SOURCES_EXCLUDES_arm="\
+"
+
+SCRYPT_SOURCES_mips="\
+"
+
+SCRYPT_SOURCES_EXCLUDES_mips="\
+"
+
+SCRYPT_SOURCES_x86="\
+lib/crypto/crypto_scrypt-sse.c \
+"
+
+SCRYPT_SOURCES_EXCLUDES_x86="\
+lib/crypto/crypto_scrypt-ref.c \
+"
+
+SCRYPT_SOURCES_x86_64="\
+lib/crypto/crypto_scrypt-sse.c \
+"
+
+SCRYPT_SOURCES_EXCLUDES_x86_64="\
+lib/crypto/crypto_scrypt-ref.c \
+"
+
+SCRYPT_PATCHES="\
+bionic.patch
+"
+
+SCRYPT_PATCHES_bionic_SOURCES="\
+lib/crypto/crypto_scrypt-ref.c \
+"
diff --git a/scrypt.version b/scrypt.version
new file mode 100644
index 0000000..155e260
--- /dev/null
+++ b/scrypt.version
@@ -0,0 +1 @@
+SCRYPT_VERSION=1.1.6
diff --git a/scrypt_platform.h b/scrypt_platform.h
new file mode 100644
index 0000000..5cec236
--- /dev/null
+++ b/scrypt_platform.h
@@ -0,0 +1,12 @@
+#ifndef _SCRYPT_PLATFORM_H_
+#define _SCRYPT_PLATFORM_H_
+
+#if defined(CONFIG_H_FILE)
+#include CONFIG_H_FILE
+#elif defined(HAVE_CONFIG_H)
+#include "config.h"
+#else
+#error Need either CONFIG_H_FILE or HAVE_CONFIG_H defined.
+#endif
+
+#endif /* !_SCRYPT_PLATFORM_H_ */