Remove vendor/scrypt

This commit is contained in:
Sebastian Messmer 2018-05-19 14:34:24 -07:00
parent eb8682887f
commit fedcd95668
76 changed files with 0 additions and 17147 deletions

View File

@ -1,4 +1,3 @@
add_subdirectory(googletest)
add_subdirectory(scrypt)
add_subdirectory(spdlog)
add_subdirectory(cryptopp)

2
vendor/README vendored
View File

@ -1,6 +1,4 @@
This directory contains external projects, taken from the following locations:
scrypt: http://www.tarsnap.com/scrypt.html
- changed: commented out compiler warnings about a workaround for a llvm bug
googletest: https://github.com/google/googletest/tree/release-1.8.0
- changed: added NOLINT comment as workaround for clang-tidy warning https://github.com/google/googletest/issues/853
spdlog: https://github.com/gabime/spdlog/tree/v0.16.3/include/spdlog

View File

@ -1,46 +0,0 @@
include(ExternalProject)
project (scrypt C)
# This builds the original scrypt source using configure & make. We don't use their build result,
# but we use the config.h it creates somewhere on the way (see target_compile_options below).
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILDTYPE)
set(SCRYPT_CFLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BUILDTYPE}}")
# Add a default location for homebrew-installed openssl on Mac OS X to include search path
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(SCRYPT_CFLAGS "${SCRYPT_CFLAGS} -I/usr/local/opt/openssl/include")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
ExternalProject_Add(scrypt_original
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt
CONFIGURE_COMMAND /usr/bin/env CC=${CMAKE_C_COMPILER} CFLAGS=${SCRYPT_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/configure --prefix=${CMAKE_BINARY_DIR}/vendor/scrypt/
PREFIX ${CMAKE_BINARY_DIR}/vendor/scrypt/
BUILD_COMMAND ${MAKE}
)
add_library(${PROJECT_NAME} STATIC
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/lib/crypto/crypto_scrypt.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/lib/crypto/crypto_scrypt_smix.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/libcperciva/util/warnp.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/libcperciva/util/insecure_memzero.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/libcperciva/alg/sha256.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/libcperciva/cpusupport/cpusupport_x86_aesni.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/libcperciva/cpusupport/cpusupport_x86_sse2.c
)
target_link_libraries(${PROJECT_NAME}
${CMAKE_CURRENT_BINARY_DIR}/src/scrypt_original-build/libscrypt_sse2.a
${CMAKE_CURRENT_BINARY_DIR}/src/scrypt_original-build/libcperciva_aesni.a
)
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/libcperciva/cpusupport
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/libcperciva/alg
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1/scrypt/libcperciva/util
)
target_compile_options(${PROJECT_NAME} PRIVATE
-DCONFIG_H_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/src/scrypt_original-build/config.h\"
-DCPUSUPPORT_CONFIG_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/src/scrypt_original-build/cpusupport-config.h\"
-std=gnu99
)
add_dependencies(${PROJECT_NAME} scrypt_original)
target_include_directories(${PROJECT_NAME} SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1)

View File

@ -1,46 +0,0 @@
Installing
----------
We strongly recommend that people use the latest official release tarball on
https://www.tarsnap.com/scrypt.html, and build with:
./configure
make
make install
Platform-specific notes
-----------------------
- On OS X, the version of OpenSSL included with the operating
system is outdated (0.9.8) and deprecated, and it is recommended
that scrypt be built with an updated version of OpenSSL. On OS X
10.11 "El Capitan" and higher, OpenSSL was removed entirely. After
installing a newer version of OpenSSL, use
CPPFLAGS="-I /path/to/openssl/headers"
LDFLAGS="-L /path/to/openssl/lib"
to build scrypt.
In particular, if you installed OpenSSL using homebrew, you may
pass the relevant directories directly to ./configure:
./configure CPPFLAGS="-I/usr/local/opt/openssl/include" LDFLAGS="-L/usr/local/opt/openssl/lib"
Alternatively, you may with to add these lines to your $HOME/.profile file:
export CPPFLAGS="-I/usr/local/opt/openssl/include $CPPFLAGS"
export LDFLAGS="-L/usr/local/opt/openssl/lib $LDFLAGS"
and then close & re-open your terminal window.
Building from git
-----------------
For experimental development from git, build with:
autoreconf -i
./configure
make
- You must have automake 1.11.2 or higher.
- In order to support the `AX_CFLAGS_WARN_ALL` autoconf directive, you will
need to install the autoconf archive. On Debian systems, use the
`autoconf-archive` package; on FreeBSD, use `devel/autoconf-archive`.

View File

@ -1,27 +0,0 @@
The included code and documentation ("scrypt") is distributed under the
following terms:
Copyright 2005-2016 Colin Percival. All rights reserved.
Copyright 2005-2016 Tarsnap Backup Inc. All rights reserved.
Copyright 2014 Sean Kelly. 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.

View File

@ -1,18 +0,0 @@
scrypt encrypted data format
----------------------------
offset length
0 6 "scrypt"
6 1 scrypt data file version number (== 0)
7 1 log2(N) (must be between 1 and 63 inclusive)
8 4 r (big-endian integer; must satisfy r * p < 2^30)
12 4 p (big-endian integer; must satisfy r * p < 2^30)
16 32 salt
48 16 first 16 bytes of SHA256(bytes 0 .. 47)
64 32 HMAC-SHA256(bytes 0 .. 63)
96 X data xor AES256-CTR key stream generated with nonce == 0
96+X 32 HMAC-SHA256(bytes 0 .. 96 + (X - 1))
AES256-CTR is computed with a 256-bit AES key key_enc, and HMAC-SHA256 is
computed with a 256-bit key key_hmac, where
scrypt(password, salt, N, r, p, 64) == [key_enc][key_hmac]

File diff suppressed because it is too large Load Diff

View File

@ -1,113 +0,0 @@
bin_PROGRAMS= scrypt
noinst_PROGRAMS= tests/test_scrypt tests/valgrind/potential-memleaks
dist_man_MANS=$(scrypt_man_MANS)
scrypt_SOURCES= main.c \
libcperciva/alg/sha256.c \
libcperciva/cpusupport/cpusupport_x86_aesni.c \
libcperciva/cpusupport/cpusupport_x86_sse2.c \
libcperciva/crypto/crypto_aes.c \
libcperciva/crypto/crypto_aesctr.c \
libcperciva/crypto/crypto_entropy.c \
libcperciva/util/asprintf.c \
libcperciva/util/entropy.c \
libcperciva/util/getopt.c \
libcperciva/util/humansize.c \
libcperciva/util/insecure_memzero.c \
libcperciva/util/readpass.c \
libcperciva/util/warnp.c \
lib/crypto/crypto_scrypt.c \
lib/crypto/crypto_scrypt_smix.c \
lib/scryptenc/scryptenc.c \
lib/scryptenc/scryptenc_cpuperf.c \
lib/util/memlimit.c \
lib/crypto/crypto_scrypt.h \
lib/crypto/crypto_scrypt_smix.h \
lib/crypto/crypto_scrypt_smix_sse2.h \
lib/scryptenc/scryptenc.h \
lib/scryptenc/scryptenc_cpuperf.h \
lib/util/memlimit.h \
libcperciva/alg/sha256.h \
libcperciva/cpusupport/cpusupport.h \
libcperciva/crypto/crypto_aes.h \
libcperciva/crypto/crypto_aes_aesni.h \
libcperciva/crypto/crypto_aesctr.h \
libcperciva/crypto/crypto_entropy.h \
libcperciva/util/asprintf.h \
libcperciva/util/entropy.h \
libcperciva/util/getopt.h \
libcperciva/util/humansize.h \
libcperciva/util/insecure_memzero.h \
libcperciva/util/readpass.h \
libcperciva/util/sysendian.h \
libcperciva/util/warnp.h \
scrypt_platform.h
AM_CPPFLAGS= -I$(srcdir)/libcperciva/alg \
-I$(srcdir)/libcperciva/cpusupport \
-I$(srcdir)/libcperciva/crypto \
-I$(srcdir)/libcperciva/util \
-I$(srcdir)/lib/crypto \
-I$(srcdir)/lib/scryptenc \
-I$(srcdir)/lib/util \
-DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" \
-D_POSIX_C_SOURCE=200809L
scrypt_LDADD= libcperciva_aesni.a libscrypt_sse2.a
scrypt_man_MANS= scrypt.1
cpusupport-config.h:
( export CC="${CC}"; export CFLAGS="${CFLAGS}"; command -p sh $(srcdir)/libcperciva/cpusupport/Build/cpusupport.sh "$$PATH") > cpusupport-config.h.tmp && command -p mv cpusupport-config.h.tmp cpusupport-config.h
BUILT_SOURCES= cpusupport-config.h
CLEANFILES= cpusupport-config.h cpusupport-config.h.tmp
noinst_LIBRARIES= libcperciva_aesni.a
libcperciva_aesni_a_SOURCES= libcperciva/crypto/crypto_aes_aesni.c
libcperciva_aesni_a_CFLAGS=`. ./cpusupport-config.h; echo $${CFLAGS_X86_AESNI}`
noinst_LIBRARIES+= libscrypt_sse2.a
libscrypt_sse2_a_SOURCES= lib/crypto/crypto_scrypt_smix_sse2.c
libscrypt_sse2_a_CFLAGS=`. ./cpusupport-config.h; echo $${CFLAGS_X86_SSE2}`
EXTRA_DIST = \
COPYRIGHT \
FORMAT \
lib/README \
README.md \
lib/crypto/crypto_scrypt-ref.c \
libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c \
libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c \
libcperciva/cpusupport/Build/cpusupport-X86-SSE2.c \
libcperciva/cpusupport/Build/cpusupport.sh \
tests/test_scrypt.good \
tests/test_scrypt_good.enc \
tests/shared_test_functions.sh \
tests/01-known-values.sh \
tests/02-decrypt-reference-file.sh \
tests/03-encrypt-decrypt-file.sh \
tests/04-force-resources.sh \
tests/05-system-scrypt-encrypt-decrypt.sh \
tests/test_scrypt.sh
tests_test_scrypt_SOURCES = tests/test_scrypt.c \
libcperciva/alg/sha256.c \
libcperciva/alg/sha256.h \
libcperciva/cpusupport/cpusupport_x86_sse2.c \
libcperciva/util/insecure_memzero.c \
libcperciva/util/insecure_memzero.h \
libcperciva/util/warnp.c \
libcperciva/util/warnp.h \
lib/crypto/crypto_scrypt.c \
lib/crypto/crypto_scrypt.h \
lib/crypto/crypto_scrypt_smix.c \
lib/crypto/crypto_scrypt_smix.h
tests_test_scrypt_LDADD= libscrypt_sse2.a
tests_valgrind_potential_memleaks_SOURCES = tests/valgrind/potential-memleaks.c
.PHONY: test
# we can't only build "scrypt tests/test_scrypt" because that won't build
# the BUILT_SOURCES.
test: all
$(top_srcdir)/tests/test_scrypt.sh .

View File

@ -1,69 +0,0 @@
AC_PREREQ([2.69])
AC_INIT([scrypt],1.2.1,
[https://github.com/Tarsnap/scrypt],[scrypt],[http://www.tarsnap.com/scrypt/])
AC_CONFIG_SRCDIR([lib/scryptenc/scryptenc.c])
AC_CONFIG_AUX_DIR([config.aux])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign subdir-objects -Wall])
# Checks for programs.
AC_PROG_CC_C99
AC_PROG_RANLIB
AM_PROG_AR
# Don't rebuild the configure script. I'm distributing a perfectly good one.
AM_MAINTAINER_MODE
# Checks for libraries.
# Check for clock_gettime. On some systems, this is provided via librt.
AC_SEARCH_LIBS([clock_gettime], [rt])
AC_CHECK_FUNCS([clock_gettime])
AC_SEARCH_LIBS([AES_encrypt], [crypto],,
AC_MSG_ERROR([function AES_ENCRYPT not found]))
# Check for a linuxy sysinfo syscall; and while we're doing that, check if
# struct sysinfo is the old version (total RAM == totalmem) or the new
# version (total RAM == totalmem * mem_unit).
AC_CHECK_HEADERS([sys/sysinfo.h])
AC_CHECK_FUNCS([sysinfo])
AC_CHECK_TYPES([struct sysinfo], [], [], [[#include <sys/sysinfo.h>]])
AC_CHECK_MEMBERS([struct sysinfo.totalram, struct sysinfo.mem_unit], [], [],
[[#include <sys/sysinfo.h>]])
# Check if we have <sys/param.h>, since some systems require it for sysctl
# to work.
AC_CHECK_HEADERS([sys/param.h])
# Check if we have <openssl/aes.h>, to fix the make failing when configure
# passes.
AC_CHECK_HEADERS([openssl/aes.h],,
[AC_MSG_ERROR([Unable to find the openssl/aes.h header])])
# Check for <sys/sysctl.h>. If it exists and it defines HW_USERMEM
# and/or HW_MEMSIZE, we'll try using those as memory limits.
AC_CHECK_HEADERS([sys/sysctl.h])
# Check for posix_memalign
AC_CHECK_FUNCS([posix_memalign])
# Check for mmap so we can work around its absence on Minix
AC_CHECK_FUNCS([mmap])
AC_SYS_LARGEFILE
# Check whether the user has requested to disable compiler warnings
AC_MSG_CHECKING([compiler_warnings])
AC_ARG_ENABLE(compiler_warnings,
AS_HELP_STRING([--disable-compiler-warnings],
[Do not request compiler warnings. @<:@default=enabled@:>@]),
[ac_compiler_warnings=$enableval],
[ac_compiler_warnings=yes])
AC_MSG_RESULT([${ac_compiler_warnings}])
AS_IF([test x${ac_compiler_warnings} = xyes],
[AX_CFLAGS_WARN_ALL])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View File

@ -1,270 +0,0 @@
#! /bin/sh
# Wrapper for Microsoft lib.exe
me=ar-lib
scriptversion=2012-03-01.08; # UTC
# Copyright (C) 2010-2014 Free Software Foundation, Inc.
# Written by Peter Rosin <peda@lysator.liu.se>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
# func_error message
func_error ()
{
echo "$me: $1" 1>&2
exit 1
}
file_conv=
# func_file_conv build_file
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv in
mingw)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin)
file=`cygpath -m "$file" || echo "$file"`
;;
wine)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_at_file at_file operation archive
# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
# for each of them.
# When interpreting the content of the @FILE, do NOT use func_file_conv,
# since the user would need to supply preconverted file names to
# binutils ar, at least for MinGW.
func_at_file ()
{
operation=$2
archive=$3
at_file_contents=`cat "$1"`
eval set x "$at_file_contents"
shift
for member
do
$AR -NOLOGO $operation:"$member" "$archive" || exit $?
done
}
case $1 in
'')
func_error "no command. Try '$0 --help' for more information."
;;
-h | --h*)
cat <<EOF
Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
Members may be specified in a file named with @FILE.
EOF
exit $?
;;
-v | --v*)
echo "$me, version $scriptversion"
exit $?
;;
esac
if test $# -lt 3; then
func_error "you must specify a program, an action and an archive"
fi
AR=$1
shift
while :
do
if test $# -lt 2; then
func_error "you must specify a program, an action and an archive"
fi
case $1 in
-lib | -LIB \
| -ltcg | -LTCG \
| -machine* | -MACHINE* \
| -subsystem* | -SUBSYSTEM* \
| -verbose | -VERBOSE \
| -wx* | -WX* )
AR="$AR $1"
shift
;;
*)
action=$1
shift
break
;;
esac
done
orig_archive=$1
shift
func_file_conv "$orig_archive"
archive=$file
# strip leading dash in $action
action=${action#-}
delete=
extract=
list=
quick=
replace=
index=
create=
while test -n "$action"
do
case $action in
d*) delete=yes ;;
x*) extract=yes ;;
t*) list=yes ;;
q*) quick=yes ;;
r*) replace=yes ;;
s*) index=yes ;;
S*) ;; # the index is always updated implicitly
c*) create=yes ;;
u*) ;; # TODO: don't ignore the update modifier
v*) ;; # TODO: don't ignore the verbose modifier
*)
func_error "unknown action specified"
;;
esac
action=${action#?}
done
case $delete$extract$list$quick$replace,$index in
yes,* | ,yes)
;;
yesyes*)
func_error "more than one action specified"
;;
*)
func_error "no action specified"
;;
esac
if test -n "$delete"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
for member
do
case $1 in
@*)
func_at_file "${1#@}" -REMOVE "$archive"
;;
*)
func_file_conv "$1"
$AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
;;
esac
done
elif test -n "$extract"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
if test $# -gt 0; then
for member
do
case $1 in
@*)
func_at_file "${1#@}" -EXTRACT "$archive"
;;
*)
func_file_conv "$1"
$AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
;;
esac
done
else
$AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
do
$AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
done
fi
elif test -n "$quick$replace"; then
if test ! -f "$orig_archive"; then
if test -z "$create"; then
echo "$me: creating $orig_archive"
fi
orig_archive=
else
orig_archive=$archive
fi
for member
do
case $1 in
@*)
func_file_conv "${1#@}"
set x "$@" "@$file"
;;
*)
func_file_conv "$1"
set x "$@" "$file"
;;
esac
shift
shift
done
if test -n "$orig_archive"; then
$AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
else
$AR -NOLOGO -OUT:"$archive" "$@" || exit $?
fi
elif test -n "$list"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
$AR -NOLOGO -LIST "$archive" || exit $?
fi

View File

@ -1,347 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,791 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2013-05-30.07; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,501 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2013-12-25.23; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,215 +0,0 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2013-10-28.13; # UTC
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,99 +0,0 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define to 1 if you have the <openssl/aes.h> header file. */
#undef HAVE_OPENSSL_AES_H
/* Define to 1 if you have the `posix_memalign' function. */
#undef HAVE_POSIX_MEMALIGN
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if the system has the type `struct sysinfo'. */
#undef HAVE_STRUCT_SYSINFO
/* Define to 1 if `mem_unit' is a member of `struct sysinfo'. */
#undef HAVE_STRUCT_SYSINFO_MEM_UNIT
/* Define to 1 if `totalram' is a member of `struct sysinfo'. */
#undef HAVE_STRUCT_SYSINFO_TOTALRAM
/* Define to 1 if you have the `sysinfo' function. */
#undef HAVE_SYSINFO
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#undef HAVE_SYS_SYSCTL_H
/* Define to 1 if you have the <sys/sysinfo.h> header file. */
#undef HAVE_SYS_SYSINFO_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* 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

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
The source code under this directory is taken from the client for the
Tarsnap online backup system (and released under the 2-clause BSD license
with permission of the author); keeping this code in sync with the Tarsnap
code is highly desirable and explains why there is some functionality
included here which is not actually used by the scrypt file encryption
utility.

View File

@ -1,285 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#include "scrypt_platform.h"
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "sha256.h"
#include "sysendian.h"
#include "crypto_scrypt.h"
static void blkcpy(uint8_t *, uint8_t *, size_t);
static void blkxor(uint8_t *, uint8_t *, size_t);
static void salsa20_8(uint8_t[64]);
static void blockmix_salsa8(uint8_t *, uint8_t *, size_t);
static uint64_t integerify(uint8_t *, size_t);
static void smix(uint8_t *, size_t, uint64_t, uint8_t *, uint8_t *);
static void
blkcpy(uint8_t * dest, uint8_t * src, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
dest[i] = src[i];
}
static void
blkxor(uint8_t * dest, uint8_t * src, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
dest[i] ^= src[i];
}
/**
* salsa20_8(B):
* Apply the salsa20/8 core to the provided block.
*/
static void
salsa20_8(uint8_t B[64])
{
uint32_t B32[16];
uint32_t x[16];
size_t i;
/* Convert little-endian values in. */
for (i = 0; i < 16; i++)
B32[i] = le32dec(&B[i * 4]);
/* Compute x = doubleround^4(B32). */
for (i = 0; i < 16; i++)
x[i] = B32[i];
for (i = 0; i < 8; i += 2) {
#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
/* Operate on columns. */
x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
/* Operate on rows. */
x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
#undef R
}
/* Compute B32 = B32 + x. */
for (i = 0; i < 16; i++)
B32[i] += x[i];
/* Convert little-endian values out. */
for (i = 0; i < 16; i++)
le32enc(&B[4 * i], B32[i]);
}
/**
* blockmix_salsa8(B, Y, r):
* Compute B = BlockMix_{salsa20/8, r}(B). The input B must be 128r bytes in
* length; the temporary space Y must also be the same size.
*/
static void
blockmix_salsa8(uint8_t * B, uint8_t * Y, size_t r)
{
uint8_t X[64];
size_t i;
/* 1: X <-- B_{2r - 1} */
blkcpy(X, &B[(2 * r - 1) * 64], 64);
/* 2: for i = 0 to 2r - 1 do */
for (i = 0; i < 2 * r; i++) {
/* 3: X <-- H(X \xor B_i) */
blkxor(X, &B[i * 64], 64);
salsa20_8(X);
/* 4: Y_i <-- X */
blkcpy(&Y[i * 64], X, 64);
}
/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
for (i = 0; i < r; i++)
blkcpy(&B[i * 64], &Y[(i * 2) * 64], 64);
for (i = 0; i < r; i++)
blkcpy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);
}
/**
* integerify(B, r):
* Return the result of parsing B_{2r-1} as a little-endian integer.
*/
static uint64_t
integerify(uint8_t * B, size_t r)
{
uint8_t * X = &B[(2 * r - 1) * 64];
return (le64dec(X));
}
/**
* smix(B, r, N, V, XY):
* Compute B = SMix_r(B, N). The input B must be 128r bytes in length; the
* temporary storage V must be 128rN bytes in length; the temporary storage
* XY must be 256r bytes in length. The value N must be a power of 2.
*/
static void
smix(uint8_t * B, size_t r, uint64_t N, uint8_t * V, uint8_t * XY)
{
uint8_t * X = XY;
uint8_t * Y = &XY[128 * r];
uint64_t i;
uint64_t j;
/* 1: X <-- B */
blkcpy(X, B, 128 * r);
/* 2: for i = 0 to N - 1 do */
for (i = 0; i < N; i++) {
/* 3: V_i <-- X */
blkcpy(&V[i * (128 * r)], X, 128 * r);
/* 4: X <-- H(X) */
blockmix_salsa8(X, Y, r);
}
/* 6: for i = 0 to N - 1 do */
for (i = 0; i < N; i++) {
/* 7: j <-- Integerify(X) mod N */
j = integerify(X, r) & (N - 1);
/* 8: X <-- H(X \xor V_j) */
blkxor(X, &V[j * (128 * r)], 128 * r);
blockmix_salsa8(X, Y, r);
}
/* 10: B' <-- X */
blkcpy(B, X, 128 * r);
}
/**
* crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
* Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
* p, buflen) and write the result into buf. The parameters r, p, and buflen
* must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
* must be a power of 2.
*
* Return 0 on success; or -1 on error.
*/
int
crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
uint8_t * buf, size_t buflen)
{
uint8_t * B;
uint8_t * V;
uint8_t * XY;
size_t r = _r, p = _p;
uint32_t i;
/* Sanity-check parameters. */
#if SIZE_MAX > UINT32_MAX
if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
errno = EFBIG;
goto err0;
}
#endif
if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
errno = EFBIG;
goto err0;
}
if (((N & (N - 1)) != 0) || (N == 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);
}

View File

@ -1,252 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#include "scrypt_platform.h"
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "cpusupport.h"
#include "sha256.h"
#include "warnp.h"
#include "crypto_scrypt_smix.h"
#include "crypto_scrypt_smix_sse2.h"
#include "crypto_scrypt.h"
static void (*smix_func)(uint8_t *, size_t, uint64_t, void *, void *) = NULL;
/**
* _crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen, smix):
* Perform the requested scrypt computation, using ${smix} as the smix routine.
*/
static int
_crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
uint8_t * buf, size_t buflen,
void (*smix)(uint8_t *, size_t, uint64_t, void *, void *))
{
void * B0, * V0, * XY0;
uint8_t * B;
uint32_t * V;
uint32_t * XY;
size_t r = _r, p = _p;
uint32_t i;
/* Sanity-check parameters. */
#if SIZE_MAX > UINT32_MAX
if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
errno = EFBIG;
goto err0;
}
#endif
if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
errno = EFBIG;
goto err0;
}
if (((N & (N - 1)) != 0) || (N < 2)) {
errno = EINVAL;
goto err0;
}
if ((r > SIZE_MAX / 128 / p) ||
#if SIZE_MAX / 256 <= UINT32_MAX
(r > (SIZE_MAX - 64) / 256) ||
#endif
(N > SIZE_MAX / 128 / r)) {
errno = ENOMEM;
goto err0;
}
/* Allocate memory. */
#ifdef HAVE_POSIX_MEMALIGN
if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
goto err0;
B = (uint8_t *)(B0);
if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
goto err1;
XY = (uint32_t *)(XY0);
#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
if ((errno = posix_memalign(&V0, 64, (size_t)(128 * r * N))) != 0)
goto err2;
V = (uint32_t *)(V0);
#endif
#else
if ((B0 = malloc(128 * r * p + 63)) == NULL)
goto err0;
B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
goto err1;
XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
if ((V0 = malloc(128 * r * N + 63)) == NULL)
goto err2;
V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
#endif
#endif
#if defined(MAP_ANON) && defined(HAVE_MMAP)
if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
#ifdef MAP_NOCORE
MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
#else
MAP_ANON | MAP_PRIVATE,
#endif
-1, 0)) == MAP_FAILED)
goto err2;
V = (uint32_t *)(V0);
#endif
/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
/* 2: for i = 0 to p - 1 do */
for (i = 0; i < p; i++) {
/* 3: B_i <-- MF(B_i, N) */
(smix)(&B[i * 128 * r], r, N, V, XY);
}
/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
/* Free memory. */
#if defined(MAP_ANON) && defined(HAVE_MMAP)
if (munmap(V0, 128 * r * N))
goto err2;
#else
free(V0);
#endif
free(XY0);
free(B0);
/* Success! */
return (0);
err2:
free(XY0);
err1:
free(B0);
err0:
/* Failure! */
return (-1);
}
#define TESTLEN 64
static struct scrypt_test {
const char * passwd;
const char * salt;
uint64_t N;
uint32_t r;
uint32_t p;
uint8_t result[TESTLEN];
} testcase = {
.passwd = "pleaseletmein",
.salt = "SodiumChloride",
.N = 16,
.r = 8,
.p = 1,
.result = {
0x25, 0xa9, 0xfa, 0x20, 0x7f, 0x87, 0xca, 0x09,
0xa4, 0xef, 0x8b, 0x9f, 0x77, 0x7a, 0xca, 0x16,
0xbe, 0xb7, 0x84, 0xae, 0x18, 0x30, 0xbf, 0xbf,
0xd3, 0x83, 0x25, 0xaa, 0xbb, 0x93, 0x77, 0xdf,
0x1b, 0xa7, 0x84, 0xd7, 0x46, 0xea, 0x27, 0x3b,
0xf5, 0x16, 0xa4, 0x6f, 0xbf, 0xac, 0xf5, 0x11,
0xc5, 0xbe, 0xba, 0x4c, 0x4a, 0xb3, 0xac, 0xc7,
0xfa, 0x6f, 0x46, 0x0b, 0x6c, 0x0f, 0x47, 0x7b,
}
};
static int
testsmix(void (*smix)(uint8_t *, size_t, uint64_t, void *, void *))
{
uint8_t hbuf[TESTLEN];
/* Perform the computation. */
if (_crypto_scrypt(
(const uint8_t *)testcase.passwd, strlen(testcase.passwd),
(const uint8_t *)testcase.salt, strlen(testcase.salt),
testcase.N, testcase.r, testcase.p, hbuf, TESTLEN, smix))
return (-1);
/* Does it match? */
return (memcmp(testcase.result, hbuf, TESTLEN));
}
static void
selectsmix(void)
{
#ifdef CPUSUPPORT_X86_SSE2
/* If we're running on an SSE2-capable CPU, try that code. */
if (cpusupport_x86_sse2()) {
/* If SSE2ized smix works, use it. */
if (!testsmix(crypto_scrypt_smix_sse2)) {
smix_func = crypto_scrypt_smix_sse2;
return;
}
warn0("Disabling broken SSE2 scrypt support - please report bug!");
}
#endif
/* If generic smix works, use it. */
if (!testsmix(crypto_scrypt_smix)) {
smix_func = crypto_scrypt_smix;
return;
}
warn0("Generic scrypt code is broken - please report bug!");
/* If we get here, something really bad happened. */
abort();
}
/**
* crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
* Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
* p, buflen) and write the result into buf. The parameters r, p, and buflen
* must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
* must be a power of 2 greater than 1.
*
* Return 0 on success; or -1 on error.
*/
int
crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
uint8_t * buf, size_t buflen)
{
if (smix_func == NULL)
selectsmix();
return (_crypto_scrypt(passwd, passwdlen, salt, saltlen, N, _r, _p,
buf, buflen, smix_func));
}

View File

@ -1,47 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#ifndef _CRYPTO_SCRYPT_H_
#define _CRYPTO_SCRYPT_H_
#include <stdint.h>
#include <unistd.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_ */

View File

@ -1,213 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#include <stdint.h>
#include "sysendian.h"
#include "crypto_scrypt_smix.h"
static void blkcpy(void *, const void *, size_t);
static void blkxor(void *, const void *, size_t);
static void salsa20_8(uint32_t[16]);
static void blockmix_salsa8(const uint32_t *, uint32_t *, uint32_t *, size_t);
static uint64_t integerify(const void *, size_t);
static 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 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 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]);
}
/**
* crypto_scrypt_smix(B, r, N, V, XY):
* Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
* the temporary storage V must be 128rN bytes in length; the temporary
* storage XY must be 256r + 64 bytes in length. The value N must be a
* power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
* multiple of 64 bytes.
*/
void
crypto_scrypt_smix(uint8_t * B, size_t r, uint64_t N, void * _V, void * XY)
{
uint32_t * X = XY;
uint32_t * Y = (void *)((uint8_t *)(XY) + 128 * r);
uint32_t * Z = (void *)((uint8_t *)(XY) + 256 * r);
uint32_t * V = _V;
uint64_t i;
uint64_t j;
size_t k;
/* 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]);
}

View File

@ -1,17 +0,0 @@
#ifndef _CRYPTO_SCRYPT_SMIX_H_
#define _CRYPTO_SCRYPT_SMIX_H_
#include <stddef.h>
#include <stdint.h>
/**
* crypto_scrypt_smix(B, r, N, V, XY):
* Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
* the temporary storage V must be 128rN bytes in length; the temporary
* storage XY must be 256r + 64 bytes in length. The value N must be a
* power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
* multiple of 64 bytes.
*/
void crypto_scrypt_smix(uint8_t *, size_t, uint64_t, void *, void *);
#endif /* !_CRYPTO_SCRYPT_SMIX_H_ */

View File

@ -1,248 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#include "cpusupport.h"
#ifdef CPUSUPPORT_X86_SSE2
#include <emmintrin.h>
#include <stdint.h>
#include "sysendian.h"
#include "crypto_scrypt_smix_sse2.h"
static void blkcpy(void *, const void *, size_t);
static void blkxor(void *, const void *, size_t);
static void salsa20_8(__m128i *);
static void blockmix_salsa8(const __m128i *, __m128i *, __m128i *, size_t);
static uint64_t integerify(const void *, size_t);
static void
blkcpy(void * dest, const void * src, size_t len)
{
__m128i * D = dest;
const __m128i * S = src;
size_t L = len / 16;
size_t i;
for (i = 0; i < L; i++)
D[i] = S[i];
}
static void
blkxor(void * dest, const void * src, size_t len)
{
__m128i * D = dest;
const __m128i * S = src;
size_t L = len / 16;
size_t i;
for (i = 0; i < L; i++)
D[i] = _mm_xor_si128(D[i], S[i]);
}
/**
* salsa20_8(B):
* Apply the salsa20/8 core to the provided block.
*/
static void
salsa20_8(__m128i B[4])
{
__m128i X0, X1, X2, X3;
__m128i T;
size_t i;
X0 = B[0];
X1 = B[1];
X2 = B[2];
X3 = B[3];
for (i = 0; i < 8; i += 2) {
/* Operate on "columns". */
T = _mm_add_epi32(X0, X3);
X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7));
X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25));
T = _mm_add_epi32(X1, X0);
X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
T = _mm_add_epi32(X2, X1);
X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13));
X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19));
T = _mm_add_epi32(X3, X2);
X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
/* Rearrange data. */
X1 = _mm_shuffle_epi32(X1, 0x93);
X2 = _mm_shuffle_epi32(X2, 0x4E);
X3 = _mm_shuffle_epi32(X3, 0x39);
/* Operate on "rows". */
T = _mm_add_epi32(X0, X1);
X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7));
X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25));
T = _mm_add_epi32(X3, X0);
X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
T = _mm_add_epi32(X2, X3);
X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13));
X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19));
T = _mm_add_epi32(X1, X2);
X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
/* Rearrange data. */
X1 = _mm_shuffle_epi32(X1, 0x39);
X2 = _mm_shuffle_epi32(X2, 0x4E);
X3 = _mm_shuffle_epi32(X3, 0x93);
}
B[0] = _mm_add_epi32(B[0], X0);
B[1] = _mm_add_epi32(B[1], X1);
B[2] = _mm_add_epi32(B[2], X2);
B[3] = _mm_add_epi32(B[3], X3);
}
/**
* blockmix_salsa8(Bin, Bout, X, r):
* Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
* bytes in length; the output Bout must also be the same size. The
* temporary space X must be 64 bytes.
*/
static void
blockmix_salsa8(const __m128i * Bin, __m128i * Bout, __m128i * X, size_t r)
{
size_t i;
/* 1: X <-- B_{2r - 1} */
blkcpy(X, &Bin[8 * r - 4], 64);
/* 2: for i = 0 to 2r - 1 do */
for (i = 0; i < r; i++) {
/* 3: X <-- H(X \xor B_i) */
blkxor(X, &Bin[i * 8], 64);
salsa20_8(X);
/* 4: Y_i <-- X */
/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
blkcpy(&Bout[i * 4], X, 64);
/* 3: X <-- H(X \xor B_i) */
blkxor(X, &Bin[i * 8 + 4], 64);
salsa20_8(X);
/* 4: Y_i <-- X */
/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
blkcpy(&Bout[(r + i) * 4], X, 64);
}
}
/**
* integerify(B, r):
* Return the result of parsing B_{2r-1} as a little-endian integer.
* Note that B's layout is permuted compared to the generic implementation.
*/
static uint64_t
integerify(const void * B, size_t r)
{
const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64);
return (((uint64_t)(X[13]) << 32) + X[0]);
}
/**
* crypto_scrypt_smix_sse2(B, r, N, V, XY):
* Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
* the temporary storage V must be 128rN bytes in length; the temporary
* storage XY must be 256r + 64 bytes in length. The value N must be a
* power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
* multiple of 64 bytes.
*
* Use SSE2 instructions.
*/
void
crypto_scrypt_smix_sse2(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)
{
__m128i * X = XY;
__m128i * Y = (void *)((uintptr_t)(XY) + 128 * r);
__m128i * Z = (void *)((uintptr_t)(XY) + 256 * r);
uint32_t * X32 = (void *)X;
uint64_t i, j;
size_t k;
/* 1: X <-- B */
for (k = 0; k < 2 * r; k++) {
for (i = 0; i < 16; i++) {
X32[k * 16 + i] =
le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
}
}
/* 2: for i = 0 to N - 1 do */
for (i = 0; i < N; i += 2) {
/* 3: V_i <-- X */
blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r);
/* 4: X <-- H(X) */
blockmix_salsa8(X, Y, Z, r);
/* 3: V_i <-- X */
blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r),
Y, 128 * r);
/* 4: X <-- H(X) */
blockmix_salsa8(Y, X, Z, r);
}
/* 6: for i = 0 to N - 1 do */
for (i = 0; i < N; i += 2) {
/* 7: j <-- Integerify(X) mod N */
j = integerify(X, r) & (N - 1);
/* 8: X <-- H(X \xor V_j) */
blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
blockmix_salsa8(X, Y, Z, r);
/* 7: j <-- Integerify(X) mod N */
j = integerify(Y, r) & (N - 1);
/* 8: X <-- H(X \xor V_j) */
blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
blockmix_salsa8(Y, X, Z, r);
}
/* 10: B' <-- X */
for (k = 0; k < 2 * r; k++) {
for (i = 0; i < 16; i++) {
le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],
X32[k * 16 + i]);
}
}
}
#endif /* CPUSUPPORT_X86_SSE2 */

View File

@ -1,19 +0,0 @@
#ifndef _CRYPTO_SCRYPT_SMIX_SSE2_H_
#define _CRYPTO_SCRYPT_SMIX_SSE2_H_
#include <stddef.h>
#include <stdint.h>
/**
* crypto_scrypt_smix_sse2(B, r, N, V, XY):
* Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
* the temporary storage V must be 128rN bytes in length; the temporary
* storage XY must be 256r + 64 bytes in length. The value N must be a
* power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
* multiple of 64 bytes.
*
* Use SSE2 instructions.
*/
void crypto_scrypt_smix_sse2(uint8_t *, size_t, uint64_t, void *, void *);
#endif /* !_CRYPTO_SCRYPT_SMIX_SSE2_H_ */

View File

@ -1,609 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#include "scrypt_platform.h"
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "crypto_aes.h"
#include "crypto_aesctr.h"
#include "crypto_entropy.h"
#include "humansize.h"
#include "insecure_memzero.h"
#include "sha256.h"
#include "sysendian.h"
#include "crypto_scrypt.h"
#include "memlimit.h"
#include "scryptenc_cpuperf.h"
#include "scryptenc.h"
#define ENCBLOCK 65536
static int pickparams(size_t, double, double,
int *, uint32_t *, uint32_t *, int);
static int checkparams(size_t, double, double, int, uint32_t, uint32_t, int,
int);
static void
display_params(int logN, uint32_t r, uint32_t p, size_t memlimit,
double opps, double maxtime)
{
uint64_t N = (uint64_t)(1) << logN;
uint64_t mem_minimum = 128 * r * N;
double expected_seconds = 4 * N * p / opps;
char * human_memlimit = humansize(memlimit);
char * human_mem_minimum = humansize(mem_minimum);
fprintf(stderr, "Parameters used: N = %" PRIu64 "; r = %" PRIu32
"; p = %" PRIu32 ";\n", N, r, p);
fprintf(stderr, " This requires at least %s bytes of memory "
"(%s available),\n", human_mem_minimum, human_memlimit);
fprintf(stderr, " and will take approximately %.1f seconds "
"(limit: %.1f seconds).\n", expected_seconds, maxtime);
free(human_memlimit);
free(human_mem_minimum);
}
static int
pickparams(size_t maxmem, double maxmemfrac, double maxtime,
int * logN, uint32_t * r, uint32_t * p, int verbose)
{
size_t memlimit;
double opps;
double opslimit;
double maxN, maxrp;
int rc;
/* Figure out how much memory to use. */
if (memtouse(maxmem, maxmemfrac, &memlimit))
return (1);
/* Figure out how fast the CPU is. */
if ((rc = scryptenc_cpuperf(&opps)) != 0)
return (rc);
opslimit = opps * maxtime;
/* Allow a minimum of 2^15 salsa20/8 cores. */
if (opslimit < 32768)
opslimit = 32768;
/* Fix r = 8 for now. */
*r = 8;
/*
* The memory limit requires that 128Nr <= memlimit, while the CPU
* limit requires that 4Nrp <= opslimit. If opslimit < memlimit/32,
* opslimit imposes the stronger limit on N.
*/
#ifdef DEBUG
fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n",
memlimit, opslimit);
#endif
if (opslimit < (double)memlimit / 32) {
/* Set p = 1 and choose N based on the CPU limit. */
*p = 1;
maxN = opslimit / (*r * 4);
for (*logN = 1; *logN < 63; *logN += 1) {
if ((uint64_t)(1) << *logN > maxN / 2)
break;
}
} else {
/* Set N based on the memory limit. */
maxN = memlimit / (*r * 128);
for (*logN = 1; *logN < 63; *logN += 1) {
if ((uint64_t)(1) << *logN > maxN / 2)
break;
}
/* Choose p based on the CPU limit. */
maxrp = (opslimit / 4) / ((uint64_t)(1) << *logN);
if (maxrp > 0x3fffffff)
maxrp = 0x3fffffff;
*p = (uint32_t)(maxrp) / *r;
}
if (verbose)
display_params(*logN, *r, *p, memlimit, opps, maxtime);
/* Success! */
return (0);
}
static int
checkparams(size_t maxmem, double maxmemfrac, double maxtime,
int logN, uint32_t r, uint32_t p, int verbose, int force)
{
size_t memlimit;
double opps;
double opslimit;
uint64_t N;
int rc;
/* Sanity-check values. */
if ((logN < 1) || (logN > 63))
return (7);
if ((uint64_t)(r) * (uint64_t)(p) >= 0x40000000)
return (7);
/* Are we forcing decryption, regardless of resource limits? */
if (!force) {
/* Figure out the maximum amount of memory we can use. */
if (memtouse(maxmem, maxmemfrac, &memlimit))
return (1);
/* Figure out how fast the CPU is. */
if ((rc = scryptenc_cpuperf(&opps)) != 0)
return (rc);
opslimit = opps * maxtime;
/* Check limits. */
N = (uint64_t)(1) << logN;
if ((memlimit / N) / r < 128)
return (9);
if ((opslimit / N) / (r * p) < 4)
return (10);
} else {
/* We have no limit. */
memlimit = 0;
opps = 0;
}
if (verbose)
display_params(logN, r, p, memlimit, opps, maxtime);
/* Success! */
return (0);
}
static int
scryptenc_setup(uint8_t header[96], uint8_t dk[64],
const uint8_t * passwd, size_t passwdlen,
size_t maxmem, double maxmemfrac, double maxtime, int verbose)
{
uint8_t salt[32];
uint8_t hbuf[32];
int logN;
uint64_t N;
uint32_t r;
uint32_t p;
SHA256_CTX ctx;
uint8_t * key_hmac = &dk[32];
HMAC_SHA256_CTX hctx;
int rc;
/* Pick values for N, r, p. */
if ((rc = pickparams(maxmem, maxmemfrac, maxtime,
&logN, &r, &p, verbose)) != 0)
return (rc);
N = (uint64_t)(1) << logN;
/* Sanity check. */
assert((logN > 0) && (logN < 256));
/* Get some salt. */
if (crypto_entropy_read(salt, 32))
return (4);
/* Generate the derived keys. */
if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
return (3);
/* Construct the file header. */
memcpy(header, "scrypt", 6);
header[6] = 0;
header[7] = logN & 0xff;
be32enc(&header[8], r);
be32enc(&header[12], p);
memcpy(&header[16], salt, 32);
/* Add header checksum. */
SHA256_Init(&ctx);
SHA256_Update(&ctx, header, 48);
SHA256_Final(hbuf, &ctx);
memcpy(&header[48], hbuf, 16);
/* Add header signature (used for verifying password). */
HMAC_SHA256_Init(&hctx, key_hmac, 32);
HMAC_SHA256_Update(&hctx, header, 64);
HMAC_SHA256_Final(hbuf, &hctx);
memcpy(&header[64], hbuf, 32);
/* Success! */
return (0);
}
static int
scryptdec_setup(const uint8_t header[96], uint8_t dk[64],
const uint8_t * passwd, size_t passwdlen,
size_t maxmem, double maxmemfrac, double maxtime, int verbose,
int force)
{
uint8_t salt[32];
uint8_t hbuf[32];
int logN;
uint32_t r;
uint32_t p;
uint64_t N;
SHA256_CTX ctx;
uint8_t * key_hmac = &dk[32];
HMAC_SHA256_CTX hctx;
int rc;
/* Parse N, r, p, salt. */
logN = header[7];
r = be32dec(&header[8]);
p = be32dec(&header[12]);
memcpy(salt, &header[16], 32);
/* Verify header checksum. */
SHA256_Init(&ctx);
SHA256_Update(&ctx, header, 48);
SHA256_Final(hbuf, &ctx);
if (memcmp(&header[48], hbuf, 16))
return (7);
/*
* Check whether the provided parameters are valid and whether the
* key derivation function can be computed within the allowed memory
* and CPU time, unless the user chose to disable this test.
*/
if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p,
verbose, force)) != 0)
return (rc);
/* Compute the derived keys. */
N = (uint64_t)(1) << logN;
if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
return (3);
/* Check header signature (i.e., verify password). */
HMAC_SHA256_Init(&hctx, key_hmac, 32);
HMAC_SHA256_Update(&hctx, header, 64);
HMAC_SHA256_Final(hbuf, &hctx);
if (memcmp(hbuf, &header[64], 32))
return (11);
/* Success! */
return (0);
}
/**
* scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime, verbose):
* Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
* bytes to outbuf.
*/
int
scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
const uint8_t * passwd, size_t passwdlen,
size_t maxmem, double maxmemfrac, double maxtime, int verbose)
{
uint8_t dk[64];
uint8_t hbuf[32];
uint8_t header[96];
uint8_t * key_enc = dk;
uint8_t * key_hmac = &dk[32];
int rc;
HMAC_SHA256_CTX hctx;
struct crypto_aes_key * key_enc_exp;
struct crypto_aesctr * AES;
/* Generate the header and derived key. */
if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
maxmem, maxmemfrac, maxtime, verbose)) != 0)
return (rc);
/* Copy header into output buffer. */
memcpy(outbuf, header, 96);
/* Encrypt data. */
if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
return (5);
if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
return (6);
crypto_aesctr_stream(AES, inbuf, &outbuf[96], inbuflen);
crypto_aesctr_free(AES);
crypto_aes_key_free(key_enc_exp);
/* Add signature. */
HMAC_SHA256_Init(&hctx, key_hmac, 32);
HMAC_SHA256_Update(&hctx, outbuf, 96 + inbuflen);
HMAC_SHA256_Final(hbuf, &hctx);
memcpy(&outbuf[96 + inbuflen], hbuf, 32);
/* Zero sensitive data. */
insecure_memzero(dk, 64);
/* Success! */
return (0);
}
/**
* scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime, verbose, force):
* Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
* decrypted data length to outlen. The allocated length of outbuf must
* be at least inbuflen. If ${force} is 1, do not check whether
* decryption will exceed the estimated available memory or time.
*/
int
scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
size_t * outlen, const uint8_t * passwd, size_t passwdlen,
size_t maxmem, double maxmemfrac, double maxtime, int verbose,
int force)
{
uint8_t hbuf[32];
uint8_t dk[64];
uint8_t * key_enc = dk;
uint8_t * key_hmac = &dk[32];
int rc;
HMAC_SHA256_CTX hctx;
struct crypto_aes_key * key_enc_exp;
struct crypto_aesctr * AES;
/*
* All versions of the scrypt format will start with "scrypt" and
* have at least 7 bytes of header.
*/
if ((inbuflen < 7) || (memcmp(inbuf, "scrypt", 6) != 0))
return (7);
/* Check the format. */
if (inbuf[6] != 0)
return (8);
/* We must have at least 128 bytes. */
if (inbuflen < 128)
return (7);
/* Parse the header and generate derived keys. */
if ((rc = scryptdec_setup(inbuf, dk, passwd, passwdlen,
maxmem, maxmemfrac, maxtime, verbose, force)) != 0)
return (rc);
/* Decrypt data. */
if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
return (5);
if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
return (6);
crypto_aesctr_stream(AES, &inbuf[96], outbuf, inbuflen - 128);
crypto_aesctr_free(AES);
crypto_aes_key_free(key_enc_exp);
*outlen = inbuflen - 128;
/* Verify signature. */
HMAC_SHA256_Init(&hctx, key_hmac, 32);
HMAC_SHA256_Update(&hctx, inbuf, inbuflen - 32);
HMAC_SHA256_Final(hbuf, &hctx);
if (memcmp(hbuf, &inbuf[inbuflen - 32], 32))
return (7);
/* Zero sensitive data. */
insecure_memzero(dk, 64);
/* Success! */
return (0);
}
/**
* scryptenc_file(infile, outfile, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime, verbose):
* Read a stream from infile and encrypt it, writing the resulting stream to
* outfile.
*/
int
scryptenc_file(FILE * infile, FILE * outfile,
const uint8_t * passwd, size_t passwdlen,
size_t maxmem, double maxmemfrac, double maxtime, int verbose)
{
uint8_t buf[ENCBLOCK];
uint8_t dk[64];
uint8_t hbuf[32];
uint8_t header[96];
uint8_t * key_enc = dk;
uint8_t * key_hmac = &dk[32];
size_t readlen;
HMAC_SHA256_CTX hctx;
struct crypto_aes_key * key_enc_exp;
struct crypto_aesctr * AES;
int rc;
/* Generate the header and derived key. */
if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
maxmem, maxmemfrac, maxtime, verbose)) != 0)
return (rc);
/* Hash and write the header. */
HMAC_SHA256_Init(&hctx, key_hmac, 32);
HMAC_SHA256_Update(&hctx, header, 96);
if (fwrite(header, 96, 1, outfile) != 1)
return (12);
/*
* Read blocks of data, encrypt them, and write them out; hash the
* data as it is produced.
*/
if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
return (5);
if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
return (6);
do {
if ((readlen = fread(buf, 1, ENCBLOCK, infile)) == 0)
break;
crypto_aesctr_stream(AES, buf, buf, readlen);
HMAC_SHA256_Update(&hctx, buf, readlen);
if (fwrite(buf, 1, readlen, outfile) < readlen) {
crypto_aesctr_free(AES);
return (12);
}
} while (1);
crypto_aesctr_free(AES);
crypto_aes_key_free(key_enc_exp);
/* Did we exit the loop due to a read error? */
if (ferror(infile))
return (13);
/* Compute the final HMAC and output it. */
HMAC_SHA256_Final(hbuf, &hctx);
if (fwrite(hbuf, 32, 1, outfile) != 1)
return (12);
/* Zero sensitive data. */
insecure_memzero(dk, 64);
/* Success! */
return (0);
}
/**
* scryptdec_file(infile, outfile, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime, verbose, force):
* Read a stream from infile and decrypt it, writing the resulting stream to
* outfile. If ${force} is 1, do not check whether decryption
* will exceed the estimated available memory or time.
*/
int
scryptdec_file(FILE * infile, FILE * outfile,
const uint8_t * passwd, size_t passwdlen,
size_t maxmem, double maxmemfrac, double maxtime, int verbose,
int force)
{
uint8_t buf[ENCBLOCK + 32];
uint8_t header[96];
uint8_t hbuf[32];
uint8_t dk[64];
uint8_t * key_enc = dk;
uint8_t * key_hmac = &dk[32];
size_t buflen = 0;
size_t readlen;
HMAC_SHA256_CTX hctx;
struct crypto_aes_key * key_enc_exp;
struct crypto_aesctr * AES;
int rc;
/*
* Read the first 7 bytes of the file; all future versions of scrypt
* are guaranteed to have at least 7 bytes of header.
*/
if (fread(header, 7, 1, infile) < 1) {
if (ferror(infile))
return (13);
else
return (7);
}
/* Do we have the right magic? */
if (memcmp(header, "scrypt", 6))
return (7);
if (header[6] != 0)
return (8);
/*
* Read another 89 bytes of the file; version 0 of the scrypt file
* format has a 96-byte header.
*/
if (fread(&header[7], 89, 1, infile) < 1) {
if (ferror(infile))
return (13);
else
return (7);
}
/* Parse the header and generate derived keys. */
if ((rc = scryptdec_setup(header, dk, passwd, passwdlen,
maxmem, maxmemfrac, maxtime, verbose, force)) != 0)
return (rc);
/* Start hashing with the header. */
HMAC_SHA256_Init(&hctx, key_hmac, 32);
HMAC_SHA256_Update(&hctx, header, 96);
/*
* We don't know how long the encrypted data block is (we can't know,
* since data can be streamed into 'scrypt enc') so we need to read
* data and decrypt all of it except the final 32 bytes, then check
* if that final 32 bytes is the correct signature.
*/
if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
return (5);
if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
return (6);
do {
/* Read data until we have more than 32 bytes of it. */
if ((readlen = fread(&buf[buflen], 1,
ENCBLOCK + 32 - buflen, infile)) == 0)
break;
buflen += readlen;
if (buflen <= 32)
continue;
/*
* Decrypt, hash, and output everything except the last 32
* bytes out of what we have in our buffer.
*/
HMAC_SHA256_Update(&hctx, buf, buflen - 32);
crypto_aesctr_stream(AES, buf, buf, buflen - 32);
if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32) {
crypto_aesctr_free(AES);
return (12);
}
/* Move the last 32 bytes to the start of the buffer. */
memmove(buf, &buf[buflen - 32], 32);
buflen = 32;
} while (1);
crypto_aesctr_free(AES);
crypto_aes_key_free(key_enc_exp);
/* Did we exit the loop due to a read error? */
if (ferror(infile))
return (13);
/* Did we read enough data that we *might* have a valid signature? */
if (buflen < 32)
return (7);
/* Verify signature. */
HMAC_SHA256_Final(hbuf, &hctx);
if (memcmp(hbuf, buf, 32))
return (7);
/* Zero sensitive data. */
insecure_memzero(dk, 64);
return (0);
}

View File

@ -1,122 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#ifndef _SCRYPTENC_H_
#define _SCRYPTENC_H_
#include <stdint.h>
#include <stdio.h>
/**
* NOTE: This file provides prototypes for routines which encrypt/decrypt data
* using a key derived from a password by using the scrypt key derivation
* function. If you are just trying to "hash" a password for user logins,
* this is not the code you are looking for. You want to use the crypto_scrypt
* function directly.
*/
/**
* The parameters maxmem, maxmemfrac, and maxtime used by all of these
* functions are defined as follows:
* maxmem - maximum number of bytes of storage to use for V array (which is
* by far the largest consumer of memory). If this value is set to 0, no
* maximum will be enforced; any other value less than 1 MiB will be
* treated as 1 MiB.
* maxmemfrac - maximum fraction of available storage to use for the V array,
* where "available storage" is defined as the minimum out of the
* RLIMIT_AS, RLIMIT_DATA. and RLIMIT_RSS resource limits (if any are
* set). If this value is set to 0 or more than 0.5 it will be treated
* as 0.5; and this value will never cause a limit of less than 1 MiB to
* be enforced.
* maxtime - maximum amount of CPU time to spend computing the derived keys,
* in seconds. This limit is only approximately enforced; the CPU
* performance is estimated and parameter limits are chosen accordingly.
* For the encryption functions, the parameters to the scrypt key derivation
* function are chosen to make the key as strong as possible subject to the
* specified limits; for the decryption functions, the parameters used are
* compared to the computed limits and an error is returned if decrypting
* the data would take too much memory or CPU time.
*/
/**
* Return codes from scrypt(enc|dec)_(buf|file):
* 0 success
* 1 getrlimit or sysctl(hw.usermem) failed
* 2 clock_getres or clock_gettime failed
* 3 error computing derived key
* 4 could not read salt from /dev/urandom
* 5 error in OpenSSL
* 6 malloc failed
* 7 data is not a valid scrypt-encrypted block
* 8 unrecognized scrypt format
* 9 decrypting file would take too much memory
* 10 decrypting file would take too long
* 11 password is incorrect
* 12 error writing output file
* 13 error reading input file
*/
/**
* scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime, verbose):
* Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
* bytes to outbuf.
*/
int scryptenc_buf(const uint8_t *, size_t, uint8_t *,
const uint8_t *, size_t, size_t, double, double, int);
/**
* scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime, verbose, force):
* Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
* decrypted data length to outlen. The allocated length of outbuf must
* be at least inbuflen. If ${force} is 1, do not check whether
* decryption will exceed the estimated available memory or time.
*/
int scryptdec_buf(const uint8_t *, size_t, uint8_t *, size_t *,
const uint8_t *, size_t, size_t, double, double, int, int);
/**
* scryptenc_file(infile, outfile, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime, verbose):
* Read a stream from infile and encrypt it, writing the resulting stream to
* outfile.
*/
int scryptenc_file(FILE *, FILE *, const uint8_t *, size_t,
size_t, double, double, int);
/**
* scryptdec_file(infile, outfile, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime, verbose, force):
* Read a stream from infile and decrypt it, writing the resulting stream to
* outfile. If ${force} is 1, do not check whether decryption
* will exceed the estimated available memory or time.
*/
int scryptdec_file(FILE *, FILE *, const uint8_t *, size_t,
size_t, double, double, int, int);
#endif /* !_SCRYPTENC_H_ */

View File

@ -1,185 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#include "scrypt_platform.h"
#include <sys/time.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include "crypto_scrypt.h"
#include "scryptenc_cpuperf.h"
#ifdef HAVE_CLOCK_GETTIME
static clockid_t clocktouse;
static int
getclockres(double * resd)
{
struct timespec res;
/*
* Try clocks in order of preference until we find one which works.
* (We assume that if clock_getres works, clock_gettime will, too.)
* The use of if/else/if/else/if/else rather than if/elif/elif/else
* is ugly but legal, and allows us to #ifdef things appropriately.
*/
#ifdef CLOCK_VIRTUAL
if (clock_getres(CLOCK_VIRTUAL, &res) == 0)
clocktouse = CLOCK_VIRTUAL;
else
#endif
#ifdef CLOCK_MONOTONIC
if (clock_getres(CLOCK_MONOTONIC, &res) == 0)
clocktouse = CLOCK_MONOTONIC;
else
#endif
if (clock_getres(CLOCK_REALTIME, &res) == 0)
clocktouse = CLOCK_REALTIME;
else
return (-1);
/* Convert clock resolution to a double. */
*resd = res.tv_sec + res.tv_nsec * 0.000000001;
return (0);
}
static int
getclocktime(struct timespec * ts)
{
if (clock_gettime(clocktouse, ts))
return (-1);
return (0);
}
#else
static int
getclockres(double * resd)
{
*resd = 1.0 / CLOCKS_PER_SEC;
return (0);
}
static int
getclocktime(struct timespec * ts)
{
struct timeval tv;
if (gettimeofday(&tv, NULL))
return (-1);
ts->tv_sec = tv.tv_sec;
ts->tv_nsec = tv.tv_usec * 1000;
return (0);
}
#endif
static int
getclockdiff(struct timespec * st, double * diffd)
{
struct timespec en;
if (getclocktime(&en))
return (1);
*diffd = (en.tv_nsec - st->tv_nsec) * 0.000000001 +
(en.tv_sec - st->tv_sec);
return (0);
}
/**
* scryptenc_cpuperf(opps):
* Estimate the number of salsa20/8 cores which can be executed per second,
* and return the value via opps.
*/
int
scryptenc_cpuperf(double * opps)
{
struct timespec st;
double resd, diffd;
uint64_t i = 0;
/* Get the clock resolution. */
if (getclockres(&resd))
return (2);
#ifdef DEBUG
fprintf(stderr, "Clock resolution is %f\n", resd);
#endif
/* Loop until the clock ticks. */
if (getclocktime(&st))
return (2);
do {
/* Do an scrypt. */
if (crypto_scrypt(NULL, 0, NULL, 0, 16, 1, 1, NULL, 0))
return (3);
/* Has the clock ticked? */
if (getclockdiff(&st, &diffd))
return (2);
if (diffd > 0)
break;
} while (1);
/* Count how many scrypts we can do before the next tick. */
if (getclocktime(&st))
return (2);
do {
/* Do an scrypt. */
if (crypto_scrypt(NULL, 0, NULL, 0, 128, 1, 1, NULL, 0))
return (3);
/* We invoked the salsa20/8 core 512 times. */
i += 512;
/* Check if we have looped for long enough. */
if (getclockdiff(&st, &diffd))
return (2);
if (diffd > resd)
break;
} while (1);
#ifdef DEBUG
fprintf(stderr, "%ju salsa20/8 cores performed in %f seconds\n",
(uintmax_t)i, diffd);
#endif
/* We can do approximately i salsa20/8 cores per diffd seconds. */
*opps = i / diffd;
return (0);
}

View File

@ -1,39 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#ifndef _SCRYPTENC_CPUPERF_H_
#define _SCRYPTENC_CPUPERF_H_
/**
* scryptenc_cpuperf(opps):
* Estimate the number of salsa20/8 cores which can be executed per second,
* and return the value via opps.
*/
int scryptenc_cpuperf(double *);
#endif /* !_SCRYPTENC_CPUPERF_H_ */

View File

@ -1,325 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
/* We use non-POSIX functionality in this file. */
#undef _POSIX_C_SOURCE
#include "scrypt_platform.h"
#include <sys/types.h>
#include <sys/resource.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#ifdef HAVE_SYS_SYSINFO_H
#include <sys/sysinfo.h>
#endif
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#include "memlimit.h"
/* If we don't have CTL_HW, we can't use HW_USERMEM. */
#ifndef CTL_HW
#undef HW_USERMEM
#endif
#ifdef CTL_HW
static int
memlimit_sysctl_hw(size_t * memlimit, int mibleaf)
{
int mib[2];
uint8_t sysctlbuf[8];
size_t sysctlbuflen = 8;
uint64_t sysctlval;
/* Ask the kernel how much RAM we have. */
mib[0] = CTL_HW;
mib[1] = mibleaf;
if (sysctl(mib, 2, sysctlbuf, &sysctlbuflen, NULL, 0))
return (1);
/*
* If we read 8 bytes out, assume this is a system-endian uint64_t.
* If we only read 4 bytes out, the OS is trying to give us a
* uint32_t answer -- but given how many systems now have 4GB+ of RAM,
* it's probably truncating, and we really can't trust the value we
* have returned to us.
*/
if (sysctlbuflen == sizeof(uint64_t))
memcpy(&sysctlval, sysctlbuf, sizeof(uint64_t));
else if (sysctlbuflen == sizeof(uint32_t))
sysctlval = SIZE_MAX;
else
return (1);
/* Return the sysctl value, but clamp to SIZE_MAX if necessary. */
#if UINT64_MAX > SIZE_MAX
if (sysctlval > SIZE_MAX)
*memlimit = SIZE_MAX;
else
*memlimit = (size_t)sysctlval;
#else
*memlimit = sysctlval;
#endif
/* Success! */
return (0);
}
#endif
/* If we don't HAVE_STRUCT_SYSINFO, we can't use sysinfo. */
#ifndef HAVE_STRUCT_SYSINFO
#undef HAVE_SYSINFO
#endif
/* If we don't HAVE_STRUCT_SYSINFO_TOTALRAM, we can't use sysinfo. */
#ifndef HAVE_STRUCT_SYSINFO_TOTALRAM
#undef HAVE_SYSINFO
#endif
#ifdef HAVE_SYSINFO
static int
memlimit_sysinfo(size_t * memlimit)
{
struct sysinfo info;
uint64_t totalmem;
/* Get information from the kernel. */
if (sysinfo(&info))
return (1);
totalmem = info.totalram;
/* If we're on a modern kernel, adjust based on mem_unit. */
#ifdef HAVE_STRUCT_SYSINFO_MEM_UNIT
totalmem = totalmem * info.mem_unit;
#endif
/* Return the value, but clamp to SIZE_MAX if necessary. */
#if UINT64_MAX > SIZE_MAX
if (totalmem > SIZE_MAX)
*memlimit = SIZE_MAX;
else
*memlimit = (size_t)totalmem;
#else
*memlimit = totalmem;
#endif
/* Success! */
return (0);
}
#endif /* HAVE_SYSINFO */
static int
memlimit_rlimit(size_t * memlimit)
{
struct rlimit rl;
uint64_t memrlimit;
/* Find the least of... */
memrlimit = (uint64_t)(-1);
/* ... RLIMIT_AS... */
#ifdef RLIMIT_AS
if (getrlimit(RLIMIT_AS, &rl))
return (1);
if ((rl.rlim_cur != RLIM_INFINITY) &&
((uint64_t)rl.rlim_cur < memrlimit))
memrlimit = (uint64_t)rl.rlim_cur;
#endif
/* ... RLIMIT_DATA... */
if (getrlimit(RLIMIT_DATA, &rl))
return (1);
if ((rl.rlim_cur != RLIM_INFINITY) &&
((uint64_t)rl.rlim_cur < memrlimit))
memrlimit = (uint64_t)rl.rlim_cur;
/* ... and RLIMIT_RSS. */
#ifdef RLIMIT_RSS
if (getrlimit(RLIMIT_RSS, &rl))
return (1);
if ((rl.rlim_cur != RLIM_INFINITY) &&
((uint64_t)rl.rlim_cur < memrlimit))
memrlimit = (uint64_t)rl.rlim_cur;
#endif
/* Return the value, but clamp to SIZE_MAX if necessary. */
#if UINT64_MAX > SIZE_MAX
if (memrlimit > SIZE_MAX)
*memlimit = SIZE_MAX;
else
*memlimit = (size_t)memrlimit;
#else
*memlimit = memrlimit;
#endif
/* Success! */
return (0);
}
#ifdef _SC_PHYS_PAGES
/* Some systems define _SC_PAGESIZE instead of _SC_PAGE_SIZE. */
#ifndef _SC_PAGE_SIZE
#define _SC_PAGE_SIZE _SC_PAGESIZE
#endif
static int
memlimit_sysconf(size_t * memlimit)
{
long pagesize;
long physpages;
uint64_t totalmem;
/* Set errno to 0 in order to distinguish "no limit" from "error". */
errno = 0;
/* Read the two limits. */
if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) ||
((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) {
/*
* Did an error occur? OS X may return EINVAL due to not
* supporting _SC_PHYS_PAGES in spite of defining it.
*/
if (errno != 0 && errno != EINVAL)
return (1);
/* If not, there is no limit. */
totalmem = (uint64_t)(-1);
} else {
/* Compute the limit. */
totalmem = (uint64_t)(pagesize) * (uint64_t)(physpages);
}
/* Return the value, but clamp to SIZE_MAX if necessary. */
#if UINT64_MAX > SIZE_MAX
if (totalmem > SIZE_MAX)
*memlimit = SIZE_MAX;
else
*memlimit = (size_t)totalmem;
#else
*memlimit = totalmem;
#endif
/* Success! */
return (0);
}
#endif
int
memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit)
{
size_t usermem_memlimit, memsize_memlimit;
size_t sysinfo_memlimit, rlimit_memlimit;
size_t sysconf_memlimit;
size_t memlimit_min;
size_t memavail;
/* Get memory limits. */
#ifdef HW_USERMEM
if (memlimit_sysctl_hw(&usermem_memlimit, HW_USERMEM))
return (1);
#else
usermem_memlimit = SIZE_MAX;
#endif
#ifdef HW_MEMSIZE
if (memlimit_sysctl_hw(&memsize_memlimit, HW_MEMSIZE))
return (1);
#else
memsize_memlimit = SIZE_MAX;
#endif
#ifdef HAVE_SYSINFO
if (memlimit_sysinfo(&sysinfo_memlimit))
return (1);
#else
sysinfo_memlimit = SIZE_MAX;
#endif
if (memlimit_rlimit(&rlimit_memlimit))
return (1);
#ifdef _SC_PHYS_PAGES
if (memlimit_sysconf(&sysconf_memlimit))
return (1);
#else
sysconf_memlimit = SIZE_MAX;
#endif
#ifdef DEBUG
fprintf(stderr, "Memory limits are %zu %zu %zu %zu %zu\n",
usermem_memlimit, memsize_memlimit,
sysinfo_memlimit, rlimit_memlimit,
sysconf_memlimit);
#endif
/* Find the smallest of them. */
memlimit_min = SIZE_MAX;
if (memlimit_min > usermem_memlimit)
memlimit_min = usermem_memlimit;
if (memlimit_min > memsize_memlimit)
memlimit_min = memsize_memlimit;
if (memlimit_min > sysinfo_memlimit)
memlimit_min = sysinfo_memlimit;
if (memlimit_min > rlimit_memlimit)
memlimit_min = rlimit_memlimit;
if (memlimit_min > sysconf_memlimit)
memlimit_min = sysconf_memlimit;
/* Only use the specified fraction of the available memory. */
if ((maxmemfrac > 0.5) || (maxmemfrac == 0.0))
maxmemfrac = 0.5;
memavail = (size_t)(maxmemfrac * memlimit_min);
/* Don't use more than the specified maximum. */
if ((maxmem > 0) && (memavail > maxmem))
memavail = maxmem;
/* But always allow at least 1 MiB. */
if (memavail < 1048576)
memavail = 1048576;
#ifdef DEBUG
fprintf(stderr, "Allowing up to %zu memory to be used\n", memavail);
#endif
/* Return limit via the provided pointer. */
*memlimit = memavail;
return (0);
}

View File

@ -1,42 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#ifndef _MEMLIMIT_H_
#define _MEMLIMIT_H_
#include <stddef.h>
/**
* memtouse(maxmem, maxmemfrac, memlimit):
* Examine the system and return via memlimit the amount of RAM which should
* be used -- the specified fraction of the available RAM, but no more than
* maxmem, and no less than 1MiB.
*/
int memtouse(size_t, double, size_t *);
#endif /* !_MEMLIMIT_H_ */

View File

@ -1,527 +0,0 @@
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "insecure_memzero.h"
#include "sysendian.h"
#include "sha256.h"
/*
* Encode a length len/4 vector of (uint32_t) into a length len vector of
* (uint8_t) in big-endian form. Assumes len is a multiple of 4.
*/
static void
be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len)
{
size_t i;
/* Sanity-check. */
assert(len % 4 == 0);
/* Encode vector, one word at a time. */
for (i = 0; i < len / 4; i++)
be32enc(dst + i * 4, src[i]);
}
/*
* Decode a big-endian length len vector of (uint8_t) into a length
* len/4 vector of (uint32_t). Assumes len is a multiple of 4.
*/
static void
be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len)
{
size_t i;
/* Sanity-check. */
assert(len % 4 == 0);
/* Decode vector, one word at a time. */
for (i = 0; i < len / 4; i++)
dst[i] = be32dec(src + i * 4);
}
/* SHA256 round constants. */
static const uint32_t Krnd[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
/* 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) \
h += S1(e) + Ch(e, f, g) + k; \
d += h; \
h += S0(a) + Maj(a, b, c);
/* Adjusted round function for rotating state */
#define RNDr(S, W, i, ii) \
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 + ii] + Krnd[i + ii])
/* Message schedule computation */
#define MSCH(W, ii, i) \
W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
/*
* 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[static restrict 8],
const uint8_t block[static restrict 64],
uint32_t W[static restrict 64], uint32_t S[static restrict 8])
{
int i;
/* 1. Prepare the first part of the message schedule W. */
be32dec_vect(W, block, 64);
/* 2. Initialize working variables. */
memcpy(S, state, 32);
/* 3. Mix. */
for (i = 0; i < 64; i += 16) {
RNDr(S, W, 0, i);
RNDr(S, W, 1, i);
RNDr(S, W, 2, i);
RNDr(S, W, 3, i);
RNDr(S, W, 4, i);
RNDr(S, W, 5, i);
RNDr(S, W, 6, i);
RNDr(S, W, 7, i);
RNDr(S, W, 8, i);
RNDr(S, W, 9, i);
RNDr(S, W, 10, i);
RNDr(S, W, 11, i);
RNDr(S, W, 12, i);
RNDr(S, W, 13, i);
RNDr(S, W, 14, i);
RNDr(S, W, 15, i);
if (i == 48)
break;
MSCH(W, 0, i);
MSCH(W, 1, i);
MSCH(W, 2, i);
MSCH(W, 3, i);
MSCH(W, 4, i);
MSCH(W, 5, i);
MSCH(W, 6, i);
MSCH(W, 7, i);
MSCH(W, 8, i);
MSCH(W, 9, i);
MSCH(W, 10, i);
MSCH(W, 11, i);
MSCH(W, 12, i);
MSCH(W, 13, i);
MSCH(W, 14, i);
MSCH(W, 15, i);
}
/* 4. Mix local working variables into global state. */
for (i = 0; i < 8; i++)
state[i] += S[i];
}
static const uint8_t PAD[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* Add padding and terminating bit-count. */
static void
SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[static restrict 72])
{
size_t r;
/* Figure out how many bytes we have buffered. */
r = (ctx->count >> 3) & 0x3f;
/* Pad to 56 mod 64, transforming if we finish a block en route. */
if (r < 56) {
/* Pad to 56 mod 64. */
memcpy(&ctx->buf[r], PAD, 56 - r);
} else {
/* Finish the current block and mix. */
memcpy(&ctx->buf[r], PAD, 64 - r);
SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
/* The start of the final block is all zeroes. */
memset(&ctx->buf[0], 0, 56);
}
/* Add the terminating bit-count. */
be64enc(&ctx->buf[56], ctx->count);
/* Mix in the final block. */
SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
}
/* Magic initialization constants. */
static const uint32_t initial_state[8] = {
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
};
/**
* SHA256_Init(ctx):
* Initialize the SHA256 context ${ctx}.
*/
void
SHA256_Init(SHA256_CTX * ctx)
{
/* Zero bits processed so far. */
ctx->count = 0;
/* Initialize state. */
memcpy(ctx->state, initial_state, sizeof(initial_state));
}
/**
* SHA256_Update(ctx, in, len):
* Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
*/
static void
_SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len,
uint32_t tmp32[static restrict 72])
{
uint32_t r;
const uint8_t * src = in;
/* Return immediately if we have nothing to do. */
if (len == 0)
return;
/* Number of bytes left in the buffer from previous updates. */
r = (ctx->count >> 3) & 0x3f;
/* Update number of bits. */
ctx->count += (uint64_t)(len) << 3;
/* Handle the case where we don't need to perform any transforms. */
if (len < 64 - r) {
memcpy(&ctx->buf[r], src, len);
return;
}
/* Finish the current block. */
memcpy(&ctx->buf[r], src, 64 - r);
SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
src += 64 - r;
len -= 64 - r;
/* Perform complete blocks. */
while (len >= 64) {
SHA256_Transform(ctx->state, src, &tmp32[0], &tmp32[64]);
src += 64;
len -= 64;
}
/* Copy left over data into buffer. */
memcpy(ctx->buf, src, len);
}
/* Wrapper function for intermediate-values sanitization. */
void
SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len)
{
uint32_t tmp32[72];
/* Call the real function. */
_SHA256_Update(ctx, in, len, tmp32);
/* Clean the stack. */
insecure_memzero(tmp32, 288);
}
/**
* SHA256_Final(digest, ctx):
* Output the SHA256 hash of the data input to the context ${ctx} into the
* buffer ${digest}.
*/
static void
_SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx,
uint32_t tmp32[static restrict 72])
{
/* Add padding. */
SHA256_Pad(ctx, tmp32);
/* Write the hash. */
be32enc_vect(digest, ctx->state, 32);
}
/* Wrapper function for intermediate-values sanitization. */
void
SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx)
{
uint32_t tmp32[72];
/* Call the real function. */
_SHA256_Final(digest, ctx, tmp32);
/* Clear the context state. */
insecure_memzero(ctx, sizeof(SHA256_CTX));
/* Clean the stack. */
insecure_memzero(tmp32, 288);
}
/**
* SHA256_Buf(in, len, digest):
* Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}.
*/
void
SHA256_Buf(const void * in, size_t len, uint8_t digest[32])
{
SHA256_CTX ctx;
uint32_t tmp32[72];
SHA256_Init(&ctx);
_SHA256_Update(&ctx, in, len, tmp32);
_SHA256_Final(digest, &ctx, tmp32);
/* Clean the stack. */
insecure_memzero(&ctx, sizeof(SHA256_CTX));
insecure_memzero(tmp32, 288);
}
/**
* HMAC_SHA256_Init(ctx, K, Klen):
* Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
* ${K}.
*/
static void
_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen,
uint32_t tmp32[static restrict 72], uint8_t pad[static restrict 64],
uint8_t khash[static restrict 32])
{
const uint8_t * K = _K;
size_t i;
/* If Klen > 64, the key is really SHA256(K). */
if (Klen > 64) {
SHA256_Init(&ctx->ictx);
_SHA256_Update(&ctx->ictx, K, Klen, tmp32);
_SHA256_Final(khash, &ctx->ictx, tmp32);
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, tmp32);
/* 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, tmp32);
}
/* Wrapper function for intermediate-values sanitization. */
void
HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
{
uint32_t tmp32[72];
uint8_t pad[64];
uint8_t khash[32];
/* Call the real function. */
_HMAC_SHA256_Init(ctx, _K, Klen, tmp32, pad, khash);
/* Clean the stack. */
insecure_memzero(tmp32, 288);
insecure_memzero(khash, 32);
insecure_memzero(pad, 64);
}
/**
* HMAC_SHA256_Update(ctx, in, len):
* Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
*/
static void
_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len,
uint32_t tmp32[static restrict 72])
{
/* Feed data to the inner SHA256 operation. */
_SHA256_Update(&ctx->ictx, in, len, tmp32);
}
/* Wrapper function for intermediate-values sanitization. */
void
HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len)
{
uint32_t tmp32[72];
/* Call the real function. */
_HMAC_SHA256_Update(ctx, in, len, tmp32);
/* Clean the stack. */
insecure_memzero(tmp32, 288);
}
/**
* HMAC_SHA256_Final(digest, ctx):
* Output the HMAC-SHA256 of the data input to the context ${ctx} into the
* buffer ${digest}.
*/
static void
_HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx,
uint32_t tmp32[static restrict 72], uint8_t ihash[static restrict 32])
{
/* Finish the inner SHA256 operation. */
_SHA256_Final(ihash, &ctx->ictx, tmp32);
/* Feed the inner hash to the outer SHA256 operation. */
_SHA256_Update(&ctx->octx, ihash, 32, tmp32);
/* Finish the outer SHA256 operation. */
_SHA256_Final(digest, &ctx->octx, tmp32);
}
/* Wrapper function for intermediate-values sanitization. */
void
HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx)
{
uint32_t tmp32[72];
uint8_t ihash[32];
/* Call the real function. */
_HMAC_SHA256_Final(digest, ctx, tmp32, ihash);
/* Clean the stack. */
insecure_memzero(tmp32, 288);
insecure_memzero(ihash, 32);
}
/**
* HMAC_SHA256_Buf(K, Klen, in, len, digest):
* Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
* length ${Klen}, and write the result to ${digest}.
*/
void
HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len,
uint8_t digest[32])
{
HMAC_SHA256_CTX ctx;
uint32_t tmp32[72];
uint8_t tmp8[96];
_HMAC_SHA256_Init(&ctx, K, Klen, tmp32, &tmp8[0], &tmp8[64]);
_HMAC_SHA256_Update(&ctx, in, len, tmp32);
_HMAC_SHA256_Final(digest, &ctx, tmp32, &tmp8[0]);
/* Clean the stack. */
insecure_memzero(&ctx, sizeof(HMAC_SHA256_CTX));
insecure_memzero(tmp32, 288);
insecure_memzero(tmp8, 96);
}
/**
* 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 Phctx, PShctx, hctx;
uint32_t tmp32[72];
uint8_t tmp8[96];
size_t i;
uint8_t ivec[4];
uint8_t U[32];
uint8_t T[32];
uint64_t j;
int k;
size_t clen;
/* Sanity-check. */
assert(dkLen <= 32 * (size_t)(UINT32_MAX));
/* Compute HMAC state after processing P. */
_HMAC_SHA256_Init(&Phctx, passwd, passwdlen,
tmp32, &tmp8[0], &tmp8[64]);
/* Compute HMAC state after processing P and S. */
memcpy(&PShctx, &Phctx, sizeof(HMAC_SHA256_CTX));
_HMAC_SHA256_Update(&PShctx, salt, saltlen, tmp32);
/* 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, tmp32);
_HMAC_SHA256_Final(U, &hctx, tmp32, tmp8);
/* T_i = U_1 ... */
memcpy(T, U, 32);
for (j = 2; j <= c; j++) {
/* Compute U_j. */
memcpy(&hctx, &Phctx, sizeof(HMAC_SHA256_CTX));
_HMAC_SHA256_Update(&hctx, U, 32, tmp32);
_HMAC_SHA256_Final(U, &hctx, tmp32, tmp8);
/* ... 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 the stack. */
insecure_memzero(&Phctx, sizeof(HMAC_SHA256_CTX));
insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX));
insecure_memzero(&hctx, sizeof(HMAC_SHA256_CTX));
insecure_memzero(tmp32, 288);
insecure_memzero(tmp8, 96);
insecure_memzero(U, 32);
insecure_memzero(T, 32);
}

View File

@ -1,95 +0,0 @@
#ifndef _SHA256_H_
#define _SHA256_H_
#include <stddef.h>
#include <stdint.h>
/*
* Use #defines in order to avoid namespace collisions with anyone else's
* SHA256 code (e.g., the code in OpenSSL).
*/
#define SHA256_Init libcperciva_SHA256_Init
#define SHA256_Update libcperciva_SHA256_Update
#define SHA256_Final libcperciva_SHA256_Final
#define SHA256_Buf libcperciva_SHA256_Buf
#define SHA256_CTX libcperciva_SHA256_CTX
#define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init
#define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update
#define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final
#define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf
#define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX
/* Context structure for SHA256 operations. */
typedef struct {
uint32_t state[8];
uint64_t count;
uint8_t buf[64];
} SHA256_CTX;
/**
* SHA256_Init(ctx):
* Initialize the SHA256 context ${ctx}.
*/
void SHA256_Init(SHA256_CTX *);
/**
* SHA256_Update(ctx, in, len):
* Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
*/
void SHA256_Update(SHA256_CTX *, const void *, size_t);
/**
* SHA256_Final(digest, ctx):
* Output the SHA256 hash of the data input to the context ${ctx} into the
* buffer ${digest}.
*/
void SHA256_Final(uint8_t[32], SHA256_CTX *);
/**
* SHA256_Buf(in, len, digest):
* Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}.
*/
void SHA256_Buf(const void *, size_t, uint8_t[32]);
/* Context structure for HMAC-SHA256 operations. */
typedef struct {
SHA256_CTX ictx;
SHA256_CTX octx;
} HMAC_SHA256_CTX;
/**
* HMAC_SHA256_Init(ctx, K, Klen):
* Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
* ${K}.
*/
void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
/**
* HMAC_SHA256_Update(ctx, in, len):
* Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
*/
void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
/**
* HMAC_SHA256_Final(digest, ctx):
* Output the HMAC-SHA256 of the data input to the context ${ctx} into the
* buffer ${digest}.
*/
void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *);
/**
* HMAC_SHA256_Buf(K, Klen, in, len, digest):
* Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
* length ${Klen}, and write the result to ${digest}.
*/
void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[32]);
/**
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
*/
void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
uint64_t, uint8_t *, size_t);
#endif /* !_SHA256_H_ */

View File

@ -1,14 +0,0 @@
#include <wmmintrin.h>
static char a[16];
int
main(void)
{
__m128i x, y;
x = _mm_loadu_si128((__m128i *)a);
y = _mm_aesenc_si128(x, x);
_mm_storeu_si128((__m128i *)a, y);
return (a[0]);
}

View File

@ -1,9 +0,0 @@
#include <cpuid.h>
int
main(void)
{
unsigned int a, b, c, d;
return __get_cpuid(0, &a, &b, &c, &d);
}

View File

@ -1,13 +0,0 @@
#include <emmintrin.h>
static char a[16];
int
main(void)
{
__m128i x;
x = _mm_loadu_si128((__m128i *)a);
_mm_storeu_si128((__m128i *)a, x);
return (a[0]);
}

View File

@ -1,48 +0,0 @@
# Should be sourced by `command -p sh path/to/cpusupport.sh "$PATH"` from
# within a Makefile.
if ! [ ${PATH} = "$1" ]; then
echo "WARNING: POSIX violation: $SHELL's command -p resets \$PATH" 1>&2
PATH=$1
fi
# Standard output should be written to cpusupport-config.h, which is both a
# C header file defining CPUSUPPORT_ARCH_FEATURE macros and sourceable sh
# code which sets CFLAGS_ARCH_FEATURE environment variables.
SRCDIR=`command -p dirname "$0"`
feature() {
ARCH=$1
FEATURE=$2
shift 2;
if ! [ -f ${SRCDIR}/cpusupport-$ARCH-$FEATURE.c ]; then
return
fi
printf "Checking if compiler supports $ARCH $FEATURE feature..." 1>&2
for CFLAG in "$@"; do
if ${CC} ${CFLAGS} -D_POSIX_C_SOURCE=200809L ${CFLAG} \
${SRCDIR}/cpusupport-$ARCH-$FEATURE.c 2>/dev/null; then
rm -f a.out
break;
fi
CFLAG=NOTSUPPORTED;
done
case $CFLAG in
NOTSUPPORTED)
echo " no" 1>&2
;;
"")
echo " yes" 1>&2
echo "#define CPUSUPPORT_${ARCH}_${FEATURE} 1"
;;
*)
echo " yes, via $CFLAG" 1>&2
echo "#define CPUSUPPORT_${ARCH}_${FEATURE} 1"
echo "#ifdef cpusupport_dummy"
echo "export CFLAGS_${ARCH}_${FEATURE}=\"${CFLAG}\""
echo "#endif"
;;
esac
}
feature X86 CPUID ""
feature X86 SSE2 "" "-msse2" "-msse2 -Wno-cast-align"
feature X86 AESNI "" "-maes" "-maes -Wno-cast-align" "-maes -Wno-missing-prototypes -Wno-cast-qual"

View File

@ -1,106 +0,0 @@
#ifndef _CPUSUPPORT_H_
#define _CPUSUPPORT_H_
/*
* To enable support for non-portable CPU features at compile time, one or
* more CPUSUPPORT_ARCH_FEATURE macros should be defined. This can be done
* directly on the compiler command line via -D CPUSUPPORT_ARCH_FEATURE or
* -D CPUSUPPORT_ARCH_FEATURE=1; or a file can be created with the
* necessary #define lines and then -D CPUSUPPORT_CONFIG_FILE=cpuconfig.h
* (or similar) can be provided to include that file here.
*/
#ifdef CPUSUPPORT_CONFIG_FILE
#include CPUSUPPORT_CONFIG_FILE
#endif
/**
* The CPUSUPPORT_FEATURE macro declares the necessary variables and
* functions for detecting CPU feature support at run time. The function
* defined in the macro acts to cache the result of the ..._detect function
* using the ..._present and ..._init variables. The _detect function and the
* _present and _init variables are turn defined by CPUSUPPORT_FEATURE_DECL in
* appropriate cpusupport_foo_bar.c file.
*
* In order to allow CPUSUPPORT_FEATURE to be used for features which do not
* have corresponding CPUSUPPORT_FEATURE_DECL blocks in another source file,
* we abuse the C preprocessor: If CPUSUPPORT_${enabler} is defined to 1, then
* we access _present_1, _init_1, and _detect_1; but if it is not defined, we
* access _present_CPUSUPPORT_${enabler} etc., which we define as static, thus
* preventing the compiler from emitting a reference to an external symbol.
*
* In this way, it becomes possible to issue CPUSUPPORT_FEATURE invocations
* for nonexistent features without running afoul of the requirement that
* "If an identifier declared with external linkage is used... in the entire
* program there shall be exactly one external definition" (C99 standard, 6.9
* paragraph 5). In practice, this means that users of the cpusupport code
* can omit build and runtime detection files without changing the framework
* code.
*/
#define CPUSUPPORT_FEATURE__(arch_feature, enabler, enabled) \
static int cpusupport_ ## arch_feature ## _present ## _CPUSUPPORT_ ## enabler; \
static int cpusupport_ ## arch_feature ## _init ## _CPUSUPPORT_ ## enabler; \
static inline int cpusupport_ ## arch_feature ## _detect ## _CPUSUPPORT_ ## enabler(void) { return (0); } \
extern int cpusupport_ ## arch_feature ## _present_ ## enabled; \
extern int cpusupport_ ## arch_feature ## _init_ ## enabled; \
int cpusupport_ ## arch_feature ## _detect_ ## enabled(void); \
\
static inline int \
cpusupport_ ## arch_feature(void) \
{ \
\
if (cpusupport_ ## arch_feature ## _present_ ## enabled) \
return (1); \
else if (cpusupport_ ## arch_feature ## _init_ ## enabled) \
return (0); \
cpusupport_ ## arch_feature ## _present_ ## enabled = \
cpusupport_ ## arch_feature ## _detect_ ## enabled(); \
cpusupport_ ## arch_feature ## _init_ ## enabled = 1; \
return (cpusupport_ ## arch_feature ## _present_ ## enabled); \
} \
static void (* cpusupport_ ## arch_feature ## _dummyptr)(void); \
static inline void \
cpusupport_ ## arch_feature ## _dummyfunc(void) \
{ \
\
(void)cpusupport_ ## arch_feature ## _present ## _CPUSUPPORT_ ## enabler; \
(void)cpusupport_ ## arch_feature ## _init ## _CPUSUPPORT_ ## enabler; \
(void)cpusupport_ ## arch_feature ## _detect ## _CPUSUPPORT_ ## enabler; \
(void)cpusupport_ ## arch_feature ## _present_ ## enabled; \
(void)cpusupport_ ## arch_feature ## _init_ ## enabled; \
(void)cpusupport_ ## arch_feature ## _detect_ ## enabled; \
(void)cpusupport_ ## arch_feature ## _dummyptr; \
} \
static void (* cpusupport_ ## arch_feature ## _dummyptr)(void) = cpusupport_ ## arch_feature ## _dummyfunc; \
struct cpusupport_ ## arch_feature ## _dummy
#define CPUSUPPORT_FEATURE_(arch_feature, enabler, enabled) \
CPUSUPPORT_FEATURE__(arch_feature, enabler, enabled)
#define CPUSUPPORT_FEATURE(arch, feature, enabler) \
CPUSUPPORT_FEATURE_(arch ## _ ## feature, enabler, CPUSUPPORT_ ## enabler)
/*
* CPUSUPPORT_FEATURE_DECL(arch, feature):
* Macro which defines variables and provides a function declaration for
* detecting the presence of "feature" on the "arch" architecture. The
* function body following this macro expansion must return nonzero if the
* feature is present, or zero if the feature is not present or the detection
* fails for any reason.
*/
#define CPUSUPPORT_FEATURE_DECL(arch, feature) \
int cpusupport_ ## arch ## _ ## feature ## _present_1 = 0; \
int cpusupport_ ## arch ## _ ## feature ## _init_1 = 0; \
int cpusupport_ ## arch ## _ ## feature ## _detect_1(void); \
int \
cpusupport_ ## arch ## _ ## feature ## _detect_1(void)
/*
* List of features. If a feature here is not enabled by the appropriate
* CPUSUPPORT_ARCH_FEATURE macro being defined, it has no effect; but if the
* relevant macro may be defined (e.g., by Build/cpusupport.sh successfully
* compiling Build/cpusupport-ARCH-FEATURE.c) then the C file containing the
* corresponding run-time detection code (cpusupport_arch_feature.c) must be
* compiled and linked in.
*/
CPUSUPPORT_FEATURE(x86, aesni, X86_AESNI);
CPUSUPPORT_FEATURE(x86, sse2, X86_SSE2);
#endif /* !_CPUSUPPORT_H_ */

View File

@ -1,30 +0,0 @@
#include "cpusupport.h"
#ifdef CPUSUPPORT_X86_CPUID
#include <cpuid.h>
#define CPUID_AESNI_BIT (1 << 25)
#endif
CPUSUPPORT_FEATURE_DECL(x86, aesni)
{
#ifdef CPUSUPPORT_X86_CPUID
unsigned int eax, ebx, ecx, edx;
/* Check if CPUID supports the level we need. */
if (!__get_cpuid(0, &eax, &ebx, &ecx, &edx))
goto unsupported;
if (eax < 1)
goto unsupported;
/* Ask about CPU features. */
if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx))
goto unsupported;
/* Return the relevant feature bit. */
return ((ecx & CPUID_AESNI_BIT) ? 1 : 0);
unsupported:
#endif
return (0);
}

View File

@ -1,30 +0,0 @@
#include "cpusupport.h"
#ifdef CPUSUPPORT_X86_CPUID
#include <cpuid.h>
#define CPUID_SSE2_BIT (1 << 26)
#endif
CPUSUPPORT_FEATURE_DECL(x86, sse2)
{
#ifdef CPUSUPPORT_X86_CPUID
unsigned int eax, ebx, ecx, edx;
/* Check if CPUID supports the level we need. */
if (!__get_cpuid(0, &eax, &ebx, &ecx, &edx))
goto unsupported;
if (eax < 1)
goto unsupported;
/* Ask about CPU features. */
if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx))
goto unsupported;
/* Return the relevant feature bit. */
return ((edx & CPUID_SSE2_BIT) ? 1 : 0);
unsupported:
#endif
return (0);
}

View File

@ -1,173 +0,0 @@
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include "cpusupport.h"
#include "crypto_aes_aesni.h"
#include "insecure_memzero.h"
#include "warnp.h"
#include "crypto_aes.h"
/**
* This represents either an AES_KEY or a struct crypto_aes_key_aesni; we
* know which it is based on whether we're using AESNI code or not. As such,
* it's just an opaque pointer; but declaring it as a named structure type
* prevents type-mismatch bugs in upstream code.
*/
struct crypto_aes_key;
#ifdef CPUSUPPORT_X86_AESNI
/* Test whether OpenSSL and AESNI code produce the same AES ciphertext. */
static int
aesnitest(uint8_t ptext[16], uint8_t * key, size_t len)
{
AES_KEY kexp_openssl;
void * kexp_aesni;
uint8_t ctext_openssl[16];
uint8_t ctext_aesni[16];
/* Sanity-check. */
assert((len == 16) || (len == 32));
/* Expand the key. */
AES_set_encrypt_key(key, (int)(len * 8), &kexp_openssl);
if ((kexp_aesni = crypto_aes_key_expand_aesni(key, len)) == NULL)
goto err0;
/* Encrypt the block. */
AES_encrypt(ptext, ctext_openssl, &kexp_openssl);
crypto_aes_encrypt_block_aesni(ptext, ctext_aesni, kexp_aesni);
/* Free the AESNI expanded key. */
crypto_aes_key_free_aesni(kexp_aesni);
/* Do the outputs match? */
return (memcmp(ctext_openssl, ctext_aesni, 16));
err0:
/* Failure! */
return (-1);
}
/* Should we use AESNI? */
static int
useaesni(void)
{
static int aesnigood = -1;
uint8_t key[32];
uint8_t ptext[16];
size_t i;
/* If we haven't decided which code to use yet, decide now. */
while (aesnigood == -1) {
/* Default to OpenSSL. */
aesnigood = 0;
/* If the CPU doesn't claim to support AESNI, stop here. */
if (!cpusupport_x86_aesni())
break;
/* Test cases: key is 0x00010203..., ptext is 0x00112233... */
for (i = 0; i < 16; i++)
ptext[i] = (0x11 * i) & 0xff;
for (i = 0; i < 32; i++)
key[i] = i & 0xff;
/* Test that AESNI and OpenSSL produce the same results. */
if (aesnitest(ptext, key, 16) || aesnitest(ptext, key, 32)) {
warn0("Disabling AESNI due to failed self-test");
break;
}
/* AESNI works; use it. */
aesnigood = 1;
}
return (aesnigood);
}
#endif /* CPUSUPPORT_X86_AESNI */
/**
* crypto_aes_key_expand(key, len):
* Expand the ${len}-byte AES key ${key} into a structure which can be passed
* to crypto_aes_encrypt_block. The length must be 16 or 32.
*/
struct crypto_aes_key *
crypto_aes_key_expand(const uint8_t * key, size_t len)
{
AES_KEY * kexp;
/* Sanity-check. */
assert((len == 16) || (len == 32));
#ifdef CPUSUPPORT_X86_AESNI
/* Use AESNI if we can. */
if (useaesni())
return (crypto_aes_key_expand_aesni(key, len));
#endif
/* Allocate structure. */
if ((kexp = malloc(sizeof(AES_KEY))) == NULL)
goto err0;
/* Expand the key. */
AES_set_encrypt_key(key, (int)(len * 8), kexp);
/* Success! */
return ((void *)kexp);
err0:
/* Failure! */
return (NULL);
}
/**
* crypto_aes_encrypt_block(in, out, key):
* Using the expanded AES key ${key}, encrypt the block ${in} and write the
* resulting ciphertext to ${out}.
*/
void
crypto_aes_encrypt_block(const uint8_t * in, uint8_t * out,
const struct crypto_aes_key * key)
{
#ifdef CPUSUPPORT_X86_AESNI
if (useaesni()) {
crypto_aes_encrypt_block_aesni(in, out, (const void *)key);
return;
}
#endif
/* Get AES to do the work. */
AES_encrypt(in, out, (const void *)key);
}
/**
* crypto_aes_key_free(key):
* Free the expanded AES key ${key}.
*/
void
crypto_aes_key_free(struct crypto_aes_key * key)
{
#ifdef CPUSUPPORT_X86_AESNI
if (useaesni()) {
crypto_aes_key_free_aesni((void *)key);
return;
}
#endif
/* Behave consistently with free(NULL). */
if (key == NULL)
return;
/* Attempt to zero the expanded key. */
insecure_memzero(key, sizeof(AES_KEY));
/* Free the key. */
free(key);
}

View File

@ -1,31 +0,0 @@
#ifndef _CRYPTO_AES_H_
#define _CRYPTO_AES_H_
#include <stddef.h>
#include <stdint.h>
/* Opaque structure. */
struct crypto_aes_key;
/**
* crypto_aes_key_expand(key, len):
* Expand the ${len}-byte AES key ${key} into a structure which can be passed
* to crypto_aes_encrypt_block. The length must be 16 or 32.
*/
struct crypto_aes_key * crypto_aes_key_expand(const uint8_t *, size_t);
/**
* crypto_aes_encrypt_block(in, out, key):
* Using the expanded AES key ${key}, encrypt the block ${in} and write the
* resulting ciphertext to ${out}.
*/
void crypto_aes_encrypt_block(const uint8_t *, uint8_t *,
const struct crypto_aes_key *);
/**
* crypto_aes_key_free(key):
* Free the expanded AES key ${key}.
*/
void crypto_aes_key_free(struct crypto_aes_key *);
#endif /* !_CRYPTO_AES_H_ */

View File

@ -1,239 +0,0 @@
#include "cpusupport.h"
#ifdef CPUSUPPORT_X86_AESNI
#include <stdint.h>
#include <stdlib.h>
#include <wmmintrin.h>
#include "insecure_memzero.h"
#include "warnp.h"
#include "crypto_aes_aesni.h"
/* Expanded-key structure. */
struct crypto_aes_key_aesni {
uint8_t rkeys_buf[15 * sizeof(__m128i) + (sizeof(__m128i) - 1)];
__m128i * rkeys;
size_t nr;
};
/* Compute an AES-128 round key. */
#define MKRKEY128(rkeys, i, rcon) do { \
__m128i _s = rkeys[i - 1]; \
__m128i _t = rkeys[i - 1]; \
_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \
_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \
_t = _mm_aeskeygenassist_si128(_t, rcon); \
_t = _mm_shuffle_epi32(_t, 0xff); \
rkeys[i] = _mm_xor_si128(_s, _t); \
} while (0)
/**
* crypto_aes_key_expand_128_aesni(key, rkeys):
* Expand the 128-bit AES key ${key} into the 11 round keys ${rkeys}. This
* implementation uses x86 AESNI instructions, and should only be used if
* CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
*/
static void
crypto_aes_key_expand_128_aesni(const uint8_t key[16], __m128i rkeys[11])
{
/* The first round key is just the key. */
/**
* XXX Compiler breakage:
* The intrinsic defined by Intel for _mm_loadu_si128 defines it as
* taking a (const __m128i *) parameter. This forces us to write a
* bug: The cast to (const __m128i *) is invalid since it increases
* the alignment requirement of the pointer. Alas, until compilers
* get fixed intrinsics, all we can do is code the bug and require
* that alignment-requirement-increasing compiler warnings get
* disabled.
*/
rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]);
/*
* Each of the remaining round keys are computed from the preceding
* round key: rotword+subword+rcon (provided as aeskeygenassist) to
* compute the 'temp' value, then xor with 1, 2, 3, or all 4 of the
* 32-bit words from the preceding round key. Unfortunately, 'rcon'
* is encoded as an immediate value, so we need to write the loop out
* ourselves rather than allowing the compiler to expand it.
*/
MKRKEY128(rkeys, 1, 0x01);
MKRKEY128(rkeys, 2, 0x02);
MKRKEY128(rkeys, 3, 0x04);
MKRKEY128(rkeys, 4, 0x08);
MKRKEY128(rkeys, 5, 0x10);
MKRKEY128(rkeys, 6, 0x20);
MKRKEY128(rkeys, 7, 0x40);
MKRKEY128(rkeys, 8, 0x80);
MKRKEY128(rkeys, 9, 0x1b);
MKRKEY128(rkeys, 10, 0x36);
}
/* Compute an AES-256 round key. */
#define MKRKEY256(rkeys, i, shuffle, rcon) do { \
__m128i _s = rkeys[i - 2]; \
__m128i _t = rkeys[i - 1]; \
_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \
_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \
_t = _mm_aeskeygenassist_si128(_t, rcon); \
_t = _mm_shuffle_epi32(_t, shuffle); \
rkeys[i] = _mm_xor_si128(_s, _t); \
} while (0)
/**
* crypto_aes_key_expand_256_aesni(key, rkeys):
* Expand the 256-bit AES key ${key} into the 15 round keys ${rkeys}. This
* implementation uses x86 AESNI instructions, and should only be used if
* CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
*/
static void
crypto_aes_key_expand_256_aesni(const uint8_t key[32], __m128i rkeys[15])
{
/* The first two round keys are just the key. */
/**
* XXX Compiler breakage:
* The intrinsic defined by Intel for _mm_loadu_si128 defines it as
* taking a (const __m128i *) parameter. This forces us to write a
* bug: The cast to (const __m128i *) is invalid since it increases
* the alignment requirement of the pointer. Alas, until compilers
* get fixed intrinsics, all we can do is code the bug and require
* that alignment-requirement-increasing compiler warnings get
* disabled.
*/
rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]);
rkeys[1] = _mm_loadu_si128((const __m128i *)&key[16]);
/*
* Each of the remaining round keys are computed from the preceding
* pair of keys. Even rounds use rotword+subword+rcon, while odd
* rounds just use subword; the aeskeygenassist instruction computes
* both, and we use 0xff or 0xaa to select the one we need. The rcon
* value used is irrelevant for odd rounds since we ignore the value
* which it feeds into. Unfortunately, the 'shuffle' and 'rcon'
* values are encoded into the instructions as immediates, so we need
* to write the loop out ourselves rather than allowing the compiler
* to expand it.
*/
MKRKEY256(rkeys, 2, 0xff, 0x01);
MKRKEY256(rkeys, 3, 0xaa, 0x00);
MKRKEY256(rkeys, 4, 0xff, 0x02);
MKRKEY256(rkeys, 5, 0xaa, 0x00);
MKRKEY256(rkeys, 6, 0xff, 0x04);
MKRKEY256(rkeys, 7, 0xaa, 0x00);
MKRKEY256(rkeys, 8, 0xff, 0x08);
MKRKEY256(rkeys, 9, 0xaa, 0x00);
MKRKEY256(rkeys, 10, 0xff, 0x10);
MKRKEY256(rkeys, 11, 0xaa, 0x00);
MKRKEY256(rkeys, 12, 0xff, 0x20);
MKRKEY256(rkeys, 13, 0xaa, 0x00);
MKRKEY256(rkeys, 14, 0xff, 0x40);
}
/**
* crypto_aes_key_expand_aesni(key, len):
* Expand the ${len}-byte AES key ${key} into a structure which can be passed
* to crypto_aes_encrypt_block_aesni. The length must be 16 or 32. This
* implementation uses x86 AESNI instructions, and should only be used if
* CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
*/
void *
crypto_aes_key_expand_aesni(const uint8_t * key, size_t len)
{
struct crypto_aes_key_aesni * kexp;
size_t rkey_offset;
/* Allocate structure. */
if ((kexp = malloc(sizeof(struct crypto_aes_key_aesni))) == NULL)
goto err0;
/* Figure out where to put the round keys. */
rkey_offset = (uintptr_t)(&kexp->rkeys_buf[0]) % sizeof(__m128i);
rkey_offset = (sizeof(__m128i) - rkey_offset) % sizeof(__m128i);
kexp->rkeys = (void *)&kexp->rkeys_buf[rkey_offset];
/* Compute round keys. */
if (len == 16) {
kexp->nr = 10;
crypto_aes_key_expand_128_aesni(key, kexp->rkeys);
} else if (len == 32) {
kexp->nr = 14;
crypto_aes_key_expand_256_aesni(key, kexp->rkeys);
} else {
warn0("Unsupported AES key length: %zu bytes", len);
goto err1;
}
/* Success! */
return (kexp);
err1:
free(kexp);
err0:
/* Failure! */
return (NULL);
}
/**
* crypto_aes_encrypt_block_aesni(in, out, key):
* Using the expanded AES key ${key}, encrypt the block ${in} and write the
* resulting ciphertext to ${out}. This implementation uses x86 AESNI
* instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined
* and cpusupport_x86_aesni() returns nonzero.
*/
void
crypto_aes_encrypt_block_aesni(const uint8_t * in, uint8_t * out,
const void * key)
{
const struct crypto_aes_key_aesni * _key = key;
const __m128i * aes_key = _key->rkeys;
__m128i aes_state;
size_t nr = _key->nr;
aes_state = _mm_loadu_si128((const __m128i *)in);
aes_state = _mm_xor_si128(aes_state, aes_key[0]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[1]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[2]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[3]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[4]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[5]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[6]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[7]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[8]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[9]);
if (nr > 10) {
aes_state = _mm_aesenc_si128(aes_state, aes_key[10]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[11]);
if (nr > 12) {
aes_state = _mm_aesenc_si128(aes_state, aes_key[12]);
aes_state = _mm_aesenc_si128(aes_state, aes_key[13]);
}
}
aes_state = _mm_aesenclast_si128(aes_state, aes_key[nr]);
_mm_storeu_si128((__m128i *)out, aes_state);
}
/**
* crypto_aes_key_free_aesni(key):
* Free the expanded AES key ${key}.
*/
void
crypto_aes_key_free_aesni(void * key)
{
/* Behave consistently with free(NULL). */
if (key == NULL)
return;
/* Attempt to zero the expanded key. */
insecure_memzero(key, sizeof(struct crypto_aes_key_aesni));
/* Free the key. */
free(key);
}
#endif /* CPUSUPPORT_X86_AESNI */

View File

@ -1,31 +0,0 @@
#ifndef _CRYPTO_AES_AESNI_H_
#define _CRYPTO_AES_AESNI_H_
#include <stddef.h>
#include <stdint.h>
/**
* crypto_aes_key_expand_aesni(key, len):
* Expand the ${len}-byte AES key ${key} into a structure which can be passed
* to crypto_aes_encrypt_block_aesni. The length must be 16 or 32. This
* implementation uses x86 AESNI instructions, and should only be used if
* CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
*/
void * crypto_aes_key_expand_aesni(const uint8_t *, size_t);
/**
* crypto_aes_encrypt_block_aesni(in, out, key):
* Using the expanded AES key ${key}, encrypt the block ${in} and write the
* resulting ciphertext to ${out}. This implementation uses x86 AESNI
* instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined
* and cpusupport_x86_aesni() returns nonzero.
*/
void crypto_aes_encrypt_block_aesni(const uint8_t *, uint8_t *, const void *);
/**
* crypto_aes_key_free_aesni(key):
* Free the expanded AES key ${key}.
*/
void crypto_aes_key_free_aesni(void *);
#endif /* !_CRYPTO_AES_AESNI_H_ */

View File

@ -1,119 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include "crypto_aes.h"
#include "insecure_memzero.h"
#include "sysendian.h"
#include "crypto_aesctr.h"
struct crypto_aesctr {
const struct crypto_aes_key * key;
uint64_t nonce;
uint64_t bytectr;
uint8_t buf[16];
};
/**
* crypto_aesctr_init(key, nonce):
* Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
* expanded key and nonce. The key provided must remain valid for the
* lifetime of the stream.
*/
struct crypto_aesctr *
crypto_aesctr_init(const struct crypto_aes_key * key, uint64_t nonce)
{
struct crypto_aesctr * stream;
/* Allocate memory. */
if ((stream = malloc(sizeof(struct crypto_aesctr))) == NULL)
goto err0;
/* Initialize values. */
stream->key = key;
stream->nonce = nonce;
stream->bytectr = 0;
/* Success! */
return (stream);
err0:
/* Failure! */
return (NULL);
}
/**
* crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
* Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
* bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers
* ${inbuf} and ${outbuf} overlap, they must be identical.
*/
void
crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf,
uint8_t * outbuf, size_t buflen)
{
uint8_t pblk[16];
size_t pos;
int bytemod;
for (pos = 0; pos < buflen; pos++) {
/* How far through the buffer are we? */
bytemod = stream->bytectr % 16;
/* Generate a block of cipherstream if needed. */
if (bytemod == 0) {
be64enc(pblk, stream->nonce);
be64enc(pblk + 8, stream->bytectr / 16);
crypto_aes_encrypt_block(pblk, stream->buf,
stream->key);
}
/* Encrypt a byte. */
outbuf[pos] = inbuf[pos] ^ stream->buf[bytemod];
/* Move to the next byte of cipherstream. */
stream->bytectr += 1;
}
}
/**
* crypto_aesctr_free(stream):
* Free the provided stream object.
*/
void
crypto_aesctr_free(struct crypto_aesctr * stream)
{
/* Behave consistently with free(NULL). */
if (stream == NULL)
return;
/* Zero potentially sensitive information. */
insecure_memzero(stream, sizeof(struct crypto_aesctr));
/* Free the stream. */
free(stream);
}
/**
* crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
* Equivalent to _init(key, nonce); _stream(inbuf, outbuf, buflen); _free().
*/
void
crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce,
const uint8_t * inbuf, uint8_t * outbuf, size_t buflen)
{
struct crypto_aesctr stream_rec;
struct crypto_aesctr * stream = &stream_rec;
/* Initialize values. */
stream->key = key;
stream->nonce = nonce;
stream->bytectr = 0;
/* Perform the encryption. */
crypto_aesctr_stream(stream, inbuf, outbuf, buflen);
/* Zero potentially sensitive information. */
insecure_memzero(stream, sizeof(struct crypto_aesctr));
}

View File

@ -1,42 +0,0 @@
#ifndef _CRYPTO_AESCTR_H_
#define _CRYPTO_AESCTR_H_
#include <stddef.h>
#include <stdint.h>
/* Opaque types. */
struct crypto_aes_key;
struct crypto_aesctr;
/**
* crypto_aesctr_init(key, nonce):
* Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
* expanded key and nonce. The key provided must remain valid for the
* lifetime of the stream.
*/
struct crypto_aesctr * crypto_aesctr_init(const struct crypto_aes_key *,
uint64_t);
/**
* crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
* Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
* bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers
* ${inbuf} and ${outbuf} overlap, they must be identical.
*/
void crypto_aesctr_stream(struct crypto_aesctr *, const uint8_t *,
uint8_t *, size_t);
/**
* crypto_aesctr_free(stream):
* Free the provided stream object.
*/
void crypto_aesctr_free(struct crypto_aesctr *);
/**
* crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
* Equivalent to _init(key, nonce); _stream(inbuf, outbuf, buflen); _free().
*/
void crypto_aesctr_buf(const struct crypto_aes_key *, uint64_t,
const uint8_t *, uint8_t *, size_t);
#endif /* !_CRYPTO_AESCTR_H_ */

View File

@ -1,215 +0,0 @@
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "entropy.h"
#include "insecure_memzero.h"
#include "sha256.h"
#include "crypto_entropy.h"
/**
* This system implements the HMAC_DRBG pseudo-random number generator as
* specified in section 10.1.2 of the NIST SP 800-90 standard. In this
* implementation, the optional personalization_string and additional_input
* specified in the standard are not implemented.
*/
/* Internal HMAC_DRBG state. */
static struct {
uint8_t Key[32];
uint8_t V[32];
uint32_t reseed_counter;
} drbg;
/* Set to non-zero once the PRNG has been instantiated. */
static int instantiated = 0;
/* Could be as high as 2^48 if we wanted... */
#define RESEED_INTERVAL 256
/* Limited to 2^16 by specification. */
#define GENERATE_MAXLEN 65536
static int instantiate(void);
static void update(uint8_t *, size_t);
static int reseed(void);
static void generate(uint8_t *, size_t);
/**
* instantiate(void):
* Initialize the DRBG state. (Section 10.1.2.3)
*/
static int
instantiate(void)
{
uint8_t seed_material[48];
/* Obtain random seed_material = (entropy_input || nonce). */
if (entropy_read(seed_material, 48))
return (-1);
/* Initialize Key, V, and reseed_counter. */
memset(drbg.Key, 0x00, 32);
memset(drbg.V, 0x01, 32);
drbg.reseed_counter = 1;
/* Mix the random seed into the state. */
update(seed_material, 48);
/* Clean the stack. */
insecure_memzero(seed_material, 48);
/* Success! */
return (0);
}
/**
* update(data, datalen):
* Update the DRBG state using the provided data. (Section 10.1.2.2)
*/
static void
update(uint8_t * data, size_t datalen)
{
HMAC_SHA256_CTX ctx;
uint8_t K[32];
uint8_t Vx[33];
/* Load (Key, V) into (K, Vx). */
memcpy(K, drbg.Key, 32);
memcpy(Vx, drbg.V, 32);
/* K <- HMAC(K, V || 0x00 || data). */
Vx[32] = 0x00;
HMAC_SHA256_Init(&ctx, K, 32);
HMAC_SHA256_Update(&ctx, Vx, 33);
HMAC_SHA256_Update(&ctx, data, datalen);
HMAC_SHA256_Final(K, &ctx);
/* V <- HMAC(K, V). */
HMAC_SHA256_Buf(K, 32, Vx, 32, Vx);
/* If the provided data is non-Null, perform another mixing stage. */
if (datalen != 0) {
/* K <- HMAC(K, V || 0x01 || data). */
Vx[32] = 0x01;
HMAC_SHA256_Init(&ctx, K, 32);
HMAC_SHA256_Update(&ctx, Vx, 33);
HMAC_SHA256_Update(&ctx, data, datalen);
HMAC_SHA256_Final(K, &ctx);
/* V <- HMAC(K, V). */
HMAC_SHA256_Buf(K, 32, Vx, 32, Vx);
}
/* Copy (K, Vx) back to (Key, V). */
memcpy(drbg.Key, K, 32);
memcpy(drbg.V, Vx, 32);
/* Clean the stack. */
insecure_memzero(K, 32);
insecure_memzero(Vx, 33);
}
/**
* reseed(void):
* Reseed the DRBG state (mix in new entropy). (Section 10.1.2.4)
*/
static int
reseed(void)
{
uint8_t seed_material[32];
/* Obtain random seed_material = entropy_input. */
if (entropy_read(seed_material, 32))
return (-1);
/* Mix the random seed into the state. */
update(seed_material, 32);
/* Reset the reseed_counter. */
drbg.reseed_counter = 1;
/* Clean the stack. */
insecure_memzero(seed_material, 32);
/* Success! */
return (0);
}
/**
* generate(buf, buflen):
* Fill the provided buffer with random bits, assuming that reseed_counter
* is less than RESEED_INTERVAL (the caller is responsible for calling
* reseed() as needed) and ${buflen} is less than 2^16 (the caller is
* responsible for splitting up larger requests). (Section 10.1.2.5)
*/
static void
generate(uint8_t * buf, size_t buflen)
{
size_t bufpos;
assert(buflen <= GENERATE_MAXLEN);
assert(drbg.reseed_counter <= RESEED_INTERVAL);
/* Iterate until we've filled the buffer. */
for (bufpos = 0; bufpos < buflen; bufpos += 32) {
HMAC_SHA256_Buf(drbg.Key, 32, drbg.V, 32, drbg.V);
if (buflen - bufpos >= 32)
memcpy(&buf[bufpos], drbg.V, 32);
else
memcpy(&buf[bufpos], drbg.V, buflen - bufpos);
}
/* Mix up state. */
update(NULL, 0);
/* We're one data-generation step closer to needing a reseed. */
drbg.reseed_counter += 1;
}
/**
* crypto_entropy_read(buf, buflen):
* Fill the buffer with unpredictable bits.
*/
int
crypto_entropy_read(uint8_t * buf, size_t buflen)
{
size_t bytes_to_provide;
/* Instantiate if needed. */
if (instantiated == 0) {
/* Try to instantiate the PRNG. */
if (instantiate())
return (-1);
/* We have instantiated the PRNG. */
instantiated = 1;
}
/* Loop until we've filled the buffer. */
while (buflen > 0) {
/* Do we need to reseed? */
if (drbg.reseed_counter > RESEED_INTERVAL) {
if (reseed())
return (-1);
}
/* How much data are we generating in this step? */
if (buflen > GENERATE_MAXLEN)
bytes_to_provide = GENERATE_MAXLEN;
else
bytes_to_provide = buflen;
/* Generate bytes. */
generate(buf, bytes_to_provide);
/* We've done part of the buffer. */
buf += bytes_to_provide;
buflen -= bytes_to_provide;
}
/* Success! */
return (0);
}

View File

@ -1,14 +0,0 @@
#ifndef _CRYPTO_ENTROPY_H_
#define _CRYPTO_ENTROPY_H_
#include <stddef.h>
#include <stdint.h>
/**
* crypto_entropy_read(buf, buflen):
* Fill the buffer with unpredictable bits. The value ${buflen} must be
* less than 2^16.
*/
int crypto_entropy_read(uint8_t *, size_t);
#endif /* !_CRYPTO_ENTROPY_H_ */

View File

@ -1,49 +0,0 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "asprintf.h"
/**
* asprintf(ret, format, ...):
* Do asprintf(3) like GNU and BSD do.
*/
int
asprintf(char ** ret, const char * format, ...)
{
va_list ap;
int len;
size_t buflen;
/* Figure out how long the string needs to be. */
va_start(ap, format);
len = vsnprintf(NULL, 0, format, ap);
va_end(ap);
/* Did we fail? */
if (len < 0)
goto err0;
buflen = (size_t)(len) + 1;
/* Allocate memory. */
if ((*ret = malloc(buflen)) == NULL)
goto err0;
/* Actually generate the string. */
va_start(ap, format);
len = vsnprintf(*ret, buflen, format, ap);
va_end(ap);
/* Did we fail? */
if (len < 0)
goto err1;
/* Success! */
return (len);
err1:
free(*ret);
err0:
/* Failure! */
return (-1);
}

View File

@ -1,16 +0,0 @@
#ifndef _ASPRINTF_H_
#define _ASPRINTF_H_
/* Avoid namespace collisions with BSD/GNU asprintf. */
#ifdef asprintf
#undef asprintf
#endif
#define asprintf libcperciva_asprintf
/**
* asprintf(ret, format, ...):
* Do asprintf(3) like GNU and BSD do.
*/
int asprintf(char **, const char *, ...);
#endif /* !_ASPRINTF_H_ */

View File

@ -1,77 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>
#include <unistd.h>
#include "warnp.h"
#include "entropy.h"
/**
* XXX Portability
* XXX We obtain random bytes from the operating system by opening
* XXX /dev/urandom and reading them from that device; this works on
* XXX modern UNIX-like operating systems but not on systems like
* XXX win32 where there is no concept of /dev/urandom.
*/
/**
* entropy_read(buf, buflen):
* Fill the given buffer with random bytes provided by the operating system.
*/
int
entropy_read(uint8_t * buf, size_t buflen)
{
int fd;
ssize_t lenread;
/* Sanity-check the buffer size. */
if (buflen > SSIZE_MAX) {
warn0("Programmer error: "
"Trying to read insane amount of random data: %zu",
buflen);
goto err0;
}
/* Open /dev/urandom. */
if ((fd = open("/dev/urandom", O_RDONLY)) == -1) {
warnp("open(/dev/urandom)");
goto err0;
}
/* Read bytes until we have filled the buffer. */
while (buflen > 0) {
if ((lenread = read(fd, buf, buflen)) == -1) {
warnp("read(/dev/urandom)");
goto err1;
}
/* The random device should never EOF. */
if (lenread == 0) {
warn0("EOF on /dev/urandom?");
goto err1;
}
/* We've filled a portion of the buffer. */
buf += (size_t)lenread;
buflen -= (size_t)lenread;
}
/* Close the device. */
while (close(fd) == -1) {
if (errno != EINTR) {
warnp("close(/dev/urandom)");
goto err0;
}
}
/* Success! */
return (0);
err1:
close(fd);
err0:
/* Failure! */
return (-1);
}

View File

@ -1,13 +0,0 @@
#ifndef _ENTROPY_H_
#define _ENTROPY_H_
#include <stddef.h>
#include <stdint.h>
/**
* entropy_read(buf, buflen):
* Fill the given buffer with random bytes provided by the operating system.
*/
int entropy_read(uint8_t *, size_t);
#endif /* !_ENTROPY_H_ */

View File

@ -1,358 +0,0 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
/*
* Standard getopt global variables. optreset starts as non-zero in order to
* trigger initialization behaviour.
*/
const char * optarg = NULL;
int optind = 1;
int opterr = 1;
int optreset = 1;
/*
* Quasi-internal global variables -- these are used via GETOPT macros.
*/
const char * getopt_dummy = "(dummy)";
int getopt_initialized = 0;
/*
* Internal variables.
*/
static const char * cmdname = NULL;
static struct opt {
const char * os;
size_t olen;
int hasarg;
} * opts = NULL;
static size_t nopts;
static size_t opt_missing;
static size_t opt_default;
static size_t opt_found;
static const char * packedopts;
static char popt[3];
static int atexit_registered = 0;
/* Print a message. */
#define PRINTMSG(...) do { \
if (cmdname != NULL) \
fprintf(stderr, "%s: ", cmdname); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (0)
/* Print an error message and die. */
#define DIE(...) do { \
PRINTMSG(__VA_ARGS__); \
abort(); \
} while (0)
/* Print a warning, if warnings are enabled. */
#define WARN(...) do { \
if (opterr == 0) \
break; \
if (opt_missing != opt_default) \
break; \
PRINTMSG(__VA_ARGS__); \
} while (0)
/* Free allocated options array. */
static void
atexit_handler(void)
{
free(opts);
opts = NULL;
}
/* Reset internal state. */
static void
reset(int argc, char * const argv[])
{
const char * p;
/* If we have arguments, stash argv[0] for error messages. */
if (argc > 0) {
/* Find the basename, without leading directories. */
for (p = cmdname = argv[0]; *p != '\0'; p++) {
if (*p == '/')
cmdname = p + 1;
}
}
/* Discard any registered command-line options. */
free(opts);
opts = NULL;
/* Register atexit handler if we haven't done so already. */
if (!atexit_registered) {
atexit(atexit_handler);
atexit_registered = 1;
}
/* We will start scanning from the first option. */
optind = 1;
/* We're not in the middle of any packed options. */
packedopts = NULL;
/* We haven't found any option yet. */
opt_found = (size_t)(-1);
/* We're not initialized yet. */
getopt_initialized = 0;
/* Finished resetting state. */
optreset = 0;
}
/* Search for an option string. */
static size_t
searchopt(const char * os)
{
size_t i;
/* Scan the array of options. */
for (i = 0; i < nopts; i++) {
/* Is there an option in this slot? */
if (opts[i].os == NULL)
continue;
/* Does this match up to the length of the option string? */
if (strncmp(opts[i].os, os, opts[i].olen))
continue;
/* Do we have <option>\0 or <option>= ? */
if ((os[opts[i].olen] == '\0') || (os[opts[i].olen] == '='))
return (i);
}
/* Not found. */
return (opt_default);
}
const char *
getopt(int argc, char * const argv[])
{
const char * os = NULL;
const char * canonical_os = NULL;
/* No argument yet. */
optarg = NULL;
/* Reset the getopt state if needed. */
if (optreset)
reset(argc, argv);
/* If not initialized, return dummy option. */
if (!getopt_initialized)
return (GETOPT_DUMMY);
/* If we've run out of arguments, we're done. */
if (optind >= argc)
return (NULL);
/*
* If we're not already in the middle of a packed single-character
* options, see if we should start.
*/
if ((packedopts == NULL) && (argv[optind][0] == '-') &&
(argv[optind][1] != '-') && (argv[optind][1] != '\0')) {
/* We have one or more single-character options. */
packedopts = &argv[optind][1];
}
/* If we're processing single-character options, fish one out. */
if (packedopts != NULL) {
/* Construct the option string. */
popt[0] = '-';
popt[1] = *packedopts;
popt[2] = '\0';
os = popt;
/* We've done this character. */
packedopts++;
/* Are we done with this string? */
if (*packedopts == '\0') {
packedopts = NULL;
optind++;
}
}
/* If we don't have an option yet, do we have dash-dash? */
if ((os == NULL) && (argv[optind][0] == '-') &&
(argv[optind][1] == '-')) {
/* If this is not "--\0", it's an option. */
if (argv[optind][2] != '\0')
os = argv[optind];
/* Either way, we want to eat the string. */
optind++;
}
/* If we have found nothing which looks like an option, we're done. */
if (os == NULL)
return (NULL);
/* Search for the potential option. */
opt_found = searchopt(os);
/* If the option is not registered, give up now. */
if (opt_found == opt_default) {
WARN("unknown option: %s", os);
return (os);
}
/* The canonical option string is the one registered. */
canonical_os = opts[opt_found].os;
/* Does the option take an argument? */
if (opts[opt_found].hasarg) {
/*
* If we're processing packed single-character options, the
* rest of the string is the argument to this option.
*/
if (packedopts != NULL) {
optarg = packedopts;
packedopts = NULL;
optind++;
}
/*
* If the option string is <option>=<value>, extract that
* value as the option argument.
*/
if (os[opts[opt_found].olen] == '=')
optarg = &os[opts[opt_found].olen + 1];
/*
* If we don't have an argument yet, take one from the
* remaining command line.
*/
if ((optarg == NULL) && (optind < argc))
optarg = argv[optind++];
/* If we still have no option, declare it MIA. */
if (optarg == NULL) {
WARN("option requires an argument: %s",
opts[opt_found].os);
opt_found = opt_missing;
}
} else {
/* If we have --foo=bar, something went wrong. */
if (os[opts[opt_found].olen] == '=') {
WARN("option doesn't take an argument: %s",
opts[opt_found].os);
opt_found = opt_default;
}
}
/* Return the canonical option string. */
return (canonical_os);
}
size_t
getopt_lookup(const char * os)
{
/* Can't reset here. */
if (optreset)
DIE("Can't reset in the middle of getopt loop");
/* We should only be called after initialization is complete. */
assert(getopt_initialized);
/* GETOPT_DUMMY should never get passed back to us. */
assert(os != GETOPT_DUMMY);
/*
* Make sure the option passed back to us corresponds to the one we
* found earlier.
*/
assert((opt_found == opt_missing) || (opt_found == opt_default) ||
((opt_found < nopts) && (strcmp(os, opts[opt_found].os) == 0)));
/* Return the option number we identified earlier. */
return (opt_found);
}
void
getopt_register_opt(const char * os, size_t ln, int hasarg)
{
/* Can't reset here. */
if (optreset)
DIE("Can't reset in the middle of getopt loop");
/* We should only be called during initialization. */
assert(!getopt_initialized);
/* We should have space allocated for registering options. */
assert(opts != NULL);
/* We should not have registered an option here yet. */
assert(opts[ln].os == NULL);
/* Options should be "-X" or "--foo". */
if ((os[0] != '-') || (os[1] == '\0') ||
((os[1] == '-') && (os[2] == '\0')) ||
((os[1] != '-') && (os[2] != '\0')))
DIE("Not a valid command-line option: %s", os);
/* Make sure we haven't already registered this option. */
if (searchopt(os) != opt_default)
DIE("Command-line option registered twice: %s", os);
/* Record option. */
opts[ln].os = os;
opts[ln].olen = strlen(os);
opts[ln].hasarg = hasarg;
}
void
getopt_register_missing(size_t ln)
{
/* Can't reset here. */
if (optreset)
DIE("Can't reset in the middle of getopt loop");
/* We should only be called during initialization. */
assert(!getopt_initialized);
/* Record missing-argument value. */
opt_missing = ln;
}
void
getopt_setrange(size_t ln)
{
size_t i;
/* Can't reset here. */
if (optreset)
DIE("Can't reset in the middle of getopt loop");
/* We should only be called during initialization. */
assert(!getopt_initialized);
/* Allocate space for options. */
opts = malloc(ln * sizeof(struct opt));
if ((ln > 0) && (opts == NULL))
DIE("Failed to allocate memory in getopt");
/* Initialize options. */
for (i = 0; i < ln; i++)
opts[i].os = NULL;
/* Record the number of (potential) options. */
nopts = ln;
/* Record default missing-argument and no-such-option values. */
opt_missing = opt_default = ln + 1;
}

View File

@ -1,175 +0,0 @@
#ifndef _GETOPT_H_
#define _GETOPT_H_
#include <setjmp.h>
#include <stddef.h>
/**
* This getopt implementation parses options of the following forms:
* -a -b -c foo (single-character options)
* -abc foo (packed single-character options)
* -abcfoo (packed single-character options and an argument)
* --foo bar (long option)
* --foo=bar (long option and argument separated by '=')
*
* It does not support abbreviated options (e.g., interpreting --foo as
* --foobar when there are no other --foo* options) since that misfeature
* results in breakage when new options are added. It also does not support
* options appearing after non-options (e.g., "cp foo bar -R") since that is
* a horrible GNU perversion.
*/
/* Work around LLVM bug. */
#ifdef __clang__
//#warning Working around bug in LLVM optimizer
//#warning For more details see https://llvm.org/bugs/show_bug.cgi?id=27190
#define DO_SETJMP _DO_SETJMP(__LINE__)
#define _DO_SETJMP(x) __DO_SETJMP(x)
#define __DO_SETJMP(x) \
void * getopt_initloop = && getopt_initloop_ ## x; \
getopt_initloop_ ## x:
#define DO_LONGJMP \
goto *getopt_initloop
#else
#define DO_SETJMP \
sigjmp_buf getopt_initloop; \
if (!getopt_initialized) \
sigsetjmp(getopt_initloop, 0)
#define DO_LONGJMP \
siglongjmp(getopt_initloop, 1)
#endif
/* Avoid namespace collisions with libc getopt. */
#define getopt libcperciva_getopt
#define optarg libcperciva_optarg
#define optind libcperciva_optind
#define opterr libcperciva_opterr
#define optreset libcperciva_optreset
/* Standard getopt global variables. */
extern const char * optarg;
extern int optind, opterr, optreset;
/* Dummy option string, equal to "(dummy)". */
#define GETOPT_DUMMY getopt_dummy
/**
* GETOPT(argc, argv):
* When called for the first time (or the first time after optreset is set to
* a nonzero value), return GETOPT_DUMMY, aka. "(dummy)". Thereafter, return
* the next option string and set optarg / optind appropriately; abort if not
* properly initialized when not being called for the first time.
*/
#define GETOPT(argc, argv) getopt(argc, argv)
/**
* GETOPT_SWITCH(ch):
* Jump to the appropriate GETOPT_OPT, GETOPT_OPTARG, GETOPT_MISSING_ARG, or
* GETOPT_DEFAULT based on the option string ${ch}. When called for the first
* time, perform magic to index the options.
*
* GETOPT_SWITCH(ch) is equivalent to "switch (ch)" in a standard getopt loop.
*/
#define GETOPT_SWITCH(ch) \
volatile size_t getopt_ln_min = __LINE__; \
volatile size_t getopt_ln = getopt_ln_min - 1; \
volatile int getopt_default_missing = 0; \
DO_SETJMP; \
switch (getopt_initialized ? getopt_lookup(ch) + getopt_ln_min : getopt_ln++)
/**
* GETOPT_OPT(os):
* Jump to this point when the option string ${os} is passed to GETOPT_SWITCH.
*
* GETOPT_OPT("-x") is equivalent to "case 'x'" in a standard getopt loop
* which has an optstring containing "x".
*/
#define GETOPT_OPT(os) _GETOPT_OPT(os, __LINE__)
#define _GETOPT_OPT(os, ln) __GETOPT_OPT(os, ln)
#define __GETOPT_OPT(os, ln) \
case ln: \
if (getopt_initialized) \
goto getopt_skip_ ## ln; \
getopt_register_opt(os, ln - getopt_ln_min, 0); \
DO_LONGJMP; \
getopt_skip_ ## ln
/**
* GETOPT_OPTARG(os):
* Jump to this point when the option string ${os} is passed to GETOPT_SWITCH,
* unless no argument is available, in which case jump to GETOPT_MISSING_ARG
* (if present) or GETOPT_DEFAULT (if not).
*
* GETOPT_OPTARG("-x") is equivalent to "case 'x'" in a standard getopt loop
* which has an optstring containing "x:".
*/
#define GETOPT_OPTARG(os) _GETOPT_OPTARG(os, __LINE__)
#define _GETOPT_OPTARG(os, ln) __GETOPT_OPTARG(os, ln)
#define __GETOPT_OPTARG(os, ln) \
case ln: \
if (getopt_initialized) \
goto getopt_skip_ ## ln; \
getopt_register_opt(os, ln - getopt_ln_min, 1); \
DO_LONGJMP; \
getopt_skip_ ## ln
/**
* GETOPT_MISSING_ARG:
* Jump to this point if an option string specified in GETOPT_OPTARG is seen
* but no argument is available.
*
* GETOPT_MISSING_ARG is equivalent to "case ':'" in a standard getopt loop
* which has an optstring starting with ":". As such, it also has the effect
* of disabling warnings about invalid options, as if opterr had been zeroed.
*/
#define GETOPT_MISSING_ARG _GETOPT_MISSING_ARG(__LINE__)
#define _GETOPT_MISSING_ARG(ln) __GETOPT_MISSING_ARG(ln)
#define __GETOPT_MISSING_ARG(ln) \
case ln: \
if (getopt_initialized) \
goto getopt_skip_ ## ln; \
getopt_register_missing(ln - getopt_ln_min); \
DO_LONGJMP; \
getopt_skip_ ## ln
/**
* GETOPT_DEFAULT:
* Jump to this point if an unrecognized option is seen or if an option
* specified in GETOPT_OPTARG is seen, no argument is available, and there is
* no GETOPT_MISSING_ARG label.
*
* GETOPT_DEFAULT is equivalent to "case '?'" in a standard getopt loop.
*
* NOTE: This MUST be present in the GETOPT_SWITCH statement, and MUST occur
* after all other GETOPT_* labels.
*/
#define GETOPT_DEFAULT _GETOPT_DEFAULT(__LINE__)
#define _GETOPT_DEFAULT(ln) __GETOPT_DEFAULT(ln)
#define __GETOPT_DEFAULT(ln) \
goto getopt_skip_ ## ln; \
case ln: \
getopt_initialized = 1; \
break; \
default: \
if (getopt_initialized) \
goto getopt_skip_ ## ln; \
if (!getopt_default_missing) { \
getopt_setrange(ln - getopt_ln_min); \
getopt_default_missing = 1; \
} \
DO_LONGJMP; \
getopt_skip_ ## ln
/*
* The back-end implementation. These should be considered internal
* interfaces and not used directly.
*/
const char * getopt(int, char * const []);
size_t getopt_lookup(const char *);
void getopt_register_opt(const char *, size_t, int);
void getopt_register_missing(size_t);
void getopt_setrange(size_t);
extern const char * getopt_dummy;
extern int getopt_initialized;
#endif /* !_GETOPT_H_ */

View File

@ -1,165 +0,0 @@
#include <stdio.h>
#include "asprintf.h"
#include "warnp.h"
#include "humansize.h"
/**
* humansize(size):
* Given a size in bytes, allocate and return a string of the form "<N> B"
* for 0 <= N <= 999 or "<X> <prefix>B" where either 10 <= X <= 999 or
* 1.0 <= X <= 9.9 and <prefix> is "k", "M", "G", "T", "P", or "E"; and where
* the value returned is the largest valid value <= the provided size.
*/
char *
humansize(uint64_t size)
{
char * s;
char prefix;
int shiftcnt;
int rc;
/* Special-case for size < 1000. */
if (size < 1000) {
rc = asprintf(&s, "%d B", (int)size);
} else {
/* Keep 10 * size / 1000^(3n) in size. */
for (size /= 100, shiftcnt = 1; size >= 10000; shiftcnt++)
size /= 1000;
/*
* Figure out what prefix to use. Since 1 EB = 10^18 B and
* the maximum value of a uint64_t is 2^64 which is roughly
* 18.4 * 10^18, this cannot reference beyond the end of the
* string.
*/
prefix = " kMGTPE"[shiftcnt];
/* Construct the string. */
if (size < 100)
rc = asprintf(&s, "%d.%d %cB", (int)size / 10,
(int)size % 10, prefix);
else
rc = asprintf(&s, "%d %cB", (int)size / 10, prefix);
}
if (rc == -1) {
warnp("asprintf");
goto err0;
}
/* Success! */
return (s);
err0:
/* Failure! */
return (NULL);
}
/**
* humansize_parse(s, size):
* Parse a string matching /[0-9]+ ?[kMGTPE]?B?/ as a size in bytes.
*/
int
humansize_parse(const char * s, uint64_t * size)
{
int state = 0;
uint64_t multiplier = 1;
do {
switch (state) {
case -1:
/* Error state. */
break;
case 0:
/* Initial state. */
*size = 0;
/* We must start with at least one digit. */
if ((*s < '0') || (*s > '9')) {
state = -1;
break;
}
/* FALLTHROUGH */
case 1:
/* We're now processing digits. */
state = 1;
/* Digit-parsing state. */
if (('0' <= *s) && (*s <= '9')) {
if (*size > UINT64_MAX / 10)
state = -1;
else
*size *= 10;
if (*size > UINT64_MAX - (uint64_t)(*s - '0'))
state = -1;
else
*size += (uint64_t)(*s - '0');
break;
}
/* FALLTHROUGH */
case 2:
/* We move into state 3 after an optional ' '. */
state = 3;
if (*s == ' ')
break;
/* FALLTHROUGH */
case 3:
/* We may have one SI prefix. */
switch (*s) {
case 'E':
multiplier *= 1000;
/* FALLTHROUGH */
case 'P':
multiplier *= 1000;
/* FALLTHROUGH */
case 'T':
multiplier *= 1000;
/* FALLTHROUGH */
case 'G':
multiplier *= 1000;
/* FALLTHROUGH */
case 'M':
multiplier *= 1000;
/* FALLTHROUGH */
case 'k':
multiplier *= 1000;
break;
}
/* We move into state 4 after the optional prefix. */
state = 4;
if (multiplier != 1)
break;
/* FALLTHROUGH */
case 4:
/* We move into state 5 after an optional 'B'. */
state = 5;
if (*s == 'B')
break;
/* FALLTHROUGH */
case 5:
/* We have trailing garbage. */
state = -1;
break;
}
/* Move on to the next character. */
s++;
} while (*s != '\0');
/* Multiply by multiplier. */
if (*size > UINT64_MAX / multiplier)
state = -1;
else
*size *= multiplier;
/* Anything other than state -1 is success. */
return ((state == -1) ? -1 : 0);
}

View File

@ -1,21 +0,0 @@
#ifndef _HUMANSIZE_H_
#define _HUMANSIZE_H_
#include <stdint.h>
/**
* humansize(size):
* Given a size in bytes, allocate and return a string of the form "<N> B"
* for 0 <= N <= 999 or "<X> <prefix>B" where either 10 <= X <= 999 or
* 1.0 <= X <= 9.9 and <prefix> is "k", "M", "G", "T", "P", or "E"; and where
* the value returned is the largest valid value <= the provided size.
*/
char * humansize(uint64_t);
/**
* humansize_parse(s, size):
* Parse a string matching /[0-9]+ ?[kMGTPE]?B?/ as a size in bytes.
*/
int humansize_parse(const char *, uint64_t *);
#endif /* !_HUMANSIZE_H_ */

View File

@ -1,19 +0,0 @@
#include <stddef.h>
#include <stdint.h>
#include "insecure_memzero.h"
/* Function which does the zeroing. */
static void
insecure_memzero_func(volatile void * buf, size_t len)
{
volatile uint8_t * _buf = buf;
size_t i;
for (i = 0; i < len; i++)
_buf[i] = 0;
}
/* Pointer to memory-zeroing function. */
void (* volatile insecure_memzero_ptr)(volatile void *, size_t) =
insecure_memzero_func;

View File

@ -1,37 +0,0 @@
#ifndef _INSECURE_MEMZERO_H_
#define _INSECURE_MEMZERO_H_
#include <stddef.h>
/* Pointer to memory-zeroing function. */
extern void (* volatile insecure_memzero_ptr)(volatile void *, size_t);
/**
* insecure_memzero(buf, len):
* Attempt to zero ${len} bytes at ${buf} in spite of optimizing compilers'
* best (standards-compliant) attempts to remove the buffer-zeroing. In
* particular, to avoid performing the zeroing, a compiler would need to
* use optimistic devirtualization; recognize that non-volatile objects do not
* need to be treated as volatile, even if they are accessed via volatile
* qualified pointers; and perform link-time optimization; in addition to the
* dead-code elimination which often causes buffer-zeroing to be elided.
*
* Note however that zeroing a buffer does not guarantee that the data held
* in the buffer is not stored elsewhere; in particular, there may be copies
* held in CPU registers or in anonymous allocations on the stack, even if
* every named variable is successfully sanitized. Solving the "wipe data
* from the system" problem will require a C language extension which does not
* yet exist.
*
* For more information, see:
* http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
* http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html
*/
static inline void
insecure_memzero(volatile void * buf, size_t len)
{
(insecure_memzero_ptr)(buf, len);
}
#endif /* !_INSECURE_MEMZERO_H_ */

View File

@ -1,202 +0,0 @@
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "insecure_memzero.h"
#include "warnp.h"
#include "readpass.h"
#define MAXPASSLEN 2048
/* Signals we need to block. */
static const int badsigs[] = {
SIGALRM, SIGHUP, SIGINT,
SIGPIPE, SIGQUIT, SIGTERM,
SIGTSTP, SIGTTIN, SIGTTOU
};
#define NSIGS sizeof(badsigs)/sizeof(badsigs[0])
/* Highest signal number we care about. */
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
#define MAX4(a, b, c, d) MAX2(MAX2(a, b), MAX2(c, d))
#define MAX8(a, b, c, d, e, f, g, h) MAX2(MAX4(a, b, c, d), MAX4(e, f, g, h))
#define MAXBADSIG MAX2(SIGALRM, MAX8(SIGHUP, SIGINT, SIGPIPE, SIGQUIT, \
SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU))
/* Has a signal of this type been received? */
static volatile sig_atomic_t gotsig[MAXBADSIG + 1];
/* Signal handler. */
static void
handle(int sig)
{
gotsig[sig] = 1;
}
/* Restore old signals and re-issue intercepted signals. */
static void
resetsigs(struct sigaction savedsa[NSIGS])
{
size_t i;
/* Restore old signals. */
for (i = 0; i < NSIGS; i++)
sigaction(badsigs[i], &savedsa[i], NULL);
/* If we intercepted a signal, re-issue it. */
for (i = 0; i < NSIGS; i++) {
if (gotsig[badsigs[i]])
raise(badsigs[i]);
}
}
/**
* readpass(passwd, prompt, confirmprompt, devtty)
* If ${devtty} is non-zero, read a password from /dev/tty if possible; if
* not, read from stdin. If reading from a tty (either /dev/tty or stdin),
* disable echo and prompt the user by printing ${prompt} to stderr. If
* ${confirmprompt} is non-NULL, read a second password (prompting if a
* terminal is being used) and repeat until the user enters the same password
* twice. Return the password as a malloced NUL-terminated string via
* ${passwd}.
*/
int
readpass(char ** passwd, const char * prompt,
const char * confirmprompt, int devtty)
{
FILE * readfrom;
char passbuf[MAXPASSLEN];
char confpassbuf[MAXPASSLEN];
struct sigaction sa, savedsa[NSIGS];
struct termios term, term_old;
size_t i;
int usingtty;
/*
* If devtty != 0, try to open /dev/tty; if that fails, or if devtty
* is zero, we'll read the password from stdin instead.
*/
if ((devtty == 0) || ((readfrom = fopen("/dev/tty", "r")) == NULL))
readfrom = stdin;
/* We have not received any signals yet. */
for (i = 0; i <= MAXBADSIG; i++)
gotsig[i] = 0;
/*
* If we receive a signal while we're reading the password, we might
* end up with echo disabled; to prevent this, we catch the signals
* here, and we'll re-send them to ourselves later after we re-enable
* terminal echo.
*/
sa.sa_handler = handle;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
for (i = 0; i < NSIGS; i++)
sigaction(badsigs[i], &sa, &savedsa[i]);
/* If we're reading from a terminal, try to disable echo. */
if ((usingtty = isatty(fileno(readfrom))) != 0) {
if (tcgetattr(fileno(readfrom), &term_old)) {
warnp("Cannot read terminal settings");
goto err2;
}
memcpy(&term, &term_old, sizeof(struct termios));
term.c_lflag = (term.c_lflag & ~((tcflag_t)ECHO)) | ECHONL;
if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
warnp("Cannot set terminal settings");
goto err2;
}
}
retry:
/* If we have a terminal, prompt the user to enter the password. */
if (usingtty)
fprintf(stderr, "%s: ", prompt);
/* Read the password. */
if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
if (feof(readfrom))
warn0("EOF reading password");
else
warnp("Cannot read password");
goto err3;
}
/* Confirm the password if necessary. */
if (confirmprompt != NULL) {
if (usingtty)
fprintf(stderr, "%s: ", confirmprompt);
if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
if (feof(readfrom))
warn0("EOF reading password");
else
warnp("Cannot read password");
goto err3;
}
if (strcmp(passbuf, confpassbuf)) {
fprintf(stderr,
"Passwords mismatch, please try again\n");
goto retry;
}
}
/* Terminate the string at the first "\r" or "\n" (if any). */
passbuf[strcspn(passbuf, "\r\n")] = '\0';
/* If we changed terminal settings, reset them. */
if (usingtty)
tcsetattr(fileno(readfrom), TCSANOW, &term_old);
/* Restore old signals and re-issue intercepted signals. */
resetsigs(savedsa);
/* Close /dev/tty if we opened it. */
if (readfrom != stdin)
fclose(readfrom);
/* Copy the password out. */
if ((*passwd = strdup(passbuf)) == NULL) {
warnp("Cannot allocate memory");
goto err1;
}
/*
* Zero any stored passwords. This is not guaranteed to work, since a
* "sufficiently intelligent" compiler can optimize these out due to
* the values not being accessed again; and even if we outwitted the
* compiler, all we can do is ensure that *a* buffer is zeroed but
* not that it is the only buffer containing the data in question.
* Unfortunately the C standard does not provide any way to mark data
* as "sensitive" in order to prevent extra copies being sprinkled
* around the implementation address space.
*/
insecure_memzero(passbuf, MAXPASSLEN);
insecure_memzero(confpassbuf, MAXPASSLEN);
/* Success! */
return (0);
err3:
/* Reset terminal settings if necessary. */
if (usingtty)
tcsetattr(fileno(readfrom), TCSAFLUSH, &term_old);
err2:
/* Close /dev/tty if we opened it. */
if (readfrom != stdin)
fclose(readfrom);
/* Restore old signals and re-issue intercepted signals. */
resetsigs(savedsa);
err1:
/* Zero any stored passwords. */
insecure_memzero(passbuf, MAXPASSLEN);
insecure_memzero(confpassbuf, MAXPASSLEN);
/* Failure! */
return (-1);
}

View File

@ -1,22 +0,0 @@
#ifndef _READPASS_H_
#define _READPASS_H_
/* Avoid namespace collisions with other "readpass" functions. */
#ifdef readpass
#undef readpass
#endif
#define readpass libcperciva_readpass
/**
* readpass(passwd, prompt, confirmprompt, devtty)
* If ${devtty} is non-zero, read a password from /dev/tty if possible; if
* not, read from stdin. If reading from a tty (either /dev/tty or stdin),
* disable echo and prompt the user by printing ${prompt} to stderr. If
* ${confirmprompt} is non-NULL, read a second password (prompting if a
* terminal is being used) and repeat until the user enters the same password
* twice. Return the password as a malloced NUL-terminated string via
* ${passwd}.
*/
int readpass(char **, const char *, const char *, int);
#endif /* !_READPASS_H_ */

View File

@ -1,146 +0,0 @@
#ifndef _SYSENDIAN_H_
#define _SYSENDIAN_H_
#include <stdint.h>
/* Avoid namespace collisions with BSD <sys/endian.h>. */
#define be16dec libcperciva_be16dec
#define be16enc libcperciva_be16enc
#define be32dec libcperciva_be32dec
#define be32enc libcperciva_be32enc
#define be64dec libcperciva_be64dec
#define be64enc libcperciva_be64enc
#define le16dec libcperciva_le16dec
#define le16enc libcperciva_le16enc
#define le32dec libcperciva_le32dec
#define le32enc libcperciva_le32enc
#define le64dec libcperciva_le64dec
#define le64enc libcperciva_le64enc
static inline uint16_t
be16dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return (uint16_t)((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8));
}
static inline void
be16enc(void * pp, uint16_t x)
{
uint8_t * p = (uint8_t *)pp;
p[1] = x & 0xff;
p[0] = (x >> 8) & 0xff;
}
static inline uint32_t
be32dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
}
static inline void
be32enc(void * pp, uint32_t x)
{
uint8_t * p = (uint8_t *)pp;
p[3] = x & 0xff;
p[2] = (x >> 8) & 0xff;
p[1] = (x >> 16) & 0xff;
p[0] = (x >> 24) & 0xff;
}
static inline uint64_t
be64dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
}
static inline void
be64enc(void * pp, uint64_t x)
{
uint8_t * p = (uint8_t *)pp;
p[7] = x & 0xff;
p[6] = (x >> 8) & 0xff;
p[5] = (x >> 16) & 0xff;
p[4] = (x >> 24) & 0xff;
p[3] = (x >> 32) & 0xff;
p[2] = (x >> 40) & 0xff;
p[1] = (x >> 48) & 0xff;
p[0] = (x >> 56) & 0xff;
}
static inline uint16_t
le16dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return (uint16_t)((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8));
}
static inline void
le16enc(void * pp, uint16_t x)
{
uint8_t * p = (uint8_t *)pp;
p[0] = x & 0xff;
p[1] = (x >> 8) & 0xff;
}
static inline uint32_t
le32dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
}
static inline void
le32enc(void * pp, uint32_t x)
{
uint8_t * p = (uint8_t *)pp;
p[0] = x & 0xff;
p[1] = (x >> 8) & 0xff;
p[2] = (x >> 16) & 0xff;
p[3] = (x >> 24) & 0xff;
}
static inline uint64_t
le64dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
}
static inline void
le64enc(void * pp, uint64_t x)
{
uint8_t * p = (uint8_t *)pp;
p[0] = x & 0xff;
p[1] = (x >> 8) & 0xff;
p[2] = (x >> 16) & 0xff;
p[3] = (x >> 24) & 0xff;
p[4] = (x >> 32) & 0xff;
p[5] = (x >> 40) & 0xff;
p[6] = (x >> 48) & 0xff;
p[7] = (x >> 56) & 0xff;
}
#endif /* !_SYSENDIAN_H_ */

View File

@ -1,76 +0,0 @@
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "warnp.h"
static int initialized = 0;
static char * name = NULL;
/* Free the name string. */
static void
done(void)
{
free(name);
name = NULL;
}
/**
* warnp_setprogname(progname):
* Set the program name to be used by warn() and warnx() to ${progname}.
*/
void
warnp_setprogname(const char * progname)
{
const char * p;
/* Free the name if we already have one. */
free(name);
/* Find the last segment of the program name. */
for (p = progname; progname[0] != '\0'; progname++)
if (progname[0] == '/')
p = progname + 1;
/* Copy the name string. */
name = strdup(p);
/* If we haven't already done so, register our exit handler. */
if (initialized == 0) {
atexit(done);
initialized = 1;
}
}
void
warn(const char * fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
if (fmt != NULL) {
fprintf(stderr, ": ");
vfprintf(stderr, fmt, ap);
}
fprintf(stderr, ": %s\n", strerror(errno));
va_end(ap);
}
void
warnx(const char * fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
if (fmt != NULL) {
fprintf(stderr, ": ");
vfprintf(stderr, fmt, ap);
}
fprintf(stderr, "\n");
va_end(ap);
}

View File

@ -1,60 +0,0 @@
#ifndef _WARNP_H_
#define _WARNP_H_
#include <errno.h>
#include <stddef.h>
/* Avoid namespace collisions with BSD <err.h>. */
#define warn libcperciva_warn
#define warnx libcperciva_warnx
/**
* warnp_setprogname(progname):
* Set the program name to be used by warn() and warnx() to ${progname}.
*/
void warnp_setprogname(const char *);
#define WARNP_INIT do { \
if (argv[0] != NULL) \
warnp_setprogname(argv[0]); \
} while (0)
/* As in BSD <err.h>. */
void warn(const char *, ...);
void warnx(const char *, ...);
/*
* If compiled with DEBUG defined, print __FILE__ and __LINE__.
*/
#ifdef DEBUG
#define warnline do { \
warnx("%s, %d", __FILE__, __LINE__); \
} while (0)
#else
#define warnline
#endif
/*
* Call warn(3) or warnx(3) depending upon whether errno == 0; and clear
* errno (so that the standard error message isn't repeated later).
*/
#define warnp(...) do { \
warnline; \
if (errno != 0) { \
warn(__VA_ARGS__); \
errno = 0; \
} else \
warnx(__VA_ARGS__); \
} while (0)
/*
* Call warnx(3) and set errno == 0. Unlike warnp, this should be used
* in cases where we're reporting a problem which we discover ourselves
* rather than one which is reported to us from a library or the kernel.
*/
#define warn0(...) do { \
warnline; \
warnx(__VA_ARGS__); \
errno = 0; \
} while (0)
#endif /* !_WARNP_H_ */

View File

@ -1,226 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "scrypt_platform.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
#include "humansize.h"
#include "insecure_memzero.h"
#include "readpass.h"
#include "scryptenc.h"
#include "warnp.h"
static void
usage(void)
{
fprintf(stderr,
"usage: scrypt {enc | dec} [-f] [-M maxmem]"
" [-m maxmemfrac]\n"
" [-t maxtime] [-v] [-P] infile [outfile]\n"
" scrypt --version\n");
exit(1);
}
int
main(int argc, char *argv[])
{
FILE * infile;
FILE * outfile;
int devtty = 1;
int dec = 0;
size_t maxmem = 0;
int force_resources = 0;
uint64_t maxmem64;
double maxmemfrac = 0.5;
double maxtime = 300.0;
const char * ch;
char * passwd;
int rc;
int verbose = 0;
WARNP_INIT;
/* We should have "enc" or "dec" first. */
if (argc < 2)
usage();
if (strcmp(argv[1], "enc") == 0) {
maxmem = 0;
maxmemfrac = 0.125;
maxtime = 5.0;
} else if (strcmp(argv[1], "dec") == 0) {
dec = 1;
} else if (strcmp(argv[1], "--version") == 0) {
fprintf(stdout, "scrypt %s\n", PACKAGE_VERSION);
exit(0);
} else {
warn0("First argument must be 'enc' or 'dec'.\n");
usage();
}
argc--;
argv++;
/* Parse arguments. */
while ((ch = GETOPT(argc, argv)) != NULL) {
GETOPT_SWITCH(ch) {
GETOPT_OPT("-f"):
force_resources = 1;
break;
GETOPT_OPTARG("-M"):
if (humansize_parse(optarg, &maxmem64)) {
warn0("Could not parse the parameter to -M.");
exit(1);
}
if (maxmem64 > SIZE_MAX) {
warn0("The parameter to -M is too large.");
exit(1);
}
maxmem = (size_t)maxmem64;
break;
GETOPT_OPTARG("-m"):
maxmemfrac = strtod(optarg, NULL);
break;
GETOPT_OPTARG("-t"):
maxtime = strtod(optarg, NULL);
break;
GETOPT_OPT("-v"):
verbose = 1;
break;
GETOPT_OPT("-P"):
devtty = 0;
break;
GETOPT_MISSING_ARG:
warn0("Missing argument to %s\n", ch);
usage();
GETOPT_DEFAULT:
warn0("illegal option -- %s\n", ch);
usage();
}
}
argc -= optind;
argv += optind;
/* We must have one or two parameters left. */
if ((argc < 1) || (argc > 2))
usage();
/* If the input isn't stdin, open the file. */
if (strcmp(argv[0], "-")) {
if ((infile = fopen(argv[0], "rb")) == NULL) {
warnp("Cannot open input file: %s", argv[0]);
exit(1);
}
} else {
infile = stdin;
}
/* If we have an output file, open it. */
if (argc > 1) {
if ((outfile = fopen(argv[1], "wb")) == NULL) {
warnp("Cannot open output file: %s", argv[1]);
exit(1);
}
} else {
outfile = stdout;
}
/* Prompt for a password. */
if (readpass(&passwd, "Please enter passphrase",
(dec || !devtty) ? NULL : "Please confirm passphrase", devtty))
exit(1);
/* Encrypt or decrypt. */
if (dec)
rc = scryptdec_file(infile, outfile, (uint8_t *)passwd,
strlen(passwd), maxmem, maxmemfrac, maxtime, verbose,
force_resources);
else
rc = scryptenc_file(infile, outfile, (uint8_t *)passwd,
strlen(passwd), maxmem, maxmemfrac, maxtime, verbose);
/* Zero and free the password. */
insecure_memzero(passwd, strlen(passwd));
free(passwd);
/* Close any files we opened. */
if (infile != stdin)
fclose(infile);
if (outfile != stdout)
fclose(outfile);
/* If we failed, print the right error message and exit. */
if (rc != 0) {
switch (rc) {
case 1:
warnp("Error determining amount of available memory");
break;
case 2:
warnp("Error reading clocks");
break;
case 3:
warnp("Error computing derived key");
break;
case 4:
warnp("Error reading salt");
break;
case 5:
warnp("OpenSSL error");
break;
case 6:
warnp("Error allocating memory");
break;
case 7:
warn0("Input is not valid scrypt-encrypted block");
break;
case 8:
warn0("Unrecognized scrypt format version");
break;
case 9:
warn0("Decrypting file would require too much memory");
break;
case 10:
warn0("Decrypting file would take too much CPU time");
break;
case 11:
warn0("Passphrase is incorrect");
break;
case 12:
warnp("Error writing file: %s",
(argc > 1) ? argv[1] : "standard output");
break;
case 13:
warnp("Error reading file: %s", argv[0]);
break;
}
exit(1);
}
return (0);
}

View File

@ -1,140 +0,0 @@
.\" Copyright 2009 Colin Percival
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.Dd February 10, 2017
.Dt SCRYPT 1
.Os
.Sh NAME
.Nm scrypt
.Nd encrypt and decrypt files.
.Sh SYNOPSIS
.Nm
.Brq Cm enc | Cm dec
.Op Fl f
.Op Fl M Ar maxmem
.Op Fl m Ar maxmemfrac
.Op Fl t Ar maxtime
.Op Fl P
.Ar infile
.Op Ar outfile
.Nm
.Fl -version
.Sh DESCRIPTION
.Nm Cm enc
encrypts
.Ar infile
and writes the result to
.Ar outfile
if specified, or the standard output otherwise.
The user will be prompted to enter a passphrase (twice) to
be used to generate a derived encryption key.
.Pp
.Nm Cm dec
decrypts
.Ar infile
and writes the result to
.Ar outfile
if specified, or the standard output otherwise.
The user will be prompted to enter the passphrase used at
encryption time to generate the derived encryption key.
.Pp
If
.Fl P
is not given,
.Nm
reads passphrases from its controlling terminal, or failing that,
from stdin. Prompts are only printed when
.Nm
is reading passphrases from some terminal. If
.Fl P
is given, then
.Nm
does not print any prompts, and reads a passphrase from stdin.
.Sh OPTIONS
.Bl -tag -width "-m maxmemfrac"
.It Fl f
Force the decryption to proceed even if it is anticipated to
require an excessive amount of memory or CPU time.
.It Fl M Ar maxmem
Use at most
.Ar maxmem
bytes of RAM to compute the derived encryption key.
.It Fl m Ar maxmemfrac
Use at most the fraction
.Ar maxmemfrac
of the available RAM to compute the derived encryption key.
.It Fl t Ar maxtime
Use at most
.Ar maxtime
seconds of CPU time to compute the derived encryption key.
.It Fl P
Always read passphrase from stdin, and do so only once even
when encrypting.
.It Fl -version
Print version of scrypt, and exit.
.El
.Pp
In
.Nm Cm enc ,
the memory and CPU time limits are enforced by picking
appropriate parameters to the
.Nm
key derivation function.
In
.Nm Cm dec ,
the memory and CPU time limits are enforced by exiting with
an error if decrypting the file would require too much memory
or CPU time.
.Sh EXIT STATUS
The
.Nm
utility exits 0 on success, and >0 if an error occurs.
.Pp
Note that if the input encrypted file is corrupted,
.Nm Cm dec
may produce output prior to determining that the input
was corrupt and exiting with a non-zero status; so
users should direct the output to a safe location and
check the exit status of
.Nm
before using the decrypted data.
.Sh SEE ALSO
.Rs
.%A "Colin Percival"
.%T "Stronger Key Derivation via Sequential Memory-Hard Functions"
.%O "Presented at BSDCan'09"
.%D "May 2009"
.Re
.Sh HISTORY
The
.Nm
utility was written in May 2009 by Colin Percival as a
demonstration of the
.Nm
key derivation function.
The
.Nm
key derivation function was invented in March 2009 by Colin
Percival in order to allow key files from the
.Nm tarsnap
backup system to be passphrase protected.

View File

@ -1,12 +0,0 @@
#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_ */

View File

@ -1,26 +0,0 @@
#!/bin/sh
### Constants
# The scenario command requires a lot of memory, so valgrind is only enabled
# if $USE_VALGRIND > 1.
c_valgrind_min=2
test_output="${s_basename}-stdout.txt"
reference="${scriptdir}/test_scrypt.good"
### Actual command
scenario_cmd() {
# Run the binary which tests known input/output strings.
setup_check_variables
(
${c_valgrind_cmd} ${bindir}/tests/test_scrypt 1> ${test_output}
echo $? > ${c_exitfile}
)
# The generated values should match the known good values.
setup_check_variables
if cmp -s ${test_output} ${reference}; then
echo "0"
else
echo "1"
fi > ${c_exitfile}
}

View File

@ -1,26 +0,0 @@
#!/bin/sh
### Constants
c_valgrind_min=1
reference_file="${scriptdir}/test_scrypt.good"
encrypted_reference_file="${scriptdir}/test_scrypt_good.enc"
decrypted_reference_file="${out}/attempt_reference.txt"
scenario_cmd() {
# Decrypt a reference file.
setup_check_variables
(
echo ${password} | ${c_valgrind_cmd} ${bindir}/scrypt \
dec -P ${encrypted_reference_file} \
${decrypted_reference_file}
echo $? > ${c_exitfile}
)
# The decrypted reference file should match the reference.
setup_check_variables
if cmp -s ${decrypted_reference_file} ${reference_file}; then
echo "0"
else
echo "1"
fi > ${c_exitfile}
}

View File

@ -1,44 +0,0 @@
#!/bin/sh
### Constants
c_valgrind_min=1
reference_file="${scriptdir}/test_scrypt.good"
encrypted_file="${out}/attempt.enc"
decrypted_file="${out}/attempt.txt"
scenario_cmd() {
# Encrypt a file.
setup_check_variables
(
echo ${password} | ${c_valgrind_cmd} ${bindir}/scrypt \
enc -P -t 1 ${reference_file} ${encrypted_file}
echo $? > ${c_exitfile}
)
# The encrypted file should be different from the original file.
# We cannot check against the "reference" encrypted file, because
# encrypted files include random salt. If successful, don't delete
# ${encrypted_file} yet; we need it for the next test.
setup_check_variables
if cmp -s ${encrypted_file} ${reference_file}; then
echo "1"
else
echo "0"
fi > ${c_exitfile}
# Decrypt the file we just encrypted.
setup_check_variables
(
echo ${password} | ${c_valgrind_cmd} ${bindir}/scrypt \
dec -P ${encrypted_file} ${decrypted_file}
echo $? > ${c_exitfile}
)
# The decrypted file should match the reference.
setup_check_variables
if cmp -s ${decrypted_file} ${reference_file}; then
echo "0"
else
echo "1"
fi > ${c_exitfile}
}

View File

@ -1,57 +0,0 @@
#!/bin/sh
### Constants
c_valgrind_min=1
reference_file="${scriptdir}/test_scrypt.good"
longwait_encrypted_file="${out}/longwait.enc"
longwait_decrypted_file="${out}/longwait.txt"
longwait_failed_log="${out}/longwait-failed.log"
scenario_cmd() {
# Encrypt file which should take a long time to decrypt.
setup_check_variables
(
echo ${password} | ${c_valgrind_cmd} ${bindir}/scrypt \
enc -P -t 10 ${reference_file} \
${longwait_encrypted_file}
echo $? > ${c_exitfile}
)
# Attempt to decrypt it with limited time. We want this
# command to fail, so we negate the normal return code.
setup_check_variables
(
echo ${password} | ${c_valgrind_cmd} ${bindir}/scrypt \
dec -P -t 1 ${longwait_encrypted_file} \
${longwait_decrypted_file} \
2> ${longwait_failed_log}
test ! $? -eq 0
echo $? > ${c_exitfile}
)
# We should have received an error message.
setup_check_variables
if grep -q "scrypt: Decrypting file would take too much CPU time" \
${longwait_failed_log}; then
echo "0"
else
echo "1"
fi > ${c_exitfile}
# Attempt to decrypt it with limited time, but force success.
setup_check_variables
(
echo ${password} | ${c_valgrind_cmd} ${bindir}/scrypt \
dec -P -t 1 -f ${longwait_encrypted_file} \
${longwait_decrypted_file}
echo $? > ${c_exitfile}
)
# The decrypted reference file should match the reference.
setup_check_variables
if cmp -s ${longwait_decrypted_file} ${reference_file}; then
echo "0"
else
echo "1"
fi > ${c_exitfile}
}

View File

@ -1,69 +0,0 @@
#!/bin/sh
### Constants
c_valgrind_min=1
reference_file="${scriptdir}/test_scrypt.good"
encrypted_file_1="${out}/sys-scrypt.enc"
decrypted_file_1="${out}/sys-scrypt.txt"
encrypted_file_2="${out}/our-scrypt.enc"
decrypted_file_2="${out}/our-scrypt.txt"
scenario_cmd() {
if [ -z "${system_scrypt}" ]; then
printf "no suitable system scrypt: "
# Inform test suite that we are skipping.
setup_check_variables
echo "-1" > ${c_exitfile}
return
fi
# Encrypt a file with our scrypt.
setup_check_variables
(
echo ${password} | ${c_valgrind_cmd} ${bindir}/scrypt \
enc -P -t 1 ${reference_file} ${encrypted_file_1}
echo $? > ${c_exitfile}
)
# Use the system scrypt to decrypt the file we just
# encrypted. Don't use valgrind for this.
setup_check_variables
(
echo ${password} | ${system_scrypt} \
dec -P ${encrypted_file_1} ${decrypted_file_1}
echo $? > ${c_exitfile}
)
# The decrypted file should match the reference.
setup_check_variables
if cmp -s ${decrypted_file_1} ${reference_file}; then
echo "0"
else
echo "1"
fi > ${c_exitfile}
# Encrypt a file with the system scrypt. Don't use
# valgrind for this.
setup_check_variables
(
echo ${password} | ${system_scrypt} \
enc -P -t 1 ${reference_file} ${encrypted_file_2}
echo $? > ${c_exitfile}
)
# Use our scrypt to decrypt the file we just encrypted.
setup_check_variables
(
echo ${password} | ${c_valgrind_cmd} ${bindir}/scrypt \
dec -P ${encrypted_file_2} ${decrypted_file_2}
echo $? > ${c_exitfile}
)
# The decrypted file should match the reference.
setup_check_variables
if cmp -s ${decrypted_file_2} ${reference_file}; then
echo "0"
else
echo "1"
fi > ${c_exitfile}
}

View File

@ -1,268 +0,0 @@
#!/bin/sh
### Definitions
#
# This test suite uses the following terminology:
# - scenario: a series of commands to test. Each must be in a
# separate file, and must be completely self-contained
# (other than the variables listed below).
# - check: a series of commands that produces an exit code which
# the test suite should check. A scenario may contain any
# number of checks.
#
### Design
#
# The main function is scenario_runner(scenario_filename), which
# takes a scenario file as the argument, and runs a
# scenario_cmd()
# function which was defined in that file.
#
### Variables
#
# Wherever possible, this suite uses local variables and
# explicitly-passed arguments, with the following exceptions:
# - s_basename: this is the basename for the scenario's temporary
# and log files.
# - s_val_basename: this is the basename for the scenario's
# valgrind log files.
# - s_count: this is the count of the scenario's checks (so that
# each check can have distinct files).
# - s_retval: this is the overall exit code of the scenario.
# - c_exitfile: this contains the exit code of each check.
# - c_valgrind_min: this is the minimum value of USE_VALGRIND
# which will enable valgrind checking for this check.
# - c_valgrind_cmd: this is the valgrind command (including
# appropriate log file) if necessary, or is "" otherwise.
set -o nounset
### Constants
out="tests-output"
out_valgrind="tests-valgrind"
valgrind_suppressions="${out_valgrind}/suppressions"
valgrind_suppressions_log="${out_valgrind}/suppressions.pre"
# Keep the user-specified ${USE_VALGRIND}, or initialize to 0.
USE_VALGRIND=${USE_VALGRIND:-0}
# A non-zero value unlikely to be used as an exit code by the programs being
# tested.
valgrind_exit_code=108
## prepare_directories():
# Delete any old directories, and create new ones as necessary. Must be run
# after check_optional_valgrind().
prepare_directories() {
# Clean up previous directories.
if [ -d "${out}" ]; then
rm -rf ${out}
fi
if [ -d "${out_valgrind}" ]; then
rm -rf ${out_valgrind}
fi
# Make new directories.
mkdir ${out}
if [ "$USE_VALGRIND" -gt 0 ]; then
mkdir ${out_valgrind}
fi
}
## find_system (cmd, args...):
# Looks for ${cmd} in the $PATH, and ensure that it supports ${args}.
find_system() {
cmd=$1
cmd_with_args=$@
# Look for ${cmd}.
system_binary=`command -v ${cmd}`
if [ -z "${system_binary}" ]; then
system_binary=""
printf "System ${cmd} not found.\n" 1>&2
# If the command exists, check it ensures the ${args}.
elif ${cmd_with_args} 2>&1 >/dev/null | \
grep -qE "(invalid|illegal) option"; then
system_binary=""
printf "Cannot use system ${cmd}; does not" 1>&2
printf " support necessary arguments.\n" 1>&2
fi
echo "${system_binary}"
}
## check_optional_valgrind ():
# Return a $USE_VALGRIND variable defined; if it was previously defined and
# was greater than 0, then check that valgrind is available in the $PATH.
check_optional_valgrind() {
if [ "$USE_VALGRIND" -gt 0 ]; then
# Look for valgrind in $PATH.
if ! command -v valgrind >/dev/null 2>&1; then
printf "valgrind not found\n" 1>&2
exit 1
fi
fi
}
## ensure_valgrind_suppresssion (potential_memleaks_binary):
# Runs the ${potential_memleaks_binary} through valgrind, keeping
# track of any apparent memory leak in order to suppress reporting
# those leaks when testing other binaries.
ensure_valgrind_suppression() {
potential_memleaks_binary=$1
# Quit if we're not using valgrind.
if [ ! "$USE_VALGRIND" -gt 0 ]; then
return
fi;
printf "Generating valgrind suppressions... "
# Run valgrind on the binary, sending it a "\n" so that
# a test which uses STDIN will not wait for user input.
printf "\n" | (valgrind --leak-check=full --show-leak-kinds=all \
--gen-suppressions=all \
--log-file=${valgrind_suppressions_log} \
${potential_memleaks_binary})
# Strip out useless parts from the log file, as well as
# removing references to the main and "pl_*" ("potential
# loss") functions so that the suppressions can apply to
# other binaries.
(grep -v "^==" ${valgrind_suppressions_log} \
| grep -v " fun:pl_" - \
| grep -v " fun:main" - \
> ${valgrind_suppressions} )
# Clean up
rm -f ${valgrind_suppressions_log}
printf "done.\n"
}
## setup_check_variables ():
# Set up the "check" variables ${c_exitfile} and ${c_valgrind_cmd}, the
# latter depending on the previously-defined ${c_valgrind_min}.
# Advances the number of checks ${s_count} so that the next call to this
# function will set up new filenames.
setup_check_variables() {
# Set up the "exit" file.
c_exitfile="${s_basename}-`printf %02d ${s_count}`.exit"
# If we don't have a suppressions file, don't try to use it.
if [ ! -e ${valgrind_suppressions} ]; then
valgrind_suppressions=/dev/null
fi
# Set up the valgrind command if $USE_VALGRIND is greater
# than or equal to ${valgrind_min}; otherwise, produce an
# empty string. Using --error-exitcode means that if
# there is a serious problem (such that scrypt calls
# exit(1)) *and* a memory leak, the test suite reports an
# exit value of ${valgrind_exit_code}. However, if there
# is a serious problem but no memory leak, we still
# receive a non-zero exit code. The most important thing
# is that we only receive an exit code of 0 if both the
# program and valgrind are happy.
if [ "$USE_VALGRIND" -ge "${c_valgrind_min}" ]; then
val_logfilename=${s_val_basename}-`printf %02d ${s_count}`.log
c_valgrind_cmd="valgrind \
--log-file=${val_logfilename} \
--leak-check=full --show-leak-kinds=all \
--errors-for-leak-kinds=all \
--suppressions=${valgrind_suppressions} \
--error-exitcode=${valgrind_exit_code} "
else
c_valgrind_cmd=""
fi
# Advances the number of checks.
s_count=$((s_count + 1))
}
## get_val_logfile (val_basename, exitfile):
# Return the valgrind logfile corresponding to ${exitfile}.
get_val_logfile() {
val_basename=$1
exitfile=$2
num=`echo "${exitfile}" | rev | cut -c 1-7 | rev | cut -c 1-2 `
echo "${val_basename}-${num}.log"
}
## notify_success_or_fail (log_basename, val_log_basename):
# Examine all "exit code" files beginning with ${log_basename} and
# print "SUCCESS!" or "FAILED!" as appropriate. If the test failed
# with the code ${valgrind_exit_code}, output the appropriate
# valgrind logfile to stdout.
notify_success_or_fail() {
log_basename=$1
val_log_basename=$2
# Check each exitfile.
for exitfile in `ls ${log_basename}-*.exit | sort`; do
ret=`cat ${exitfile}`
if [ "${ret}" -lt 0 ]; then
echo "SKIP!"
return
fi
if [ "${ret}" -gt 0 ]; then
echo "FAILED!"
retval=${ret}
if [ "${ret}" -eq "${valgrind_exit_code}" ]; then
val_logfilename=$( get_val_logfile \
${val_log_basename} ${exitfile} )
cat ${val_logfilename}
fi
s_retval=${ret}
return
fi
done
echo "SUCCESS!"
}
## scenario_runner (scenario_filename):
# Runs a test scenario from ${scenario_filename}.
scenario_runner() {
scenario_filename=$1
basename=`basename ${scenario_filename} .sh`
printf " ${basename}... " 1>&2
# Initialize "scenario" and "check" variables.
s_basename=${out}/${basename}
s_val_basename=${out_valgrind}/${basename}
s_count=0
c_exitfile=/dev/null
c_valgrind_min=9
c_valgrind_cmd=""
# Load scenario_cmd() from the scenario file.
unset scenario_cmd
. ${scenario_filename}
if ! command -v scenario_cmd 1>/dev/null ; then
printf "ERROR: scenario_cmd() is not defined in\n"
printf " ${scenario_filename}\n"
exit 1
fi
# Run the scenario command.
scenario_cmd
# Print PASS or FAIL, and return result.
s_retval=0
notify_success_or_fail ${s_basename} ${s_val_basename}
return "${s_retval}"
}
## run_scenarios (scenario_filenames):
# Runs all scenarios matching ${scenario_filenames}.
run_scenarios() {
printf -- "Running tests\n"
printf -- "-------------\n"
scenario_filenames=$@
for scenario in ${scenario_filenames}; do
# We can't call this function with $( ... ) because we
# want to allow it to echo values to stdout.
scenario_runner ${scenario}
retval=$?
if [ ${retval} -gt 0 ]; then
exit ${retval}
fi
done
}

View File

@ -1,51 +0,0 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "crypto_scrypt.h"
#include "warnp.h"
static struct scrypt_test {
const char * passwd;
const char * salt;
uint64_t N;
uint32_t r;
uint32_t p;
} tests[4] = {
{ "", "", 16, 1, 1 },
{ "password", "NaCl", 1024, 8, 16 },
{ "pleaseletmein", "SodiumChloride", 16384, 8, 1 },
{ "pleaseletmein", "SodiumChloride", 1048576, 8, 1 }
};
int
main(int argc, char * argv[])
{
struct scrypt_test * test;
char kbuf[64];
size_t i;
WARNP_INIT;
(void)argc; /* UNUSED */
(void)argv; /* UNUSED */
for (test = tests;
test < tests + sizeof(tests) / sizeof(tests[0]);
test++) {
crypto_scrypt((const uint8_t *)test->passwd,
strlen(test->passwd), (const uint8_t *)test->salt,
strlen(test->salt), test->N, test->r, test->p,
(uint8_t *)kbuf, 64);
printf("scrypt(\"%s\", \"%s\", %u, %u, %u, 64) =\n",
test->passwd, test->salt, (unsigned int)test->N,
(unsigned int)(test->r), (unsigned int)test->p);
for (i = 0; i < 64; i++) {
printf("%02x ", (uint8_t)kbuf[i]);
if ((i % 16) == 15)
printf("\n");
}
}
return (0);
}

View File

@ -1,20 +0,0 @@
scrypt("", "", 16, 1, 1, 64) =
77 d6 57 62 38 65 7b 20 3b 19 ca 42 c1 8a 04 97
f1 6b 48 44 e3 07 4a e8 df df fa 3f ed e2 14 42
fc d0 06 9d ed 09 48 f8 32 6a 75 3a 0f c8 1f 17
e8 d3 e0 fb 2e 0d 36 28 cf 35 e2 0c 38 d1 89 06
scrypt("password", "NaCl", 1024, 8, 16, 64) =
fd ba be 1c 9d 34 72 00 78 56 e7 19 0d 01 e9 fe
7c 6a d7 cb c8 23 78 30 e7 73 76 63 4b 37 31 62
2e af 30 d9 2e 22 a3 88 6f f1 09 27 9d 98 30 da
c7 27 af b9 4a 83 ee 6d 83 60 cb df a2 cc 06 40
scrypt("pleaseletmein", "SodiumChloride", 16384, 8, 1, 64) =
70 23 bd cb 3a fd 73 48 46 1c 06 cd 81 fd 38 eb
fd a8 fb ba 90 4f 8e 3e a9 b5 43 f6 54 5d a1 f2
d5 43 29 55 61 3f 0f cf 62 d4 97 05 24 2a 9a f9
e6 1e 85 dc 0d 65 1e 40 df cf 01 7b 45 57 58 87
scrypt("pleaseletmein", "SodiumChloride", 1048576, 8, 1, 64) =
21 01 cb 9b 6a 51 1a ae ad db be 09 cf 70 f8 81
ec 56 8d 57 4a 2f fd 4d ab e5 ee 98 20 ad aa 47
8e 56 fd 8f 4b a5 d0 9f fa 1c 6d 92 7c 40 f4 c3
37 30 40 49 e8 a9 52 fb cb f4 5c 6f a7 7a 41 a4

View File

@ -1,34 +0,0 @@
#!/bin/sh
# Build directory (allowing flexible out-of-tree builds).
bindir=$1
# Constants used in multiple scenarios.
password="hunter2"
# Find script directory and load helper functions.
scriptdir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
. ${scriptdir}/shared_test_functions.sh
# We need a ${bindir}.
if [ -z ${bindir} ]; then
printf "Warning: Scrypt binary directory not given.\n"
printf "Attempting to use default values for in-source-tree build.\n"
bindir=".."
fi
# Find system scrypt, and ensure it supports -P.
system_scrypt=$( find_system scrypt enc -P )
# Check for optional valgrind.
check_optional_valgrind
# Clean up previous directories, and create new ones.
prepare_directories
# Generate valgrind suppression file if it is required. Must be
# done after preparing directories.
ensure_valgrind_suppression ${bindir}/tests/valgrind/potential-memleaks
# Run the test scenarios; this will exit on the first failure.
run_scenarios ${scriptdir}/??-*.sh

View File

@ -1,25 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#define FGETS_BUFSIZE 64
/* Problem with FreeBSD 10.3 fgets() with stdin. */
static void
pl_freebsd_fgets()
{
char buf[FGETS_BUFSIZE];
if (fgets(buf, FGETS_BUFSIZE, stdin) == NULL)
exit(1);
}
int
main()
{
/* Test potential memory leaks. */
pl_freebsd_fgets();
/* Success! */
exit(0);
}