Update to scrypt 1.2.1

This commit is contained in:
Sebastian Messmer 2017-07-07 16:19:31 +02:00
parent 999a5ef96e
commit 3d2f133c42
77 changed files with 4363 additions and 1823 deletions

View File

@ -13,33 +13,33 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
ExternalProject_Add(scrypt_original
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt
CONFIGURE_COMMAND /usr/bin/env CC=${CMAKE_C_COMPILER} CFLAGS=${SCRYPT_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/configure --prefix=${CMAKE_BINARY_DIR}/vendor/scrypt/
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.0/scrypt/lib/crypto/crypto_scrypt.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/lib/crypto/crypto_scrypt_smix.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/libcperciva/util/warnp.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/libcperciva/util/insecure_memzero.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/libcperciva/alg/sha256.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/libcperciva/cpusupport/cpusupport_x86_aesni.c
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/libcperciva/cpusupport/cpusupport_x86_sse2.c
${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.0/scrypt
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/libcperciva/cpusupport
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/libcperciva/alg
${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0/scrypt/libcperciva/util
${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\"
)
add_dependencies(${PROJECT_NAME} scrypt_original)
target_include_directories(${PROJECT_NAME} SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.0)
target_include_directories(${PROJECT_NAME} SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/scrypt-1.2.1)

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +0,0 @@
AUTOMAKE_OPTIONS= foreign subdir-objects
bin_PROGRAMS= scrypt
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/entropy.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 \
cpusupport-config.h
scrypt_CFLAGS= -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 \
-I . -D CPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\"
scrypt_LDADD= -lcrypto 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 ) > 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= $(scrypt_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= $(scrypt_CFLAGS) \
`. ./cpusupport-config.h; echo $${CFLAGS_X86_SSE2}`

View File

@ -1,64 +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; or a file can be created with the
* necessary #define lines and then -D CPUSUPPORT_CONFIG_FILE=cpuconfig.h
* (or similar) can be provided to include that file here.
*/
#ifdef CPUSUPPORT_CONFIG_FILE
#include CPUSUPPORT_CONFIG_FILE
#endif
/*
* The CPUSUPPORT_FEATURE macro declares the necessary variables and
* functions for detecting CPU feature support at run time. The function
* defined in the macro acts to cache the result of the ..._detect function
* using the ..._present and ..._init variables.
*/
#define CPUSUPPORT_FEATURE(arch, feature) \
extern int cpusupport_ ## arch ## _ ## feature ## _present; \
extern int cpusupport_ ## arch ## _ ## feature ## _init; \
int cpusupport_ ## arch ## _ ## feature ## _detect(void); \
\
static inline int \
cpusupport_ ## arch ## _ ## feature(void) \
{ \
\
if (cpusupport_ ## arch ## _ ## feature ## _present) \
return (1); \
else if (cpusupport_ ## arch ## _ ## feature ## _init) \
return (0); \
cpusupport_ ## arch ## _ ## feature ## _present = \
cpusupport_ ## arch ##_ ## feature ## _detect(); \
cpusupport_ ## arch ## _ ## feature ## _init = 1; \
return (cpusupport_ ## arch ## _ ## feature ## _present); \
} \
struct cpusupport_ ## arch ## _ ## feature ## _dummy
/*
* CPUSUPPORT_FEATURE_DECL(arch, feature):
* Macro which defines variables and provides a function declaration for
* detecting the presence of "feature" on the "arch" architecture. The
* function body following this macro expansion must return nonzero if the
* feature is present, or zero if the feature is not present or the detection
* fails for any reason.
*/
#define CPUSUPPORT_FEATURE_DECL(arch, feature) \
int cpusupport_ ## arch ## _ ## feature ## _present = 0; \
int cpusupport_ ## arch ## _ ## feature ## _init = 0; \
int \
cpusupport_ ## arch ## _ ## feature ## _detect(void)
/*
* Any features listed here must have associated C files compiled and linked
* in, since the macro references symbols which must be defined. Projects
* which do not need to detect certain CPU features may wish to remove lines
* from this list so that the associated C files can be omitted.
*/
CPUSUPPORT_FEATURE(x86, aesni);
CPUSUPPORT_FEATURE(x86, sse2);
#endif /* !_CPUSUPPORT_H_ */

View File

@ -0,0 +1,46 @@
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,7 +1,8 @@
The code and documentation in this directory ("libcperciva") is distributed
under the following terms:
The included code and documentation ("scrypt") is distributed under the
following terms:
Copyright 2005-2014 Colin Percival. All rights reserved.
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
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,17 +1,28 @@
m4_define([SCRYPT_VERS],m4_include([scrypt-version]))
AC_INIT([scrypt],SCRYPT_VERS())
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])
AM_INIT_AUTOMAKE()
AC_PROG_CC
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_CHECK_LIB(rt, clock_gettime)
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).
@ -25,6 +36,11 @@ AC_CHECK_MEMBERS([struct sysinfo.totalram, struct sysinfo.mem_unit], [], [],
# 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])
@ -37,6 +53,17 @@ 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

@ -0,0 +1,270 @@
#! /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

@ -6,15 +6,15 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `rt' library (-lrt). */
#undef HAVE_LIBRT
/* 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

View File

@ -1,6 +1,8 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for scrypt 1.2.0.
# Generated by GNU Autoconf 2.69 for scrypt 1.2.1.
#
# Report bugs to <https://github.com/Tarsnap/scrypt>.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@ -264,7 +266,8 @@ fi
$as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
$as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
$as_echo "$0: Please tell bug-autoconf@gnu.org and
$0: https://github.com/Tarsnap/scrypt about your system,
$0: including any error possibly output before this
$0: message. Then install a modern shell, or manually run
$0: the script under such a shell if you do have one."
@ -577,11 +580,12 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='scrypt'
PACKAGE_TARNAME='scrypt'
PACKAGE_VERSION='1.2.0'
PACKAGE_STRING='scrypt 1.2.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
PACKAGE_VERSION='1.2.1'
PACKAGE_STRING='scrypt 1.2.1'
PACKAGE_BUGREPORT='https://github.com/Tarsnap/scrypt'
PACKAGE_URL='http://www.tarsnap.com/scrypt/'
ac_unique_file="lib/scryptenc/scryptenc.c"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
@ -628,6 +632,8 @@ CPP
MAINT
MAINTAINER_MODE_FALSE
MAINTAINER_MODE_TRUE
ac_ct_AR
AR
RANLIB
am__fastdepCC_FALSE
am__fastdepCC_TRUE
@ -718,6 +724,7 @@ enable_silent_rules
enable_dependency_tracking
enable_maintainer_mode
enable_largefile
enable_compiler_warnings
'
ac_precious_vars='build_alias
host_alias
@ -1268,7 +1275,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures scrypt 1.2.0 to adapt to many kinds of systems.
\`configure' configures scrypt 1.2.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1334,7 +1341,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of scrypt 1.2.0:";;
short | recursive ) echo "Configuration of scrypt 1.2.1:";;
esac
cat <<\_ACEOF
@ -1352,6 +1359,8 @@ Optional Features:
enable make rules and dependencies not useful (and
sometimes confusing) to the casual installer
--disable-largefile omit support for large files
--disable-compiler-warnings
Do not request compiler warnings. [default=enabled]
Some influential environment variables:
CC C compiler command
@ -1366,7 +1375,8 @@ Some influential environment variables:
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to the package provider.
Report bugs to <https://github.com/Tarsnap/scrypt>.
scrypt home page: <http://www.tarsnap.com/scrypt/>.
_ACEOF
ac_status=$?
fi
@ -1429,7 +1439,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
scrypt configure 1.2.0
scrypt configure 1.2.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -1701,6 +1711,10 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
( $as_echo "## ------------------------------------------------ ##
## Report this to https://github.com/Tarsnap/scrypt ##
## ------------------------------------------------ ##"
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
@ -1905,7 +1919,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by scrypt $as_me 1.2.0, which was
It was created by scrypt $as_me 1.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -2253,6 +2267,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_aux_dir=
for ac_dir in config.aux "$srcdir"/config.aux; do
if test -f "$ac_dir/install-sh"; then
@ -2282,6 +2297,7 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
am__api_version='1.15'
# Find a good install program. We prefer a C program (faster),
@ -2768,7 +2784,7 @@ fi
# Define the identity of the package.
PACKAGE='scrypt'
VERSION='1.2.0'
VERSION='1.2.1'
cat >>confdefs.h <<_ACEOF
@ -2861,6 +2877,71 @@ END
fi
fi
# Checks for programs.
DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo this is the am__doit target
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
$as_echo_n "checking for style of include used by $am_make... " >&6; }
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
am__quote=
_am_result=GNU
;;
esac
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=.include
am__quote="\""
_am_result=BSD
;;
esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
$as_echo "$_am_result" >&6; }
rm -f confinc confmf
# Check whether --enable-dependency-tracking was given.
if test "${enable_dependency_tracking+set}" = set; then :
enableval=$enable_dependency_tracking;
fi
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
am__nodep='_no'
fi
if test "x$enable_dependency_tracking" != xno; then
AMDEP_TRUE=
AMDEP_FALSE='#'
else
AMDEP_TRUE='#'
AMDEP_FALSE=
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@ -3708,69 +3789,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo this is the am__doit target
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
$as_echo_n "checking for style of include used by $am_make... " >&6; }
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
am__quote=
_am_result=GNU
;;
esac
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=.include
am__quote="\""
_am_result=BSD
;;
esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
$as_echo "$_am_result" >&6; }
rm -f confinc confmf
# Check whether --enable-dependency-tracking was given.
if test "${enable_dependency_tracking+set}" = set; then :
enableval=$enable_dependency_tracking;
fi
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
am__nodep='_no'
fi
if test "x$enable_dependency_tracking" != xno; then
AMDEP_TRUE=
AMDEP_FALSE='#'
else
AMDEP_TRUE='#'
AMDEP_FALSE=
fi
depcc="$CC" am_compiler_list=
@ -3900,6 +3918,183 @@ else
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
if ${ac_cv_prog_cc_c99+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_prog_cc_c99=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>
// Check varargs macros. These examples are taken from C99 6.10.3.5.
#define debug(...) fprintf (stderr, __VA_ARGS__)
#define showlist(...) puts (#__VA_ARGS__)
#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
static void
test_varargs_macros (void)
{
int x = 1234;
int y = 5678;
debug ("Flag");
debug ("X = %d\n", x);
showlist (The first, second, and third items.);
report (x>y, "x is %d but y is %d", x, y);
}
// Check long long types.
#define BIG64 18446744073709551615ull
#define BIG32 4294967295ul
#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
#if !BIG_OK
your preprocessor is broken;
#endif
#if BIG_OK
#else
your preprocessor is broken;
#endif
static long long int bignum = -9223372036854775807LL;
static unsigned long long int ubignum = BIG64;
struct incomplete_array
{
int datasize;
double data[];
};
struct named_init {
int number;
const wchar_t *name;
double average;
};
typedef const char *ccp;
static inline int
test_restrict (ccp restrict text)
{
// See if C++-style comments work.
// Iterate through items via the restricted pointer.
// Also check for declarations in for loops.
for (unsigned int i = 0; *(text+i) != '\0'; ++i)
continue;
return 0;
}
// Check varargs and va_copy.
static void
test_varargs (const char *format, ...)
{
va_list args;
va_start (args, format);
va_list args_copy;
va_copy (args_copy, args);
const char *str;
int number;
float fnumber;
while (*format)
{
switch (*format++)
{
case 's': // string
str = va_arg (args_copy, const char *);
break;
case 'd': // int
number = va_arg (args_copy, int);
break;
case 'f': // float
fnumber = va_arg (args_copy, double);
break;
default:
break;
}
}
va_end (args_copy);
va_end (args);
}
int
main ()
{
// Check bool.
_Bool success = false;
// Check restrict.
if (test_restrict ("String literal") == 0)
success = true;
char *restrict newvar = "Another string";
// Check varargs.
test_varargs ("s, d' f .", "string", 65, 34.234);
test_varargs_macros ();
// Check flexible array members.
struct incomplete_array *ia =
malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
ia->datasize = 10;
for (int i = 0; i < ia->datasize; ++i)
ia->data[i] = i * 1.234;
// Check named initializers.
struct named_init ni = {
.number = 34,
.name = L"Test wide string",
.average = 543.34343,
};
ni.number = 58;
int dynamic_array[ni.number];
dynamic_array[ni.number - 1] = 543;
// work around unused variable warnings
return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
|| dynamic_array[ni.number - 1] != 543);
;
return 0;
}
_ACEOF
for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
do
CC="$ac_save_CC $ac_arg"
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_c99=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext
test "x$ac_cv_prog_cc_c99" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC
fi
# AC_CACHE_VAL
case "x$ac_cv_prog_cc_c99" in
x)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
$as_echo "none needed" >&6; } ;;
xno)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
$as_echo "unsupported" >&6; } ;;
*)
CC="$CC $ac_cv_prog_cc_c99"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c99" != xno; then :
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
@ -3993,6 +4188,178 @@ else
fi
if test -n "$ac_tool_prefix"; then
for ac_prog in ar lib "link -lib"
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AR"; then
ac_cv_prog_AR="$AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
$as_echo "$AR" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$AR" && break
done
fi
if test -z "$AR"; then
ac_ct_AR=$AR
for ac_prog in ar lib "link -lib"
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_AR"; then
ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
$as_echo "$ac_ct_AR" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$ac_ct_AR" && break
done
if test "x$ac_ct_AR" = x; then
AR="false"
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
AR=$ac_ct_AR
fi
fi
: ${AR=ar}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
$as_echo_n "checking the archiver ($AR) interface... " >&6; }
if ${am_cv_ar_interface+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
am_cv_ar_interface=ar
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int some_variable = 0;
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
(eval $am_ar_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
if test "$ac_status" -eq 0; then
am_cv_ar_interface=ar
else
am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
(eval $am_ar_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
if test "$ac_status" -eq 0; then
am_cv_ar_interface=lib
else
am_cv_ar_interface=unknown
fi
fi
rm -f conftest.lib libconftest.a
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
$as_echo "$am_cv_ar_interface" >&6; }
case $am_cv_ar_interface in
ar)
;;
lib)
# Microsoft lib, so override with the ar-lib wrapper script.
# FIXME: It is wrong to rewrite AR.
# But if we don't then we get into trouble of one sort or another.
# A longer-term fix would be to have automake use am__AR in this case,
# and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
# similar.
AR="$am_aux_dir/ar-lib $AR"
;;
unknown)
as_fn_error $? "could not determine $AR interface" "$LINENO" 5
;;
esac
# Don't rebuild the configure script. I'm distributing a perfectly good one.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
@ -4018,15 +4385,15 @@ fi
# Check for clock_gettime. On some systems, this is provided via librt.
# Checks for libraries.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
if ${ac_cv_lib_rt_clock_gettime+:} false; then :
# Check for clock_gettime. On some systems, this is provided via librt.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
$as_echo_n "checking for library containing clock_gettime... " >&6; }
if ${ac_cv_search_clock_gettime+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lrt $LIBS"
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@ -4045,23 +4412,35 @@ return clock_gettime ();
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_rt_clock_gettime=yes
for ac_lib in '' rt; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_cv_lib_rt_clock_gettime=no
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_clock_gettime=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
conftest$ac_exeext
if ${ac_cv_search_clock_gettime+:} false; then :
break
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBRT 1
_ACEOF
done
if ${ac_cv_search_clock_gettime+:} false; then :
LIBS="-lrt $LIBS"
else
ac_cv_search_clock_gettime=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
$as_echo "$ac_cv_search_clock_gettime" >&6; }
ac_res=$ac_cv_search_clock_gettime
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
fi
@ -4077,6 +4456,65 @@ fi
done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing AES_encrypt" >&5
$as_echo_n "checking for library containing AES_encrypt... " >&6; }
if ${ac_cv_search_AES_encrypt+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char AES_encrypt ();
int
main ()
{
return AES_encrypt ();
;
return 0;
}
_ACEOF
for ac_lib in '' crypto; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_AES_encrypt=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_AES_encrypt+:} false; then :
break
fi
done
if ${ac_cv_search_AES_encrypt+:} false; then :
else
ac_cv_search_AES_encrypt=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_AES_encrypt" >&5
$as_echo "$ac_cv_search_AES_encrypt" >&6; }
ac_res=$ac_cv_search_AES_encrypt
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
as_fn_error $? "function AES_ENCRYPT not found" "$LINENO" 5
fi
# 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).
@ -4548,6 +4986,23 @@ fi
done
# Check if we have <openssl/aes.h>, to fix the make failing when configure
# passes.
for ac_header in openssl/aes.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "openssl/aes.h" "ac_cv_header_openssl_aes_h" "$ac_includes_default"
if test "x$ac_cv_header_openssl_aes_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_OPENSSL_AES_H 1
_ACEOF
else
as_fn_error $? "Unable to find the openssl/aes.h header" "$LINENO" 5
fi
done
# 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.
for ac_header in sys/sysctl.h
@ -4790,6 +5245,103 @@ rm -rf conftest*
fi
# Check whether the user has requested to disable compiler warnings
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler_warnings" >&5
$as_echo_n "checking compiler_warnings... " >&6; }
# Check whether --enable-compiler_warnings was given.
if test "${enable_compiler_warnings+set}" = set; then :
enableval=$enable_compiler_warnings; ac_compiler_warnings=$enableval
else
ac_compiler_warnings=yes
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_compiler_warnings}" >&5
$as_echo "${ac_compiler_warnings}" >&6; }
if test x${ac_compiler_warnings} = xyes; then :
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5
$as_echo_n "checking CFLAGS for maximum warnings... " >&6; }
if ${ac_cv_cflags_warn_all+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_cflags_warn_all="no, unknown"
ac_save_CFLAGS="$CFLAGS"
for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" #
do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
done
CFLAGS="$ac_save_CFLAGS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5
$as_echo "$ac_cv_cflags_warn_all" >&6; }
case ".$ac_cv_cflags_warn_all" in
.ok|.ok,*) ;;
.|.no|.no,*) ;;
*)
if ${CFLAGS+:} false; then :
case " $CFLAGS " in #(
*" $ac_cv_cflags_warn_all "*) :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5
(: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } ;; #(
*) :
as_fn_append CFLAGS " $ac_cv_cflags_warn_all"
{ { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
(: CFLAGS="$CFLAGS") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
;;
esac
else
CFLAGS=$ac_cv_cflags_warn_all
{ { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
(: CFLAGS="$CFLAGS") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
fi
;;
esac
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
ac_config_headers="$ac_config_headers config.h"
ac_config_files="$ac_config_files Makefile"
@ -5328,7 +5880,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by scrypt $as_me 1.2.0, which was
This file was extended by scrypt $as_me 1.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -5388,13 +5940,14 @@ $config_headers
Configuration commands:
$config_commands
Report bugs to the package provider."
Report bugs to <https://github.com/Tarsnap/scrypt>.
scrypt home page: <http://www.tarsnap.com/scrypt/>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
scrypt config.status 1.2.0
scrypt config.status 1.2.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@ -97,7 +97,7 @@ _crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
goto err1;
XY = (uint32_t *)(XY0);
#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
if ((errno = posix_memalign(&V0, 64, (size_t)(128 * r * N))) != 0)
goto err2;
V = (uint32_t *)(V0);
#endif

View File

@ -27,9 +27,7 @@
* online backup system.
*/
#include <stdint.h>
#include <string.h>
#include "sha256.h"
#include "sysendian.h"
#include "crypto_scrypt_smix.h"

View File

@ -1,6 +1,9 @@
#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;

View File

@ -165,6 +165,7 @@ blockmix_salsa8(const __m128i * Bin, __m128i * Bout, __m128i * X, size_t r)
/**
* 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)

View File

@ -1,6 +1,9 @@
#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;

View File

@ -28,16 +28,17 @@
*/
#include "scrypt_platform.h"
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.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"
@ -51,12 +52,34 @@
#define ENCBLOCK 65536
static int pickparams(size_t, double, double,
int *, uint32_t *, uint32_t *);
static int checkparams(size_t, double, double, int, uint32_t, uint32_t);
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 * logN, uint32_t * r, uint32_t * p, int verbose)
{
size_t memlimit;
double opps;
@ -89,7 +112,7 @@ pickparams(size_t maxmem, double maxmemfrac, double maxtime,
fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n",
memlimit, opslimit);
#endif
if (opslimit < memlimit/32) {
if (opslimit < (double)memlimit / 32) {
/* Set p = 1 and choose N based on the CPU limit. */
*p = 1;
maxN = opslimit / (*r * 4);
@ -112,10 +135,8 @@ pickparams(size_t maxmem, double maxmemfrac, double maxtime,
*p = (uint32_t)(maxrp) / *r;
}
#ifdef DEBUG
fprintf(stderr, "N = %zu r = %d p = %d\n",
(size_t)(1) << *logN, (int)(*r), (int)(*p));
#endif
if (verbose)
display_params(*logN, *r, *p, memlimit, opps, maxtime);
/* Success! */
return (0);
@ -123,7 +144,7 @@ pickparams(size_t maxmem, double maxmemfrac, double maxtime,
static int
checkparams(size_t maxmem, double maxmemfrac, double maxtime,
int logN, uint32_t r, uint32_t p)
int logN, uint32_t r, uint32_t p, int verbose, int force)
{
size_t memlimit;
double opps;
@ -131,6 +152,14 @@ checkparams(size_t maxmem, double maxmemfrac, double maxtime,
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);
@ -140,18 +169,20 @@ checkparams(size_t maxmem, double maxmemfrac, double maxtime,
return (rc);
opslimit = opps * maxtime;
/* Sanity-check values. */
if ((logN < 1) || (logN > 63))
return (7);
if ((uint64_t)(r) * (uint64_t)(p) >= 0x40000000)
return (7);
/* Check limits. */
N = (uint64_t)(1) << logN;
if ((memlimit / N) / r < 128)
return (9);
if ((opslimit / N) / (r * p) < 4)
return (10);
} else {
/* We have no limit. */
memlimit = 0;
opps = 0;
}
if (verbose)
display_params(logN, r, p, memlimit, opps, maxtime);
/* Success! */
return (0);
@ -160,7 +191,7 @@ checkparams(size_t maxmem, double maxmemfrac, double maxtime,
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)
size_t maxmem, double maxmemfrac, double maxtime, int verbose)
{
uint8_t salt[32];
uint8_t hbuf[32];
@ -175,10 +206,13 @@ scryptenc_setup(uint8_t header[96], uint8_t dk[64],
/* Pick values for N, r, p. */
if ((rc = pickparams(maxmem, maxmemfrac, maxtime,
&logN, &r, &p)) != 0)
&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);
@ -190,7 +224,7 @@ scryptenc_setup(uint8_t header[96], uint8_t dk[64],
/* Construct the file header. */
memcpy(header, "scrypt", 6);
header[6] = 0;
header[7] = logN;
header[7] = logN & 0xff;
be32enc(&header[8], r);
be32enc(&header[12], p);
memcpy(&header[16], salt, 32);
@ -214,7 +248,8 @@ scryptenc_setup(uint8_t header[96], uint8_t dk[64],
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)
size_t maxmem, double maxmemfrac, double maxtime, int verbose,
int force)
{
uint8_t salt[32];
uint8_t hbuf[32];
@ -243,9 +278,10 @@ scryptdec_setup(const uint8_t header[96], uint8_t dk[64],
/*
* Check whether the provided parameters are valid and whether the
* key derivation function can be computed within the allowed memory
* and CPU time.
* and CPU time, unless the user chose to disable this test.
*/
if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p)) != 0)
if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p,
verbose, force)) != 0)
return (rc);
/* Compute the derived keys. */
@ -266,14 +302,14 @@ scryptdec_setup(const uint8_t header[96], uint8_t dk[64],
/**
* scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime):
* 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)
size_t maxmem, double maxmemfrac, double maxtime, int verbose)
{
uint8_t dk[64];
uint8_t hbuf[32];
@ -287,7 +323,7 @@ scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
/* Generate the header and derived key. */
if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
maxmem, maxmemfrac, maxtime)) != 0)
maxmem, maxmemfrac, maxtime, verbose)) != 0)
return (rc);
/* Copy header into output buffer. */
@ -317,15 +353,17 @@ scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
/**
* scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime):
* 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.
* 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)
size_t maxmem, double maxmemfrac, double maxtime, int verbose,
int force)
{
uint8_t hbuf[32];
uint8_t dk[64];
@ -353,7 +391,7 @@ scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
/* Parse the header and generate derived keys. */
if ((rc = scryptdec_setup(inbuf, dk, passwd, passwdlen,
maxmem, maxmemfrac, maxtime)) != 0)
maxmem, maxmemfrac, maxtime, verbose, force)) != 0)
return (rc);
/* Decrypt data. */
@ -382,14 +420,14 @@ scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
/**
* scryptenc_file(infile, outfile, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime):
* 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)
size_t maxmem, double maxmemfrac, double maxtime, int verbose)
{
uint8_t buf[ENCBLOCK];
uint8_t dk[64];
@ -405,7 +443,7 @@ scryptenc_file(FILE * infile, FILE * outfile,
/* Generate the header and derived key. */
if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
maxmem, maxmemfrac, maxtime)) != 0)
maxmem, maxmemfrac, maxtime, verbose)) != 0)
return (rc);
/* Hash and write the header. */
@ -453,14 +491,16 @@ scryptenc_file(FILE * infile, FILE * outfile,
/**
* scryptdec_file(infile, outfile, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime):
* maxmem, maxmemfrac, maxtime, verbose, force):
* Read a stream from infile and decrypt it, writing the resulting stream to
* outfile.
* 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)
size_t maxmem, double maxmemfrac, double maxtime, int verbose,
int force)
{
uint8_t buf[ENCBLOCK + 32];
uint8_t header[96];
@ -505,7 +545,7 @@ scryptdec_file(FILE * infile, FILE * outfile,
/* Parse the header and generate derived keys. */
if ((rc = scryptdec_setup(header, dk, passwd, passwdlen,
maxmem, maxmemfrac, maxtime)) != 0)
maxmem, maxmemfrac, maxtime, verbose, force)) != 0)
return (rc);
/* Start hashing with the header. */

View File

@ -36,7 +36,7 @@
* NOTE: This file provides prototypes for routines which encrypt/decrypt data
* using a key derived from a password by using the scrypt key derivation
* function. If you are just trying to "hash" a password for user logins,
* this is not the code you are looking for. You want to use the crypt_scrypt
* this is not the code you are looking for. You want to use the crypto_scrypt
* function directly.
*/
@ -82,39 +82,41 @@
/**
* scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime):
* 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);
const uint8_t *, size_t, size_t, double, double, int);
/**
* scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime):
* 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.
* 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);
const uint8_t *, size_t, size_t, double, double, int, int);
/**
* scryptenc_file(infile, outfile, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime):
* 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);
size_t, double, double, int);
/**
* scryptdec_file(infile, outfile, passwd, passwdlen,
* maxmem, maxmemfrac, maxtime):
* maxmem, maxmemfrac, maxtime, verbose, force):
* Read a stream from infile and decrypt it, writing the resulting stream to
* outfile.
* 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);
size_t, double, double, int, int);
#endif /* !_SCRYPTENC_H_ */

View File

@ -40,7 +40,7 @@
#ifdef HAVE_CLOCK_GETTIME
static clock_t clocktouse;
static clockid_t clocktouse;
static int
getclockres(double * resd)

View File

@ -26,6 +26,10 @@
* 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>
@ -92,7 +96,7 @@ memlimit_sysctl_hw(size_t * memlimit, int mibleaf)
if (sysctlval > SIZE_MAX)
*memlimit = SIZE_MAX;
else
*memlimit = sysctlval;
*memlimit = (size_t)sysctlval;
#else
*memlimit = sysctlval;
#endif
@ -134,7 +138,7 @@ memlimit_sysinfo(size_t * memlimit)
if (totalmem > SIZE_MAX)
*memlimit = SIZE_MAX;
else
*memlimit = totalmem;
*memlimit = (size_t)totalmem;
#else
*memlimit = totalmem;
#endif
@ -159,7 +163,7 @@ memlimit_rlimit(size_t * memlimit)
return (1);
if ((rl.rlim_cur != RLIM_INFINITY) &&
((uint64_t)rl.rlim_cur < memrlimit))
memrlimit = rl.rlim_cur;
memrlimit = (uint64_t)rl.rlim_cur;
#endif
/* ... RLIMIT_DATA... */
@ -167,7 +171,7 @@ memlimit_rlimit(size_t * memlimit)
return (1);
if ((rl.rlim_cur != RLIM_INFINITY) &&
((uint64_t)rl.rlim_cur < memrlimit))
memrlimit = rl.rlim_cur;
memrlimit = (uint64_t)rl.rlim_cur;
/* ... and RLIMIT_RSS. */
#ifdef RLIMIT_RSS
@ -175,7 +179,7 @@ memlimit_rlimit(size_t * memlimit)
return (1);
if ((rl.rlim_cur != RLIM_INFINITY) &&
((uint64_t)rl.rlim_cur < memrlimit))
memrlimit = rl.rlim_cur;
memrlimit = (uint64_t)rl.rlim_cur;
#endif
/* Return the value, but clamp to SIZE_MAX if necessary. */
@ -183,7 +187,7 @@ memlimit_rlimit(size_t * memlimit)
if (memrlimit > SIZE_MAX)
*memlimit = SIZE_MAX;
else
*memlimit = memrlimit;
*memlimit = (size_t)memrlimit;
#else
*memlimit = memrlimit;
#endif
@ -212,8 +216,11 @@ memlimit_sysconf(size_t * memlimit)
/* Read the two limits. */
if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) ||
((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) {
/* Did an error occur? */
if (errno != 0)
/*
* 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. */
@ -228,7 +235,7 @@ memlimit_sysconf(size_t * memlimit)
if (totalmem > SIZE_MAX)
*memlimit = SIZE_MAX;
else
*memlimit = totalmem;
*memlimit = (size_t)totalmem;
#else
*memlimit = totalmem;
#endif
@ -298,7 +305,7 @@ memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit)
/* Only use the specified fraction of the available memory. */
if ((maxmemfrac > 0.5) || (maxmemfrac == 0.0))
maxmemfrac = 0.5;
memavail = maxmemfrac * memlimit_min;
memavail = (size_t)(maxmemfrac * memlimit_min);
/* Don't use more than the specified maximum. */
if ((maxmem > 0) && (memavail > maxmem))

View File

@ -41,6 +41,26 @@ be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len)
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))
@ -53,117 +73,84 @@ be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len)
/* SHA256 round function */
#define RND(a, b, c, d, e, f, g, h, k) \
t0 = h + S1(e) + Ch(e, f, g) + k; \
t1 = S0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
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, k) \
#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] + k)
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, const uint8_t block[64])
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])
{
uint32_t W[64];
uint32_t S[8];
uint32_t t0, t1;
int i;
/* 1. Prepare message schedule W. */
/* 1. Prepare the first part of the message schedule W. */
be32dec_vect(W, block, 64);
for (i = 16; i < 64; i++)
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
/* 2. Initialize working variables. */
memcpy(S, state, 32);
/* 3. Mix. */
RNDr(S, W, 0, 0x428a2f98);
RNDr(S, W, 1, 0x71374491);
RNDr(S, W, 2, 0xb5c0fbcf);
RNDr(S, W, 3, 0xe9b5dba5);
RNDr(S, W, 4, 0x3956c25b);
RNDr(S, W, 5, 0x59f111f1);
RNDr(S, W, 6, 0x923f82a4);
RNDr(S, W, 7, 0xab1c5ed5);
RNDr(S, W, 8, 0xd807aa98);
RNDr(S, W, 9, 0x12835b01);
RNDr(S, W, 10, 0x243185be);
RNDr(S, W, 11, 0x550c7dc3);
RNDr(S, W, 12, 0x72be5d74);
RNDr(S, W, 13, 0x80deb1fe);
RNDr(S, W, 14, 0x9bdc06a7);
RNDr(S, W, 15, 0xc19bf174);
RNDr(S, W, 16, 0xe49b69c1);
RNDr(S, W, 17, 0xefbe4786);
RNDr(S, W, 18, 0x0fc19dc6);
RNDr(S, W, 19, 0x240ca1cc);
RNDr(S, W, 20, 0x2de92c6f);
RNDr(S, W, 21, 0x4a7484aa);
RNDr(S, W, 22, 0x5cb0a9dc);
RNDr(S, W, 23, 0x76f988da);
RNDr(S, W, 24, 0x983e5152);
RNDr(S, W, 25, 0xa831c66d);
RNDr(S, W, 26, 0xb00327c8);
RNDr(S, W, 27, 0xbf597fc7);
RNDr(S, W, 28, 0xc6e00bf3);
RNDr(S, W, 29, 0xd5a79147);
RNDr(S, W, 30, 0x06ca6351);
RNDr(S, W, 31, 0x14292967);
RNDr(S, W, 32, 0x27b70a85);
RNDr(S, W, 33, 0x2e1b2138);
RNDr(S, W, 34, 0x4d2c6dfc);
RNDr(S, W, 35, 0x53380d13);
RNDr(S, W, 36, 0x650a7354);
RNDr(S, W, 37, 0x766a0abb);
RNDr(S, W, 38, 0x81c2c92e);
RNDr(S, W, 39, 0x92722c85);
RNDr(S, W, 40, 0xa2bfe8a1);
RNDr(S, W, 41, 0xa81a664b);
RNDr(S, W, 42, 0xc24b8b70);
RNDr(S, W, 43, 0xc76c51a3);
RNDr(S, W, 44, 0xd192e819);
RNDr(S, W, 45, 0xd6990624);
RNDr(S, W, 46, 0xf40e3585);
RNDr(S, W, 47, 0x106aa070);
RNDr(S, W, 48, 0x19a4c116);
RNDr(S, W, 49, 0x1e376c08);
RNDr(S, W, 50, 0x2748774c);
RNDr(S, W, 51, 0x34b0bcb5);
RNDr(S, W, 52, 0x391c0cb3);
RNDr(S, W, 53, 0x4ed8aa4a);
RNDr(S, W, 54, 0x5b9cca4f);
RNDr(S, W, 55, 0x682e6ff3);
RNDr(S, W, 56, 0x748f82ee);
RNDr(S, W, 57, 0x78a5636f);
RNDr(S, W, 58, 0x84c87814);
RNDr(S, W, 59, 0x8cc70208);
RNDr(S, W, 60, 0x90befffa);
RNDr(S, W, 61, 0xa4506ceb);
RNDr(S, W, 62, 0xbef9a3f7);
RNDr(S, W, 63, 0xc67178f2);
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];
/* Clean the stack. */
insecure_memzero(W, 256);
insecure_memzero(S, 32);
insecure_memzero(&t0, sizeof(uint32_t));
insecure_memzero(&t1, sizeof(uint32_t));
}
static uint8_t PAD[64] = {
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,
@ -172,28 +159,35 @@ static uint8_t PAD[64] = {
/* Add padding and terminating bit-count. */
static void
SHA256_Pad(SHA256_CTX * ctx)
SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[static restrict 72])
{
uint8_t len[8];
uint32_t r, plen;
size_t r;
/*
* Convert length to a vector of bytes -- we do this now rather
* than later because the length will change after we pad.
*/
be64enc(len, ctx->count);
/* Add 1--64 bytes so that the resulting length is 56 mod 64. */
/* Figure out how many bytes we have buffered. */
r = (ctx->count >> 3) & 0x3f;
plen = (r < 56) ? (56 - r) : (120 - r);
SHA256_Update(ctx, PAD, (size_t)plen);
/* 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. */
SHA256_Update(ctx, len, 8);
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 initstate[8] = {
static const uint32_t initial_state[8] = {
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
};
@ -210,15 +204,16 @@ SHA256_Init(SHA256_CTX * ctx)
ctx->count = 0;
/* Initialize state. */
memcpy(ctx->state, initstate, sizeof(initstate));
memcpy(ctx->state, initial_state, sizeof(initial_state));
}
/**
* SHA256_Update(ctx, in, len):
* Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
*/
void
SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len)
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;
@ -241,13 +236,13 @@ SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len)
/* Finish the current block. */
memcpy(&ctx->buf[r], src, 64 - r);
SHA256_Transform(ctx->state, ctx->buf);
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);
SHA256_Transform(ctx->state, src, &tmp32[0], &tmp32[64]);
src += 64;
len -= 64;
}
@ -256,37 +251,69 @@ SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len)
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}.
*/
void
SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx)
static void
_SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx,
uint32_t tmp32[static restrict 72])
{
/* Add padding. */
SHA256_Pad(ctx);
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}.
* 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);
SHA256_Final(digest, &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);
}
/**
@ -294,19 +321,19 @@ SHA256_Buf(const void * in, size_t len, uint8_t digest[32])
* Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
* ${K}.
*/
void
HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
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])
{
uint8_t pad[64];
uint8_t khash[32];
const uint8_t * K = _K;
size_t i;
/* If Klen > 64, the key is really SHA256(K). */
if (Klen > 64) {
SHA256_Init(&ctx->ictx);
SHA256_Update(&ctx->ictx, K, Klen);
SHA256_Final(khash, &ctx->ictx);
_SHA256_Update(&ctx->ictx, K, Klen, tmp32);
_SHA256_Final(khash, &ctx->ictx, tmp32);
K = khash;
Klen = 32;
}
@ -316,16 +343,29 @@ HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
memset(pad, 0x36, 64);
for (i = 0; i < Klen; i++)
pad[i] ^= K[i];
SHA256_Update(&ctx->ictx, pad, 64);
_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);
_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);
}
@ -334,12 +374,26 @@ HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
* HMAC_SHA256_Update(ctx, in, len):
* Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
*/
void
HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len)
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);
_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);
}
/**
@ -347,21 +401,33 @@ HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len)
* 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];
/* Finish the inner SHA256 operation. */
SHA256_Final(ihash, &ctx->ictx);
/* Feed the inner hash to the outer SHA256 operation. */
SHA256_Update(&ctx->octx, ihash, 32);
/* Finish the outer SHA256 operation. */
SHA256_Final(digest, &ctx->octx);
/* Call the real function. */
_HMAC_SHA256_Final(digest, ctx, tmp32, ihash);
/* Clean the stack. */
insecure_memzero(tmp32, 288);
insecure_memzero(ihash, 32);
}
@ -375,10 +441,17 @@ 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);
HMAC_SHA256_Update(&ctx, in, len);
HMAC_SHA256_Final(digest, &ctx);
_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);
}
/**
@ -390,7 +463,9 @@ void
PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
{
HMAC_SHA256_CTX PShctx, hctx;
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];
@ -402,9 +477,13 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
/* 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. */
HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
HMAC_SHA256_Update(&PShctx, salt, saltlen);
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++) {
@ -413,17 +492,17 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
/* Compute U_1 = PRF(P, S || INT(i)). */
memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
HMAC_SHA256_Update(&hctx, ivec, 4);
HMAC_SHA256_Final(U, &hctx);
_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. */
HMAC_SHA256_Init(&hctx, passwd, passwdlen);
HMAC_SHA256_Update(&hctx, U, 32);
HMAC_SHA256_Final(U, &hctx);
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++)
@ -437,6 +516,12 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
memcpy(&buf[i * 32], T, clen);
}
/* Clean PShctx, since we never called _Final on it. */
/* 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

@ -47,7 +47,7 @@ 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}.
* Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}.
*/
void SHA256_Buf(const void *, size_t, uint8_t[32]);

View File

@ -0,0 +1,106 @@
#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

@ -2,9 +2,9 @@
#ifdef CPUSUPPORT_X86_CPUID
#include <cpuid.h>
#endif
#define CPUID_AESNI_BIT (1 << 25)
#endif
CPUSUPPORT_FEATURE_DECL(x86, aesni)
{
@ -22,7 +22,7 @@ CPUSUPPORT_FEATURE_DECL(x86, aesni)
goto unsupported;
/* Return the relevant feature bit. */
return (ecx & CPUID_AESNI_BIT);
return ((ecx & CPUID_AESNI_BIT) ? 1 : 0);
unsupported:
#endif

View File

@ -2,9 +2,9 @@
#ifdef CPUSUPPORT_X86_CPUID
#include <cpuid.h>
#endif
#define CPUID_SSE2_BIT (1 << 26)
#endif
CPUSUPPORT_FEATURE_DECL(x86, sse2)
{
@ -22,7 +22,7 @@ CPUSUPPORT_FEATURE_DECL(x86, sse2)
goto unsupported;
/* Return the relevant feature bit. */
return (edx & CPUID_SSE2_BIT);
return ((edx & CPUID_SSE2_BIT) ? 1 : 0);
unsupported:
#endif

View File

@ -23,16 +23,19 @@ struct crypto_aes_key;
#ifdef CPUSUPPORT_X86_AESNI
/* Test whether OpenSSL and AESNI code produce the same AES ciphertext. */
static int
aesnitest(uint8_t ptext[16], uint8_t * key, size_t keylen)
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, keylen * 8, &kexp_openssl);
if ((kexp_aesni = crypto_aes_key_expand_aesni(key, keylen)) == NULL)
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. */
@ -70,9 +73,9 @@ useaesni(void)
/* Test cases: key is 0x00010203..., ptext is 0x00112233... */
for (i = 0; i < 16; i++)
ptext[i] = 0x11 * i;
ptext[i] = (0x11 * i) & 0xff;
for (i = 0; i < 32; i++)
key[i] = i;
key[i] = i & 0xff;
/* Test that AESNI and OpenSSL produce the same results. */
if (aesnitest(ptext, key, 16) || aesnitest(ptext, key, 32)) {
@ -112,7 +115,7 @@ crypto_aes_key_expand(const uint8_t * key, size_t len)
goto err0;
/* Expand the key. */
AES_set_encrypt_key(key, len * 8, kexp);
AES_set_encrypt_key(key, (int)(len * 8), kexp);
/* Success! */
return ((void *)kexp);
@ -158,6 +161,10 @@ crypto_aes_key_free(struct crypto_aes_key * key)
}
#endif
/* Behave consistently with free(NULL). */
if (key == NULL)
return;
/* Attempt to zero the expanded key. */
insecure_memzero(key, sizeof(AES_KEY));

View File

@ -3,7 +3,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wmmintrin.h>
#include "insecure_memzero.h"
@ -226,6 +225,10 @@ 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));

View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#include "crypto_aes.h"
#include "insecure_memzero.h"
#include "sysendian.h"
#include "crypto_aesctr.h"
@ -82,16 +83,13 @@ crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf,
void
crypto_aesctr_free(struct crypto_aesctr * stream)
{
int i;
/* Be compatible with free(NULL). */
/* Behave consistently with free(NULL). */
if (stream == NULL)
return;
/* Zero potentially sensitive information. */
for (i = 0; i < 16; i++)
stream->buf[i] = 0;
stream->bytectr = stream->nonce = 0;
insecure_memzero(stream, sizeof(struct crypto_aesctr));
/* Free the stream. */
free(stream);
@ -99,7 +97,7 @@ crypto_aesctr_free(struct crypto_aesctr * stream)
/**
* crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
* Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free.
* Equivalent to _init(key, nonce); _stream(inbuf, outbuf, buflen); _free().
*/
void
crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce,
@ -107,7 +105,6 @@ crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce,
{
struct crypto_aesctr stream_rec;
struct crypto_aesctr * stream = &stream_rec;
int i;
/* Initialize values. */
stream->key = key;
@ -118,7 +115,5 @@ crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce,
crypto_aesctr_stream(stream, inbuf, outbuf, buflen);
/* Zero potentially sensitive information. */
for (i = 0; i < 16; i++)
stream->buf[i] = 0;
stream->bytectr = stream->nonce = 0;
insecure_memzero(stream, sizeof(struct crypto_aesctr));
}

View File

@ -4,8 +4,9 @@
#include <stddef.h>
#include <stdint.h>
/* Opaque type. */
/* Opaque types. */
struct crypto_aes_key;
struct crypto_aesctr;
/**
* crypto_aesctr_init(key, nonce):
@ -33,7 +34,7 @@ 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.
* 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);

View File

@ -0,0 +1,49 @@
#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

@ -0,0 +1,16 @@
#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,3 +1,4 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>
@ -53,8 +54,8 @@ entropy_read(uint8_t * buf, size_t buflen)
}
/* We've filled a portion of the buffer. */
buf += lenread;
buflen -= lenread;
buf += (size_t)lenread;
buflen -= (size_t)lenread;
}
/* Close the device. */

View File

@ -0,0 +1,358 @@
#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

@ -0,0 +1,175 @@
#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

@ -0,0 +1,165 @@
#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

@ -0,0 +1,21 @@
#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,6 +1,5 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
@ -38,6 +37,23 @@ 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
@ -90,7 +106,7 @@ readpass(char ** passwd, const char * prompt,
goto err2;
}
memcpy(&term, &term_old, sizeof(struct termios));
term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL;
term.c_lflag = (term.c_lflag & ~((tcflag_t)ECHO)) | ECHONL;
if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
warnp("Cannot set terminal settings");
goto err2;
@ -104,6 +120,9 @@ retry:
/* Read the password. */
if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
if (feof(readfrom))
warn0("EOF reading password");
else
warnp("Cannot read password");
goto err3;
}
@ -113,6 +132,9 @@ retry:
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;
}
@ -130,15 +152,8 @@ retry:
if (usingtty)
tcsetattr(fileno(readfrom), TCSANOW, &term_old);
/* 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]);
}
/* Restore old signals and re-issue intercepted signals. */
resetsigs(savedsa);
/* Close /dev/tty if we opened it. */
if (readfrom != stdin)
@ -174,6 +189,9 @@ 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);

View File

@ -22,7 +22,7 @@ be16dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8));
return (uint16_t)((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8));
}
static inline void
@ -85,7 +85,7 @@ le16dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8));
return (uint16_t)((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8));
}
static inline void

View File

@ -2,6 +2,7 @@
#define _WARNP_H_
#include <errno.h>
#include <stddef.h>
/* Avoid namespace collisions with BSD <err.h>. */
#define warn libcperciva_warn

View File

@ -25,13 +25,13 @@
*/
#include "scrypt_platform.h"
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "getopt.h"
#include "humansize.h"
#include "insecure_memzero.h"
#include "readpass.h"
#include "scryptenc.h"
@ -42,7 +42,10 @@ usage(void)
{
fprintf(stderr,
"usage: scrypt {enc | dec} [...] infile [outfile]\n");
"usage: scrypt {enc | dec} [-f] [-M maxmem]"
" [-m maxmemfrac]\n"
" [-t maxtime] [-v] [-P] infile [outfile]\n"
" scrypt --version\n");
exit(1);
}
@ -51,13 +54,17 @@ 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;
int ch;
const char * ch;
char * passwd;
int rc;
int verbose = 0;
WARNP_INIT;
@ -70,24 +77,50 @@ main(int argc, char *argv[])
maxtime = 5.0;
} else if (strcmp(argv[1], "dec") == 0) {
dec = 1;
} else
} 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, "hm:M:t:")) != -1) {
switch (ch) {
case 'M':
maxmem = strtoumax(optarg, NULL, 0);
while ((ch = GETOPT(argc, argv)) != NULL) {
GETOPT_SWITCH(ch) {
GETOPT_OPT("-f"):
force_resources = 1;
break;
case 'm':
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;
case 't':
GETOPT_OPTARG("-t"):
maxtime = strtod(optarg, NULL);
break;
default:
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();
}
}
@ -120,21 +153,28 @@ main(int argc, char *argv[])
/* Prompt for a password. */
if (readpass(&passwd, "Please enter passphrase",
dec ? NULL : "Please confirm passphrase", 1))
(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);
strlen(passwd), maxmem, maxmemfrac, maxtime, verbose,
force_resources);
else
rc = scryptenc_file(infile, outfile, (uint8_t *)passwd,
strlen(passwd), maxmem, maxmemfrac, maxtime);
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) {

View File

@ -21,7 +21,7 @@
.\" 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 May 24, 2009
.Dd February 10, 2017
.Dt SCRYPT 1
.Os
.Sh NAME
@ -30,11 +30,15 @@
.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
@ -53,8 +57,24 @@ and writes the result to
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
@ -67,6 +87,11 @@ of the available RAM to compute the derived encryption key.
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

View File

@ -0,0 +1,26 @@
#!/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

@ -0,0 +1,26 @@
#!/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

@ -0,0 +1,44 @@
#!/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

@ -0,0 +1,57 @@
#!/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

@ -0,0 +1,69 @@
#!/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

@ -0,0 +1,268 @@
#!/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

@ -0,0 +1,51 @@
#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

@ -0,0 +1,20 @@
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

@ -0,0 +1,34 @@
#!/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

Binary file not shown.

View File

@ -0,0 +1,25 @@
#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);
}