mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-05 14:22:36 +00:00
The Assimilation Bridge (Scrypt-Yescrypt GPU-CPU hybrid plugin -m 70200)
This commit is contained in:
parent
22c25b3ea1
commit
ed71e41ae1
200
deps/yescrypt-master/CHANGES
vendored
Normal file
200
deps/yescrypt-master/CHANGES
vendored
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
Changes made since 1.1.0 (2019/06/30).
|
||||||
|
|
||||||
|
Use AVX512VL XOP-like bit rotates for faster Salsa20 on supporting CPUs.
|
||||||
|
|
||||||
|
Implemented a little-known SHA-2 Maj() optimization proposed by Wei Dai.
|
||||||
|
|
||||||
|
Minor code cleanups and documentation updates.
|
||||||
|
|
||||||
|
|
||||||
|
Changes made between 1.0.3 (2018/06/13) and 1.1.0 (2019/06/30).
|
||||||
|
|
||||||
|
Merged yescrypt-opt.c and yescrypt-simd.c into one source file, which is
|
||||||
|
a closer match to -simd but is called -opt (and -simd is now gone).
|
||||||
|
With this change, performance of SIMD builds should be almost unchanged,
|
||||||
|
while scalar builds should be faster than before on register-rich 64-bit
|
||||||
|
architectures but may be slower than before on register-starved 32-bit
|
||||||
|
architectures (this shortcoming may be addressed later). This also
|
||||||
|
happens to make SSE prefetch available even in otherwise-scalar builds
|
||||||
|
and it paves the way for adding SIMD support on big-endian architectures
|
||||||
|
(previously, -simd assumed little-endian).
|
||||||
|
|
||||||
|
Added x32 ABI support (x86-64 with 32-bit pointers).
|
||||||
|
|
||||||
|
|
||||||
|
Changes made between 1.0.2 (2018/06/06) and 1.0.3 (2018/06/13).
|
||||||
|
|
||||||
|
In SMix1, optimized out the indexing of V for the sequential writes.
|
||||||
|
|
||||||
|
|
||||||
|
Changes made between 1.0.1 (2018/04/22) and 1.0.2 (2018/06/06).
|
||||||
|
|
||||||
|
Don't use MAP_POPULATE anymore because new multi-threaded benchmarks on
|
||||||
|
RHEL6'ish and RHEL7'ish systems revealed that it sometimes has adverse
|
||||||
|
effect far in excess of its occasional positive effect.
|
||||||
|
|
||||||
|
In the SIMD code, we now reuse the same buffer for BlockMix_pwxform's
|
||||||
|
input and output in SMix2. This might slightly improve cache hit rate
|
||||||
|
and thus performance.
|
||||||
|
|
||||||
|
Also in the SIMD code, a compiler memory barrier has been added between
|
||||||
|
sub-blocks to ensure that none of the writes into what was S2 during
|
||||||
|
processing of the previous sub-block are postponed until after a read
|
||||||
|
from S0 or S1 in the inline asm code for the current sub-block. This
|
||||||
|
potential problem was never observed so far due to other constraints
|
||||||
|
that we have, but strictly speaking those constraints were insufficient
|
||||||
|
to guarantee it couldn't occur.
|
||||||
|
|
||||||
|
|
||||||
|
Changes made between 1.0.0 (2018/03/09) and 1.0.1 (2018/04/22).
|
||||||
|
|
||||||
|
The included documentation has been improved, most notably adding new
|
||||||
|
text files PARAMETERS (guidelines on parameter selection, and currently
|
||||||
|
recommended parameter sets by use case) and COMPARISON (comparison to
|
||||||
|
scrypt and Argon2).
|
||||||
|
|
||||||
|
Code cleanups have been made, including removal of AVX2 support, which
|
||||||
|
was deliberately temporarily preserved for the 1.0.0 release, but which
|
||||||
|
almost always hurt performance with currently recommended low-level
|
||||||
|
yescrypt parameters on Intel & AMD CPUs tested so far. (The low-level
|
||||||
|
parameters are chosen with consideration for relative performance of
|
||||||
|
defensive vs. offensive implementations on different hardware, and not
|
||||||
|
only for seemingly best performance on CPUs. It is possible to change
|
||||||
|
them such that AVX2 would be worthwhile, and this might happen in the
|
||||||
|
future, but currently this wouldn't be obviously beneficial overall.)
|
||||||
|
|
||||||
|
|
||||||
|
Changes made between 0.8.1 (2015/10/25) and 1.0.0 (2018/03/09).
|
||||||
|
|
||||||
|
Hash string encoding has been finalized under the "$y$" prefix for both
|
||||||
|
native yescrypt and classic scrypt hashes, using a new variable-length
|
||||||
|
and extremely compact encoding of (ye)scrypt's many parameters. (Also
|
||||||
|
still recognized under the "$7$" prefix is the previously used encoding
|
||||||
|
for classic scrypt hashes, which is fixed-length and not so compact.)
|
||||||
|
|
||||||
|
Optional format-preserving salt and hash (re-)encryption has been added,
|
||||||
|
using the Luby-Rackoff construction with SHA-256 as the PRF.
|
||||||
|
|
||||||
|
Support for hash upgrades has been temporarily excluded to allow for its
|
||||||
|
finalization at a later time and based on actual needs (e.g., will 3x
|
||||||
|
ROM size upgrades be in demand now that Intel went from 4 to 6 memory
|
||||||
|
channels in their server CPUs, bringing a factor of 3 into RAM sizes?)
|
||||||
|
|
||||||
|
ROM initialization has been sped up through a new simplified algorithm.
|
||||||
|
|
||||||
|
ROM tags (magic constant values) and digests (values that depend on the
|
||||||
|
entire computation of the ROM contents) have been added to the last
|
||||||
|
block of ROM. (The placement of these tags/digests is such that nested
|
||||||
|
ROMs are possible, to allow for ROM size upgrades later.)
|
||||||
|
|
||||||
|
The last block of ROM is now checked for the tag and is always used for
|
||||||
|
hash computation before a secret-dependent memory access is first made.
|
||||||
|
This ensures that hashes won't be computed with a partially initialized
|
||||||
|
ROM or with one initialized using different machine word endianness, and
|
||||||
|
that they will be consistently miscomputed if the ROM digest is other
|
||||||
|
than what the caller expected. This in turn helps early detection of
|
||||||
|
problems with ROM initialization even if the calling application fails
|
||||||
|
to check for them. This also helps mitigate cache-timing attacks when
|
||||||
|
the attacker doesn't know the contents of the last block of ROM.
|
||||||
|
|
||||||
|
Many implementation changes have been made, such as for performance,
|
||||||
|
portability, security (intentional reuse and thus rewrite of memory
|
||||||
|
where practical and optional zeroization elsewhere), and coding style.
|
||||||
|
This includes addition of optional SSE2 inline assembly code (a macro
|
||||||
|
with 8 instructions) to yescrypt-simd.c, which tends to slightly
|
||||||
|
outperform compiler-generated code, including AVX(2)-enabled code, for
|
||||||
|
yescrypt's currently recommended settings. This is no surprise since
|
||||||
|
yescrypt was designed to fit the 64-bit mode extended SSE2 instruction
|
||||||
|
set perfectly (including SSE2's lack of 3-register instructions), so for
|
||||||
|
its optimal implementation AVX would merely result in extra instruction
|
||||||
|
prefixes and not provide any benefit (except for the uses of Salsa20
|
||||||
|
inherited from scrypt, but those are infrequent).
|
||||||
|
|
||||||
|
The auxiliary files inherited from scrypt have been sync'ed with scrypt
|
||||||
|
1.2.1, and the implementation of PBKDF2 has been further optimized,
|
||||||
|
especially for its use in (ye)scrypt where the "iteration count" is 1
|
||||||
|
but the output size is relatively large. (The speedup is measurable at
|
||||||
|
realistically low settings for yescrypt, such as at 2 MiB of memory.)
|
||||||
|
|
||||||
|
The included tests have been revised and test vectors regenerated to
|
||||||
|
account for the ROM initialization/use updates and hash (re-)encryption.
|
||||||
|
|
||||||
|
The PHC test vectors have been compacted into a single SHA-256 hash of
|
||||||
|
the expected output of phc.c, but have otherwise remained unchanged as
|
||||||
|
none of the incompatible changes have affected the subset of yescrypt
|
||||||
|
exposed via the PHS() interface for the Password Hashing Competition.
|
||||||
|
|
||||||
|
The specification document and extra programs that were included with
|
||||||
|
the PHC submission and its updates are now excluded from this release.
|
||||||
|
|
||||||
|
The rest of documentation files have been updated for the 1.0.0 release.
|
||||||
|
|
||||||
|
|
||||||
|
Changes made between 0.7.1 (2015/01/31) and 0.8.1 (2015/10/25).
|
||||||
|
|
||||||
|
pwxform became stateful, through writes to its S-boxes. This further
|
||||||
|
discourages TMTO attacks on yescrypt as a whole, as well as on pwxform
|
||||||
|
S-boxes separately. It also increases the total size of the S-boxes by
|
||||||
|
a factor of 1.5 (8 KiB to 12 KiB by default) and it puts the previously
|
||||||
|
mostly idle L1 cache write ports on CPUs to use.
|
||||||
|
|
||||||
|
Salsa20/8 in BlockMix_pwxform has been replaced with Salsa20/2.
|
||||||
|
|
||||||
|
An extra HMAC-SHA256 update of the password buffer (which is eventually
|
||||||
|
passed into the final PBKDF2 invocation) is now performed right after
|
||||||
|
the pwxform S-boxes initialization.
|
||||||
|
|
||||||
|
Nloop_rw rounding has been adjusted to be the same as Nloop_all's.
|
||||||
|
This avoids an unnecessary invocation of SMix2 with Nloop = 2, which
|
||||||
|
would otherwise have occurred in some cases.
|
||||||
|
|
||||||
|
t is now halved per hash upgrade (rather than reset to 0 right away on
|
||||||
|
the very first upgrade, like it was in 0.7.1).
|
||||||
|
|
||||||
|
Minor corrections and improvements to the specification and the code
|
||||||
|
have been made.
|
||||||
|
|
||||||
|
|
||||||
|
Changes made between 0.6.4 (2015/01/30) and 0.7.1 (2015/01/31).
|
||||||
|
|
||||||
|
The YESCRYPT_PARALLEL_SMIX and YESCRYPT_PWXFORM flags have been removed,
|
||||||
|
with the corresponding functionality enabled along with the YESCRYPT_RW
|
||||||
|
flag. This change has simplified the SIMD implementation a little bit
|
||||||
|
(eliminating specialized code for some flag combinations that are no
|
||||||
|
longer possible), and it should help simplify documentation, analysis,
|
||||||
|
testing, and benchmarking (fewer combinations of settings to test).
|
||||||
|
|
||||||
|
Adjustments to pre- and post-hashing have been made to address subtle
|
||||||
|
issues and non-intuitive behavior, as well as in some cases to reduce
|
||||||
|
impact of garbage collector attacks.
|
||||||
|
|
||||||
|
Support for hash upgrades has been added (the g parameter).
|
||||||
|
|
||||||
|
Extra tests have been written and test vectors re-generated.
|
||||||
|
|
||||||
|
|
||||||
|
Changes made between 0.5.2 (2014/03/31) and 0.6.4 (2015/01/30).
|
||||||
|
|
||||||
|
Dropped support for ROM access frequency mask since it made little sense
|
||||||
|
when supporting only one ROM at a time. (It'd make sense with two ROMs,
|
||||||
|
for simultaneous use of a ROM-in-RAM and a ROM-on-SSD. With just one
|
||||||
|
ROM, the mask could still be used for a ROM-on-SSD, but only in lieu of
|
||||||
|
a ROM-in-RAM, which would arguably be unreasonable.)
|
||||||
|
|
||||||
|
Simplified the API by having it accept NULL for the "shared" parameter
|
||||||
|
to indicate no ROM in use. (Previously, a dummy "shared" structure had
|
||||||
|
to be created.)
|
||||||
|
|
||||||
|
Completed the specification of pwxform, BlockMix_pwxform, Salsa20 SIMD
|
||||||
|
shuffling, and potential endianness conversion. (No change to these has
|
||||||
|
been made - they have just been specified in the included document more
|
||||||
|
completely.)
|
||||||
|
|
||||||
|
Provided rationale for the default compile-time settings for pwxform.
|
||||||
|
|
||||||
|
Revised the reference and optimized implementations' source code to more
|
||||||
|
closely match the current specification document in terms of identifier
|
||||||
|
names, compile-time constant expressions, source code comments, and in
|
||||||
|
some cases the ordering of source code lines. None of these changes
|
||||||
|
affect the computed hash values, hence the test vectors have remained
|
||||||
|
the same.
|
129
deps/yescrypt-master/COMPARISON
vendored
Normal file
129
deps/yescrypt-master/COMPARISON
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
Comparison of yescrypt to scrypt and Argon2.
|
||||||
|
|
||||||
|
yescrypt's advantages:
|
||||||
|
|
||||||
|
+ Greater resistance to offline attacks (increasing attacker's cost at
|
||||||
|
same defender's cost)
|
||||||
|
|
||||||
|
+ yescrypt supports optional ROM for protection from use of botnet
|
||||||
|
nodes (and other relatively small memory devices)
|
||||||
|
|
||||||
|
+ yescrypt has a dependency not only on RAM and maybe ROM, but
|
||||||
|
also on fast on-die local memory (such as a CPU's L1 or L2 cache),
|
||||||
|
which provides bcrypt-like anti-GPU properties even at very low
|
||||||
|
per-hash RAM sizes (where scrypt and Argon2 are more likely to lose
|
||||||
|
to bcrypt in terms of GPU attack speed) and even without ROM
|
||||||
|
|
||||||
|
+ yescrypt and scrypt currently have little low-level
|
||||||
|
parallelism within processing of a block (yescrypt allows for
|
||||||
|
tuning this later, scrypt does not), whereas Argon2 has a fixed and
|
||||||
|
currently commonly excessive amount of such parallelism, which may
|
||||||
|
be extracted to speed up e.g. GPU attacks through use of more
|
||||||
|
computing resources per the same total memory size due to each hash
|
||||||
|
computation's memory needs being split between 32 threads (yescrypt
|
||||||
|
currently has four 16-byte lanes that can be processed in parallel
|
||||||
|
within a 64-byte sub-block before running into a data dependency
|
||||||
|
for the next sub-block, whereas Argon2 allows for parallel
|
||||||
|
processing of eight 128-byte chunks within a 1 KiB block with only
|
||||||
|
two synchronization points for the entire block, as well as of four
|
||||||
|
32-byte parts of the 128-byte chunks with only two more
|
||||||
|
synchronization points for the entire 1 KiB block)
|
||||||
|
|
||||||
|
+ yescrypt uses computation latency hardening based on integer
|
||||||
|
multiplication and local memory access speed, which ties its
|
||||||
|
per-hash RAMs up for a guaranteed minimum amount of time regardless
|
||||||
|
of possibly much higher memory bandwidth on the attacker's
|
||||||
|
hardware, whereas Argon2 uses only the multiplications and performs
|
||||||
|
6 times fewer of those sequentially (96 sequential multiplications
|
||||||
|
per 1 KiB for yescrypt vs. 16 per 1 KiB for Argon2, providing
|
||||||
|
correspondingly different minimum time guarantees) and scrypt does
|
||||||
|
not use this technique at all (but is no worse than Argon2 in this
|
||||||
|
respect anyway due to having less low-level parallelism)
|
||||||
|
|
||||||
|
+ yescrypt and Argon2 are time-memory trade-off (TMTO) resistant
|
||||||
|
(thus, computing them in less memory takes disproportionately
|
||||||
|
longer), whereas scrypt is deliberately TMTO-friendly (and
|
||||||
|
moreover, computing it in less memory takes up to 4x less than
|
||||||
|
proportionately longer)
|
||||||
|
|
||||||
|
+ Extra optional built-in features
|
||||||
|
|
||||||
|
+ Hash encryption so that the hashes are not crackable without
|
||||||
|
the key (to be stored separately)
|
||||||
|
|
||||||
|
+ Hash upgrade to higher settings without knowledge of password
|
||||||
|
(temporarily removed from 1.0, to be re-added later)
|
||||||
|
|
||||||
|
+ SCRAM-like client-side computation of challenge responses
|
||||||
|
(already part of the algorithm, not yet exposed via the API)
|
||||||
|
|
||||||
|
+ yescrypt's and Argon2's running time is tunable on top of
|
||||||
|
memory usage and parallelism, unlike in scrypt's
|
||||||
|
|
||||||
|
+ Cryptographic security provided by NIST-approved primitives
|
||||||
|
|
||||||
|
+ (ye)scrypt's cryptographic security is provided by SHA-256,
|
||||||
|
HMAC, and PBKDF2, which are NIST-approved and time-tested (the rest
|
||||||
|
of yescrypt's processing, while most crucial for its offline attack
|
||||||
|
resistance properties, provably does not affect its basic
|
||||||
|
cryptographic hash properties), whereas Argon2 relies on the newer
|
||||||
|
BLAKE2 (either choice is just fine for security, but use of
|
||||||
|
approved algorithms may sometimes be required for compliance)
|
||||||
|
|
||||||
|
+ SHA-256, HMAC, PBKDF2, and scrypt are usable from the same codebase
|
||||||
|
|
||||||
|
yescrypt's drawbacks:
|
||||||
|
|
||||||
|
- Complex (higher risk of human error occurring and remaining
|
||||||
|
unnoticed for long)
|
||||||
|
|
||||||
|
- Cache-timing unsafe (like bcrypt, scrypt, and Argon2d, but
|
||||||
|
unlike Argon2i)
|
||||||
|
|
||||||
|
- Not the PHC winner (Argon2 is), but is merely a "special recognition"
|
||||||
|
|
||||||
|
- Supported in fewer third-party projects (as of this writing, there's
|
||||||
|
yescrypt support in libxcrypt, Linux-PAM, shadow, and mkpasswd)
|
||||||
|
|
||||||
|
Other observations:
|
||||||
|
|
||||||
|
* yescrypt's complexity is related to its current primary target use
|
||||||
|
case (mass user authentication) and is relatively small compared to
|
||||||
|
the total complexity of the authentication service, so the risk may
|
||||||
|
be justified
|
||||||
|
|
||||||
|
* Cache-timing safety is unimportant on dedicated servers, is
|
||||||
|
mitigated for some use cases and threat models by proper use of
|
||||||
|
salts, and is fully achieved in Argon2 only in its 2i flavor and only
|
||||||
|
through reduction of resistance to the usual offline attacks compared
|
||||||
|
to the 2d flavor
|
||||||
|
|
||||||
|
* yescrypt's single-threaded memory filling speed on an otherwise
|
||||||
|
idle machine and at our currently recommended settings is lower than
|
||||||
|
Argon2's, but that's a result of our deliberate tuning (there's a
|
||||||
|
knob to change that, but we don't recommend doing so) preventing
|
||||||
|
yescrypt from bumping into memory access speed prematurely, and is
|
||||||
|
irrelevant for determining server request rate capacity and maximum
|
||||||
|
response latency where multiple instances or threads would be run
|
||||||
|
(under that scenario, the algorithms deliver similar speeds)
|
||||||
|
|
||||||
|
* yescrypt has been designed and currently configured to fit the
|
||||||
|
SSE2 and NEON instruction sets and 128-bit SIMD perfectly, not
|
||||||
|
benefiting from AVX's 3-register instructions (unlike classic scrypt,
|
||||||
|
which doesn't fit SSE2 as perfectly and thus benefits from AVX and
|
||||||
|
XOP) nor from AVX2's and AVX-512's wider SIMD (although it can be
|
||||||
|
reconfigured for wider SIMD later), whereas Argon2 significantly
|
||||||
|
benefits from those at least when running fewer threads or concurrent
|
||||||
|
instances than are supported by the hardware (yet yescrypt's SSE2
|
||||||
|
code is competitive with Argon2's AVX2 code under full server load)
|
||||||
|
|
||||||
|
* yescrypt vs. Argon2 benchmarks are further complicated by these
|
||||||
|
two schemes having different minimum amount of processing over memory
|
||||||
|
(yescrypt's is 4/3 of Argon2's), and thus different average memory
|
||||||
|
usage (5/8 of peak for yescrypt t=0 vs. 1/2 of peak for Argon2 t=1),
|
||||||
|
which needs to be taken into account
|
||||||
|
|
||||||
|
* scrypt benchmarks are also different in amount of processing over
|
||||||
|
memory (twice Argon2's minimum) and average memory usage (3/4 of
|
||||||
|
peak), but that's even further complicated by scrypt's
|
||||||
|
TMTO-friendliness providing up to a 4x advantage to some attackers
|
85
deps/yescrypt-master/Makefile
vendored
Normal file
85
deps/yescrypt-master/Makefile
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# Copyright 2013-2018 Alexander Peslyak
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
# SUCH DAMAGE.
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
LD = $(CC)
|
||||||
|
RM = rm -f
|
||||||
|
OMPFLAGS = -fopenmp
|
||||||
|
OMPFLAGS_MAYBE = $(OMPFLAGS)
|
||||||
|
#CFLAGS = -Wall -O2 -fomit-frame-pointer $(OMPFLAGS_MAYBE) -DSKIP_MEMZERO
|
||||||
|
CFLAGS = -Wall -O2 -march=native -fomit-frame-pointer $(OMPFLAGS_MAYBE) -DSKIP_MEMZERO
|
||||||
|
#CFLAGS = -Wall -O2 -funroll-loops -fomit-frame-pointer $(OMPFLAGS_MAYBE) -DSKIP_MEMZERO
|
||||||
|
#CFLAGS = -Wall -O2 -march=native -funroll-loops -fomit-frame-pointer $(OMPFLAGS_MAYBE) -DSKIP_MEMZERO
|
||||||
|
# -lrt is for userom's use of clock_gettime()
|
||||||
|
LDFLAGS = -s -lrt $(OMPFLAGS_MAYBE)
|
||||||
|
|
||||||
|
PROJ = tests phc-test initrom userom
|
||||||
|
OBJS_CORE = yescrypt-opt.o
|
||||||
|
OBJS_COMMON = yescrypt-common.o sha256.o insecure_memzero.o
|
||||||
|
OBJS_TESTS = $(OBJS_CORE) $(OBJS_COMMON) tests.o
|
||||||
|
OBJS_PHC = $(OBJS_CORE) $(OBJS_COMMON) phc-test.o
|
||||||
|
OBJS_INITROM = $(OBJS_CORE) $(OBJS_COMMON) initrom.o
|
||||||
|
OBJS_USEROM = $(OBJS_CORE) $(OBJS_COMMON) userom.o
|
||||||
|
OBJS_RM = yescrypt-*.o
|
||||||
|
|
||||||
|
all: $(PROJ)
|
||||||
|
|
||||||
|
check: tests phc-test
|
||||||
|
@echo 'Running main tests'
|
||||||
|
@time ./tests | tee TESTS-OUT
|
||||||
|
@diff -U0 TESTS-OK TESTS-OUT && echo PASSED || echo FAILED
|
||||||
|
@if [ -e PHC-TEST-OK-SHA256 ]; then \
|
||||||
|
echo 'Running PHC tests'; \
|
||||||
|
time ./phc-test > PHC-TEST-OUT; \
|
||||||
|
sha256sum -c PHC-TEST-OK-SHA256; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
ref:
|
||||||
|
$(MAKE) $(PROJ) OBJS_CORE=yescrypt-ref.o
|
||||||
|
|
||||||
|
check-ref:
|
||||||
|
$(MAKE) check OBJS_CORE=yescrypt-ref.o
|
||||||
|
|
||||||
|
tests: $(OBJS_TESTS)
|
||||||
|
$(LD) $(LDFLAGS) $(OBJS_TESTS) -o $@
|
||||||
|
|
||||||
|
phc-test.o: phc.c
|
||||||
|
$(CC) -c $(CFLAGS) -DTEST phc.c -o $@
|
||||||
|
|
||||||
|
phc-test: $(OBJS_PHC)
|
||||||
|
$(LD) $(LDFLAGS) $(OBJS_PHC) -o $@
|
||||||
|
|
||||||
|
initrom: $(OBJS_INITROM)
|
||||||
|
$(LD) $(LDFLAGS) $(OBJS_INITROM) -o $@
|
||||||
|
|
||||||
|
userom: $(OBJS_USEROM)
|
||||||
|
$(LD) $(LDFLAGS) $(OMPFLAGS) $(OBJS_USEROM) -o $@
|
||||||
|
|
||||||
|
userom.o: userom.c
|
||||||
|
$(CC) -c $(CFLAGS) $(OMPFLAGS) $*.c
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -c $(CFLAGS) $*.c
|
||||||
|
|
||||||
|
yescrypt-opt.o: yescrypt-platform.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(PROJ)
|
||||||
|
$(RM) $(OBJS_TESTS) $(OBJS_PHC) $(OBJS_INITROM) $(OBJS_USEROM)
|
||||||
|
$(RM) $(OBJS_RM)
|
||||||
|
$(RM) TESTS-OUT PHC-TEST-OUT
|
196
deps/yescrypt-master/PARAMETERS
vendored
Normal file
196
deps/yescrypt-master/PARAMETERS
vendored
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
Optimal yescrypt configuration.
|
||||||
|
|
||||||
|
yescrypt is very flexible, but configuring it optimally is complicated.
|
||||||
|
Here are some guidelines to simplify near-optimal configuration. We
|
||||||
|
start by listing the parameters and their typical values, and then give
|
||||||
|
currently recommended parameter sets by use case.
|
||||||
|
|
||||||
|
|
||||||
|
Parameters and their typical values.
|
||||||
|
|
||||||
|
Set flags (yescrypt flavor) to YESCRYPT_DEFAULTS to use the currently
|
||||||
|
recommended flavor. (Other flags values exist for compatibility and for
|
||||||
|
specialized cases where you think you know what you're doing.)
|
||||||
|
|
||||||
|
Set N (block count) based on target memory usage and running time, as
|
||||||
|
well as on the value of r (block size in 128 byte units). N must be a
|
||||||
|
power of two.
|
||||||
|
|
||||||
|
Set r (block size) to 8 (so that N is in KiB, which is convenient) or to
|
||||||
|
another small value (if more optimal or for fine-tuning of the total
|
||||||
|
size and/or running time). Reasonable values for r are from 8 to 96.
|
||||||
|
|
||||||
|
Set p (parallelism) to 1 meaning no thread-level parallelism within one
|
||||||
|
computation of yescrypt. (Use of thread-level parallelism within
|
||||||
|
yescrypt makes sense for ROM initialization and for key derivation at
|
||||||
|
high memory usage, but usually not for password hashing where
|
||||||
|
parallelism is available through concurrent authentication attempts.
|
||||||
|
Don't use p > 1 unnecessarily.)
|
||||||
|
|
||||||
|
Set t (time) to 0 to use the optimal running time for a given memory
|
||||||
|
usage. This will allow you to maximize the memory usage (the value of
|
||||||
|
N*r) while staying within your running time constraints. (Non-zero t
|
||||||
|
makes sense in specialized cases where you can't afford higher memory
|
||||||
|
usage but can afford more time.)
|
||||||
|
|
||||||
|
Set g (upgrades) to 0 because there have been no hash upgrades yet.
|
||||||
|
|
||||||
|
Set NROM (block count of ROM) to 0 unless you use a ROM (see below).
|
||||||
|
NROM must be a power of two.
|
||||||
|
|
||||||
|
|
||||||
|
Password hashing for user authentication, no ROM.
|
||||||
|
|
||||||
|
Small and fast (memory usage 2 MiB, performance like bcrypt cost 2^5 -
|
||||||
|
latency 2-3 ms and throughput 10,000+ per second on a 16-core server):
|
||||||
|
|
||||||
|
flags = YESCRYPT_DEFAULTS, N = 2048, r = 8, p = 1, t = 0, g = 0, NROM = 0
|
||||||
|
|
||||||
|
Large and slow (memory usage 16 MiB, performance like bcrypt cost 2^8 -
|
||||||
|
latency 10-30 ms and throughput 1000+ per second on a 16-core server):
|
||||||
|
|
||||||
|
flags = YESCRYPT_DEFAULTS, N = 4096, r = 32, p = 1, t = 0, g = 0, NROM = 0
|
||||||
|
|
||||||
|
Of course, even heavier and slower settings are possible, if affordable.
|
||||||
|
Simply double the value of N as many times as needed. Since N must be a
|
||||||
|
power of two, you may use r (in the range of 8 to 32) or/and t (in the
|
||||||
|
range of 0 to 2) for fine-tuning the running time, but first bring N to
|
||||||
|
the maximum you can afford. If this feels too complicated, just use one
|
||||||
|
of the two parameter sets given above (preferably the second) as-is.
|
||||||
|
|
||||||
|
|
||||||
|
Password hashing for user authentication, with ROM.
|
||||||
|
|
||||||
|
It's similar to the above, except that you need to adjust r, set NROM,
|
||||||
|
and initialize the ROM.
|
||||||
|
|
||||||
|
First decide on a ROM size, such as making it a large portion of your
|
||||||
|
dedicated authentication servers' RAM sizes. Since NROM (block count)
|
||||||
|
must be a power of two, you might need to choose r (block size) based on
|
||||||
|
how your desired ROM size corresponds to a power of two. Also tuning
|
||||||
|
for performance on current hardware, you'll likely end up with r in the
|
||||||
|
range from slightly below 16 to 32. For example, to use 15/16 of a
|
||||||
|
server's 256 GiB RAM as ROM (thus, making it 240 GiB), you could use
|
||||||
|
r=15 or r=30. To use 23/24 of a server's 384 GiB RAM as ROM (thus,
|
||||||
|
making it 368 GiB), you'd use r=23. Then set NROM to your desired ROM
|
||||||
|
size in KiB divided by 128*r. Note that these examples might (or might
|
||||||
|
not) be too extreme, leaving little memory for the rest of the system.
|
||||||
|
You could as well opt for 7/8 with r=14 or 11/12 with r=11 or r=22.
|
||||||
|
|
||||||
|
Note that higher r may make placing of ROM in e.g. NVMe flash memory
|
||||||
|
instead of in RAM more reasonable (or less unreasonable) than it would
|
||||||
|
have been with a lower r. If this is a concern as it relates to
|
||||||
|
possible attacks and you do not intend to ever do it defensively, you
|
||||||
|
might want to keep r lower (e.g., prefer r=15 over r=30 in the example
|
||||||
|
above, even if 30 performs slightly faster).
|
||||||
|
|
||||||
|
Your adjustments to r, if you deviate from powers of two, will also
|
||||||
|
result in weirder memory usage per hash. Like 1.75 MiB at r=14 instead
|
||||||
|
of 2 MiB at r=8 that you would have used without a ROM. That's OK.
|
||||||
|
|
||||||
|
For ROM initialization, which you do with yescrypt_init_shared(), use
|
||||||
|
the same r and NROM that you'd later use for password hashing, choose p
|
||||||
|
based on your servers' physical and/or logical CPU count (maybe
|
||||||
|
considering eventual upgrades as you won't be able to change this later,
|
||||||
|
but without going unnecessarily high - e.g., p=28, p=56, or p=112 make
|
||||||
|
sense on servers that currently have 28 physical / 56 logical CPUs), and
|
||||||
|
set the rest of the parameters to:
|
||||||
|
|
||||||
|
flags = YESCRYPT_DEFAULTS, N = 0, t = 0, g = 0
|
||||||
|
|
||||||
|
N is set to 0 because it isn't relevant during ROM initialization (you
|
||||||
|
can use different values of N for hashing passwords with the same ROM).
|
||||||
|
|
||||||
|
To keep the ROM in e.g. SysV shared memory and reuse it across your
|
||||||
|
authentication service restarts, you'd need to allocate the memory and
|
||||||
|
set the flags to "YESCRYPT_DEFAULTS | YESCRYPT_SHARED_PREALLOCATED".
|
||||||
|
|
||||||
|
For actual password hashing, you'd use your chosen values for N, r,
|
||||||
|
NROM, and set the rest of the parameters to:
|
||||||
|
|
||||||
|
flags = YESCRYPT_DEFAULTS, p = 1, t = 0, g = 0
|
||||||
|
|
||||||
|
Note that although you'd use a large p for ROM initialization, you
|
||||||
|
should use p=1 for actual password hashing like you would without a ROM.
|
||||||
|
|
||||||
|
Do not forget to pass the ROM into the actual password hashing (and keep
|
||||||
|
r and NROM set accordingly).
|
||||||
|
|
||||||
|
Since N must be a power of two and r is dependent on ROM size, you may
|
||||||
|
use t (in the range of 0 to 2) for fine-tuning the running time, but
|
||||||
|
first bring N to the maximum you can afford.
|
||||||
|
|
||||||
|
If this feels too complicated, or even if it doesn't, please consider
|
||||||
|
engaging Openwall for your yescrypt deployment. We'd be happy to help.
|
||||||
|
|
||||||
|
|
||||||
|
Password-based key derivation.
|
||||||
|
|
||||||
|
(Or rather passphrase-based.)
|
||||||
|
|
||||||
|
Use settings similar to those for password hashing without a ROM, but
|
||||||
|
adjusted for higher memory usage and running time, and optionally with
|
||||||
|
thread-level parallelism.
|
||||||
|
|
||||||
|
Small and fast (memory usage 128 MiB, running time under 100 ms on a
|
||||||
|
fast desktop):
|
||||||
|
|
||||||
|
flags = YESCRYPT_DEFAULTS, N = 32768, r = 32, p = 1, t = 0, g = 0, NROM = 0
|
||||||
|
|
||||||
|
Large and fast (memory usage 1 GiB, running time under 200 ms on a fast
|
||||||
|
quad-core desktop not including memory allocation overhead, under 250 ms
|
||||||
|
with the overhead included), but requires build with OpenMP support (or
|
||||||
|
otherwise will run as slow as yet be weaker than its p=1 alternative):
|
||||||
|
|
||||||
|
flags = YESCRYPT_DEFAULTS, N = 262144, r = 32, p = 4, t = 0, g = 0, NROM = 0
|
||||||
|
|
||||||
|
Large and slower (memory usage 1 GiB, running time under 300 ms on a
|
||||||
|
fast quad-core desktop not including memory allocation overhead, under
|
||||||
|
350 ms with the overhead included), also requires build with OpenMP
|
||||||
|
support (or otherwise will run slower than the p=1 alternative below):
|
||||||
|
|
||||||
|
flags = YESCRYPT_DEFAULTS, N = 262144, r = 32, p = 4, t = 2, g = 0, NROM = 0
|
||||||
|
|
||||||
|
Large and slow (memory usage 1 GiB, running time under 600 ms on a fast
|
||||||
|
desktop not including memory allocation overhead, under 650 ms with the
|
||||||
|
overhead included):
|
||||||
|
|
||||||
|
flags = YESCRYPT_DEFAULTS, N = 262144, r = 32, p = 1, t = 0, g = 0, NROM = 0
|
||||||
|
|
||||||
|
Just like with password hashing, even heavier and slower settings are
|
||||||
|
possible, if affordable, and you achieve them by adjusting N, r, t in
|
||||||
|
the same way and in the same preferred ranges (please see the section on
|
||||||
|
password hashing without a ROM, above). Unlike with password hashing,
|
||||||
|
it makes some sense to go above t=2 if you expect that your users might
|
||||||
|
not be able to afford more memory but can afford more time. However,
|
||||||
|
increasing the memory usage provides better protection, and we don't
|
||||||
|
recommend forcing your users to wait for more than 1 second as they
|
||||||
|
could as well type more characters in that time. If this feels too
|
||||||
|
complicated, just use one of the above parameter sets as-is.
|
||||||
|
|
||||||
|
|
||||||
|
Amortization of memory allocation overhead.
|
||||||
|
|
||||||
|
It takes a significant fraction of yescrypt's total running time to
|
||||||
|
allocate memory from the operating system, especially considering that
|
||||||
|
the kernel zeroizes the memory before handing it over to your program.
|
||||||
|
|
||||||
|
Unless you naturally need to compute yescrypt just once per process, you
|
||||||
|
may achieve greater efficiency by fully using advanced yescrypt APIs
|
||||||
|
that let you preserve and reuse the memory allocation across yescrypt
|
||||||
|
invocations. This is done by reusing the structure pointed to by the
|
||||||
|
"yescrypt_local_t *local" argument of yescrypt_r() or yescrypt_kdf()
|
||||||
|
without calling yescrypt_free_local() inbetween the repeated invocations
|
||||||
|
of yescrypt.
|
||||||
|
|
||||||
|
|
||||||
|
YESCRYPT_DEFAULTS macro.
|
||||||
|
|
||||||
|
Please note that the value of the YESCRYPT_DEFAULTS macro might change
|
||||||
|
later, so if you use the macro like it's recommended here then for
|
||||||
|
results reproducible across versions you might need to store its value
|
||||||
|
somewhere along with the hashes or the encrypted data.
|
||||||
|
|
||||||
|
If you use yescrypt's standard hash string encoding, then yescrypt
|
||||||
|
already encodes and decodes this value for you, so you don't need to
|
||||||
|
worry about this.
|
206
deps/yescrypt-master/PERFORMANCE
vendored
Normal file
206
deps/yescrypt-master/PERFORMANCE
vendored
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
Although yescrypt is usable for a variety of purposes (password hashing,
|
||||||
|
KDF, PoW) and is extremely scalable (from 1 CPU core to many, from
|
||||||
|
kilobytes to terabytes and beyond) while achieving good security
|
||||||
|
properties across this whole range of use cases and settings, at this
|
||||||
|
time we're primarily targeting the mass user authentication use case.
|
||||||
|
Hence, this is what the setup and benchmarks shown in here focus on.
|
||||||
|
|
||||||
|
The test system is a server (kindly provided by Packet.net) with dual
|
||||||
|
Xeon Gold 5120 CPUs (2.2 GHz, turbo to up to 3.2 GHz) and 384 GiB RAM
|
||||||
|
(12x DDR4-2400 ECC Reg). These CPUs have 14 cores and 6 memory channels
|
||||||
|
each, for a total of 28 physical cores, 56 logical CPUs (HT is enabled),
|
||||||
|
and 12 memory channels. The OS is Ubuntu 17.10 with kernel
|
||||||
|
"4.13.0-25-generic #29-Ubuntu SMP Mon Jan 8 21:14:41 UTC 2018 x86_64"
|
||||||
|
and compiler "gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0".
|
||||||
|
|
||||||
|
First, we need to configure the Linux system, as root. Grant our user
|
||||||
|
account's group the privilege to access "huge pages" (2 MiB or 1 GiB as
|
||||||
|
opposed to x86's default 4 KiB pages):
|
||||||
|
|
||||||
|
# sysctl -w vm.hugetlb_shm_group=1000
|
||||||
|
|
||||||
|
(You may need to replace the "1000" with your user account's actual
|
||||||
|
group id.)
|
||||||
|
|
||||||
|
Disable swap, so that it doesn't get in the way:
|
||||||
|
|
||||||
|
# swapoff -a
|
||||||
|
|
||||||
|
Let processes allocate shared memory segments of up to 368 GiB each, and
|
||||||
|
up to 369 GiB total for the system:
|
||||||
|
|
||||||
|
# sysctl -w kernel.shmmax=395136991232
|
||||||
|
# sysctl -w kernel.shmall=396210733056
|
||||||
|
|
||||||
|
(The allowance for an extra gigabyte is in case any processes unrelated
|
||||||
|
to ours make use of SysV shared memory as well.)
|
||||||
|
|
||||||
|
Preallocate the 368 GiB and 2 GiB more (to be potentially used for
|
||||||
|
threads' "RAM" lookup tables), thus 370 GiB total, into huge pages (this
|
||||||
|
will only work when existing memory allocations aren't too fragmented
|
||||||
|
yet, so is normally to be performed right upon system bootup):
|
||||||
|
|
||||||
|
# sysctl -w vm.nr_hugepages=189440
|
||||||
|
|
||||||
|
Check that the preallocation has succeeded by examining /proc/meminfo:
|
||||||
|
|
||||||
|
# grep ^Huge /proc/meminfo
|
||||||
|
HugePages_Total: 189440
|
||||||
|
HugePages_Free: 189440
|
||||||
|
|
||||||
|
(If the memory were too fragmented, this would show lower numbers, which
|
||||||
|
would be problematic - worse than no use of huge pages at all.)
|
||||||
|
|
||||||
|
This is quite extreme. Although it sort of leaves 14 GiB free (as the
|
||||||
|
difference between 370 GiB and the physical RAM of 384 GiB), in practice
|
||||||
|
on our test system only less than 5 GiB remains allocatable by user
|
||||||
|
processes after this point. For actual use, you might consider using a
|
||||||
|
slightly lower fraction (than 23/24 that we're targeting here) of total
|
||||||
|
memory for yescrypt ROM, or/and not pre-allocating any huge pages for
|
||||||
|
the RAMs (especially if they won't be used that way anyway, which
|
||||||
|
depends on the HUGEPAGE_THRESHOLD setting in yescrypt-platform.c -
|
||||||
|
currently at 32 MiB).
|
||||||
|
|
||||||
|
Now initialization of the ROM is possible, and we can work as non-root
|
||||||
|
from this point on:
|
||||||
|
|
||||||
|
$ GOMP_CPU_AFFINITY=0-55 time ./initrom 368 1
|
||||||
|
r=23 N=2^9 NROM=2^27
|
||||||
|
Will use 385875968.00 KiB ROM
|
||||||
|
1472.00 KiB RAM
|
||||||
|
Initializing ROM ... DONE (98764b03)
|
||||||
|
'$y$j6K5O$LdJMENpBABJJ3hIHjB1Bi.$VtHhEYlX3mDbxmXUUYt9Xldf.2R5/G0E/tMioNUQ/F8'
|
||||||
|
1058.64user 163.70system 0:22.04elapsed 5544%CPU (0avgtext+0avgdata 4692maxresident)k
|
||||||
|
0inputs+0outputs (0major+193094minor)pagefaults 0swaps
|
||||||
|
|
||||||
|
It took 22 seconds to initialize our 368 GiB ROM, and now we may hash
|
||||||
|
passwords from another process (this may be the authentication service):
|
||||||
|
|
||||||
|
$ GOMP_CPU_AFFINITY=0-55 ./userom 368 1
|
||||||
|
r=23 N=2^9 NROM=2^27
|
||||||
|
Will use 385875968.00 KiB ROM
|
||||||
|
1472.00 KiB RAM
|
||||||
|
Plaintext: '$y$j6K5O$LdJMENpBABJJ3hIHjB1Bi.$VtHhEYlX3mDbxmXUUYt9Xldf.2R5/G0E/tMioNUQ/F8'
|
||||||
|
Encrypted: '$y$j6K5O$LdJMENpBABJJ3hIHjB1Bi.$LZropFwwbIVeo/8DfHbxg6VhFLkUqdvdNy7L.T8tud.'
|
||||||
|
Benchmarking 1 thread ...
|
||||||
|
809 c/s real, 812 c/s virtual (2047 hashes in 2.53 seconds)
|
||||||
|
Benchmarking 56 threads ...
|
||||||
|
21307 c/s real, 384 c/s virtual (114632 hashes in 5.38 seconds)
|
||||||
|
min 1.393 ms, avg 2.591 ms, max 3.628 ms
|
||||||
|
|
||||||
|
$ GOMP_CPU_AFFINITY=0-55 ./userom 368 2
|
||||||
|
r=23 N=2^10 NROM=2^27
|
||||||
|
Will use 385875968.00 KiB ROM
|
||||||
|
2944.00 KiB RAM
|
||||||
|
Plaintext: '$y$j7K5O$LdJMENpBABJJ3hIHjB1Bi.$ljg0jm5/lpMa98qlF1GeAI9YkqWXSA4KVTGxidC6Gy0'
|
||||||
|
Encrypted: '$y$j7K5O$LdJMENpBABJJ3hIHjB1Bi.$7X1fd6TFYK5VQOH.7M2dRJMxvFTZbv5d1i7.GwQ/7YC'
|
||||||
|
Benchmarking 1 thread ...
|
||||||
|
419 c/s real, 420 c/s virtual (1023 hashes in 2.44 seconds)
|
||||||
|
Benchmarking 56 threads ...
|
||||||
|
10248 c/s real, 184 c/s virtual (57288 hashes in 5.59 seconds)
|
||||||
|
min 2.571 ms, avg 5.413 ms, max 6.704 ms
|
||||||
|
|
||||||
|
$ GOMP_CPU_AFFINITY=0-55 ./userom 368 23
|
||||||
|
r=23 N=2^13 NROM=2^27
|
||||||
|
Will use 385875968.00 KiB ROM
|
||||||
|
23552.00 KiB RAM
|
||||||
|
Plaintext: '$y$jAK5O$LdJMENpBABJJ3hIHjB1Bi.$UL29LYGiz.rXa6c620meFuqT3IiZmBO0BlW6HenRmA4'
|
||||||
|
Encrypted: '$y$jAK5O$LdJMENpBABJJ3hIHjB1Bi.$U15LiKcR4vHbUmCbt7SUllXp/jUyNXYOC1I.426Vk80'
|
||||||
|
Benchmarking 1 thread ...
|
||||||
|
50 c/s real, 50 c/s virtual (127 hashes in 2.52 seconds)
|
||||||
|
Benchmarking 56 threads ...
|
||||||
|
1201 c/s real, 21 c/s virtual (7112 hashes in 5.92 seconds)
|
||||||
|
min 32.444 ms, avg 46.362 ms, max 48.067 ms
|
||||||
|
|
||||||
|
While using the ROM, we're able to compute over 21k, over 10k, or around
|
||||||
|
1200 password hashes per second with per-thread RAM sizes of 1.4375 MiB,
|
||||||
|
2.875 MiB, or 23 MiB, respectively.
|
||||||
|
|
||||||
|
We can also reasonably use yescrypt without a ROM:
|
||||||
|
|
||||||
|
$ GOMP_CPU_AFFINITY=0-55 ./userom 0 2
|
||||||
|
r=16 N=2^10 NROM=2^0
|
||||||
|
Will use 0.00 KiB ROM
|
||||||
|
2048.00 KiB RAM
|
||||||
|
Plaintext: '$y$j7D$LdJMENpBABJJ3hIHjB1Bi.$MpcIFGNF/2yn.6pugGKCS3k6Js5sbJ7j3qLBBqKLUk4'
|
||||||
|
Encrypted: '$y$j7D$LdJMENpBABJJ3hIHjB1Bi.$7yuShztNep5CDrsQE9Ms9DkH1zqJzTy8wRiSHozJy.9'
|
||||||
|
Benchmarking 1 thread ...
|
||||||
|
828 c/s real, 828 c/s virtual (2047 hashes in 2.47 seconds)
|
||||||
|
Benchmarking 56 threads ...
|
||||||
|
21710 c/s real, 388 c/s virtual (114632 hashes in 5.28 seconds)
|
||||||
|
min 1.679 ms, avg 2.571 ms, max 3.591 ms
|
||||||
|
|
||||||
|
$ GOMP_CPU_AFFINITY=0-55 ./userom 0 4
|
||||||
|
r=16 N=2^11 NROM=2^0
|
||||||
|
Will use 0.00 KiB ROM
|
||||||
|
4096.00 KiB RAM
|
||||||
|
Plaintext: '$y$j8D$LdJMENpBABJJ3hIHjB1Bi.$dT8UO1PVT6lpQcAuWsreFpgdw9TeYdEkqsCp5syNoL9'
|
||||||
|
Encrypted: '$y$j8D$LdJMENpBABJJ3hIHjB1Bi.$evEI7SjEM6GKYxcIaNYmanAesDLMRezuOfT4V01aj33'
|
||||||
|
Benchmarking 1 thread ...
|
||||||
|
417 c/s real, 417 c/s virtual (1023 hashes in 2.45 seconds)
|
||||||
|
Benchmarking 56 threads ...
|
||||||
|
10434 c/s real, 186 c/s virtual (57288 hashes in 5.49 seconds)
|
||||||
|
min 3.120 ms, avg 5.339 ms, max 6.878 ms
|
||||||
|
|
||||||
|
$ GOMP_CPU_AFFINITY=0-55 ./userom 0 16
|
||||||
|
r=16 N=2^13 NROM=2^0
|
||||||
|
Will use 0.00 KiB ROM
|
||||||
|
16384.00 KiB RAM
|
||||||
|
Plaintext: '$y$jAD$LdJMENpBABJJ3hIHjB1Bi.$Cap65IlIDN8g9Lh0aVhLLWORQhpwxvh0rhkIB6OOpqC'
|
||||||
|
Encrypted: '$y$jAD$LdJMENpBABJJ3hIHjB1Bi.$d5Qoew0sKNt63xBRsAxNDhGV52p1jHAFN1/fglibMbA'
|
||||||
|
Benchmarking 1 thread ...
|
||||||
|
100 c/s real, 100 c/s virtual (255 hashes in 2.54 seconds)
|
||||||
|
Benchmarking 56 threads ...
|
||||||
|
2314 c/s real, 41 c/s virtual (14280 hashes in 6.17 seconds)
|
||||||
|
min 13.440 ms, avg 24.049 ms, max 25.467 ms
|
||||||
|
|
||||||
|
$ GOMP_CPU_AFFINITY=0-55 ./userom 0 32
|
||||||
|
r=16 N=2^14 NROM=2^0
|
||||||
|
Will use 0.00 KiB ROM
|
||||||
|
32768.00 KiB RAM
|
||||||
|
Plaintext: '$y$jBD$LdJMENpBABJJ3hIHjB1Bi.$zdJjnnDFSqeRbC8ZUQFZShGpP2gvFCGjAZ01h10dWa9'
|
||||||
|
Encrypted: '$y$jBD$LdJMENpBABJJ3hIHjB1Bi.$U45EV25V/KtqyetJ7AHsJaeeNTJwvQ3hBG7lokzkyR6'
|
||||||
|
Benchmarking 1 thread ...
|
||||||
|
48 c/s real, 49 c/s virtual (127 hashes in 2.61 seconds)
|
||||||
|
Benchmarking 56 threads ...
|
||||||
|
1136 c/s real, 20 c/s virtual (7112 hashes in 6.26 seconds)
|
||||||
|
min 27.844 ms, avg 48.837 ms, max 50.792 ms
|
||||||
|
|
||||||
|
Slightly higher speeds are possible for 4 MiB and higher with larger
|
||||||
|
yescrypt block size (r=32 instead of r=16, thus 4 KiB blocks instead of
|
||||||
|
2 KiB blocks benchmarked above). Here they are for 4 MiB, 16 MiB, and
|
||||||
|
32 MiB, respectively:
|
||||||
|
|
||||||
|
10589 c/s real, 189 c/s virtual (57288 hashes in 5.41 seconds)
|
||||||
|
min 3.465 ms, avg 5.260 ms, max 6.705 ms
|
||||||
|
|
||||||
|
2462 c/s real, 44 c/s virtual (14280 hashes in 5.80 seconds)
|
||||||
|
min 13.923 ms, avg 22.638 ms, max 24.042 ms
|
||||||
|
|
||||||
|
1221 c/s real, 21 c/s virtual (7112 hashes in 5.82 seconds)
|
||||||
|
min 28.909 ms, avg 45.658 ms, max 47.265 ms
|
||||||
|
|
||||||
|
Thus, when not using a ROM we're able to compute over 21k, over 10k,
|
||||||
|
around 2400, or around 1200 hashes per second with per-thread RAM sizes
|
||||||
|
of 2 MiB, 4 MiB, 16 MiB, or 32 MiB, respectively.
|
||||||
|
|
||||||
|
The same might not hold on another machine.
|
||||||
|
|
||||||
|
By the way, here's what our SysV shared memory segment looks like:
|
||||||
|
|
||||||
|
$ ipcs -m
|
||||||
|
|
||||||
|
------ Shared Memory Segments --------
|
||||||
|
key shmid owner perms bytes nattch status
|
||||||
|
[...]
|
||||||
|
0x7965730a 327683 user 640 395136991232 0
|
||||||
|
|
||||||
|
The 395+ GB size corresponds to 368 GiB.
|
||||||
|
|
||||||
|
To cleanup, let's remove the SysV shared memory segment holding the ROM:
|
||||||
|
|
||||||
|
$ ipcrm -M 0x7965730a
|
||||||
|
|
||||||
|
and free up the preallocated huge pages, as root:
|
||||||
|
|
||||||
|
# sysctl -w vm.nr_hugepages=0
|
1
deps/yescrypt-master/PHC-TEST-OK-SHA256
vendored
Normal file
1
deps/yescrypt-master/PHC-TEST-OK-SHA256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
05ad49b9d9fb9eb65df78c919c3a778b7952e2e63f2e8ddb6b2b3f4b645e3cd0 PHC-TEST-OUT
|
197
deps/yescrypt-master/README
vendored
Normal file
197
deps/yescrypt-master/README
vendored
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
What is yescrypt?
|
||||||
|
|
||||||
|
yescrypt is a password-based key derivation function (KDF) and password
|
||||||
|
hashing scheme. It builds upon Colin Percival's scrypt. This
|
||||||
|
implementation is able to compute native yescrypt hashes as well as
|
||||||
|
classic scrypt.
|
||||||
|
|
||||||
|
As of this writing, yescrypt is the default password hashing scheme on
|
||||||
|
recent ALT Linux, Arch Linux, Debian 11+, Fedora 35+, Kali Linux 2021.1+,
|
||||||
|
and Ubuntu 22.04+. It is also supported in Fedora 29+, RHEL 9+, and
|
||||||
|
Ubuntu 20.04+, and is recommended for new passwords in Fedora CoreOS.
|
||||||
|
|
||||||
|
|
||||||
|
Why yescrypt?
|
||||||
|
|
||||||
|
Like it or not, password authentication remains relevant (including as
|
||||||
|
one of several authentication factors), password hash database leaks
|
||||||
|
happen, the leaks are not always detected and fully dealt with right
|
||||||
|
away, and even once they are many users' same or similar passwords
|
||||||
|
reused elsewhere remain exposed. To mitigate these risks (as well as
|
||||||
|
those present in other scenarios where password-based key derivation or
|
||||||
|
password hashing is relevant), computationally expensive (bcrypt,
|
||||||
|
PBKDF2, etc.) and more recently also memory-hard (scrypt, Argon2, etc.)
|
||||||
|
password hashing schemes have been introduced. Unfortunately, at high
|
||||||
|
target throughput and/or low target latency their memory usage is
|
||||||
|
unreasonably low, up to the point where they're not obviously better
|
||||||
|
than the much older bcrypt (considering attackers with pre-existing
|
||||||
|
hardware). This is a primary drawback that yescrypt addresses.
|
||||||
|
|
||||||
|
Most notable for large-scale deployments is yescrypt's optional
|
||||||
|
initialization and reuse of a large lookup table, typically occupying
|
||||||
|
at least tens of gigabytes of RAM and essentially forming a
|
||||||
|
site-specific ROM. This limits attackers' use of pre-existing hardware
|
||||||
|
such as botnet nodes.
|
||||||
|
|
||||||
|
yescrypt's other changes from scrypt additionally slow down GPUs and to
|
||||||
|
a lesser extent FPGAs and ASICs even when its memory usage is low and
|
||||||
|
even when there's no ROM, and provide extra knobs and built-in features.
|
||||||
|
|
||||||
|
Technically, yescrypt is the most scalable password hashing scheme so
|
||||||
|
far, providing near-optimal security from offline password cracking
|
||||||
|
across the whole range from kilobytes to terabytes and beyond. However,
|
||||||
|
the price for this is complexity, and we recognize that complexity is a
|
||||||
|
major drawback of any software. Thus, at this time we focus on
|
||||||
|
large-scale deployments, where the added complexity is relatively small
|
||||||
|
compared to the total complexity of the authentication service setup.
|
||||||
|
For smaller deployments, bcrypt with its simplicity and existing library
|
||||||
|
support is a reasonable short-term choice (although we're making
|
||||||
|
progress towards more efficient FPGA attacks on bcrypt under a separate
|
||||||
|
project). We might introduce a cut-down yescrypt-lite later or/and
|
||||||
|
yescrypt might become part of standard or popular libraries, making it
|
||||||
|
more suitable for smaller deployments as well.
|
||||||
|
|
||||||
|
|
||||||
|
Parameter selection.
|
||||||
|
|
||||||
|
Please refer to PARAMETERS for guidelines on parameter selection and the
|
||||||
|
currently recommended parameter sets by use case (password hashing with
|
||||||
|
or without a ROM, and KDF).
|
||||||
|
|
||||||
|
|
||||||
|
Performance.
|
||||||
|
|
||||||
|
Please refer to PERFORMANCE for example setup and benchmarks relevant to
|
||||||
|
the mass user authentication use case.
|
||||||
|
|
||||||
|
The test system is a server (kindly provided by Packet.net) with dual
|
||||||
|
Xeon Gold 5120 CPUs (2.2 GHz, turbo to up to 3.2 GHz) and 384 GiB RAM
|
||||||
|
(12x DDR4-2400 ECC Reg). These CPUs have 14 cores and 6 memory channels
|
||||||
|
each, for a total of 28 physical cores, 56 logical CPUs (HT is enabled),
|
||||||
|
and 12 memory channels.
|
||||||
|
|
||||||
|
Some highlights: initialization of a 368 GiB ROM takes 22 seconds (to
|
||||||
|
be done on server bootup), and while using the ROM we're able to compute
|
||||||
|
over 21k, over 10k, or around 1200 hashes per second with per-hash RAM
|
||||||
|
usage of 1.4375 MiB, 2.875 MiB, or 23 MiB, respectively.
|
||||||
|
|
||||||
|
When not using a ROM, we're able to compute over 21k, over 10k, or
|
||||||
|
around 1200 hashes per second with per-hash RAM usage of 2 MiB, 4 MiB,
|
||||||
|
or 32 MiB, respectively.
|
||||||
|
|
||||||
|
|
||||||
|
Comparison to scrypt and Argon2.
|
||||||
|
|
||||||
|
yescrypt's advantages:
|
||||||
|
|
||||||
|
+ Greater resistance to offline attacks
|
||||||
|
+ Extra optional built-in features
|
||||||
|
+ Cryptographic security provided by NIST-approved primitives
|
||||||
|
+ SHA-256, HMAC, PBKDF2, and scrypt are usable from the same codebase
|
||||||
|
|
||||||
|
yescrypt's drawbacks:
|
||||||
|
|
||||||
|
- Complex
|
||||||
|
- Cache-timing unsafe (like scrypt and Argon2d, but unlike Argon2i)
|
||||||
|
- Not the PHC winner (Argon2 is), but is merely a "special recognition"
|
||||||
|
- Supported in fewer third-party projects
|
||||||
|
|
||||||
|
Please refer to COMPARISON for a lot more detail and other observations.
|
||||||
|
|
||||||
|
|
||||||
|
A note on cryptocurrencies.
|
||||||
|
|
||||||
|
For historical reasons, multiple CPU mining focused cryptocurrencies use
|
||||||
|
yescrypt 0.5'ish as their proof-of-work (PoW) scheme. We currently have
|
||||||
|
a separate project for the PoW use case: yespower. Thus, rather than
|
||||||
|
misuse yescrypt 1.0+ for PoW, those and other projects are advised to
|
||||||
|
use yespower 1.0+ instead. The yespower homepage is:
|
||||||
|
|
||||||
|
https://www.openwall.com/yespower/
|
||||||
|
|
||||||
|
|
||||||
|
How to test yescrypt for proper operation.
|
||||||
|
|
||||||
|
On a Unix-like system, invoke "make check". This will build and run a
|
||||||
|
program called "tests", and check its output against the supplied file
|
||||||
|
TESTS-OK. It will also build a program called "phc-test", and if a file
|
||||||
|
called PHC-TEST-OK-SHA256 is present will run that program and check its
|
||||||
|
output against that file's contents. If everything matches, each of
|
||||||
|
these two sets of tests prints one word "PASSED", so there will be two
|
||||||
|
such lines among "make check" output, one of them being the final line
|
||||||
|
of output.
|
||||||
|
|
||||||
|
We do most of our testing on Linux systems with gcc. The supplied
|
||||||
|
Makefile assumes that you use gcc.
|
||||||
|
|
||||||
|
|
||||||
|
ROM in SysV shared memory demo and benchmark.
|
||||||
|
|
||||||
|
Also included with this version of yescrypt are "initrom" and "userom"
|
||||||
|
demo programs. They're built by simply typing "make". Please refer to
|
||||||
|
PERFORMANCE for their usage.
|
||||||
|
|
||||||
|
|
||||||
|
Alternate code versions and make targets.
|
||||||
|
|
||||||
|
Two implementations of yescrypt are included: reference and optimized.
|
||||||
|
By default, the optimized implementation is built. Internally, the
|
||||||
|
optimized implementation uses conditional compilation to choose between
|
||||||
|
usage of various SIMD instruction sets where supported and scalar code.
|
||||||
|
|
||||||
|
The reference implementation is unoptimized and is very slow, but it has
|
||||||
|
simpler and shorter source code. Its purpose is to provide a simple
|
||||||
|
human- and machine-readable specification that implementations intended
|
||||||
|
for actual use should be tested against. It is deliberately mostly not
|
||||||
|
optimized, and it is not meant to be used in production.
|
||||||
|
|
||||||
|
Similarly to "make check", there's "make check-ref" to build and test
|
||||||
|
the reference implementation. There's also "make ref" to build the
|
||||||
|
reference implementation and have the "initrom" and "userom" programs
|
||||||
|
use it.
|
||||||
|
|
||||||
|
"make clean" may need to be run between making different builds.
|
||||||
|
|
||||||
|
|
||||||
|
Development status.
|
||||||
|
|
||||||
|
This yescrypt distribution is a work-in-progress. Its interfaces other
|
||||||
|
than crypto_scrypt() are subject to change in future revisions, however
|
||||||
|
no incompatible changes to the yescrypt algorithm are expected.
|
||||||
|
|
||||||
|
|
||||||
|
Credits.
|
||||||
|
|
||||||
|
scrypt has been designed by Colin Percival. yescrypt has been designed
|
||||||
|
by Solar Designer building upon scrypt.
|
||||||
|
|
||||||
|
The following other people and projects have also indirectly helped make
|
||||||
|
yescrypt what it is:
|
||||||
|
|
||||||
|
- Bill Cox
|
||||||
|
- Rich Felker
|
||||||
|
- Anthony Ferrara
|
||||||
|
- Christian Forler
|
||||||
|
- Taylor Hornby
|
||||||
|
- Dmitry Khovratovich
|
||||||
|
- Samuel Neves
|
||||||
|
- Marcos Simplicio
|
||||||
|
- Ken T Takusagawa
|
||||||
|
- Jakob Wenzel
|
||||||
|
- Christian Winnerlein
|
||||||
|
|
||||||
|
- DARPA Cyber Fast Track
|
||||||
|
- Password Hashing Competition
|
||||||
|
|
||||||
|
|
||||||
|
Contact info.
|
||||||
|
|
||||||
|
First, please check the yescrypt homepage for new versions, etc.:
|
||||||
|
|
||||||
|
https://www.openwall.com/yescrypt/
|
||||||
|
|
||||||
|
If you have anything valuable to add or a non-trivial question to ask,
|
||||||
|
you may join and post to the yescrypt mailing list (referenced on the
|
||||||
|
yescrypt homepage above) or contact the maintainer of yescrypt at:
|
||||||
|
|
||||||
|
Solar Designer <solar at openwall.com>
|
80
deps/yescrypt-master/TESTS-OK
vendored
Normal file
80
deps/yescrypt-master/TESTS-OK
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
scrypt("", "", 16, 1, 1) = 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) = 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) = 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) = 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
|
||||||
|
yescrypt("", "", 0, 16, 1, 1, 0, 0) = 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
|
||||||
|
yescrypt("", "", 0, 16, 1, 1, 0, 0) = 77 d6 57 62 38 65 7b 20
|
||||||
|
yescrypt("", "", 0, 4, 1, 1, 0, 0) = ef ad 0c 23 31 4c b5 72 bc 3c fb 15 43 da 42 f8 a8 b0 73 00 4c 86 6b 64 ab 50 55 a4 f0 9f a5 f5 71 14 2e bf e7 e0 5a 3b 92 c4 32 f3 1d ea 95 ad 5f 9c 85 4b 64 56 46 2f 4b d0 f7 32 b7 cd c5 49
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 0, 0) = 85 dd a4 8c 9e c9 de 2f 7f 1a e8 b4 df ed a5 1f 8b 6d 56 f3 08 1b e1 a7 c0 83 3b a2 71 9a 36 ab 02 88 5d ae 36 55 7d 34 26 86 b1 7b a7 5f 2c 21 77 92 de 09 70 ab 1d 07 a9 c7 50 93 6d 31 42 6f
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 0, 0) = 85 dd a4 8c 9e c9 de 2f
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 1, 0) = 4b aa 8c d8 60 8b a9 1f 3e 34 39 d9 ec 4f ae 8f 9f c0 92 d9 ca 22 b7 37 7e 31 ae 5b 9a d7 87 7c 11 68 69 11 62 dd 0e 5e f0 49 e5 70 65 0c be d4 38 4a d6 05 34 fb 0c be d1 9f f3 f0 33 c9 4b 0c
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 2, 0) = e6 e8 bb a0 9b 64 12 ff b0 b3 cc 35 e3 7d 0b 78 2a 47 fb aa dc 57 a0 76 d7 c6 cc 2e 70 91 9a 1b 8d 47 38 c4 f8 33 55 69 07 42 d9 be d7 1c 3b 8f b0 d7 eb 08 6a b1 34 c5 e5 57 07 c2 c1 3c 75 ef
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 3, 0) = ac d9 a4 20 1c f4 a4 76 ec f7 ba a6 11 3d 86 fb 65 cd 07 10 2b 40 04 e4 f9 d9 9c d3 42 55 a1 08 99 7d 70 ae 0a 64 bf 0a 4d 96 c1 73 ab f8 82 79 c1 a9 4a d9 bd f1 68 ed fb bd 90 f6 6e d5 c8 0d
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 3, 0) = ac d9 a4 20 1c f4 a4 76 ec f7 ba a6 11 3d 86 fb 65 cd 07 10 2b 40 04 e4 f9 d9 9c d3 42 55 a1 08 99
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 3, 0) = ac d9 a4 20 1c f4 a4 76 ec f7 ba a6 11 3d 86 fb 65 cd 07 10 2b 40 04 e4 f9 d9 9c d3 42 55 a1 08
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 3, 0) = ac d9 a4 20 1c f4 a4 76 ec f7 ba a6 11 3d 86 fb 65 cd 07 10 2b 40 04 e4 f9 d9 9c d3 42 55 a1
|
||||||
|
yescrypt("", "", 1, 4, 1, 1, 3, 0) = ac
|
||||||
|
yescrypt("", "", 182, 4, 1, 1, 0, 0) = 0c d5 af 76 eb 24 1d f8 11 9a 9a 12 2a e3 69 20 bc c7 f4 14 b9 c0 d5 8f 45 00 80 60 da de 46 b0 c8 09 22 bd cc 16 a3 ab 5d 20 1d 4c 61 40 c6 71 be 1f 75 27 2c a9 04 73 9d 5a d1 ff 67 2b 0c 21
|
||||||
|
yescrypt("", "", 182, 4, 1, 1, 0, 0) = 0c d5 af 76
|
||||||
|
yescrypt("", "", 182, 4, 1, 1, 1, 0) = 23 b6 ad f0 b6 0c 9a 99 7f 58 58 3d 80 cd a4 8c 63 8c dc 2f 28 9e df 93 a7 08 07 72 5a 0d 35 c4 68 ca 36 2c 55 57 cc 04 b6 81 1e 2e 73 08 41 f5 26 d8 f4 f7 ac fb fa 9e 06 fe 1f 38 3a 71 15 5e
|
||||||
|
yescrypt("", "", 182, 4, 1, 1, 1, 0) = 23 b6 ad f0 b6 0c 9a 99 7f 58 58 3d 80 cd a4 8c 63 8c dc 2f 28 9e df 93 a7 08 07 72 5a 0d 35 c4 68
|
||||||
|
yescrypt("", "", 182, 4, 1, 1, 1, 0) = 23 b6 ad f0 b6 0c 9a 99 7f 58 58 3d 80 cd a4 8c 63 8c dc 2f 28 9e df 93 a7 08 07 72 5a 0d 35 c4
|
||||||
|
yescrypt("", "", 182, 4, 1, 1, 1, 0) = 23 b6 ad f0 b6 0c 9a 99 7f 58 58 3d 80 cd a4 8c 63 8c dc 2f 28 9e df 93 a7 08 07 72 5a 0d 35
|
||||||
|
yescrypt("", "", 182, 4, 1, 1, 1, 0) = 23
|
||||||
|
yescrypt("p", "s", 182, 16, 8, 1, 10, 0) = e1 f9 81 73 3a 94 05 2f cd 7a cb 14 05 df 0b bd e8 e4 99 b6 a1 33 1b 77 59 09 b4 8c 2f 51 6c 40 dc c8 30 16 35 b7 23 7b
|
||||||
|
yescrypt("p", "s", 1, 16, 8, 1, 10, 0) = 9e 7a 40 97 64 42 84 cf 3b 73 b6 04 50 ff 23 0c dc b6 b1 b1 9b 15 09 ee b4 82 f6 96 c4 f1 c7 05 c0 0f 74 02 16 18 3a 12
|
||||||
|
yescrypt("p", "s", 182, 16, 8, 1, 0, 0) = c8 c7 ff 11 22 b0 b2 91 c3 f2 60 89 48 78 2c d6 89 cc 45 57 90 17 aa a5 ff 8b aa 74 a6 32 ec 99 c3 d6 69 30 fb 20 23 bb
|
||||||
|
yescrypt("p", "s", 1, 16, 8, 1, 0, 0) = 9d d6 36 c2 d0 bb 92 34 52 86 ef da f8 a6 8c fc 1b 4f fd c4 b1 ad ac cc 7d 86 4b 9a 67 87 b8 5d 6a e0 f5 28 0d a8 88 9f
|
||||||
|
yescrypt("p", "s", 182, 16, 8, 1, 0, 0) = c8 c7 ff 11 22 b0 b2 91 c3 f2 60 89 48 78 2c d6 89 cc 45 57 90 17 aa a5 ff 8b aa 74 a6 32 ec 99
|
||||||
|
yescrypt("p", "s", 182, 16, 8, 1, 0, 0) = c8 c7 ff 11 22 b0 b2 91
|
||||||
|
'$y$jD5.7$LdJMENpBABJJ3hIHjB1Bi.'
|
||||||
|
Plaintext: '$y$jD5.7$LdJMENpBABJJ3hIHjB1Bi.$HboGM6qPrsK.StKYGt6KErmUYtioHreJd98oIugoNB6'
|
||||||
|
Encrypted: '$y$jD5.7$BkbiDbyWZnzlLWOAcru671$zLAHafRUyp9n9XZWnltUbj3ULWUtMN4fteTltjWkARC'
|
||||||
|
Plaintext: '$y$jC4$LdJMENpBABJJ3hIHjB1B$jVg4HoqqpbmQv/NCpin.QCMagJ8o4QX7lXdzvVV0xFC'
|
||||||
|
Encrypted: '$y$jC4$qiyh2SQgE5vrF3ORvFho$HurI7MuukXHz..TpxrwKuakji/j9VKDh2WVUK4DIsq5'
|
||||||
|
Plaintext: '$y$/B3.6$LdJMENpBABJJ3hIHjB1$h8sE4hJo.BsdlfJr0.d8bNJNPZymH7Y3kLj4aY1Rfc8'
|
||||||
|
Encrypted: '$y$/B3.6$YiN5s/dKpjNrdKm9ND0$lBNMoUaAsw.JR0zMq9IBKIi/VPxj7lD7Sg64nB5LFw2'
|
||||||
|
Plaintext: '$y$/A2$LdJMENpBABJJ3hIHj/$5IEld1eWdmh5lylrqHLF5dvA3ISpimEM9J1Dd05n/.3'
|
||||||
|
Encrypted: '$y$/A2$TqjvmGXoqnsNU/8Y40$ZB43..7UnMt6ySU7XbpPyvyahahHSkJJgztkLWp6/IC'
|
||||||
|
Plaintext: '$y$j91.5$LdJMENpBABJJ3hIH$ebKnn23URD5vyLgF9cP2EvVosrUXf7UErGRV0KmC6e6'
|
||||||
|
Encrypted: '$y$j91.5$bICydADAaInC9UR/$rpsDDkULkr1caCVYV9PNAsiZxijoQ2/gDcbonlowRi7'
|
||||||
|
Plaintext: '$y$j80$LdJMENpBABJJ3h2$ysXVVJwuaVlI1BWoEKt/Bz3WNDDmdOWz/8KTQaHL1cC'
|
||||||
|
Encrypted: '$y$j80$fmxyeGYOC34lh19$mm9FRBs0iHLTHfSNznm1kJVchXN4PaS8hoNI6TTAlB7'
|
||||||
|
Plaintext: '$y$/7/.4$LdJMENpBABJJ3/$lXHleh7bIZMGNtJVxGVrsIWkEIXfBedlfPui/PITflC'
|
||||||
|
Encrypted: '$y$/7/.4$EuTbL3Wtm3khW0$1jvKQzIcAqYnYxfb4TEs.FeAZ7rLDl5vNQEkPPcj2KC'
|
||||||
|
Plaintext: '$y$/6.$LdJMENpBABJJ$zQITmYSih5.CTY47x0IuE4wl.b3HzYGKKCSggakaQ22'
|
||||||
|
Encrypted: '$y$/6.$x0G/jIr053ui$4O.aVGTPptkjx6eXrW8fdvqcPEV28w7a1PSos6CXV31'
|
||||||
|
Plaintext: '$y$j5..3$LdJMENpBAB3$xi27PTUNd8NsChHeLOz85JFnUOyibRHkWzprowRlR5/'
|
||||||
|
Encrypted: '$y$j5..3$/nwg3UXJWp/$5jcvDgeotKpaG9IeSJx0fJNSz33JjTYYD4Kwao3Eki5'
|
||||||
|
Plaintext: '$y$j4/$LdJMENpBA/$tHlkpTQ8V/eEnTVau1uW36T97LIXlfPrEzdeV5SE5K7'
|
||||||
|
Encrypted: '$y$j4/$yoneNBwae0$uPBnH0yXBCOM5v5BU9qlvUUtUr3QD5btS0upc6sdvf4'
|
||||||
|
Plaintext: '$y$/3..2$LdJMENpB$tNczXFuNUd3HMqypStCRsEaL4e4KF7ZYLBe8Hbeg0B7'
|
||||||
|
Encrypted: '$y$/3..2$VD20uHT3$AV5WWaN6bEKRvZlCuurj.mnHMmZmJ9ExQ9HjiReCDwC'
|
||||||
|
Plaintext: '$y$/2/$LdJMEN3$RRorHhfsw1/P/WR6Aurg4U72e9Q7qt9vFPURdyfiqK8'
|
||||||
|
Encrypted: '$y$/2/$BYujKJA$fsMwVvFm8r1caFQP.mem3OUuMYBCDGj9CEoDfSwFDLB'
|
||||||
|
Plaintext: '$y$j2..1$LdJME/$iLEt6kuTwHch6XdCxtTHfsQzYwWFmpUwgl6Ax8RH4d1'
|
||||||
|
Encrypted: '$y$j2..1$.mZga/$X6GFMkoYPxFapo.3H4LllEjltFapONQcKUOdEd9oPa/'
|
||||||
|
Plaintext: '$y$j0/$LdJM$k7BXzSDuoGHW56SY3HxROCiA0gWRscZe2aA0q5oHPM0'
|
||||||
|
Encrypted: '$y$j0/$SkNZ$DQ06H0br45bpE7lGgCD9gOxTMP9SsO6Mt1T9lo5PHz1'
|
||||||
|
Plaintext: '$y$//..0$Ld3$6BJXezMFxaMiO5wsuoEmztvtCs/79085dZO56ADlV5B'
|
||||||
|
Encrypted: '$y$//..0$lM1$60gjeUIW/3QidfN6zU9NqB09Ni1NBMfj2VaSZMjDd18'
|
||||||
|
Plaintext: '$y$///$L/$Rrrkp6OVljrIk0kcwkCDhAiHJiSthh3cKeIGHUW7Z0C'
|
||||||
|
Encrypted: '$y$///$q.$/.tR4GqigxciLYGoB8fmzudWQR7IzSu9s3dR8wp3VsD'
|
||||||
|
Plaintext: '$y$j1../$LdJMENpBABJJ3hIHjB1Bi.$L8OQFc8mxJPd7CpUFgkS7KqJM2I9jGXu3BdqX2D.647'
|
||||||
|
Encrypted: '$y$j1../$BkbiDbyWZnzlLWOAcru671$iicGI2gNZyhimPVgz2VoKrJAB9fWykBN.3Mh0AwEy29'
|
||||||
|
Plaintext: '$y$j//$LdJMENpBABJJ3hIHjB1B$U8a2MaK.yesqWySK8Owk6PWeWmp/XuagMbpP45q1/q1'
|
||||||
|
Encrypted: '$y$j//$qiyh2SQgE5vrF3ORvFho$5dD9ick8ugystfp8wa3xbV7ASDux0dpoOh0QJxFuXH5'
|
||||||
|
'$7$C6..../....SodiumChloride$kBGj9fHznVYFQMEn/qDCfrDevf9YDtcDdKvEqHJLV8D'
|
||||||
|
'$7$06..../....SodiumChloride$ENlyo6fGw4PCcDBOFepfSZjFUnVatHzCcW55.ZGz3B0'
|
||||||
|
r=8 N=2^11 NROM=2^18
|
||||||
|
Will use 262144.00 KiB ROM
|
||||||
|
2048.00 KiB RAM
|
||||||
|
Initializing ROM ... DONE (696ebab2)
|
||||||
|
'$y$j8567F$LdJMENpBABJJ3hIHjB1Bi.'
|
||||||
|
'$y$j8567F$LdJMENpBABJJ3hIHjB1Bi.$4XJGTsv75AjIN60Z31kPN3.86vkCYzIq7LMz2Pb2lC.'
|
||||||
|
Initializing ROM in preallocated memory ... DONE (696ebab2)
|
||||||
|
'$y$j8567F$LdJMENpBABJJ3hIHjB1Bi.$4XJGTsv75AjIN60Z31kPN3.86vkCYzIq7LMz2Pb2lC.'
|
||||||
|
'$y$j8567F$LdJMENpBABJJ3hIHjB1Bi.$K3wFVK9/t3QsjCk/oK2s8dKzzZ4m7QTP8Ms5uywhWv8'
|
||||||
|
'$y$j8567F$LdJMENpBABJJ3ZIHjB1Bi.$/OnmIkP0UK5OxyxD0Af/V1oL0zWvTLAUWg3Nr0bsFEB'
|
||||||
|
'$y$j8567F$LdJMENpBABJJ3ZIHjB1Bi.$DskEGULspNduIZVFK5SOK8enlXnSs/vkuXFdi0wkQ1.'
|
||||||
|
'$y$j/.5I$LdJMENpBABJJ3hIHjB1Bi.$NqCMKxN9Y9Uw821.72ScGDMpyk7U7V51qnHSRPapzW8'
|
217
deps/yescrypt-master/initrom.c
vendored
Normal file
217
deps/yescrypt-master/initrom.c
vendored
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2013-2018 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define YESCRYPT_FLAGS YESCRYPT_DEFAULTS
|
||||||
|
|
||||||
|
#define ROM_SHM_KEY 0x7965730a
|
||||||
|
#define ROM_LOCAL_PARAM "change this before use"
|
||||||
|
|
||||||
|
/* Maximum parallelism factor during ROM initialization */
|
||||||
|
#define YESCRYPT_PROM_SHM 112
|
||||||
|
#define YESCRYPT_PROM_FILE 4
|
||||||
|
|
||||||
|
//#define USE_HUGEPAGE
|
||||||
|
//#define DUMP_SHARED
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h> /* for atoi() */
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "yescrypt.h"
|
||||||
|
|
||||||
|
int main(int argc, const char * const *argv)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
uint64_t rom_bytes = 112 * (1024ULL*1024*1024);
|
||||||
|
uint64_t ram_bytes = 1 * (1024ULL*1024);
|
||||||
|
#else
|
||||||
|
uint64_t rom_bytes = 3 * (1024ULL*1024*1024);
|
||||||
|
uint64_t ram_bytes = 2 * (1024ULL*1024);
|
||||||
|
#endif
|
||||||
|
uint32_t r, min_r;
|
||||||
|
uint64_t NROM_log2, N_log2;
|
||||||
|
int shmid;
|
||||||
|
yescrypt_shared_t shared;
|
||||||
|
yescrypt_binary_t *digest;
|
||||||
|
const char *rom_filename = NULL;
|
||||||
|
int rom_fd;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
rom_bytes = atoi(argv[1]) * (1024ULL*1024*1024);
|
||||||
|
if (argc > 2)
|
||||||
|
ram_bytes = atoi(argv[2]) * (1024ULL*1024);
|
||||||
|
if (argc > 3)
|
||||||
|
rom_filename = argv[3];
|
||||||
|
|
||||||
|
if (!rom_bytes) {
|
||||||
|
puts("Wrong ROM size requested");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
min_r = 9;
|
||||||
|
if (rom_filename)
|
||||||
|
min_r = 8 * 256;
|
||||||
|
|
||||||
|
NROM_log2 = 0;
|
||||||
|
while (((rom_bytes >> NROM_log2) & 0xff) == 0)
|
||||||
|
NROM_log2++;
|
||||||
|
r = rom_bytes >> (7 + NROM_log2);
|
||||||
|
while (r < min_r && NROM_log2 > 0) {
|
||||||
|
r <<= 1;
|
||||||
|
NROM_log2--;
|
||||||
|
}
|
||||||
|
rom_bytes = (uint64_t)r << (7 + NROM_log2);
|
||||||
|
|
||||||
|
N_log2 = 3;
|
||||||
|
while (((uint64_t)r << (7 + N_log2)) < ram_bytes)
|
||||||
|
N_log2++;
|
||||||
|
ram_bytes = (uint64_t)r << (7 + N_log2);
|
||||||
|
|
||||||
|
printf("r=%u N=2^%u NROM=2^%u\n", r,
|
||||||
|
(unsigned int)N_log2, (unsigned int)NROM_log2);
|
||||||
|
|
||||||
|
printf("Will use %.2f KiB ROM\n", rom_bytes / 1024.0);
|
||||||
|
printf(" %.2f KiB RAM\n", ram_bytes / 1024.0);
|
||||||
|
|
||||||
|
shared.aligned_size = rom_bytes;
|
||||||
|
|
||||||
|
if (rom_filename) {
|
||||||
|
rom_fd = open(rom_filename, O_CREAT|O_RDWR|O_EXCL,
|
||||||
|
S_IRUSR|S_IRGRP|S_IWUSR);
|
||||||
|
if (rom_fd < 0) {
|
||||||
|
perror("open");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ftruncate(rom_fd, rom_bytes)) {
|
||||||
|
perror("ftruncate");
|
||||||
|
close(rom_fd);
|
||||||
|
unlink(rom_filename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flags =
|
||||||
|
#ifdef MAP_NOCORE
|
||||||
|
MAP_NOCORE |
|
||||||
|
#endif
|
||||||
|
#if defined(MAP_HUGETLB) && defined(USE_HUGEPAGE)
|
||||||
|
MAP_HUGETLB |
|
||||||
|
#endif
|
||||||
|
MAP_SHARED;
|
||||||
|
void *p = mmap(NULL, rom_bytes, PROT_READ | PROT_WRITE,
|
||||||
|
flags, rom_fd, 0);
|
||||||
|
#if defined(MAP_HUGETLB) && defined(USE_HUGEPAGE)
|
||||||
|
if (p == MAP_FAILED)
|
||||||
|
p = mmap(NULL, rom_bytes, PROT_READ | PROT_WRITE,
|
||||||
|
flags & ~MAP_HUGETLB, rom_fd, 0);
|
||||||
|
#endif
|
||||||
|
if (p == MAP_FAILED) {
|
||||||
|
perror("mmap");
|
||||||
|
close(rom_fd);
|
||||||
|
unlink(rom_filename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
close(rom_fd);
|
||||||
|
shared.base = shared.aligned = p;
|
||||||
|
} else {
|
||||||
|
shmid = shmget(ROM_SHM_KEY, shared.aligned_size,
|
||||||
|
#ifdef SHM_HUGETLB
|
||||||
|
SHM_HUGETLB |
|
||||||
|
#endif
|
||||||
|
IPC_CREAT|IPC_EXCL | S_IRUSR|S_IRGRP|S_IWUSR);
|
||||||
|
if (shmid == -1) {
|
||||||
|
#ifdef SHM_HUGETLB
|
||||||
|
perror("shmget");
|
||||||
|
puts("Retrying without SHM_HUGETLB");
|
||||||
|
shmid = shmget(ROM_SHM_KEY, shared.aligned_size,
|
||||||
|
IPC_CREAT|IPC_EXCL | S_IRUSR|S_IRGRP|S_IWUSR);
|
||||||
|
#endif
|
||||||
|
if (shmid == -1) {
|
||||||
|
perror("shmget");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shared.base = shared.aligned = shmat(shmid, NULL, 0);
|
||||||
|
if (shared.base == (void *)-1) {
|
||||||
|
int save_errno = errno;
|
||||||
|
shmctl(shmid, IPC_RMID, NULL);
|
||||||
|
errno = save_errno;
|
||||||
|
perror("shmat");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Initializing ROM ...");
|
||||||
|
fflush(stdout);
|
||||||
|
yescrypt_params_t rom_params = {
|
||||||
|
.flags = YESCRYPT_DEFAULTS | YESCRYPT_SHARED_PREALLOCATED,
|
||||||
|
.NROM = (uint64_t)1 << NROM_log2,
|
||||||
|
.r = r,
|
||||||
|
.p = rom_filename ? YESCRYPT_PROM_FILE : YESCRYPT_PROM_SHM };
|
||||||
|
if (yescrypt_init_shared(&shared,
|
||||||
|
(uint8_t *)ROM_LOCAL_PARAM, strlen(ROM_LOCAL_PARAM),
|
||||||
|
&rom_params)) {
|
||||||
|
puts(" FAILED");
|
||||||
|
if (rom_filename)
|
||||||
|
unlink(rom_filename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#ifdef DUMP_SHARED
|
||||||
|
fwrite(shared.aligned, shared.aligned_size, 1, stderr);
|
||||||
|
#endif
|
||||||
|
digest = yescrypt_digest_shared(&shared);
|
||||||
|
printf(" DONE (%02x%02x%02x%02x)\n",
|
||||||
|
digest->uc[0], digest->uc[1], digest->uc[2], digest->uc[3]);
|
||||||
|
|
||||||
|
{
|
||||||
|
yescrypt_local_t local;
|
||||||
|
const uint8_t *setting;
|
||||||
|
uint8_t hash[128];
|
||||||
|
|
||||||
|
if (yescrypt_init_local(&local)) {
|
||||||
|
puts("yescrypt_init_local() FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
yescrypt_params_t params = rom_params;
|
||||||
|
params.flags = YESCRYPT_FLAGS;
|
||||||
|
params.N = (uint64_t)1 << N_log2;
|
||||||
|
params.p = 1;
|
||||||
|
setting = yescrypt_encode_params(¶ms,
|
||||||
|
(const uint8_t *)"WZaPV7LSUEKMo34.", 16);
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt_r(&shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13, setting, NULL,
|
||||||
|
hash, sizeof(hash)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rom_filename && munmap(shared.base, rom_bytes)) {
|
||||||
|
perror("munmap");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
49
deps/yescrypt-master/insecure_memzero.c
vendored
Normal file
49
deps/yescrypt-master/insecure_memzero.c
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2014 Colin Percival
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SKIP_MEMZERO
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "insecure_memzero.h"
|
||||||
|
|
||||||
|
/* Function which does the zeroing. */
|
||||||
|
static void
|
||||||
|
insecure_memzero_func(volatile void * buf, size_t len)
|
||||||
|
{
|
||||||
|
volatile uint8_t * _buf = buf;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
_buf[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pointer to memory-zeroing function. */
|
||||||
|
void (* volatile insecure_memzero_ptr)(volatile void *, size_t) =
|
||||||
|
insecure_memzero_func;
|
||||||
|
|
||||||
|
#endif
|
69
deps/yescrypt-master/insecure_memzero.h
vendored
Normal file
69
deps/yescrypt-master/insecure_memzero.h
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2014 Colin Percival
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INSECURE_MEMZERO_H_
|
||||||
|
#define _INSECURE_MEMZERO_H_
|
||||||
|
|
||||||
|
#ifdef SKIP_MEMZERO
|
||||||
|
#define insecure_memzero(buf, len) /* empty */
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Pointer to memory-zeroing function. */
|
||||||
|
extern void (* volatile insecure_memzero_ptr)(volatile void *, size_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insecure_memzero(buf, len):
|
||||||
|
* Attempt to zero ${len} bytes at ${buf} in spite of optimizing compilers'
|
||||||
|
* best (standards-compliant) attempts to remove the buffer-zeroing. In
|
||||||
|
* particular, to avoid performing the zeroing, a compiler would need to
|
||||||
|
* use optimistic devirtualization; recognize that non-volatile objects do not
|
||||||
|
* need to be treated as volatile, even if they are accessed via volatile
|
||||||
|
* qualified pointers; and perform link-time optimization; in addition to the
|
||||||
|
* dead-code elimination which often causes buffer-zeroing to be elided.
|
||||||
|
*
|
||||||
|
* Note however that zeroing a buffer does not guarantee that the data held
|
||||||
|
* in the buffer is not stored elsewhere; in particular, there may be copies
|
||||||
|
* held in CPU registers or in anonymous allocations on the stack, even if
|
||||||
|
* every named variable is successfully sanitized. Solving the "wipe data
|
||||||
|
* from the system" problem will require a C language extension which does not
|
||||||
|
* yet exist.
|
||||||
|
*
|
||||||
|
* For more information, see:
|
||||||
|
* http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
|
||||||
|
* http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
insecure_memzero(volatile void * buf, size_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
(insecure_memzero_ptr)(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_INSECURE_MEMZERO_H_ */
|
145
deps/yescrypt-master/phc.c
vendored
Normal file
145
deps/yescrypt-master/phc.c
vendored
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2014-2016,2018 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define YESCRYPT_FLAGS YESCRYPT_DEFAULTS
|
||||||
|
#define YESCRYPT_BASE_N 8
|
||||||
|
#define YESCRYPT_R 8
|
||||||
|
#define YESCRYPT_P 1
|
||||||
|
|
||||||
|
#include "yescrypt.h"
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
static
|
||||||
|
#endif
|
||||||
|
int PHS(void *out, size_t outlen, const void *in, size_t inlen,
|
||||||
|
const void *salt, size_t saltlen, unsigned int t_cost, unsigned int m_cost)
|
||||||
|
{
|
||||||
|
yescrypt_local_t local;
|
||||||
|
yescrypt_params_t params = {
|
||||||
|
.flags = YESCRYPT_FLAGS,
|
||||||
|
.N = (uint64_t)YESCRYPT_BASE_N << m_cost,
|
||||||
|
.r = YESCRYPT_R,
|
||||||
|
.p = YESCRYPT_P,
|
||||||
|
.t = t_cost,
|
||||||
|
.g = 0 };
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (yescrypt_init_local(&local))
|
||||||
|
return -1;
|
||||||
|
retval = yescrypt_kdf(NULL, &local, in, inlen, salt, saltlen, ¶ms,
|
||||||
|
out, outlen);
|
||||||
|
if (yescrypt_free_local(&local))
|
||||||
|
return -1;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h> /* for sysconf() */
|
||||||
|
#include <sys/times.h>
|
||||||
|
|
||||||
|
static void print_hex(const uint8_t *buf, size_t buflen, const char *sep)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
putchar('"');
|
||||||
|
for (i = 0; i < buflen; i++)
|
||||||
|
printf("\\x%02x", buf[i]);
|
||||||
|
printf("\"%s", sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_PHS(const void *in, size_t inlen,
|
||||||
|
const void *salt, size_t saltlen, unsigned int t_cost, unsigned int m_cost)
|
||||||
|
{
|
||||||
|
uint8_t dk[32];
|
||||||
|
|
||||||
|
printf("PHS(");
|
||||||
|
print_hex(in, inlen, ", ");
|
||||||
|
print_hex(salt, saltlen, ", ");
|
||||||
|
printf("%u, %u) = ", t_cost, m_cost);
|
||||||
|
|
||||||
|
if (PHS(dk, sizeof(dk), in, inlen, salt, saltlen, t_cost, m_cost)) {
|
||||||
|
puts("FAILED");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_hex(dk, sizeof(dk), "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_all_PHS(unsigned int t_cost, unsigned int m_cost)
|
||||||
|
{
|
||||||
|
clock_t clk_tck = sysconf(_SC_CLK_TCK);
|
||||||
|
struct tms start_tms, end_tms;
|
||||||
|
clock_t start = times(&start_tms), end, start_v, end_v;
|
||||||
|
const size_t count = 0x102;
|
||||||
|
size_t inlen, i, j;
|
||||||
|
|
||||||
|
inlen = 0;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
uint8_t in[128], salt[16];
|
||||||
|
|
||||||
|
for (j = 0; j < inlen; j++)
|
||||||
|
in[j] = (i + j) & 0xff;
|
||||||
|
for (j = 0; j < sizeof(salt); j++)
|
||||||
|
salt[j] = ~(i + j) & 0xff;
|
||||||
|
|
||||||
|
print_PHS(in, inlen, salt, sizeof(salt), t_cost, m_cost);
|
||||||
|
|
||||||
|
if (++inlen > sizeof(in))
|
||||||
|
inlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = times(&end_tms);
|
||||||
|
|
||||||
|
start_v = start_tms.tms_utime + start_tms.tms_stime +
|
||||||
|
start_tms.tms_cutime + start_tms.tms_cstime;
|
||||||
|
end_v = end_tms.tms_utime + end_tms.tms_stime +
|
||||||
|
end_tms.tms_cutime + end_tms.tms_cstime;
|
||||||
|
|
||||||
|
if (end == start)
|
||||||
|
end++;
|
||||||
|
if (end_v == start_v)
|
||||||
|
end_v++;
|
||||||
|
|
||||||
|
fprintf(stderr, "m_cost=%u (%.0f KiB), t_cost=%u\n"
|
||||||
|
"%llu c/s real, %llu c/s virtual (%llu hashes in %.2f seconds)\n",
|
||||||
|
m_cost, (YESCRYPT_BASE_N << m_cost) * YESCRYPT_R / 8.0, t_cost,
|
||||||
|
(unsigned long long)count * clk_tck / (end - start),
|
||||||
|
(unsigned long long)count * clk_tck / (end_v - start_v),
|
||||||
|
(unsigned long long)count, (double)(end - start) / clk_tck);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
print_all_PHS(0, 0);
|
||||||
|
print_all_PHS(0, 7);
|
||||||
|
print_all_PHS(0, 8);
|
||||||
|
print_all_PHS(1, 8);
|
||||||
|
print_all_PHS(2, 8);
|
||||||
|
print_all_PHS(3, 8);
|
||||||
|
print_all_PHS(0, 11);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
652
deps/yescrypt-master/sha256.c
vendored
Normal file
652
deps/yescrypt-master/sha256.c
vendored
Normal file
@ -0,0 +1,652 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2005-2016 Colin Percival
|
||||||
|
* Copyright 2016-2018,2021 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "insecure_memzero.h"
|
||||||
|
#include "sysendian.h"
|
||||||
|
|
||||||
|
#include "sha256.h"
|
||||||
|
|
||||||
|
#ifdef __ICC
|
||||||
|
/* Miscompile with icc 14.0.0 (at least), so don't use restrict there */
|
||||||
|
#define restrict
|
||||||
|
#elif __STDC_VERSION__ >= 199901L
|
||||||
|
/* Have restrict */
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define restrict __restrict
|
||||||
|
#else
|
||||||
|
#define restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode a length len*2 vector of (uint32_t) into a length len*8 vector of
|
||||||
|
* (uint8_t) in big-endian form.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Encode vector, two words at a time. */
|
||||||
|
do {
|
||||||
|
be32enc(&dst[0], src[0]);
|
||||||
|
be32enc(&dst[4], src[1]);
|
||||||
|
src += 2;
|
||||||
|
dst += 8;
|
||||||
|
} while (--len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode a big-endian length len*8 vector of (uint8_t) into a length
|
||||||
|
* len*2 vector of (uint32_t).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Decode vector, two words at a time. */
|
||||||
|
do {
|
||||||
|
dst[0] = be32dec(&src[0]);
|
||||||
|
dst[1] = be32dec(&src[4]);
|
||||||
|
src += 8;
|
||||||
|
dst += 2;
|
||||||
|
} while (--len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
#if 1 /* Explicit caching/reuse of common subexpression between rounds */
|
||||||
|
#define Maj(x, y, z) (y ^ ((x_xor_y = x ^ y) & y_xor_z))
|
||||||
|
#else /* Let the compiler cache/reuse or not */
|
||||||
|
#define Maj(x, y, z) (y ^ ((x ^ y) & (y ^ z)))
|
||||||
|
#endif
|
||||||
|
#define SHR(x, n) (x >> n)
|
||||||
|
#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
|
||||||
|
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
|
||||||
|
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
|
||||||
|
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
|
||||||
|
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
|
||||||
|
|
||||||
|
/* SHA256 round function */
|
||||||
|
#define RND(a, b, c, d, e, f, g, h, k) \
|
||||||
|
h += S1(e) + Ch(e, f, g) + k; \
|
||||||
|
d += h; \
|
||||||
|
h += S0(a) + Maj(a, b, c); \
|
||||||
|
y_xor_z = x_xor_y;
|
||||||
|
|
||||||
|
/* Adjusted round function for rotating state */
|
||||||
|
#define RNDr(S, W, i, ii) \
|
||||||
|
RND(S[(64 - i) % 8], S[(65 - i) % 8], \
|
||||||
|
S[(66 - i) % 8], S[(67 - i) % 8], \
|
||||||
|
S[(68 - i) % 8], S[(69 - i) % 8], \
|
||||||
|
S[(70 - i) % 8], S[(71 - i) % 8], \
|
||||||
|
W[i + ii] + Krnd[i + ii])
|
||||||
|
|
||||||
|
/* Message schedule computation */
|
||||||
|
#define MSCH(W, ii, i) \
|
||||||
|
W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA256 block compression function. The 256-bit state is transformed via
|
||||||
|
* the 512-bit input block to produce a new state.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
SHA256_Transform(uint32_t state[static restrict 8],
|
||||||
|
const uint8_t block[static restrict 64],
|
||||||
|
uint32_t W[static restrict 64], uint32_t S[static restrict 8])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* 1. Prepare the first part of the message schedule W. */
|
||||||
|
be32dec_vect(W, block, 8);
|
||||||
|
|
||||||
|
/* 2. Initialize working variables. */
|
||||||
|
memcpy(S, state, 32);
|
||||||
|
|
||||||
|
/* 3. Mix. */
|
||||||
|
for (i = 0; i < 64; i += 16) {
|
||||||
|
uint32_t x_xor_y, y_xor_z = S[(65 - i) % 8] ^ S[(66 - i) % 8];
|
||||||
|
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. */
|
||||||
|
state[0] += S[0];
|
||||||
|
state[1] += S[1];
|
||||||
|
state[2] += S[2];
|
||||||
|
state[3] += S[3];
|
||||||
|
state[4] += S[4];
|
||||||
|
state[5] += S[5];
|
||||||
|
state[6] += S[6];
|
||||||
|
state[7] += S[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint8_t PAD[64] = {
|
||||||
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Add padding and terminating bit-count. */
|
||||||
|
static void
|
||||||
|
SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[static restrict 72])
|
||||||
|
{
|
||||||
|
size_t r;
|
||||||
|
|
||||||
|
/* Figure out how many bytes we have buffered. */
|
||||||
|
r = (ctx->count >> 3) & 0x3f;
|
||||||
|
|
||||||
|
/* Pad to 56 mod 64, transforming if we finish a block en route. */
|
||||||
|
if (r < 56) {
|
||||||
|
/* Pad to 56 mod 64. */
|
||||||
|
memcpy(&ctx->buf[r], PAD, 56 - r);
|
||||||
|
} else {
|
||||||
|
/* Finish the current block and mix. */
|
||||||
|
memcpy(&ctx->buf[r], PAD, 64 - r);
|
||||||
|
SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
|
||||||
|
|
||||||
|
/* The start of the final block is all zeroes. */
|
||||||
|
memset(&ctx->buf[0], 0, 56);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the terminating bit-count. */
|
||||||
|
be64enc(&ctx->buf[56], ctx->count);
|
||||||
|
|
||||||
|
/* Mix in the final block. */
|
||||||
|
SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Magic initialization constants. */
|
||||||
|
static const uint32_t initial_state[8] = {
|
||||||
|
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
||||||
|
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA256_Init(ctx):
|
||||||
|
* Initialize the SHA256 context ${ctx}.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SHA256_Init(SHA256_CTX * ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Zero bits processed so far. */
|
||||||
|
ctx->count = 0;
|
||||||
|
|
||||||
|
/* Initialize state. */
|
||||||
|
memcpy(ctx->state, initial_state, sizeof(initial_state));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA256_Update(ctx, in, len):
|
||||||
|
* Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len,
|
||||||
|
uint32_t tmp32[static restrict 72])
|
||||||
|
{
|
||||||
|
uint32_t r;
|
||||||
|
const uint8_t * src = in;
|
||||||
|
|
||||||
|
/* Return immediately if we have nothing to do. */
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Number of bytes left in the buffer from previous updates. */
|
||||||
|
r = (ctx->count >> 3) & 0x3f;
|
||||||
|
|
||||||
|
/* Update number of bits. */
|
||||||
|
ctx->count += (uint64_t)(len) << 3;
|
||||||
|
|
||||||
|
/* Handle the case where we don't need to perform any transforms. */
|
||||||
|
if (len < 64 - r) {
|
||||||
|
memcpy(&ctx->buf[r], src, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish the current block. */
|
||||||
|
memcpy(&ctx->buf[r], src, 64 - r);
|
||||||
|
SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
|
||||||
|
src += 64 - r;
|
||||||
|
len -= 64 - r;
|
||||||
|
|
||||||
|
/* Perform complete blocks. */
|
||||||
|
while (len >= 64) {
|
||||||
|
SHA256_Transform(ctx->state, src, &tmp32[0], &tmp32[64]);
|
||||||
|
src += 64;
|
||||||
|
len -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy left over data into buffer. */
|
||||||
|
memcpy(ctx->buf, src, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper function for intermediate-values sanitization. */
|
||||||
|
void
|
||||||
|
SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len)
|
||||||
|
{
|
||||||
|
uint32_t tmp32[72];
|
||||||
|
|
||||||
|
/* Call the real function. */
|
||||||
|
_SHA256_Update(ctx, in, len, tmp32);
|
||||||
|
|
||||||
|
/* Clean the stack. */
|
||||||
|
insecure_memzero(tmp32, 288);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA256_Final(digest, ctx):
|
||||||
|
* Output the SHA256 hash of the data input to the context ${ctx} into the
|
||||||
|
* buffer ${digest}.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx,
|
||||||
|
uint32_t tmp32[static restrict 72])
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Add padding. */
|
||||||
|
SHA256_Pad(ctx, tmp32);
|
||||||
|
|
||||||
|
/* Write the hash. */
|
||||||
|
be32enc_vect(digest, ctx->state, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper function for intermediate-values sanitization. */
|
||||||
|
void
|
||||||
|
SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx)
|
||||||
|
{
|
||||||
|
uint32_t tmp32[72];
|
||||||
|
|
||||||
|
/* Call the real function. */
|
||||||
|
_SHA256_Final(digest, ctx, tmp32);
|
||||||
|
|
||||||
|
/* Clear the context state. */
|
||||||
|
insecure_memzero(ctx, sizeof(SHA256_CTX));
|
||||||
|
|
||||||
|
/* Clean the stack. */
|
||||||
|
insecure_memzero(tmp32, 288);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA256_Buf(in, len, digest):
|
||||||
|
* Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SHA256_Buf(const void * in, size_t len, uint8_t digest[32])
|
||||||
|
{
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
uint32_t tmp32[72];
|
||||||
|
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
_SHA256_Update(&ctx, in, len, tmp32);
|
||||||
|
_SHA256_Final(digest, &ctx, tmp32);
|
||||||
|
|
||||||
|
/* Clean the stack. */
|
||||||
|
insecure_memzero(&ctx, sizeof(SHA256_CTX));
|
||||||
|
insecure_memzero(tmp32, 288);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_SHA256_Init(ctx, K, Klen):
|
||||||
|
* Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
|
||||||
|
* ${K}.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen,
|
||||||
|
uint32_t tmp32[static restrict 72], uint8_t pad[static restrict 64],
|
||||||
|
uint8_t khash[static restrict 32])
|
||||||
|
{
|
||||||
|
const uint8_t * K = _K;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* If Klen > 64, the key is really SHA256(K). */
|
||||||
|
if (Klen > 64) {
|
||||||
|
SHA256_Init(&ctx->ictx);
|
||||||
|
_SHA256_Update(&ctx->ictx, K, Klen, tmp32);
|
||||||
|
_SHA256_Final(khash, &ctx->ictx, tmp32);
|
||||||
|
K = khash;
|
||||||
|
Klen = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
|
||||||
|
SHA256_Init(&ctx->ictx);
|
||||||
|
memset(pad, 0x36, 64);
|
||||||
|
for (i = 0; i < Klen; i++)
|
||||||
|
pad[i] ^= K[i];
|
||||||
|
_SHA256_Update(&ctx->ictx, pad, 64, tmp32);
|
||||||
|
|
||||||
|
/* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
|
||||||
|
SHA256_Init(&ctx->octx);
|
||||||
|
memset(pad, 0x5c, 64);
|
||||||
|
for (i = 0; i < Klen; i++)
|
||||||
|
pad[i] ^= K[i];
|
||||||
|
_SHA256_Update(&ctx->octx, pad, 64, tmp32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper function for intermediate-values sanitization. */
|
||||||
|
void
|
||||||
|
HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
|
||||||
|
{
|
||||||
|
uint32_t tmp32[72];
|
||||||
|
uint8_t pad[64];
|
||||||
|
uint8_t khash[32];
|
||||||
|
|
||||||
|
/* Call the real function. */
|
||||||
|
_HMAC_SHA256_Init(ctx, _K, Klen, tmp32, pad, khash);
|
||||||
|
|
||||||
|
/* Clean the stack. */
|
||||||
|
insecure_memzero(tmp32, 288);
|
||||||
|
insecure_memzero(khash, 32);
|
||||||
|
insecure_memzero(pad, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_SHA256_Update(ctx, in, len):
|
||||||
|
* Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len,
|
||||||
|
uint32_t tmp32[static restrict 72])
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Feed data to the inner SHA256 operation. */
|
||||||
|
_SHA256_Update(&ctx->ictx, in, len, tmp32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper function for intermediate-values sanitization. */
|
||||||
|
void
|
||||||
|
HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len)
|
||||||
|
{
|
||||||
|
uint32_t tmp32[72];
|
||||||
|
|
||||||
|
/* Call the real function. */
|
||||||
|
_HMAC_SHA256_Update(ctx, in, len, tmp32);
|
||||||
|
|
||||||
|
/* Clean the stack. */
|
||||||
|
insecure_memzero(tmp32, 288);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_SHA256_Final(digest, ctx):
|
||||||
|
* Output the HMAC-SHA256 of the data input to the context ${ctx} into the
|
||||||
|
* buffer ${digest}.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx,
|
||||||
|
uint32_t tmp32[static restrict 72], uint8_t ihash[static restrict 32])
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Finish the inner SHA256 operation. */
|
||||||
|
_SHA256_Final(ihash, &ctx->ictx, tmp32);
|
||||||
|
|
||||||
|
/* Feed the inner hash to the outer SHA256 operation. */
|
||||||
|
_SHA256_Update(&ctx->octx, ihash, 32, tmp32);
|
||||||
|
|
||||||
|
/* Finish the outer SHA256 operation. */
|
||||||
|
_SHA256_Final(digest, &ctx->octx, tmp32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper function for intermediate-values sanitization. */
|
||||||
|
void
|
||||||
|
HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx)
|
||||||
|
{
|
||||||
|
uint32_t tmp32[72];
|
||||||
|
uint8_t ihash[32];
|
||||||
|
|
||||||
|
/* Call the real function. */
|
||||||
|
_HMAC_SHA256_Final(digest, ctx, tmp32, ihash);
|
||||||
|
|
||||||
|
/* Clean the stack. */
|
||||||
|
insecure_memzero(tmp32, 288);
|
||||||
|
insecure_memzero(ihash, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_SHA256_Buf(K, Klen, in, len, digest):
|
||||||
|
* Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
|
||||||
|
* length ${Klen}, and write the result to ${digest}.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len,
|
||||||
|
uint8_t digest[32])
|
||||||
|
{
|
||||||
|
HMAC_SHA256_CTX ctx;
|
||||||
|
uint32_t tmp32[72];
|
||||||
|
uint8_t tmp8[96];
|
||||||
|
|
||||||
|
_HMAC_SHA256_Init(&ctx, K, Klen, tmp32, &tmp8[0], &tmp8[64]);
|
||||||
|
_HMAC_SHA256_Update(&ctx, in, len, tmp32);
|
||||||
|
_HMAC_SHA256_Final(digest, &ctx, tmp32, &tmp8[0]);
|
||||||
|
|
||||||
|
/* Clean the stack. */
|
||||||
|
insecure_memzero(&ctx, sizeof(HMAC_SHA256_CTX));
|
||||||
|
insecure_memzero(tmp32, 288);
|
||||||
|
insecure_memzero(tmp8, 96);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add padding and terminating bit-count, but don't invoke Transform yet. */
|
||||||
|
static int
|
||||||
|
SHA256_Pad_Almost(SHA256_CTX * ctx, uint8_t len[static restrict 8],
|
||||||
|
uint32_t tmp32[static restrict 72])
|
||||||
|
{
|
||||||
|
uint32_t r;
|
||||||
|
|
||||||
|
r = (ctx->count >> 3) & 0x3f;
|
||||||
|
if (r >= 56)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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--56 bytes so that the resulting length is 56 mod 64. */
|
||||||
|
_SHA256_Update(ctx, PAD, 56 - r, tmp32);
|
||||||
|
|
||||||
|
/* Add the terminating bit-count. */
|
||||||
|
ctx->buf[63] = len[7];
|
||||||
|
_SHA256_Update(ctx, len, 7, tmp32);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
||||||
|
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
|
||||||
|
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
|
||||||
|
size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
|
||||||
|
{
|
||||||
|
HMAC_SHA256_CTX Phctx, PShctx, hctx;
|
||||||
|
uint32_t tmp32[72];
|
||||||
|
union {
|
||||||
|
uint8_t tmp8[96];
|
||||||
|
uint32_t state[8];
|
||||||
|
} u;
|
||||||
|
size_t i;
|
||||||
|
uint8_t ivec[4];
|
||||||
|
uint8_t U[32];
|
||||||
|
uint8_t T[32];
|
||||||
|
uint64_t j;
|
||||||
|
int k;
|
||||||
|
size_t clen;
|
||||||
|
|
||||||
|
/* Sanity-check. */
|
||||||
|
assert(dkLen <= 32 * (size_t)(UINT32_MAX));
|
||||||
|
|
||||||
|
if (c == 1 && (dkLen & 31) == 0 && (saltlen & 63) <= 51) {
|
||||||
|
uint32_t oldcount;
|
||||||
|
uint8_t * ivecp;
|
||||||
|
|
||||||
|
/* Compute HMAC state after processing P and S. */
|
||||||
|
_HMAC_SHA256_Init(&hctx, passwd, passwdlen,
|
||||||
|
tmp32, &u.tmp8[0], &u.tmp8[64]);
|
||||||
|
_HMAC_SHA256_Update(&hctx, salt, saltlen, tmp32);
|
||||||
|
|
||||||
|
/* Prepare ictx padding. */
|
||||||
|
oldcount = hctx.ictx.count & (0x3f << 3);
|
||||||
|
_HMAC_SHA256_Update(&hctx, "\0\0\0", 4, tmp32);
|
||||||
|
if ((hctx.ictx.count & (0x3f << 3)) < oldcount ||
|
||||||
|
SHA256_Pad_Almost(&hctx.ictx, u.tmp8, tmp32))
|
||||||
|
goto generic; /* Can't happen due to saltlen check */
|
||||||
|
ivecp = hctx.ictx.buf + (oldcount >> 3);
|
||||||
|
|
||||||
|
/* Prepare octx padding. */
|
||||||
|
hctx.octx.count += 32 << 3;
|
||||||
|
SHA256_Pad_Almost(&hctx.octx, u.tmp8, tmp32);
|
||||||
|
|
||||||
|
/* Iterate through the blocks. */
|
||||||
|
for (i = 0; i * 32 < dkLen; i++) {
|
||||||
|
/* Generate INT(i + 1). */
|
||||||
|
be32enc(ivecp, (uint32_t)(i + 1));
|
||||||
|
|
||||||
|
/* Compute U_1 = PRF(P, S || INT(i)). */
|
||||||
|
memcpy(u.state, hctx.ictx.state, sizeof(u.state));
|
||||||
|
SHA256_Transform(u.state, hctx.ictx.buf,
|
||||||
|
&tmp32[0], &tmp32[64]);
|
||||||
|
be32enc_vect(hctx.octx.buf, u.state, 4);
|
||||||
|
memcpy(u.state, hctx.octx.state, sizeof(u.state));
|
||||||
|
SHA256_Transform(u.state, hctx.octx.buf,
|
||||||
|
&tmp32[0], &tmp32[64]);
|
||||||
|
be32enc_vect(&buf[i * 32], u.state, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
generic:
|
||||||
|
/* Compute HMAC state after processing P. */
|
||||||
|
_HMAC_SHA256_Init(&Phctx, passwd, passwdlen,
|
||||||
|
tmp32, &u.tmp8[0], &u.tmp8[64]);
|
||||||
|
|
||||||
|
/* Compute HMAC state after processing P and S. */
|
||||||
|
memcpy(&PShctx, &Phctx, sizeof(HMAC_SHA256_CTX));
|
||||||
|
_HMAC_SHA256_Update(&PShctx, salt, saltlen, tmp32);
|
||||||
|
|
||||||
|
/* Iterate through the blocks. */
|
||||||
|
for (i = 0; i * 32 < dkLen; i++) {
|
||||||
|
/* Generate INT(i + 1). */
|
||||||
|
be32enc(ivec, (uint32_t)(i + 1));
|
||||||
|
|
||||||
|
/* Compute U_1 = PRF(P, S || INT(i)). */
|
||||||
|
memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
|
||||||
|
_HMAC_SHA256_Update(&hctx, ivec, 4, tmp32);
|
||||||
|
_HMAC_SHA256_Final(T, &hctx, tmp32, u.tmp8);
|
||||||
|
|
||||||
|
if (c > 1) {
|
||||||
|
/* T_i = U_1 ... */
|
||||||
|
memcpy(U, T, 32);
|
||||||
|
|
||||||
|
for (j = 2; j <= c; j++) {
|
||||||
|
/* Compute U_j. */
|
||||||
|
memcpy(&hctx, &Phctx, sizeof(HMAC_SHA256_CTX));
|
||||||
|
_HMAC_SHA256_Update(&hctx, U, 32, tmp32);
|
||||||
|
_HMAC_SHA256_Final(U, &hctx, tmp32, u.tmp8);
|
||||||
|
|
||||||
|
/* ... xor U_j ... */
|
||||||
|
for (k = 0; k < 32; k++)
|
||||||
|
T[k] ^= U[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy as many bytes as necessary into buf. */
|
||||||
|
clen = dkLen - i * 32;
|
||||||
|
if (clen > 32)
|
||||||
|
clen = 32;
|
||||||
|
memcpy(&buf[i * 32], T, clen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean the stack. */
|
||||||
|
insecure_memzero(&Phctx, sizeof(HMAC_SHA256_CTX));
|
||||||
|
insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX));
|
||||||
|
insecure_memzero(U, 32);
|
||||||
|
insecure_memzero(T, 32);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
insecure_memzero(&hctx, sizeof(HMAC_SHA256_CTX));
|
||||||
|
insecure_memzero(tmp32, 288);
|
||||||
|
insecure_memzero(&u, sizeof(u));
|
||||||
|
}
|
129
deps/yescrypt-master/sha256.h
vendored
Normal file
129
deps/yescrypt-master/sha256.h
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2005-2016 Colin Percival
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SHA256_H_
|
||||||
|
#define _SHA256_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use #defines in order to avoid namespace collisions with anyone else's
|
||||||
|
* SHA256 code (e.g., the code in OpenSSL).
|
||||||
|
*/
|
||||||
|
#define SHA256_Init libcperciva_SHA256_Init
|
||||||
|
#define SHA256_Update libcperciva_SHA256_Update
|
||||||
|
#define SHA256_Final libcperciva_SHA256_Final
|
||||||
|
#define SHA256_Buf libcperciva_SHA256_Buf
|
||||||
|
#define SHA256_CTX libcperciva_SHA256_CTX
|
||||||
|
#define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init
|
||||||
|
#define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update
|
||||||
|
#define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final
|
||||||
|
#define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf
|
||||||
|
#define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX
|
||||||
|
|
||||||
|
/* Context structure for SHA256 operations. */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t state[8];
|
||||||
|
uint64_t count;
|
||||||
|
uint8_t buf[64];
|
||||||
|
} SHA256_CTX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA256_Init(ctx):
|
||||||
|
* Initialize the SHA256 context ${ctx}.
|
||||||
|
*/
|
||||||
|
void SHA256_Init(SHA256_CTX *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA256_Update(ctx, in, len):
|
||||||
|
* Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
|
||||||
|
*/
|
||||||
|
void SHA256_Update(SHA256_CTX *, const void *, size_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA256_Final(digest, ctx):
|
||||||
|
* Output the SHA256 hash of the data input to the context ${ctx} into the
|
||||||
|
* buffer ${digest}.
|
||||||
|
*/
|
||||||
|
void SHA256_Final(uint8_t[32], SHA256_CTX *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA256_Buf(in, len, digest):
|
||||||
|
* Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}.
|
||||||
|
*/
|
||||||
|
void SHA256_Buf(const void *, size_t, uint8_t[32]);
|
||||||
|
|
||||||
|
/* Context structure for HMAC-SHA256 operations. */
|
||||||
|
typedef struct {
|
||||||
|
SHA256_CTX ictx;
|
||||||
|
SHA256_CTX octx;
|
||||||
|
} HMAC_SHA256_CTX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_SHA256_Init(ctx, K, Klen):
|
||||||
|
* Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
|
||||||
|
* ${K}.
|
||||||
|
*/
|
||||||
|
void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_SHA256_Update(ctx, in, len):
|
||||||
|
* Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
|
||||||
|
*/
|
||||||
|
void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_SHA256_Final(digest, ctx):
|
||||||
|
* Output the HMAC-SHA256 of the data input to the context ${ctx} into the
|
||||||
|
* buffer ${digest}.
|
||||||
|
*/
|
||||||
|
void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC_SHA256_Buf(K, Klen, in, len, digest):
|
||||||
|
* Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
|
||||||
|
* length ${Klen}, and write the result to ${digest}.
|
||||||
|
*/
|
||||||
|
void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[32]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
||||||
|
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
|
||||||
|
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
||||||
|
*/
|
||||||
|
void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
|
||||||
|
uint64_t, uint8_t *, size_t);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_SHA256_H_ */
|
122
deps/yescrypt-master/sysendian.h
vendored
Normal file
122
deps/yescrypt-master/sysendian.h
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2007-2014 Colin Percival
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYSENDIAN_H_
|
||||||
|
#define _SYSENDIAN_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Avoid namespace collisions with BSD <sys/endian.h>. */
|
||||||
|
#define be32dec libcperciva_be32dec
|
||||||
|
#define be32enc libcperciva_be32enc
|
||||||
|
#define be64enc libcperciva_be64enc
|
||||||
|
#define le32dec libcperciva_le32dec
|
||||||
|
#define le32enc libcperciva_le32enc
|
||||||
|
#define le64dec libcperciva_le64dec
|
||||||
|
#define le64enc libcperciva_le64enc
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
be32dec(const void * pp)
|
||||||
|
{
|
||||||
|
const uint8_t * p = (uint8_t const *)pp;
|
||||||
|
|
||||||
|
return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
|
||||||
|
((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
be32enc(void * pp, uint32_t x)
|
||||||
|
{
|
||||||
|
uint8_t * p = (uint8_t *)pp;
|
||||||
|
|
||||||
|
p[3] = x & 0xff;
|
||||||
|
p[2] = (x >> 8) & 0xff;
|
||||||
|
p[1] = (x >> 16) & 0xff;
|
||||||
|
p[0] = (x >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
be64enc(void * pp, uint64_t x)
|
||||||
|
{
|
||||||
|
uint8_t * p = (uint8_t *)pp;
|
||||||
|
|
||||||
|
p[7] = x & 0xff;
|
||||||
|
p[6] = (x >> 8) & 0xff;
|
||||||
|
p[5] = (x >> 16) & 0xff;
|
||||||
|
p[4] = (x >> 24) & 0xff;
|
||||||
|
p[3] = (x >> 32) & 0xff;
|
||||||
|
p[2] = (x >> 40) & 0xff;
|
||||||
|
p[1] = (x >> 48) & 0xff;
|
||||||
|
p[0] = (x >> 56) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
le32dec(const void * pp)
|
||||||
|
{
|
||||||
|
const uint8_t * p = (uint8_t const *)pp;
|
||||||
|
|
||||||
|
return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
|
||||||
|
((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
le32enc(void * pp, uint32_t x)
|
||||||
|
{
|
||||||
|
uint8_t * p = (uint8_t *)pp;
|
||||||
|
|
||||||
|
p[0] = x & 0xff;
|
||||||
|
p[1] = (x >> 8) & 0xff;
|
||||||
|
p[2] = (x >> 16) & 0xff;
|
||||||
|
p[3] = (x >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
le64dec(const void * pp)
|
||||||
|
{
|
||||||
|
const uint8_t * p = (uint8_t const *)pp;
|
||||||
|
|
||||||
|
return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
|
||||||
|
((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
|
||||||
|
((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
|
||||||
|
((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
le64enc(void * pp, uint64_t x)
|
||||||
|
{
|
||||||
|
uint8_t * p = (uint8_t *)pp;
|
||||||
|
|
||||||
|
p[0] = x & 0xff;
|
||||||
|
p[1] = (x >> 8) & 0xff;
|
||||||
|
p[2] = (x >> 16) & 0xff;
|
||||||
|
p[3] = (x >> 24) & 0xff;
|
||||||
|
p[4] = (x >> 32) & 0xff;
|
||||||
|
p[5] = (x >> 40) & 0xff;
|
||||||
|
p[6] = (x >> 48) & 0xff;
|
||||||
|
p[7] = (x >> 56) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !_SYSENDIAN_H_ */
|
418
deps/yescrypt-master/tests.c
vendored
Normal file
418
deps/yescrypt-master/tests.c
vendored
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2013-2018 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define YESCRYPT_FLAGS YESCRYPT_DEFAULTS
|
||||||
|
#if 1
|
||||||
|
#define YESCRYPT_P 11
|
||||||
|
#define YESCRYPT_PROM 8
|
||||||
|
#else
|
||||||
|
#define YESCRYPT_P 1
|
||||||
|
#define YESCRYPT_PROM 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef TEST_PBKDF2_SHA256
|
||||||
|
#define TEST_SCRYPT
|
||||||
|
#define TEST_YESCRYPT_KDF
|
||||||
|
#define TEST_YESCRYPT_ENCODING
|
||||||
|
#define TEST_ROM
|
||||||
|
#define TEST_ROM_PREALLOC
|
||||||
|
|
||||||
|
#ifdef TEST_ROM_PREALLOC
|
||||||
|
#include <stdlib.h> /* for malloc() */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_PBKDF2_SHA256
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "sha256.h"
|
||||||
|
|
||||||
|
static void print_PBKDF2_SHA256_raw(const char *passwd, size_t passwdlen,
|
||||||
|
const char *salt, size_t saltlen, uint64_t c, size_t dkLen)
|
||||||
|
{
|
||||||
|
uint8_t dk[64];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
assert(dkLen <= sizeof(dk));
|
||||||
|
|
||||||
|
/* XXX This prints the strings truncated at first NUL */
|
||||||
|
printf("PBKDF2_SHA256(\"%s\", \"%s\", %llu, %llu) =",
|
||||||
|
passwd, salt, (unsigned long long)c, (unsigned long long)dkLen);
|
||||||
|
|
||||||
|
PBKDF2_SHA256((const uint8_t *) passwd, passwdlen,
|
||||||
|
(const uint8_t *) salt, saltlen, c, dk, dkLen);
|
||||||
|
|
||||||
|
for (i = 0; i < dkLen; i++)
|
||||||
|
printf(" %02x", dk[i]);
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_PBKDF2_SHA256(const char *passwd,
|
||||||
|
const char *salt, uint64_t c, size_t dkLen)
|
||||||
|
{
|
||||||
|
print_PBKDF2_SHA256_raw(passwd, strlen(passwd), salt, strlen(salt), c,
|
||||||
|
dkLen);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(TEST_SCRYPT) || defined(TEST_YESCRYPT_ENCODING)
|
||||||
|
#include "yescrypt.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_SCRYPT
|
||||||
|
static void print_scrypt(const char *passwd, const char *salt,
|
||||||
|
uint64_t N, uint32_t r, uint32_t p)
|
||||||
|
{
|
||||||
|
uint8_t dk[64];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
printf("scrypt(\"%s\", \"%s\", %llu, %u, %u) =",
|
||||||
|
passwd, salt, (unsigned long long)N, r, p);
|
||||||
|
|
||||||
|
if (crypto_scrypt((const uint8_t *) passwd, strlen(passwd),
|
||||||
|
(const uint8_t *) salt, strlen(salt), N, r, p, dk, sizeof(dk))) {
|
||||||
|
puts(" FAILED");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(dk); i++)
|
||||||
|
printf(" %02x", dk[i]);
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_YESCRYPT_KDF
|
||||||
|
static void print_yescrypt(const char *passwd, const char *salt,
|
||||||
|
yescrypt_flags_t flags,
|
||||||
|
uint64_t N, uint32_t r, uint32_t p, uint32_t t, uint32_t g,
|
||||||
|
uint32_t dklen)
|
||||||
|
{
|
||||||
|
yescrypt_local_t local;
|
||||||
|
yescrypt_params_t params = {flags, N, r, p, t, g, 0};
|
||||||
|
uint8_t dk[64];
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* Don't test hash upgrades */
|
||||||
|
if (g)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dklen > sizeof(dk) || yescrypt_init_local(&local)) {
|
||||||
|
puts("FAILED");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("yescrypt(\"%s\", \"%s\", %u, %llu, %u, %u, %u, %u) =",
|
||||||
|
passwd, salt, flags, (unsigned long long)N, r, p, t, g);
|
||||||
|
|
||||||
|
if (yescrypt_kdf(NULL, &local,
|
||||||
|
(const uint8_t *) passwd, strlen(passwd),
|
||||||
|
(const uint8_t *) salt, strlen(salt), ¶ms, dk, dklen)) {
|
||||||
|
yescrypt_free_local(&local);
|
||||||
|
puts(" FAILED");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yescrypt_free_local(&local);
|
||||||
|
|
||||||
|
for (i = 0; i < dklen; i++)
|
||||||
|
printf(" %02x", dk[i]);
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
|
#ifdef TEST_PBKDF2_SHA256
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 1, 20);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 2, 20);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 4096, 20);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 16777216, 20);
|
||||||
|
print_PBKDF2_SHA256("passwordPASSWORDpassword",
|
||||||
|
"saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25);
|
||||||
|
print_PBKDF2_SHA256_raw("pass\0word", 9, "sa\0lt", 5, 4096, 16);
|
||||||
|
#if 0
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 1, 32);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 2, 32);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 4096, 32);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 16777216, 32);
|
||||||
|
print_PBKDF2_SHA256("passwordPASSWORDpassword",
|
||||||
|
"saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 40);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 4096, 16);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 1, 20);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 2, 20);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 4096, 20);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 16777216, 20);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 4096, 25);
|
||||||
|
print_PBKDF2_SHA256("password", "salt", 4096, 16);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_SCRYPT
|
||||||
|
print_scrypt("", "", 16, 1, 1);
|
||||||
|
print_scrypt("password", "NaCl", 1024, 8, 16);
|
||||||
|
print_scrypt("pleaseletmein", "SodiumChloride", 16384, 8, 1);
|
||||||
|
print_scrypt("pleaseletmein", "SodiumChloride", 1048576, 8, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_YESCRYPT_KDF
|
||||||
|
print_yescrypt("", "", 0, 16, 1, 1, 0, 0, 64);
|
||||||
|
print_yescrypt("", "", 0, 16, 1, 1, 0, 0, 8);
|
||||||
|
print_yescrypt("", "", 0, 4, 1, 1, 0, 0, 64);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 0, 0, 64);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 0, 0, 8);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 1, 0, 64);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 2, 0, 64);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 3, 0, 64);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 3, 0, 33);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 3, 0, 32);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 3, 0, 31);
|
||||||
|
print_yescrypt("", "", YESCRYPT_WORM, 4, 1, 1, 3, 0, 1);
|
||||||
|
print_yescrypt("", "", YESCRYPT_DEFAULTS, 4, 1, 1, 0, 0, 64);
|
||||||
|
print_yescrypt("", "", YESCRYPT_DEFAULTS, 4, 1, 1, 0, 0, 4);
|
||||||
|
print_yescrypt("", "", YESCRYPT_DEFAULTS, 4, 1, 1, 1, 0, 64);
|
||||||
|
print_yescrypt("", "", YESCRYPT_DEFAULTS, 4, 1, 1, 1, 0, 33);
|
||||||
|
print_yescrypt("", "", YESCRYPT_DEFAULTS, 4, 1, 1, 1, 0, 32);
|
||||||
|
print_yescrypt("", "", YESCRYPT_DEFAULTS, 4, 1, 1, 1, 0, 31);
|
||||||
|
print_yescrypt("", "", YESCRYPT_DEFAULTS, 4, 1, 1, 1, 0, 1);
|
||||||
|
for (i = 0; i <= 6; i++)
|
||||||
|
print_yescrypt("p", "s", YESCRYPT_DEFAULTS, 16, 8, 1, i + 10, i, 40);
|
||||||
|
for (i = 0; i <= 6; i++)
|
||||||
|
print_yescrypt("p", "s", YESCRYPT_WORM, 16, 8, 1, i + 10, i, 40);
|
||||||
|
for (i = 0; i <= 6; i++)
|
||||||
|
print_yescrypt("p", "s", YESCRYPT_DEFAULTS, 16, 8, 1, 0, i, 40);
|
||||||
|
for (i = 0; i <= 6; i++)
|
||||||
|
print_yescrypt("p", "s", YESCRYPT_WORM, 16, 8, 1, 0, i, 40);
|
||||||
|
for (i = 0; i <= 2; i++)
|
||||||
|
print_yescrypt("p", "s", YESCRYPT_DEFAULTS, 16, 8, 1, 0, i, 32);
|
||||||
|
for (i = 0; i <= 2; i++)
|
||||||
|
print_yescrypt("p", "s", YESCRYPT_DEFAULTS, 16, 8, 1, 0, i, 8);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_YESCRYPT_ENCODING
|
||||||
|
{
|
||||||
|
uint8_t *setting;
|
||||||
|
yescrypt_binary_t key = {.uc={
|
||||||
|
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
|
||||||
|
17,18,19,20,21,22,23,24,25,26,27,28,255,128,64,32}};
|
||||||
|
|
||||||
|
for (i = 0; i < 18; i++) {
|
||||||
|
uint32_t N_log2 = (i < 14) ? (16 - i) : 2;
|
||||||
|
uint32_t r = (i < 8) ? (8 - i) : (1 + (i & 1));
|
||||||
|
uint32_t p = (i & 1) ? 1 : YESCRYPT_P;
|
||||||
|
yescrypt_flags_t flags = YESCRYPT_DEFAULTS;
|
||||||
|
if ((int)p - (i / 2) > 1)
|
||||||
|
p -= i / 2;
|
||||||
|
if (i & 2) {
|
||||||
|
flags = YESCRYPT_WORM;
|
||||||
|
} else {
|
||||||
|
while ((1ULL << N_log2) / p <= 3)
|
||||||
|
N_log2++;
|
||||||
|
}
|
||||||
|
yescrypt_params_t params =
|
||||||
|
{flags, (uint64_t)1 << N_log2, r, p, 0, 0, 0};
|
||||||
|
setting = yescrypt_encode_params(¶ms,
|
||||||
|
(const uint8_t *)"WZaPV7LSUEKMo34.", 16 - (i & 15));
|
||||||
|
if (i == 0)
|
||||||
|
printf("'%s'\n", (char *)setting);
|
||||||
|
if (!setting)
|
||||||
|
printf("%d yescrypt_encode_params() = NULL\n", i);
|
||||||
|
if (setting) {
|
||||||
|
uint8_t *hash = yescrypt(
|
||||||
|
(const uint8_t *)"pleaseletmein", setting);
|
||||||
|
printf("Plaintext: '%s'\n", (char *)hash);
|
||||||
|
hash = (uint8_t *)strdup((char *)hash);
|
||||||
|
if (!hash || strcmp(
|
||||||
|
(char *)hash, (char *)yescrypt(
|
||||||
|
(const uint8_t *)"pleaseletmein", hash)))
|
||||||
|
puts("Validation FAILED");
|
||||||
|
uint8_t *orig = (uint8_t *)strdup((char *)hash);
|
||||||
|
if (!yescrypt_reencrypt(hash, NULL, &key))
|
||||||
|
printf("%d yescrypt_reencrypt() = NULL\n", i);
|
||||||
|
printf("Encrypted: '%s'\n", (char *)hash);
|
||||||
|
yescrypt_local_t local;
|
||||||
|
if (yescrypt_init_local(&local)) {
|
||||||
|
puts("yescrypt_init_local() FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
uint8_t buf[128];
|
||||||
|
if (strcmp((char *)hash, (char *)yescrypt_r(
|
||||||
|
NULL, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13,
|
||||||
|
hash, &key, buf, sizeof(buf))))
|
||||||
|
puts("Validation of encrypted FAILED");
|
||||||
|
if (!strcmp((char *)hash, (char *)yescrypt_r(
|
||||||
|
NULL, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13,
|
||||||
|
hash, NULL, buf, sizeof(buf))))
|
||||||
|
puts("Validation of encrypted "
|
||||||
|
"unexpectedly succeeded");
|
||||||
|
if (!strcmp((char *)orig, (char *)yescrypt_r(
|
||||||
|
NULL, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13,
|
||||||
|
orig, &key, buf, sizeof(buf))))
|
||||||
|
puts("Validation of unencrypted "
|
||||||
|
"unexpectedly succeeded");
|
||||||
|
yescrypt_free_local(&local);
|
||||||
|
if (!yescrypt_reencrypt(hash, &key, NULL))
|
||||||
|
printf("%d yescrypt_reencrypt() = NULL\n", i);
|
||||||
|
if (strcmp((char *)hash, (char *)orig))
|
||||||
|
puts("Decryption FAILED");
|
||||||
|
free(orig);
|
||||||
|
free(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt(
|
||||||
|
(const uint8_t *)"pleaseletmein",
|
||||||
|
(const uint8_t *)"$7$C6..../....SodiumChloride"));
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt(
|
||||||
|
(const uint8_t *)"pleaseletmein",
|
||||||
|
(const uint8_t *)"$7$06..../....SodiumChloride"));
|
||||||
|
|
||||||
|
#ifdef TEST_ROM
|
||||||
|
uint64_t rom_bytes = 256 * (1024ULL*1024);
|
||||||
|
uint64_t ram_bytes = 2 * (1024ULL*1024);
|
||||||
|
uint32_t r;
|
||||||
|
uint64_t NROM_log2, N_log2;
|
||||||
|
yescrypt_shared_t shared;
|
||||||
|
yescrypt_local_t local;
|
||||||
|
|
||||||
|
NROM_log2 = 0;
|
||||||
|
while (((rom_bytes >> NROM_log2) & 0xff) == 0)
|
||||||
|
NROM_log2++;
|
||||||
|
r = rom_bytes >> (7 + NROM_log2);
|
||||||
|
while (r < 5 && NROM_log2 > 0) {
|
||||||
|
r <<= 1;
|
||||||
|
NROM_log2--;
|
||||||
|
}
|
||||||
|
rom_bytes = (uint64_t)r << (7 + NROM_log2);
|
||||||
|
|
||||||
|
N_log2 = 0;
|
||||||
|
while (((uint64_t)r << (7 + N_log2)) < ram_bytes)
|
||||||
|
N_log2++;
|
||||||
|
ram_bytes = (uint64_t)r << (7 + N_log2);
|
||||||
|
|
||||||
|
printf("r=%u N=2^%u NROM=2^%u\n", r,
|
||||||
|
(unsigned int)N_log2, (unsigned int)NROM_log2);
|
||||||
|
|
||||||
|
printf("Will use %.2f KiB ROM\n", rom_bytes / 1024.0);
|
||||||
|
printf(" %.2f KiB RAM\n", ram_bytes / 1024.0);
|
||||||
|
|
||||||
|
printf("Initializing ROM ...");
|
||||||
|
fflush(stdout);
|
||||||
|
yescrypt_params_t rom_params = { YESCRYPT_DEFAULTS,
|
||||||
|
0, r, YESCRYPT_PROM, 0, 0, (uint64_t)1 << NROM_log2 };
|
||||||
|
if (yescrypt_init_shared(&shared,
|
||||||
|
(const uint8_t *)"local param", 12, &rom_params)) {
|
||||||
|
puts(" FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
yescrypt_binary_t *digest = yescrypt_digest_shared(&shared);
|
||||||
|
printf(" DONE (%02x%02x%02x%02x)\n",
|
||||||
|
digest->uc[0], digest->uc[1], digest->uc[2], digest->uc[3]);
|
||||||
|
|
||||||
|
if (yescrypt_init_local(&local)) {
|
||||||
|
puts("FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
yescrypt_params_t params = rom_params;
|
||||||
|
params.flags = YESCRYPT_FLAGS;
|
||||||
|
params.N = (uint64_t)1 << N_log2;
|
||||||
|
params.p = YESCRYPT_P;
|
||||||
|
setting = yescrypt_encode_params(¶ms,
|
||||||
|
(const uint8_t *)"WZaPV7LSUEKMo34.", 16);
|
||||||
|
printf("'%s'\n", (char *)setting);
|
||||||
|
|
||||||
|
uint8_t hash[128];
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt_r(&shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13, setting, NULL,
|
||||||
|
hash, sizeof(hash)));
|
||||||
|
|
||||||
|
#ifdef TEST_ROM_PREALLOC
|
||||||
|
yescrypt_free_shared(&shared);
|
||||||
|
|
||||||
|
shared.aligned_size = ((uint64_t)1 << NROM_log2) * 128 * r;
|
||||||
|
shared.base_size = shared.aligned_size + 63;
|
||||||
|
uint8_t *where = shared.base = malloc(shared.base_size);
|
||||||
|
where += 63;
|
||||||
|
where = shared.aligned = where - ((uintptr_t)where & 63);
|
||||||
|
|
||||||
|
printf("Initializing ROM in preallocated memory ...");
|
||||||
|
fflush(stdout);
|
||||||
|
rom_params.flags |= YESCRYPT_SHARED_PREALLOCATED;
|
||||||
|
if (yescrypt_init_shared(&shared,
|
||||||
|
(const uint8_t *)"local param", 12, &rom_params)) {
|
||||||
|
puts(" FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
digest = yescrypt_digest_shared(&shared);
|
||||||
|
printf(" DONE (%02x%02x%02x%02x)\n",
|
||||||
|
digest->uc[0], digest->uc[1], digest->uc[2], digest->uc[3]);
|
||||||
|
|
||||||
|
if ((void *)where != shared.aligned)
|
||||||
|
puts("YESCRYPT_SHARED_PREALLOCATED failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt_r(&shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13, setting, NULL,
|
||||||
|
hash, sizeof(hash)));
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt_r(&shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmeIn", 13, setting, NULL,
|
||||||
|
hash, sizeof(hash)));
|
||||||
|
|
||||||
|
setting = yescrypt_encode_params(¶ms,
|
||||||
|
(const uint8_t *)"WZaPV7LSUEIMo34.", 16);
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt_r(&shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13, setting, NULL,
|
||||||
|
hash, sizeof(hash)));
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt_r(&shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmeIn", 13, setting, NULL,
|
||||||
|
hash, sizeof(hash)));
|
||||||
|
|
||||||
|
params.N = 4;
|
||||||
|
params.NROM *= params.r;
|
||||||
|
params.r = 1;
|
||||||
|
params.p = 1;
|
||||||
|
setting = yescrypt_encode_params(¶ms,
|
||||||
|
(const uint8_t *)"WZaPV7LSUEKMo34.", 16);
|
||||||
|
|
||||||
|
printf("'%s'\n", (char *)yescrypt_r(&shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13, setting, NULL,
|
||||||
|
hash, sizeof(hash)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
405
deps/yescrypt-master/userom.c
vendored
Normal file
405
deps/yescrypt-master/userom.c
vendored
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2013-2018 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define YESCRYPT_FLAGS YESCRYPT_DEFAULTS
|
||||||
|
//#define YESCRYPT_FLAGS YESCRYPT_WORM
|
||||||
|
//#define YESCRYPT_FLAGS 0
|
||||||
|
|
||||||
|
#define ROM_SHM_KEY 0x7965730a
|
||||||
|
|
||||||
|
//#define DISABLE_ROM
|
||||||
|
//#define DUMP_LOCAL
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h> /* for atoi() */
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/times.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
#include "yescrypt.h"
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#include <omp.h>
|
||||||
|
|
||||||
|
#define NSAVE 1000
|
||||||
|
|
||||||
|
static uint64_t time_us(void)
|
||||||
|
{
|
||||||
|
struct timespec t;
|
||||||
|
#ifdef CLOCK_MONOTONIC_RAW
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC_RAW, &t))
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &t))
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
return 1 + (uint64_t)t.tv_sec * 1000000 + t.tv_nsec / 1000;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, const char * const *argv)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
uint64_t rom_bytes = 112 * (1024ULL*1024*1024);
|
||||||
|
uint64_t ram_bytes = 1 * (1024ULL*1024);
|
||||||
|
#else
|
||||||
|
uint64_t rom_bytes = 3 * (1024ULL*1024*1024);
|
||||||
|
uint64_t ram_bytes = 2 * (1024ULL*1024);
|
||||||
|
#endif
|
||||||
|
uint32_t r, min_r;
|
||||||
|
uint64_t NROM_log2, N_log2;
|
||||||
|
yescrypt_shared_t shared_s;
|
||||||
|
yescrypt_shared_t *shared = NULL;
|
||||||
|
#ifndef DISABLE_ROM
|
||||||
|
int shmid;
|
||||||
|
#endif
|
||||||
|
const char *rom_filename = NULL;
|
||||||
|
int rom_fd;
|
||||||
|
yescrypt_binary_t key = {.uc={
|
||||||
|
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
|
||||||
|
17,18,19,20,21,22,23,24,25,26,27,28,255,128,64,32}};
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
rom_bytes = atoi(argv[1]) * (1024ULL*1024*1024);
|
||||||
|
if (argc > 2)
|
||||||
|
ram_bytes = atoi(argv[2]) * (1024ULL*1024);
|
||||||
|
if (argc > 3 && rom_bytes)
|
||||||
|
rom_filename = argv[3];
|
||||||
|
|
||||||
|
r = 16;
|
||||||
|
min_r = 9;
|
||||||
|
if (rom_filename)
|
||||||
|
min_r = 8 * 64;
|
||||||
|
|
||||||
|
NROM_log2 = 0;
|
||||||
|
if (rom_bytes) {
|
||||||
|
while (((rom_bytes >> NROM_log2) & 0xff) == 0)
|
||||||
|
NROM_log2++;
|
||||||
|
r = rom_bytes >> (7 + NROM_log2);
|
||||||
|
while (r < min_r && NROM_log2 > 0) {
|
||||||
|
r <<= 1;
|
||||||
|
NROM_log2--;
|
||||||
|
}
|
||||||
|
rom_bytes = (uint64_t)r << (7 + NROM_log2);
|
||||||
|
}
|
||||||
|
|
||||||
|
N_log2 = 0;
|
||||||
|
while (((uint64_t)r << (7 + N_log2)) < ram_bytes)
|
||||||
|
N_log2++;
|
||||||
|
ram_bytes = (uint64_t)r << (7 + N_log2);
|
||||||
|
|
||||||
|
printf("r=%u N=2^%u NROM=2^%u\n", r,
|
||||||
|
(unsigned int)N_log2, (unsigned int)NROM_log2);
|
||||||
|
|
||||||
|
#ifdef DISABLE_ROM
|
||||||
|
rom_bytes = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("Will use %.2f KiB ROM\n", rom_bytes / 1024.0);
|
||||||
|
printf(" %.2f KiB RAM\n", ram_bytes / 1024.0);
|
||||||
|
|
||||||
|
#ifndef DISABLE_ROM
|
||||||
|
if (rom_filename) {
|
||||||
|
rom_fd = open(rom_filename, O_RDONLY);
|
||||||
|
if (rom_fd < 0) {
|
||||||
|
perror("open");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flags =
|
||||||
|
#ifdef MAP_NOCORE
|
||||||
|
MAP_NOCORE |
|
||||||
|
#endif
|
||||||
|
#ifdef MAP_HUGETLB
|
||||||
|
MAP_HUGETLB |
|
||||||
|
#endif
|
||||||
|
MAP_SHARED;
|
||||||
|
void *p = mmap(NULL, rom_bytes, PROT_READ, flags, rom_fd, 0);
|
||||||
|
#ifdef MAP_HUGETLB
|
||||||
|
if (p == MAP_FAILED)
|
||||||
|
p = mmap(NULL, rom_bytes, PROT_READ,
|
||||||
|
flags & ~MAP_HUGETLB, rom_fd, 0);
|
||||||
|
#endif
|
||||||
|
if (p == MAP_FAILED) {
|
||||||
|
perror("mmap");
|
||||||
|
close(rom_fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
close(rom_fd);
|
||||||
|
|
||||||
|
shared = &shared_s;
|
||||||
|
shared->base = shared->aligned = p;
|
||||||
|
shared->aligned_size = rom_bytes;
|
||||||
|
} else if (rom_bytes) {
|
||||||
|
shared = &shared_s;
|
||||||
|
shared->aligned_size = rom_bytes;
|
||||||
|
shmid = shmget(ROM_SHM_KEY, shared->aligned_size, 0);
|
||||||
|
if (shmid == -1) {
|
||||||
|
perror("shmget");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared->base = shared->aligned = shmat(shmid, NULL, SHM_RDONLY);
|
||||||
|
if (shared->base == (void *)-1) {
|
||||||
|
perror("shmat");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
yescrypt_local_t local;
|
||||||
|
const uint8_t *setting;
|
||||||
|
|
||||||
|
if (yescrypt_init_local(&local)) {
|
||||||
|
puts("yescrypt_init_local() FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
yescrypt_params_t params = {
|
||||||
|
.flags = YESCRYPT_FLAGS,
|
||||||
|
.N = (uint64_t)1 << N_log2,
|
||||||
|
.NROM = NROM_log2 ? ((uint64_t)1 << NROM_log2) : 0,
|
||||||
|
.r = r,
|
||||||
|
.p = 1 };
|
||||||
|
setting = yescrypt_encode_params(¶ms,
|
||||||
|
(const uint8_t *)"WZaPV7LSUEKMo34.", 16);
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t hash[128];
|
||||||
|
if (!yescrypt_r(shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13, setting, NULL,
|
||||||
|
hash, sizeof(hash))) {
|
||||||
|
puts("yescrypt_r() FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Plaintext: '%s'\n", (char *)hash);
|
||||||
|
if (!yescrypt_r(shared, &local,
|
||||||
|
(const uint8_t *)"pleaseletmein", 13, setting, &key,
|
||||||
|
hash, sizeof(hash))) {
|
||||||
|
puts("yescrypt_r() FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Encrypted: '%s'\n", (char *)hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DUMP_LOCAL
|
||||||
|
#if 0
|
||||||
|
fwrite(local.aligned, local.aligned_size, 1, stderr);
|
||||||
|
#else
|
||||||
|
/* Skip B, dump only V */
|
||||||
|
if (local.aligned_size >= ram_bytes + 128 * r)
|
||||||
|
fwrite((char *)local.aligned + 128 * r, ram_bytes,
|
||||||
|
1, stderr);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
puts("Benchmarking 1 thread ...");
|
||||||
|
|
||||||
|
clock_t clk_tck = sysconf(_SC_CLK_TCK);
|
||||||
|
struct tms start_tms, end_tms;
|
||||||
|
clock_t start = times(&start_tms), end;
|
||||||
|
unsigned int i, n;
|
||||||
|
unsigned long long count;
|
||||||
|
#ifdef _OPENMP
|
||||||
|
char save[NSAVE][128];
|
||||||
|
unsigned int nsave = 0;
|
||||||
|
#endif
|
||||||
|
unsigned int seed = start * 1812433253U;
|
||||||
|
|
||||||
|
n = 1;
|
||||||
|
count = 0;
|
||||||
|
do {
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
unsigned int j = count + i;
|
||||||
|
char p[32];
|
||||||
|
uint8_t hash[128];
|
||||||
|
snprintf(p, sizeof(p), "%u", seed + j);
|
||||||
|
#ifdef _OPENMP
|
||||||
|
const uint8_t *h =
|
||||||
|
#endif
|
||||||
|
yescrypt_r(shared, &local,
|
||||||
|
(const uint8_t *)p, strlen(p),
|
||||||
|
setting, &key, hash, sizeof(hash));
|
||||||
|
#ifdef _OPENMP
|
||||||
|
if (j < NSAVE) {
|
||||||
|
save[j][0] = 0;
|
||||||
|
strncat(save[j], (char *)h,
|
||||||
|
sizeof(save[j]) - 1);
|
||||||
|
nsave = j;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
count += n;
|
||||||
|
|
||||||
|
end = times(&end_tms);
|
||||||
|
n <<= 1;
|
||||||
|
} while (end - start < clk_tck * 2);
|
||||||
|
|
||||||
|
clock_t start_v = start_tms.tms_utime + start_tms.tms_stime +
|
||||||
|
start_tms.tms_cutime + start_tms.tms_cstime;
|
||||||
|
clock_t end_v = end_tms.tms_utime + end_tms.tms_stime +
|
||||||
|
end_tms.tms_cutime + end_tms.tms_cstime;
|
||||||
|
|
||||||
|
printf("%llu c/s real, %llu c/s virtual "
|
||||||
|
"(%llu hashes in %.2f seconds)\n",
|
||||||
|
count * clk_tck / (end - start),
|
||||||
|
count * clk_tck / (end_v - start_v),
|
||||||
|
count, (double)(end - start) / clk_tck);
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
unsigned int nt = omp_get_max_threads();
|
||||||
|
|
||||||
|
printf("Benchmarking %u thread%s ...\n",
|
||||||
|
nt, nt == 1 ? "" : "s");
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
yescrypt_local_t local;
|
||||||
|
uint64_t min, max, total;
|
||||||
|
} thread_data_s;
|
||||||
|
union {
|
||||||
|
thread_data_s s;
|
||||||
|
uint8_t cachelines[2][64]; /* avoid false sharing */
|
||||||
|
} thread_data[nt]; /* tricky to align this when on stack */
|
||||||
|
|
||||||
|
unsigned int t;
|
||||||
|
for (t = 0; t < nt; t++) {
|
||||||
|
thread_data_s *td = &thread_data[t].s;
|
||||||
|
if (yescrypt_init_local(&td->local)) {
|
||||||
|
puts("yescrypt_init_local() FAILED");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
td->min = ~(uint64_t)0; td->max = 0; td->total = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long count1 = count, count_restart = 0;
|
||||||
|
|
||||||
|
if (!geteuid()) {
|
||||||
|
puts("Running as root, so trying to set SCHED_RR");
|
||||||
|
#pragma omp parallel
|
||||||
|
{
|
||||||
|
struct sched_param param = { .sched_priority = 1 };
|
||||||
|
if (sched_setscheduler(getpid(), SCHED_RR, ¶m))
|
||||||
|
perror("sched_setscheduler");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start = times(&start_tms);
|
||||||
|
|
||||||
|
n = count * omp_get_max_threads();
|
||||||
|
count = 0;
|
||||||
|
do {
|
||||||
|
#pragma omp parallel for default(none) private(i) shared(n, shared, thread_data, setting, seed, count, save, nsave, key)
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
unsigned int j = count + i;
|
||||||
|
char p[32];
|
||||||
|
uint8_t hash[128];
|
||||||
|
snprintf(p, sizeof(p), "%u", seed + j);
|
||||||
|
thread_data_s *td = &thread_data[omp_get_thread_num()].s;
|
||||||
|
uint64_t start1 = time_us();
|
||||||
|
#if 1
|
||||||
|
const char *h = (const char *)yescrypt_r(
|
||||||
|
shared, &td->local,
|
||||||
|
(const uint8_t *)p, strlen(p),
|
||||||
|
setting, &key, hash, sizeof(hash));
|
||||||
|
#else
|
||||||
|
yescrypt_local_t local;
|
||||||
|
yescrypt_init_local(&local);
|
||||||
|
const char *h = (const char *)yescrypt_r(
|
||||||
|
shared, &local,
|
||||||
|
(const uint8_t *)p, strlen(p),
|
||||||
|
setting, &key, hash, sizeof(hash));
|
||||||
|
yescrypt_free_local(&local);
|
||||||
|
#endif
|
||||||
|
uint64_t end1 = time_us();
|
||||||
|
if (end1 < start1)
|
||||||
|
end1 = start1;
|
||||||
|
uint64_t diff1 = end1 - start1;
|
||||||
|
td->total += diff1;
|
||||||
|
if (diff1 < td->min)
|
||||||
|
td->min = diff1;
|
||||||
|
if (diff1 > td->max)
|
||||||
|
td->max = diff1;
|
||||||
|
if (j < nsave && strcmp(save[j], h)) {
|
||||||
|
#pragma omp critical
|
||||||
|
printf("Mismatch at %u, %s != %s\n",
|
||||||
|
j, save[j], h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
count += n;
|
||||||
|
if ((count - n) < count1 && count >= count1) {
|
||||||
|
/* Disregard our repeat of single thread's results (could be partially cached
|
||||||
|
* by same core, but OTOH other cores not yet warmed up to full clock rate). */
|
||||||
|
start = times(&start_tms);
|
||||||
|
count_restart = count;
|
||||||
|
for (t = 0; t < nt; t++) {
|
||||||
|
thread_data_s *td = &thread_data[t].s;
|
||||||
|
td->min = ~(uint64_t)0; td->max = 0; td->total = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
n <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = times(&end_tms);
|
||||||
|
} while (end - start < clk_tck);
|
||||||
|
|
||||||
|
if (!count_restart)
|
||||||
|
puts("Didn't reach single-thread's hash count");
|
||||||
|
count -= count_restart;
|
||||||
|
|
||||||
|
start_v = start_tms.tms_utime + start_tms.tms_stime +
|
||||||
|
start_tms.tms_cutime + start_tms.tms_cstime;
|
||||||
|
end_v = end_tms.tms_utime + end_tms.tms_stime +
|
||||||
|
end_tms.tms_cutime + end_tms.tms_cstime;
|
||||||
|
|
||||||
|
printf("%llu c/s real, %llu c/s virtual "
|
||||||
|
"(%llu hashes in %.2f seconds)\n",
|
||||||
|
count * clk_tck / (end - start),
|
||||||
|
count * clk_tck / (end_v - start_v),
|
||||||
|
count, (double)(end - start) / clk_tck);
|
||||||
|
|
||||||
|
uint64_t min = ~(uint64_t)0, max = 0, total = 0;
|
||||||
|
for (t = 0; t < nt; t++) {
|
||||||
|
thread_data_s *td = &thread_data[t].s;
|
||||||
|
total += td->total;
|
||||||
|
if (td->min < min)
|
||||||
|
min = td->min;
|
||||||
|
if (td->max > max)
|
||||||
|
max = td->max;
|
||||||
|
}
|
||||||
|
printf("min %.3f ms, avg %.3f ms, max %.3f ms\n",
|
||||||
|
min / 1000.0, total / 1000.0 / count, max / 1000.0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rom_filename && munmap(shared->base, rom_bytes)) {
|
||||||
|
perror("munmap");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
703
deps/yescrypt-master/yescrypt-common.c
vendored
Normal file
703
deps/yescrypt-master/yescrypt-common.c
vendored
Normal file
@ -0,0 +1,703 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2013-2018 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "insecure_memzero.h"
|
||||||
|
#include "sha256.h"
|
||||||
|
|
||||||
|
#define YESCRYPT_INTERNAL
|
||||||
|
#include "yescrypt.h"
|
||||||
|
|
||||||
|
#define BYTES2CHARS(bytes) ((((bytes) * 8) + 5) / 6)
|
||||||
|
|
||||||
|
#define HASH_SIZE sizeof(yescrypt_binary_t) /* bytes */
|
||||||
|
#define HASH_LEN BYTES2CHARS(HASH_SIZE) /* base-64 chars */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "$y$", up to 8 params of up to 6 chars each, '$', salt
|
||||||
|
* Alternatively, but that's smaller:
|
||||||
|
* "$7$", 3 params encoded as 1+5+5 chars, salt
|
||||||
|
*/
|
||||||
|
#define PREFIX_LEN (3 + 8 * 6 + 1 + BYTES2CHARS(32))
|
||||||
|
|
||||||
|
static const char * const itoa64 =
|
||||||
|
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
static const uint8_t atoi64_partial[77] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||||
|
64, 64, 64, 64, 64, 64, 64,
|
||||||
|
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
|
||||||
|
64, 64, 64, 64, 64, 64,
|
||||||
|
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
|
||||||
|
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t *encode64_uint32(uint8_t *dst, size_t dstlen,
|
||||||
|
uint32_t src, uint32_t min)
|
||||||
|
{
|
||||||
|
uint32_t start = 0, end = 47, chars = 1, bits = 0;
|
||||||
|
|
||||||
|
if (src < min)
|
||||||
|
return NULL;
|
||||||
|
src -= min;
|
||||||
|
|
||||||
|
do {
|
||||||
|
uint32_t count = (end + 1 - start) << bits;
|
||||||
|
if (src < count)
|
||||||
|
break;
|
||||||
|
if (start >= 63)
|
||||||
|
return NULL;
|
||||||
|
start = end + 1;
|
||||||
|
end = start + (62 - end) / 2;
|
||||||
|
src -= count;
|
||||||
|
chars++;
|
||||||
|
bits += 6;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
if (dstlen <= chars) /* require room for a NUL terminator */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*dst++ = itoa64[start + (src >> bits)];
|
||||||
|
|
||||||
|
while (--chars) {
|
||||||
|
bits -= 6;
|
||||||
|
*dst++ = itoa64[(src >> bits) & 0x3f];
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = 0; /* NUL terminate just in case */
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t atoi64(uint8_t src)
|
||||||
|
{
|
||||||
|
if (src >= '.' && src <= 'z')
|
||||||
|
return atoi64_partial[src - '.'];
|
||||||
|
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint8_t *decode64_uint32(uint32_t *dst,
|
||||||
|
const uint8_t *src, uint32_t min)
|
||||||
|
{
|
||||||
|
uint32_t start = 0, end = 47, chars = 1, bits = 0;
|
||||||
|
uint32_t c;
|
||||||
|
|
||||||
|
c = atoi64(*src++);
|
||||||
|
if (c > 63)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
*dst = min;
|
||||||
|
while (c > end) {
|
||||||
|
*dst += (end + 1 - start) << bits;
|
||||||
|
start = end + 1;
|
||||||
|
end = start + (62 - end) / 2;
|
||||||
|
chars++;
|
||||||
|
bits += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst += (c - start) << bits;
|
||||||
|
|
||||||
|
while (--chars) {
|
||||||
|
c = atoi64(*src++);
|
||||||
|
if (c > 63)
|
||||||
|
goto fail;
|
||||||
|
bits -= 6;
|
||||||
|
*dst += c << bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
return src;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
*dst = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *encode64_uint32_fixed(uint8_t *dst, size_t dstlen,
|
||||||
|
uint32_t src, uint32_t srcbits)
|
||||||
|
{
|
||||||
|
uint32_t bits;
|
||||||
|
|
||||||
|
for (bits = 0; bits < srcbits; bits += 6) {
|
||||||
|
if (dstlen < 2)
|
||||||
|
return NULL;
|
||||||
|
*dst++ = itoa64[src & 0x3f];
|
||||||
|
dstlen--;
|
||||||
|
src >>= 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src || dstlen < 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*dst = 0; /* NUL terminate just in case */
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *encode64(uint8_t *dst, size_t dstlen,
|
||||||
|
const uint8_t *src, size_t srclen)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < srclen; ) {
|
||||||
|
uint8_t *dnext;
|
||||||
|
uint32_t value = 0, bits = 0;
|
||||||
|
do {
|
||||||
|
value |= (uint32_t)src[i++] << bits;
|
||||||
|
bits += 8;
|
||||||
|
} while (bits < 24 && i < srclen);
|
||||||
|
dnext = encode64_uint32_fixed(dst, dstlen, value, bits);
|
||||||
|
if (!dnext)
|
||||||
|
return NULL;
|
||||||
|
dstlen -= dnext - dst;
|
||||||
|
dst = dnext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dstlen < 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*dst = 0; /* NUL terminate just in case */
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint8_t *decode64_uint32_fixed(uint32_t *dst, uint32_t dstbits,
|
||||||
|
const uint8_t *src)
|
||||||
|
{
|
||||||
|
uint32_t bits;
|
||||||
|
|
||||||
|
*dst = 0;
|
||||||
|
for (bits = 0; bits < dstbits; bits += 6) {
|
||||||
|
uint32_t c = atoi64(*src++);
|
||||||
|
if (c > 63) {
|
||||||
|
*dst = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*dst |= c << bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint8_t *decode64(uint8_t *dst, size_t *dstlen,
|
||||||
|
const uint8_t *src, size_t srclen)
|
||||||
|
{
|
||||||
|
size_t dstpos = 0;
|
||||||
|
|
||||||
|
while (dstpos <= *dstlen && srclen) {
|
||||||
|
uint32_t value = 0, bits = 0;
|
||||||
|
while (srclen--) {
|
||||||
|
uint32_t c = atoi64(*src);
|
||||||
|
if (c > 63) {
|
||||||
|
srclen = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
src++;
|
||||||
|
value |= c << bits;
|
||||||
|
bits += 6;
|
||||||
|
if (bits >= 24)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!bits)
|
||||||
|
break;
|
||||||
|
if (bits < 12) /* must have at least one full byte */
|
||||||
|
goto fail;
|
||||||
|
while (dstpos++ < *dstlen) {
|
||||||
|
*dst++ = value;
|
||||||
|
value >>= 8;
|
||||||
|
bits -= 8;
|
||||||
|
if (bits < 8) { /* 2 or 4 */
|
||||||
|
if (value) /* must be 0 */
|
||||||
|
goto fail;
|
||||||
|
bits = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bits)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!srclen && dstpos <= *dstlen) {
|
||||||
|
*dstlen = dstpos;
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
*dstlen = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum { ENC = 1, DEC = -1 } encrypt_dir_t;
|
||||||
|
|
||||||
|
static void memxor(unsigned char *dst, unsigned char *src, size_t size)
|
||||||
|
{
|
||||||
|
while (size--)
|
||||||
|
*dst++ ^= *src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void encrypt(unsigned char *data, size_t datalen,
|
||||||
|
const yescrypt_binary_t *key, encrypt_dir_t dir)
|
||||||
|
{
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
unsigned char f[32 + 4];
|
||||||
|
size_t halflen, which;
|
||||||
|
unsigned char mask, round, target;
|
||||||
|
|
||||||
|
if (!datalen)
|
||||||
|
return;
|
||||||
|
if (datalen > 64)
|
||||||
|
datalen = 64;
|
||||||
|
|
||||||
|
halflen = datalen >> 1;
|
||||||
|
|
||||||
|
which = 0; /* offset to half we are working on (0 or halflen) */
|
||||||
|
mask = 0x0f; /* current half's extra nibble mask if datalen is odd */
|
||||||
|
|
||||||
|
round = 0;
|
||||||
|
target = 5; /* 6 rounds due to Jacques Patarin's CRYPTO 2004 paper */
|
||||||
|
|
||||||
|
if (dir == DEC) {
|
||||||
|
which = halflen; /* even round count, so swap the halves */
|
||||||
|
mask ^= 0xff;
|
||||||
|
|
||||||
|
round = target;
|
||||||
|
target = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f[32] = 0;
|
||||||
|
f[33] = sizeof(*key);
|
||||||
|
f[34] = datalen;
|
||||||
|
|
||||||
|
do {
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
f[35] = round;
|
||||||
|
SHA256_Update(&ctx, &f[32], 4);
|
||||||
|
SHA256_Update(&ctx, key, sizeof(*key));
|
||||||
|
SHA256_Update(&ctx, &data[which], halflen);
|
||||||
|
if (datalen & 1) {
|
||||||
|
f[0] = data[datalen - 1] & mask;
|
||||||
|
SHA256_Update(&ctx, f, 1);
|
||||||
|
}
|
||||||
|
SHA256_Final(f, &ctx);
|
||||||
|
which ^= halflen;
|
||||||
|
memxor(&data[which], f, halflen);
|
||||||
|
if (datalen & 1) {
|
||||||
|
mask ^= 0xff;
|
||||||
|
data[datalen - 1] ^= f[halflen] & mask;
|
||||||
|
}
|
||||||
|
if (round == target)
|
||||||
|
break;
|
||||||
|
round += dir;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
/* ctx is presumably zeroized by SHA256_Final() */
|
||||||
|
insecure_memzero(f, sizeof(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *yescrypt_r(const yescrypt_shared_t *shared, yescrypt_local_t *local,
|
||||||
|
const uint8_t *passwd, size_t passwdlen,
|
||||||
|
const uint8_t *setting,
|
||||||
|
const yescrypt_binary_t *key,
|
||||||
|
uint8_t *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
unsigned char saltbin[64], hashbin[32];
|
||||||
|
const uint8_t *src, *saltstr, *salt;
|
||||||
|
uint8_t *dst;
|
||||||
|
size_t need, prefixlen, saltstrlen, saltlen;
|
||||||
|
yescrypt_params_t params = { .p = 1 };
|
||||||
|
|
||||||
|
if (setting[0] != '$' ||
|
||||||
|
(setting[1] != '7' && setting[1] != 'y') ||
|
||||||
|
setting[2] != '$')
|
||||||
|
return NULL;
|
||||||
|
src = setting + 3;
|
||||||
|
|
||||||
|
if (setting[1] == '7') {
|
||||||
|
uint32_t N_log2 = atoi64(*src++);
|
||||||
|
if (N_log2 < 1 || N_log2 > 63)
|
||||||
|
return NULL;
|
||||||
|
params.N = (uint64_t)1 << N_log2;
|
||||||
|
|
||||||
|
src = decode64_uint32_fixed(¶ms.r, 30, src);
|
||||||
|
if (!src)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
src = decode64_uint32_fixed(¶ms.p, 30, src);
|
||||||
|
if (!src)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (key)
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
uint32_t flavor, N_log2;
|
||||||
|
|
||||||
|
src = decode64_uint32(&flavor, src, 0);
|
||||||
|
if (!src)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (flavor < YESCRYPT_RW) {
|
||||||
|
params.flags = flavor;
|
||||||
|
} else if (flavor <= YESCRYPT_RW + (YESCRYPT_RW_FLAVOR_MASK >> 2)) {
|
||||||
|
params.flags = YESCRYPT_RW + ((flavor - YESCRYPT_RW) << 2);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = decode64_uint32(&N_log2, src, 1);
|
||||||
|
if (!src || N_log2 > 63)
|
||||||
|
return NULL;
|
||||||
|
params.N = (uint64_t)1 << N_log2;
|
||||||
|
|
||||||
|
src = decode64_uint32(¶ms.r, src, 1);
|
||||||
|
if (!src)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (*src != '$') {
|
||||||
|
uint32_t have;
|
||||||
|
|
||||||
|
src = decode64_uint32(&have, src, 1);
|
||||||
|
if (!src)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (have & 1) {
|
||||||
|
src = decode64_uint32(¶ms.p, src, 2);
|
||||||
|
if (!src)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have & 2) {
|
||||||
|
src = decode64_uint32(¶ms.t, src, 1);
|
||||||
|
if (!src)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have & 4) {
|
||||||
|
src = decode64_uint32(¶ms.g, src, 1);
|
||||||
|
if (!src)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have & 8) {
|
||||||
|
uint32_t NROM_log2;
|
||||||
|
src = decode64_uint32(&NROM_log2, src, 1);
|
||||||
|
if (!src || NROM_log2 > 63)
|
||||||
|
return NULL;
|
||||||
|
params.NROM = (uint64_t)1 << NROM_log2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*src++ != '$')
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefixlen = src - setting;
|
||||||
|
|
||||||
|
saltstr = src;
|
||||||
|
src = (uint8_t *)strrchr((char *)saltstr, '$');
|
||||||
|
if (src)
|
||||||
|
saltstrlen = src - saltstr;
|
||||||
|
else
|
||||||
|
saltstrlen = strlen((char *)saltstr);
|
||||||
|
|
||||||
|
if (setting[1] == '7') {
|
||||||
|
salt = saltstr;
|
||||||
|
saltlen = saltstrlen;
|
||||||
|
} else {
|
||||||
|
const uint8_t *saltend;
|
||||||
|
|
||||||
|
saltlen = sizeof(saltbin);
|
||||||
|
saltend = decode64(saltbin, &saltlen, saltstr, saltstrlen);
|
||||||
|
|
||||||
|
if (!saltend || (size_t)(saltend - saltstr) != saltstrlen)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
salt = saltbin;
|
||||||
|
|
||||||
|
if (key)
|
||||||
|
encrypt(saltbin, saltlen, key, ENC);
|
||||||
|
}
|
||||||
|
|
||||||
|
need = prefixlen + saltstrlen + 1 + HASH_LEN + 1;
|
||||||
|
if (need > buflen || need < saltstrlen)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen,
|
||||||
|
¶ms, hashbin, sizeof(hashbin)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
insecure_memzero(saltbin, sizeof(saltbin));
|
||||||
|
encrypt(hashbin, sizeof(hashbin), key, ENC);
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = buf;
|
||||||
|
memcpy(dst, setting, prefixlen + saltstrlen);
|
||||||
|
dst += prefixlen + saltstrlen;
|
||||||
|
*dst++ = '$';
|
||||||
|
|
||||||
|
dst = encode64(dst, buflen - (dst - buf), hashbin, sizeof(hashbin));
|
||||||
|
insecure_memzero(hashbin, sizeof(hashbin));
|
||||||
|
if (!dst || dst >= buf + buflen)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*dst = 0; /* NUL termination */
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
insecure_memzero(saltbin, sizeof(saltbin));
|
||||||
|
insecure_memzero(hashbin, sizeof(hashbin));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *yescrypt(const uint8_t *passwd, const uint8_t *setting)
|
||||||
|
{
|
||||||
|
/* prefix, '$', hash, NUL */
|
||||||
|
static uint8_t buf[PREFIX_LEN + 1 + HASH_LEN + 1];
|
||||||
|
yescrypt_local_t local;
|
||||||
|
uint8_t *retval;
|
||||||
|
|
||||||
|
if (yescrypt_init_local(&local))
|
||||||
|
return NULL;
|
||||||
|
retval = yescrypt_r(NULL, &local,
|
||||||
|
passwd, strlen((char *)passwd), setting, NULL, buf, sizeof(buf));
|
||||||
|
if (yescrypt_free_local(&local))
|
||||||
|
return NULL;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *yescrypt_reencrypt(uint8_t *hash,
|
||||||
|
const yescrypt_binary_t *from_key,
|
||||||
|
const yescrypt_binary_t *to_key)
|
||||||
|
{
|
||||||
|
uint8_t *retval = NULL, *saltstart, *hashstart;
|
||||||
|
const uint8_t *hashend;
|
||||||
|
unsigned char saltbin[64], hashbin[32];
|
||||||
|
size_t saltstrlen, saltlen = 0, hashlen;
|
||||||
|
|
||||||
|
if (strncmp((char *)hash, "$y$", 3))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
saltstart = NULL;
|
||||||
|
hashstart = (uint8_t *)strrchr((char *)hash, '$');
|
||||||
|
if (hashstart) {
|
||||||
|
if (hashstart > (uint8_t *)hash) {
|
||||||
|
saltstart = hashstart - 1;
|
||||||
|
while (*saltstart != '$' && saltstart > hash)
|
||||||
|
saltstart--;
|
||||||
|
if (*saltstart == '$')
|
||||||
|
saltstart++;
|
||||||
|
}
|
||||||
|
hashstart++;
|
||||||
|
} else {
|
||||||
|
hashstart = hash;
|
||||||
|
}
|
||||||
|
saltstrlen = saltstart ? (hashstart - 1 - saltstart) : 0;
|
||||||
|
if (saltstrlen > BYTES2CHARS(64) ||
|
||||||
|
strlen((char *)hashstart) != HASH_LEN)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (saltstrlen) {
|
||||||
|
const uint8_t *saltend;
|
||||||
|
saltlen = sizeof(saltbin);
|
||||||
|
saltend = decode64(saltbin, &saltlen, saltstart, saltstrlen);
|
||||||
|
if (!saltend || *saltend != '$' || saltlen < 1 || saltlen > 64)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (from_key)
|
||||||
|
encrypt(saltbin, saltlen, from_key, ENC);
|
||||||
|
if (to_key)
|
||||||
|
encrypt(saltbin, saltlen, to_key, DEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
hashlen = sizeof(hashbin);
|
||||||
|
hashend = decode64(hashbin, &hashlen, hashstart, HASH_LEN);
|
||||||
|
if (!hashend || *hashend || hashlen != sizeof(hashbin))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (from_key)
|
||||||
|
encrypt(hashbin, hashlen, from_key, DEC);
|
||||||
|
if (to_key)
|
||||||
|
encrypt(hashbin, hashlen, to_key, ENC);
|
||||||
|
|
||||||
|
if (saltstrlen) {
|
||||||
|
if (!encode64(saltstart, saltstrlen + 1, saltbin, saltlen))
|
||||||
|
goto out; /* can't happen */
|
||||||
|
*(saltstart + saltstrlen) = '$';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!encode64(hashstart, HASH_LEN + 1, hashbin, hashlen))
|
||||||
|
goto out; /* can't happen */
|
||||||
|
|
||||||
|
retval = hash;
|
||||||
|
|
||||||
|
out:
|
||||||
|
insecure_memzero(saltbin, sizeof(saltbin));
|
||||||
|
insecure_memzero(hashbin, sizeof(hashbin));
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t N2log2(uint64_t N)
|
||||||
|
{
|
||||||
|
uint32_t N_log2;
|
||||||
|
|
||||||
|
if (N < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
N_log2 = 2;
|
||||||
|
while (N >> N_log2 != 0)
|
||||||
|
N_log2++;
|
||||||
|
N_log2--;
|
||||||
|
|
||||||
|
if (N >> N_log2 != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return N_log2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *yescrypt_encode_params_r(const yescrypt_params_t *params,
|
||||||
|
const uint8_t *src, size_t srclen,
|
||||||
|
uint8_t *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
uint32_t flavor, N_log2, NROM_log2, have;
|
||||||
|
uint8_t *dst;
|
||||||
|
|
||||||
|
if (srclen > SIZE_MAX / 16)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (params->flags < YESCRYPT_RW) {
|
||||||
|
flavor = params->flags;
|
||||||
|
} else if ((params->flags & YESCRYPT_MODE_MASK) == YESCRYPT_RW &&
|
||||||
|
params->flags <= (YESCRYPT_RW | YESCRYPT_RW_FLAVOR_MASK)) {
|
||||||
|
flavor = YESCRYPT_RW + (params->flags >> 2);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
N_log2 = N2log2(params->N);
|
||||||
|
if (!N_log2)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
NROM_log2 = N2log2(params->NROM);
|
||||||
|
if (params->NROM && !NROM_log2)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((uint64_t)params->r * (uint64_t)params->p >= (1U << 30))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dst = buf;
|
||||||
|
*dst++ = '$';
|
||||||
|
*dst++ = 'y';
|
||||||
|
*dst++ = '$';
|
||||||
|
|
||||||
|
dst = encode64_uint32(dst, buflen - (dst - buf), flavor, 0);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dst = encode64_uint32(dst, buflen - (dst - buf), N_log2, 1);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dst = encode64_uint32(dst, buflen - (dst - buf), params->r, 1);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
have = 0;
|
||||||
|
if (params->p != 1)
|
||||||
|
have |= 1;
|
||||||
|
if (params->t)
|
||||||
|
have |= 2;
|
||||||
|
if (params->g)
|
||||||
|
have |= 4;
|
||||||
|
if (NROM_log2)
|
||||||
|
have |= 8;
|
||||||
|
|
||||||
|
if (have) {
|
||||||
|
dst = encode64_uint32(dst, buflen - (dst - buf), have, 1);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->p != 1) {
|
||||||
|
dst = encode64_uint32(dst, buflen - (dst - buf), params->p, 2);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->t) {
|
||||||
|
dst = encode64_uint32(dst, buflen - (dst - buf), params->t, 1);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->g) {
|
||||||
|
dst = encode64_uint32(dst, buflen - (dst - buf), params->g, 1);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NROM_log2) {
|
||||||
|
dst = encode64_uint32(dst, buflen - (dst - buf), NROM_log2, 1);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst >= buf + buflen)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*dst++ = '$';
|
||||||
|
|
||||||
|
dst = encode64(dst, buflen - (dst - buf), src, srclen);
|
||||||
|
if (!dst || dst >= buf + buflen)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*dst = 0; /* NUL termination */
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *yescrypt_encode_params(const yescrypt_params_t *params,
|
||||||
|
const uint8_t *src, size_t srclen)
|
||||||
|
{
|
||||||
|
/* prefix, NUL */
|
||||||
|
static uint8_t buf[PREFIX_LEN + 1];
|
||||||
|
return yescrypt_encode_params_r(params, src, srclen, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
int crypto_scrypt(const uint8_t *passwd, size_t passwdlen,
|
||||||
|
const uint8_t *salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
|
||||||
|
uint8_t *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
yescrypt_local_t local;
|
||||||
|
yescrypt_params_t params = { .flags = 0, .N = N, .r = r, .p = p };
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (yescrypt_init_local(&local))
|
||||||
|
return -1;
|
||||||
|
retval = yescrypt_kdf(NULL, &local,
|
||||||
|
passwd, passwdlen, salt, saltlen, ¶ms, buf, buflen);
|
||||||
|
if (yescrypt_free_local(&local))
|
||||||
|
return -1;
|
||||||
|
return retval;
|
||||||
|
}
|
1533
deps/yescrypt-master/yescrypt-opt.c
vendored
Normal file
1533
deps/yescrypt-master/yescrypt-opt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
111
deps/yescrypt-master/yescrypt-platform.c
vendored
Normal file
111
deps/yescrypt-master/yescrypt-platform.c
vendored
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2013-2018,2022 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __unix__
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <linux/mman.h> /* for MAP_HUGE_2MB */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HUGEPAGE_THRESHOLD (32 * 1024 * 1024)
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define HUGEPAGE_SIZE (2 * 1024 * 1024)
|
||||||
|
#else
|
||||||
|
#undef HUGEPAGE_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void *alloc_region(yescrypt_region_t *region, size_t size)
|
||||||
|
{
|
||||||
|
size_t base_size = size;
|
||||||
|
uint8_t *base, *aligned;
|
||||||
|
#ifdef MAP_ANON
|
||||||
|
int flags =
|
||||||
|
#ifdef MAP_NOCORE
|
||||||
|
MAP_NOCORE |
|
||||||
|
#endif
|
||||||
|
MAP_ANON | MAP_PRIVATE;
|
||||||
|
#if defined(MAP_HUGETLB) && defined(MAP_HUGE_2MB) && defined(HUGEPAGE_SIZE)
|
||||||
|
size_t new_size = size;
|
||||||
|
const size_t hugepage_mask = (size_t)HUGEPAGE_SIZE - 1;
|
||||||
|
if (size >= HUGEPAGE_THRESHOLD && size + hugepage_mask >= size) {
|
||||||
|
flags |= MAP_HUGETLB | MAP_HUGE_2MB;
|
||||||
|
/*
|
||||||
|
* Linux's munmap() fails on MAP_HUGETLB mappings if size is not a multiple of
|
||||||
|
* huge page size, so let's round up to huge page size here.
|
||||||
|
*/
|
||||||
|
new_size = size + hugepage_mask;
|
||||||
|
new_size &= ~hugepage_mask;
|
||||||
|
}
|
||||||
|
base = mmap(NULL, new_size, PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||||
|
if (base != MAP_FAILED) {
|
||||||
|
base_size = new_size;
|
||||||
|
} else if (flags & MAP_HUGETLB) {
|
||||||
|
flags &= ~(MAP_HUGETLB | MAP_HUGE_2MB);
|
||||||
|
base = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
base = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||||
|
#endif
|
||||||
|
if (base == MAP_FAILED)
|
||||||
|
base = NULL;
|
||||||
|
aligned = base;
|
||||||
|
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||||
|
if ((errno = posix_memalign((void **)&base, 64, size)) != 0)
|
||||||
|
base = NULL;
|
||||||
|
aligned = base;
|
||||||
|
#else
|
||||||
|
base = aligned = NULL;
|
||||||
|
if (size + 63 < size) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
} else if ((base = malloc(size + 63)) != NULL) {
|
||||||
|
aligned = base + 63;
|
||||||
|
aligned -= (uintptr_t)aligned & 63;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
region->base = base;
|
||||||
|
region->aligned = aligned;
|
||||||
|
region->base_size = base ? base_size : 0;
|
||||||
|
region->aligned_size = base ? size : 0;
|
||||||
|
return aligned;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void init_region(yescrypt_region_t *region)
|
||||||
|
{
|
||||||
|
region->base = region->aligned = NULL;
|
||||||
|
region->base_size = region->aligned_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int free_region(yescrypt_region_t *region)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
if (region->base) {
|
||||||
|
#ifdef MAP_ANON
|
||||||
|
if (munmap(region->base, region->base_size))
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
free(region->base);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
init_region(region);
|
||||||
|
return 0;
|
||||||
|
}
|
925
deps/yescrypt-master/yescrypt-ref.c
vendored
Normal file
925
deps/yescrypt-master/yescrypt-ref.c
vendored
Normal file
@ -0,0 +1,925 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2009 Colin Percival
|
||||||
|
* Copyright 2013-2018 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file was originally written by Colin Percival as part of the Tarsnap
|
||||||
|
* online backup system.
|
||||||
|
*
|
||||||
|
* This is the reference implementation. Its purpose is to provide a simple
|
||||||
|
* human- and machine-readable specification that implementations intended
|
||||||
|
* for actual use should be tested against. It is deliberately mostly not
|
||||||
|
* optimized, and it is not meant to be used in production. Instead, use
|
||||||
|
* yescrypt-opt.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#warning "This reference implementation is deliberately mostly not optimized, nor does it make any attempt not to leave sensitive data in memory. Use yescrypt-opt.c instead unless you're testing (against) the reference implementation on purpose."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "sha256.h"
|
||||||
|
#include "sysendian.h"
|
||||||
|
|
||||||
|
#define YESCRYPT_INTERNAL
|
||||||
|
#include "yescrypt.h"
|
||||||
|
|
||||||
|
static void blkcpy(uint32_t *dst, const uint32_t *src, size_t count)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
*dst++ = *src++;
|
||||||
|
} while (--count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blkxor(uint32_t *dst, const uint32_t *src, size_t count)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
*dst++ ^= *src++;
|
||||||
|
} while (--count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* salsa20(B):
|
||||||
|
* Apply the Salsa20 core to the provided block.
|
||||||
|
*/
|
||||||
|
static void salsa20(uint32_t B[16], uint32_t rounds)
|
||||||
|
{
|
||||||
|
uint32_t x[16];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* SIMD unshuffle */
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
x[i * 5 % 16] = B[i];
|
||||||
|
|
||||||
|
for (i = 0; i < rounds; i += 2) {
|
||||||
|
#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
|
||||||
|
/* Operate on columns */
|
||||||
|
x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
|
||||||
|
x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
|
||||||
|
|
||||||
|
x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
|
||||||
|
x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
|
||||||
|
|
||||||
|
x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
|
||||||
|
x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
|
||||||
|
|
||||||
|
x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
|
||||||
|
x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
|
||||||
|
|
||||||
|
/* Operate on rows */
|
||||||
|
x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
|
||||||
|
x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
|
||||||
|
|
||||||
|
x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
|
||||||
|
x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
|
||||||
|
|
||||||
|
x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
|
||||||
|
x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
|
||||||
|
|
||||||
|
x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
|
||||||
|
x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
|
||||||
|
#undef R
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SIMD shuffle */
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
B[i] += x[i * 5 % 16];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* blockmix_salsa8(B, Y, r):
|
||||||
|
* Compute B = BlockMix_{salsa20/8, r}(B). The input B must be 128r bytes in
|
||||||
|
* length; the temporary space Y must also be the same size.
|
||||||
|
*/
|
||||||
|
static void blockmix_salsa8(uint32_t *B, uint32_t *Y, size_t r)
|
||||||
|
{
|
||||||
|
uint32_t X[16];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* 1: X <-- B_{2r - 1} */
|
||||||
|
blkcpy(X, &B[(2 * r - 1) * 16], 16);
|
||||||
|
|
||||||
|
/* 2: for i = 0 to 2r - 1 do */
|
||||||
|
for (i = 0; i < 2 * r; i++) {
|
||||||
|
/* 3: X <-- H(X xor B_i) */
|
||||||
|
blkxor(X, &B[i * 16], 16);
|
||||||
|
salsa20(X, 8);
|
||||||
|
|
||||||
|
/* 4: Y_i <-- X */
|
||||||
|
blkcpy(&Y[i * 16], X, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
|
||||||
|
for (i = 0; i < r; i++)
|
||||||
|
blkcpy(&B[i * 16], &Y[(i * 2) * 16], 16);
|
||||||
|
for (i = 0; i < r; i++)
|
||||||
|
blkcpy(&B[(i + r) * 16], &Y[(i * 2 + 1) * 16], 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* These are tunable, but they must meet certain constraints */
|
||||||
|
#define PWXsimple 2
|
||||||
|
#define PWXgather 4
|
||||||
|
#define PWXrounds 6
|
||||||
|
#define Swidth 8
|
||||||
|
|
||||||
|
/* Derived values. Not tunable on their own. */
|
||||||
|
#define PWXbytes (PWXgather * PWXsimple * 8)
|
||||||
|
#define PWXwords (PWXbytes / sizeof(uint32_t))
|
||||||
|
#define Sbytes (3 * (1 << Swidth) * PWXsimple * 8)
|
||||||
|
#define Swords (Sbytes / sizeof(uint32_t))
|
||||||
|
#define Smask (((1 << Swidth) - 1) * PWXsimple * 8)
|
||||||
|
#define rmin ((PWXbytes + 127) / 128)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t *S;
|
||||||
|
uint32_t (*S0)[2], (*S1)[2], (*S2)[2];
|
||||||
|
size_t w;
|
||||||
|
} pwxform_ctx_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pwxform(B):
|
||||||
|
* Transform the provided block using the provided S-boxes.
|
||||||
|
*/
|
||||||
|
static void pwxform(uint32_t *B, pwxform_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
uint32_t (*X)[PWXsimple][2] = (uint32_t (*)[PWXsimple][2])B;
|
||||||
|
uint32_t (*S0)[2] = ctx->S0, (*S1)[2] = ctx->S1, (*S2)[2] = ctx->S2;
|
||||||
|
size_t w = ctx->w;
|
||||||
|
size_t i, j, k;
|
||||||
|
|
||||||
|
/* 1: for i = 0 to PWXrounds - 1 do */
|
||||||
|
for (i = 0; i < PWXrounds; i++) {
|
||||||
|
/* 2: for j = 0 to PWXgather - 1 do */
|
||||||
|
for (j = 0; j < PWXgather; j++) {
|
||||||
|
uint32_t xl = X[j][0][0];
|
||||||
|
uint32_t xh = X[j][0][1];
|
||||||
|
uint32_t (*p0)[2], (*p1)[2];
|
||||||
|
|
||||||
|
/* 3: p0 <-- (lo(B_{j,0}) & Smask) / (PWXsimple * 8) */
|
||||||
|
p0 = S0 + (xl & Smask) / sizeof(*S0);
|
||||||
|
/* 4: p1 <-- (hi(B_{j,0}) & Smask) / (PWXsimple * 8) */
|
||||||
|
p1 = S1 + (xh & Smask) / sizeof(*S1);
|
||||||
|
|
||||||
|
/* 5: for k = 0 to PWXsimple - 1 do */
|
||||||
|
for (k = 0; k < PWXsimple; k++) {
|
||||||
|
uint64_t x, s0, s1;
|
||||||
|
|
||||||
|
/* 6: B_{j,k} <-- (hi(B_{j,k}) * lo(B_{j,k}) + S0_{p0,k}) xor S1_{p1,k} */
|
||||||
|
s0 = ((uint64_t)p0[k][1] << 32) + p0[k][0];
|
||||||
|
s1 = ((uint64_t)p1[k][1] << 32) + p1[k][0];
|
||||||
|
|
||||||
|
xl = X[j][k][0];
|
||||||
|
xh = X[j][k][1];
|
||||||
|
|
||||||
|
x = (uint64_t)xh * xl;
|
||||||
|
x += s0;
|
||||||
|
x ^= s1;
|
||||||
|
|
||||||
|
X[j][k][0] = x;
|
||||||
|
X[j][k][1] = x >> 32;
|
||||||
|
|
||||||
|
/* 8: if (i != 0) and (i != PWXrounds - 1) */
|
||||||
|
if (i != 0 && i != PWXrounds - 1) {
|
||||||
|
/* 9: S2_w <-- B_j */
|
||||||
|
S2[w][0] = x;
|
||||||
|
S2[w][1] = x >> 32;
|
||||||
|
/* 10: w <-- w + 1 */
|
||||||
|
w++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 14: (S0, S1, S2) <-- (S2, S0, S1) */
|
||||||
|
ctx->S0 = S2;
|
||||||
|
ctx->S1 = S0;
|
||||||
|
ctx->S2 = S1;
|
||||||
|
/* 15: w <-- w mod 2^Swidth */
|
||||||
|
ctx->w = w & ((1 << Swidth) * PWXsimple - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* blockmix_pwxform(B, ctx, r):
|
||||||
|
* Compute B = BlockMix_pwxform{salsa20/2, ctx, r}(B). The input B must be
|
||||||
|
* 128r bytes in length.
|
||||||
|
*/
|
||||||
|
static void blockmix_pwxform(uint32_t *B, pwxform_ctx_t *ctx, size_t r)
|
||||||
|
{
|
||||||
|
uint32_t X[PWXwords];
|
||||||
|
size_t r1, i;
|
||||||
|
|
||||||
|
/* Convert 128-byte blocks to PWXbytes blocks */
|
||||||
|
/* 1: r_1 <-- 128r / PWXbytes */
|
||||||
|
r1 = 128 * r / PWXbytes;
|
||||||
|
|
||||||
|
/* 2: X <-- B'_{r_1 - 1} */
|
||||||
|
blkcpy(X, &B[(r1 - 1) * PWXwords], PWXwords);
|
||||||
|
|
||||||
|
/* 3: for i = 0 to r_1 - 1 do */
|
||||||
|
for (i = 0; i < r1; i++) {
|
||||||
|
/* 4: if r_1 > 1 */
|
||||||
|
if (r1 > 1) {
|
||||||
|
/* 5: X <-- X xor B'_i */
|
||||||
|
blkxor(X, &B[i * PWXwords], PWXwords);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 7: X <-- pwxform(X) */
|
||||||
|
pwxform(X, ctx);
|
||||||
|
|
||||||
|
/* 8: B'_i <-- X */
|
||||||
|
blkcpy(&B[i * PWXwords], X, PWXwords);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10: i <-- floor((r_1 - 1) * PWXbytes / 64) */
|
||||||
|
i = (r1 - 1) * PWXbytes / 64;
|
||||||
|
|
||||||
|
/* 11: B_i <-- H(B_i) */
|
||||||
|
salsa20(&B[i * 16], 2);
|
||||||
|
|
||||||
|
#if 1 /* No-op with our current pwxform settings, but do it to make sure */
|
||||||
|
/* 12: for i = i + 1 to 2r - 1 do */
|
||||||
|
for (i++; i < 2 * r; i++) {
|
||||||
|
/* 13: B_i <-- H(B_i xor B_{i-1}) */
|
||||||
|
blkxor(&B[i * 16], &B[(i - 1) * 16], 16);
|
||||||
|
salsa20(&B[i * 16], 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* integerify(B, r):
|
||||||
|
* Return the result of parsing B_{2r-1} as a little-endian integer.
|
||||||
|
*/
|
||||||
|
static uint64_t integerify(const uint32_t *B, size_t r)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Our 32-bit words are in host byte order, and word 13 is the second word of
|
||||||
|
* B_{2r-1} due to SIMD shuffling. The 64-bit value we return is also in host
|
||||||
|
* byte order, as it should be.
|
||||||
|
*/
|
||||||
|
const uint32_t *X = &B[(2 * r - 1) * 16];
|
||||||
|
return ((uint64_t)X[13] << 32) + X[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* p2floor(x):
|
||||||
|
* Largest power of 2 not greater than argument.
|
||||||
|
*/
|
||||||
|
static uint64_t p2floor(uint64_t x)
|
||||||
|
{
|
||||||
|
uint64_t y;
|
||||||
|
while ((y = x & (x - 1)))
|
||||||
|
x = y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wrap(x, i):
|
||||||
|
* Wrap x to the range 0 to i-1.
|
||||||
|
*/
|
||||||
|
static uint64_t wrap(uint64_t x, uint64_t i)
|
||||||
|
{
|
||||||
|
uint64_t n = p2floor(i);
|
||||||
|
return (x & (n - 1)) + (i - n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* smix1(B, r, N, flags, V, NROM, VROM, XY, ctx):
|
||||||
|
* Compute first loop of B = SMix_r(B, N). The input B must be 128r bytes in
|
||||||
|
* length; the temporary storage V must be 128rN bytes in length; the temporary
|
||||||
|
* storage XY must be 256r bytes in length.
|
||||||
|
*/
|
||||||
|
static void smix1(uint32_t *B, size_t r, uint64_t N, yescrypt_flags_t flags,
|
||||||
|
uint32_t *V, uint64_t NROM, const uint32_t *VROM,
|
||||||
|
uint32_t *XY, pwxform_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
size_t s = 32 * r;
|
||||||
|
uint32_t *X = XY;
|
||||||
|
uint32_t *Y = &XY[s];
|
||||||
|
uint64_t i, j;
|
||||||
|
size_t k;
|
||||||
|
|
||||||
|
/* 1: X <-- B */
|
||||||
|
for (k = 0; k < 2 * r; k++)
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
X[k * 16 + i] = le32dec(&B[k * 16 + (i * 5 % 16)]);
|
||||||
|
|
||||||
|
/* 2: for i = 0 to N - 1 do */
|
||||||
|
for (i = 0; i < N; i++) {
|
||||||
|
/* 3: V_i <-- X */
|
||||||
|
blkcpy(&V[i * s], X, s);
|
||||||
|
|
||||||
|
if (VROM && i == 0) {
|
||||||
|
/* X <-- X xor VROM_{NROM-1} */
|
||||||
|
blkxor(X, &VROM[(NROM - 1) * s], s);
|
||||||
|
} else if (VROM && (i & 1)) {
|
||||||
|
/* j <-- Integerify(X) mod NROM */
|
||||||
|
j = integerify(X, r) & (NROM - 1);
|
||||||
|
|
||||||
|
/* X <-- X xor VROM_j */
|
||||||
|
blkxor(X, &VROM[j * s], s);
|
||||||
|
} else if ((flags & YESCRYPT_RW) && i > 1) {
|
||||||
|
/* j <-- Wrap(Integerify(X), i) */
|
||||||
|
j = wrap(integerify(X, r), i);
|
||||||
|
|
||||||
|
/* X <-- X xor V_j */
|
||||||
|
blkxor(X, &V[j * s], s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4: X <-- H(X) */
|
||||||
|
if (ctx)
|
||||||
|
blockmix_pwxform(X, ctx, r);
|
||||||
|
else
|
||||||
|
blockmix_salsa8(X, Y, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* B' <-- X */
|
||||||
|
for (k = 0; k < 2 * r; k++)
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
le32enc(&B[k * 16 + (i * 5 % 16)], X[k * 16 + i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* smix2(B, r, N, Nloop, flags, V, NROM, VROM, XY, ctx):
|
||||||
|
* Compute second loop of B = SMix_r(B, N). The input B must be 128r bytes in
|
||||||
|
* length; the temporary storage V must be 128rN bytes in length; the temporary
|
||||||
|
* storage XY must be 256r bytes in length. The value N must be a power of 2
|
||||||
|
* greater than 1.
|
||||||
|
*/
|
||||||
|
static void smix2(uint32_t *B, size_t r, uint64_t N, uint64_t Nloop,
|
||||||
|
yescrypt_flags_t flags, uint32_t *V, uint64_t NROM,
|
||||||
|
const uint32_t *VROM, uint32_t *XY, pwxform_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
size_t s = 32 * r;
|
||||||
|
uint32_t *X = XY;
|
||||||
|
uint32_t *Y = &XY[s];
|
||||||
|
uint64_t i, j;
|
||||||
|
size_t k;
|
||||||
|
|
||||||
|
/* X <-- B */
|
||||||
|
for (k = 0; k < 2 * r; k++)
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
X[k * 16 + i] = le32dec(&B[k * 16 + (i * 5 % 16)]);
|
||||||
|
|
||||||
|
/* 6: for i = 0 to N - 1 do */
|
||||||
|
for (i = 0; i < Nloop; i++) {
|
||||||
|
if (VROM && (i & 1)) {
|
||||||
|
/* j <-- Integerify(X) mod NROM */
|
||||||
|
j = integerify(X, r) & (NROM - 1);
|
||||||
|
|
||||||
|
/* X <-- H(X xor VROM_j) */
|
||||||
|
blkxor(X, &VROM[j * s], s);
|
||||||
|
} else {
|
||||||
|
/* 7: j <-- Integerify(X) mod N */
|
||||||
|
j = integerify(X, r) & (N - 1);
|
||||||
|
|
||||||
|
/* 8.1: X <-- X xor V_j */
|
||||||
|
blkxor(X, &V[j * s], s);
|
||||||
|
/* V_j <-- X */
|
||||||
|
if (flags & YESCRYPT_RW)
|
||||||
|
blkcpy(&V[j * s], X, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 8.2: X <-- H(X) */
|
||||||
|
if (ctx)
|
||||||
|
blockmix_pwxform(X, ctx, r);
|
||||||
|
else
|
||||||
|
blockmix_salsa8(X, Y, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10: B' <-- X */
|
||||||
|
for (k = 0; k < 2 * r; k++)
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
le32enc(&B[k * 16 + (i * 5 % 16)], X[k * 16 + i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* smix(B, r, N, p, t, flags, V, NROM, VROM, XY, ctx, passwd):
|
||||||
|
* Compute B = SMix_r(B, N). The input B must be 128rp bytes in length; the
|
||||||
|
* temporary storage V must be 128rN bytes in length; the temporary storage
|
||||||
|
* XY must be 256r bytes in length. The value N must be a power of 2 greater
|
||||||
|
* than 1.
|
||||||
|
*/
|
||||||
|
static void smix(uint32_t *B, size_t r, uint64_t N, uint32_t p, uint32_t t,
|
||||||
|
yescrypt_flags_t flags,
|
||||||
|
uint32_t *V, uint64_t NROM, const uint32_t *VROM,
|
||||||
|
uint32_t *XY, pwxform_ctx_t *ctx, uint8_t *passwd)
|
||||||
|
{
|
||||||
|
size_t s = 32 * r;
|
||||||
|
uint64_t Nchunk, Nloop_all, Nloop_rw, Vchunk;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
/* 1: n <-- N / p */
|
||||||
|
Nchunk = N / p;
|
||||||
|
|
||||||
|
/* 2: Nloop_all <-- fNloop(n, t, flags) */
|
||||||
|
Nloop_all = Nchunk;
|
||||||
|
if (flags & YESCRYPT_RW) {
|
||||||
|
if (t <= 1) {
|
||||||
|
if (t)
|
||||||
|
Nloop_all *= 2; /* 2/3 */
|
||||||
|
Nloop_all = (Nloop_all + 2) / 3; /* 1/3, round up */
|
||||||
|
} else {
|
||||||
|
Nloop_all *= t - 1;
|
||||||
|
}
|
||||||
|
} else if (t) {
|
||||||
|
if (t == 1)
|
||||||
|
Nloop_all += (Nloop_all + 1) / 2; /* 1.5, round up */
|
||||||
|
Nloop_all *= t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6: Nloop_rw <-- 0 */
|
||||||
|
Nloop_rw = 0;
|
||||||
|
if (flags & YESCRYPT_INIT_SHARED) {
|
||||||
|
Nloop_rw = Nloop_all;
|
||||||
|
} else {
|
||||||
|
/* 3: if YESCRYPT_RW flag is set */
|
||||||
|
if (flags & YESCRYPT_RW) {
|
||||||
|
/* 4: Nloop_rw <-- Nloop_all / p */
|
||||||
|
Nloop_rw = Nloop_all / p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 8: n <-- n - (n mod 2) */
|
||||||
|
Nchunk &= ~(uint64_t)1; /* round down to even */
|
||||||
|
/* 9: Nloop_all <-- Nloop_all + (Nloop_all mod 2) */
|
||||||
|
Nloop_all++; Nloop_all &= ~(uint64_t)1; /* round up to even */
|
||||||
|
/* 10: Nloop_rw <-- Nloop_rw + (Nloop_rw mod 2) */
|
||||||
|
Nloop_rw++; Nloop_rw &= ~(uint64_t)1; /* round up to even */
|
||||||
|
|
||||||
|
/* 11: for i = 0 to p - 1 do */
|
||||||
|
/* 12: u <-- in */
|
||||||
|
for (i = 0, Vchunk = 0; i < p; i++, Vchunk += Nchunk) {
|
||||||
|
/* 13: if i = p - 1 */
|
||||||
|
/* 14: n <-- N - u */
|
||||||
|
/* 15: end if */
|
||||||
|
/* 16: v <-- u + n - 1 */
|
||||||
|
uint64_t Np = (i < p - 1) ? Nchunk : (N - Vchunk);
|
||||||
|
uint32_t *Bp = &B[i * s];
|
||||||
|
uint32_t *Vp = &V[Vchunk * s];
|
||||||
|
pwxform_ctx_t *ctx_i = NULL;
|
||||||
|
/* 17: if YESCRYPT_RW flag is set */
|
||||||
|
if (flags & YESCRYPT_RW) {
|
||||||
|
ctx_i = &ctx[i];
|
||||||
|
/* 18: SMix1_1(B_i, Sbytes / 128, S_i, no flags) */
|
||||||
|
smix1(Bp, 1, Sbytes / 128, 0 /* no flags */,
|
||||||
|
ctx_i->S, 0, NULL, XY, NULL);
|
||||||
|
/* 19: S2_i <-- S_{i,0...2^Swidth-1} */
|
||||||
|
ctx_i->S2 = (uint32_t (*)[2])ctx_i->S;
|
||||||
|
/* 20: S1_i <-- S_{i,2^Swidth...2*2^Swidth-1} */
|
||||||
|
ctx_i->S1 = ctx_i->S2 + (1 << Swidth) * PWXsimple;
|
||||||
|
/* 21: S0_i <-- S_{i,2*2^Swidth...3*2^Swidth-1} */
|
||||||
|
ctx_i->S0 = ctx_i->S1 + (1 << Swidth) * PWXsimple;
|
||||||
|
/* 22: w_i <-- 0 */
|
||||||
|
ctx_i->w = 0;
|
||||||
|
/* 23: if i = 0 */
|
||||||
|
if (i == 0) {
|
||||||
|
/* 24: passwd <-- HMAC-SHA256(B_{0,2r-1}, passwd) */
|
||||||
|
HMAC_SHA256_Buf(Bp + (s - 16), 64,
|
||||||
|
passwd, 32, passwd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 27: SMix1_r(B_i, n, V_{u..v}, flags) */
|
||||||
|
smix1(Bp, r, Np, flags, Vp, NROM, VROM, XY, ctx_i);
|
||||||
|
/* 28: SMix2_r(B_i, p2floor(n), Nloop_rw, V_{u..v}, flags) */
|
||||||
|
smix2(Bp, r, p2floor(Np), Nloop_rw, flags, Vp,
|
||||||
|
NROM, VROM, XY, ctx_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 30: for i = 0 to p - 1 do */
|
||||||
|
for (i = 0; i < p; i++) {
|
||||||
|
uint32_t *Bp = &B[i * s];
|
||||||
|
/* 31: SMix2_r(B_i, N, Nloop_all - Nloop_rw, V, flags excluding YESCRYPT_RW) */
|
||||||
|
smix2(Bp, r, N, Nloop_all - Nloop_rw, flags & ~YESCRYPT_RW,
|
||||||
|
V, NROM, VROM, XY, (flags & YESCRYPT_RW) ? &ctx[i] : NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_kdf_body(shared, local, passwd, passwdlen, salt, saltlen,
|
||||||
|
* flags, N, r, p, t, NROM, buf, buflen):
|
||||||
|
* Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
|
||||||
|
* p, buflen), or a revision of scrypt as requested by flags and shared, and
|
||||||
|
* write the result into buf.
|
||||||
|
*
|
||||||
|
* shared and flags may request special modes as described in yescrypt.h.
|
||||||
|
*
|
||||||
|
* local is the thread-local data structure, allowing optimized implementations
|
||||||
|
* to preserve and reuse a memory allocation across calls, thereby reducing its
|
||||||
|
* overhead (this reference implementation does not make that optimization).
|
||||||
|
*
|
||||||
|
* t controls computation time while not affecting peak memory usage.
|
||||||
|
*
|
||||||
|
* Return 0 on success; or -1 on error.
|
||||||
|
*/
|
||||||
|
static int yescrypt_kdf_body(const yescrypt_shared_t *shared,
|
||||||
|
yescrypt_local_t *local,
|
||||||
|
const uint8_t *passwd, size_t passwdlen,
|
||||||
|
const uint8_t *salt, size_t saltlen,
|
||||||
|
yescrypt_flags_t flags, uint64_t N, uint32_t r, uint32_t p, uint32_t t,
|
||||||
|
uint64_t NROM,
|
||||||
|
uint8_t *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
const uint32_t *VROM;
|
||||||
|
size_t B_size, V_size;
|
||||||
|
uint32_t *B, *V, *XY, *S;
|
||||||
|
pwxform_ctx_t *pwxform_ctx;
|
||||||
|
uint32_t sha256[8];
|
||||||
|
uint8_t dk[sizeof(sha256)], *dkp = buf;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
/* Sanity-check parameters */
|
||||||
|
switch (flags & YESCRYPT_MODE_MASK) {
|
||||||
|
case 0: /* classic scrypt - can't have anything non-standard */
|
||||||
|
if (flags || t || NROM)
|
||||||
|
goto out_EINVAL;
|
||||||
|
break;
|
||||||
|
case YESCRYPT_WORM:
|
||||||
|
if (flags != YESCRYPT_WORM || NROM)
|
||||||
|
goto out_EINVAL;
|
||||||
|
break;
|
||||||
|
case YESCRYPT_RW:
|
||||||
|
if (flags != (flags & YESCRYPT_KNOWN_FLAGS))
|
||||||
|
goto out_EINVAL;
|
||||||
|
#if PWXsimple == 2 && PWXgather == 4 && PWXrounds == 6 && Sbytes == 12288
|
||||||
|
if ((flags & YESCRYPT_RW_FLAVOR_MASK) ==
|
||||||
|
(YESCRYPT_ROUNDS_6 | YESCRYPT_GATHER_4 |
|
||||||
|
YESCRYPT_SIMPLE_2 | YESCRYPT_SBOX_12K))
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
#error "Unsupported pwxform settings"
|
||||||
|
#endif
|
||||||
|
/* FALLTHRU */
|
||||||
|
default:
|
||||||
|
goto out_EINVAL;
|
||||||
|
}
|
||||||
|
#if SIZE_MAX > UINT32_MAX
|
||||||
|
if (buflen > (((uint64_t)1 << 32) - 1) * 32)
|
||||||
|
goto out_EINVAL;
|
||||||
|
#endif
|
||||||
|
if ((uint64_t)r * (uint64_t)p >= 1 << 30)
|
||||||
|
goto out_EINVAL;
|
||||||
|
if ((N & (N - 1)) != 0 || N <= 1 || r < 1 || p < 1)
|
||||||
|
goto out_EINVAL;
|
||||||
|
if (r > SIZE_MAX / 128 / p ||
|
||||||
|
#if SIZE_MAX / 256 <= UINT32_MAX
|
||||||
|
r > SIZE_MAX / 256 ||
|
||||||
|
#endif
|
||||||
|
N > SIZE_MAX / 128 / r)
|
||||||
|
goto out_EINVAL;
|
||||||
|
if (N > UINT64_MAX / ((uint64_t)t + 1))
|
||||||
|
goto out_EINVAL;
|
||||||
|
if (flags & YESCRYPT_RW) {
|
||||||
|
if (N / p <= 1 || r < rmin ||
|
||||||
|
p > SIZE_MAX / Sbytes ||
|
||||||
|
p > SIZE_MAX / sizeof(*pwxform_ctx))
|
||||||
|
goto out_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VROM = NULL;
|
||||||
|
if (shared) {
|
||||||
|
uint64_t expected_size = (size_t)128 * r * NROM;
|
||||||
|
if ((NROM & (NROM - 1)) != 0 || NROM <= 1 ||
|
||||||
|
shared->aligned_size < expected_size)
|
||||||
|
goto out_EINVAL;
|
||||||
|
if (!(flags & YESCRYPT_INIT_SHARED)) {
|
||||||
|
uint32_t *tag = (uint32_t *)
|
||||||
|
((uint8_t *)shared->aligned + expected_size - 48);
|
||||||
|
uint64_t tag1 = ((uint64_t)tag[1] << 32) + tag[0];
|
||||||
|
uint64_t tag2 = ((uint64_t)tag[3] << 32) + tag[2];
|
||||||
|
if (tag1 != YESCRYPT_ROM_TAG1 || tag2 != YESCRYPT_ROM_TAG2)
|
||||||
|
goto out_EINVAL;
|
||||||
|
}
|
||||||
|
VROM = shared->aligned;
|
||||||
|
} else {
|
||||||
|
if (NROM)
|
||||||
|
goto out_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory */
|
||||||
|
V_size = (size_t)128 * r * N;
|
||||||
|
if (flags & YESCRYPT_INIT_SHARED) {
|
||||||
|
V = (uint32_t *)local->aligned;
|
||||||
|
if (local->aligned_size < V_size) {
|
||||||
|
if (local->base || local->aligned ||
|
||||||
|
local->base_size || local->aligned_size)
|
||||||
|
goto out_EINVAL;
|
||||||
|
if ((V = malloc(V_size)) == NULL)
|
||||||
|
return -1;
|
||||||
|
local->base = local->aligned = V;
|
||||||
|
local->base_size = local->aligned_size = V_size;
|
||||||
|
}
|
||||||
|
if (flags & YESCRYPT_ALLOC_ONLY)
|
||||||
|
return -2; /* expected "failure" */
|
||||||
|
} else {
|
||||||
|
if ((V = malloc(V_size)) == NULL)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
B_size = (size_t)128 * r * p;
|
||||||
|
if ((B = malloc(B_size)) == NULL)
|
||||||
|
goto free_V;
|
||||||
|
if ((XY = malloc((size_t)256 * r)) == NULL)
|
||||||
|
goto free_B;
|
||||||
|
S = NULL;
|
||||||
|
pwxform_ctx = NULL;
|
||||||
|
if (flags & YESCRYPT_RW) {
|
||||||
|
if ((S = malloc((size_t)Sbytes * p)) == NULL)
|
||||||
|
goto free_XY;
|
||||||
|
if ((pwxform_ctx = malloc(sizeof(*pwxform_ctx) * p)) == NULL)
|
||||||
|
goto free_S;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags) {
|
||||||
|
HMAC_SHA256_Buf("yescrypt-prehash",
|
||||||
|
(flags & YESCRYPT_PREHASH) ? 16 : 8,
|
||||||
|
passwd, passwdlen, (uint8_t *)sha256);
|
||||||
|
passwd = (uint8_t *)sha256;
|
||||||
|
passwdlen = sizeof(sha256);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
|
||||||
|
PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1,
|
||||||
|
(uint8_t *)B, B_size);
|
||||||
|
|
||||||
|
if (flags)
|
||||||
|
blkcpy(sha256, B, sizeof(sha256) / sizeof(sha256[0]));
|
||||||
|
|
||||||
|
if (flags & YESCRYPT_RW) {
|
||||||
|
for (i = 0; i < p; i++)
|
||||||
|
pwxform_ctx[i].S = &S[i * Swords];
|
||||||
|
smix(B, r, N, p, t, flags, V, NROM, VROM, XY, pwxform_ctx,
|
||||||
|
(uint8_t *)sha256);
|
||||||
|
} else {
|
||||||
|
/* 2: for i = 0 to p - 1 do */
|
||||||
|
for (i = 0; i < p; i++) {
|
||||||
|
/* 3: B_i <-- MF(B_i, N) */
|
||||||
|
smix(&B[(size_t)32 * r * i], r, N, 1, t, flags, V,
|
||||||
|
NROM, VROM, XY, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dkp = buf;
|
||||||
|
if (flags && buflen < sizeof(dk)) {
|
||||||
|
PBKDF2_SHA256(passwd, passwdlen, (uint8_t *)B, B_size, 1,
|
||||||
|
dk, sizeof(dk));
|
||||||
|
dkp = dk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
|
||||||
|
PBKDF2_SHA256(passwd, passwdlen, (uint8_t *)B, B_size, 1, buf, buflen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Except when computing classic scrypt, allow all computation so far
|
||||||
|
* to be performed on the client. The final steps below match those of
|
||||||
|
* SCRAM (RFC 5802), so that an extension of SCRAM (with the steps so
|
||||||
|
* far in place of SCRAM's use of PBKDF2 and with SHA-256 in place of
|
||||||
|
* SCRAM's use of SHA-1) would be usable with yescrypt hashes.
|
||||||
|
*/
|
||||||
|
if (flags && !(flags & YESCRYPT_PREHASH)) {
|
||||||
|
/* Compute ClientKey */
|
||||||
|
HMAC_SHA256_Buf(dkp, sizeof(dk), "Client Key", 10,
|
||||||
|
(uint8_t *)sha256);
|
||||||
|
/* Compute StoredKey */
|
||||||
|
{
|
||||||
|
size_t clen = buflen;
|
||||||
|
if (clen > sizeof(dk))
|
||||||
|
clen = sizeof(dk);
|
||||||
|
SHA256_Buf((uint8_t *)sha256, sizeof(sha256), dk);
|
||||||
|
memcpy(buf, dk, clen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success! */
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
/* Free memory */
|
||||||
|
free(pwxform_ctx);
|
||||||
|
free_S:
|
||||||
|
free(S);
|
||||||
|
free_XY:
|
||||||
|
free(XY);
|
||||||
|
free_B:
|
||||||
|
free(B);
|
||||||
|
free_V:
|
||||||
|
if (!(flags & YESCRYPT_INIT_SHARED))
|
||||||
|
free(V);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
out_EINVAL:
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, params,
|
||||||
|
* buf, buflen):
|
||||||
|
* Compute scrypt or its revision as requested by the parameters. The inputs
|
||||||
|
* to this function are the same as those for yescrypt_kdf_body() above, with
|
||||||
|
* the addition of g, which controls hash upgrades (0 for no upgrades so far).
|
||||||
|
*/
|
||||||
|
int yescrypt_kdf(const yescrypt_shared_t *shared, yescrypt_local_t *local,
|
||||||
|
const uint8_t *passwd, size_t passwdlen,
|
||||||
|
const uint8_t *salt, size_t saltlen,
|
||||||
|
const yescrypt_params_t *params,
|
||||||
|
uint8_t *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
yescrypt_flags_t flags = params->flags;
|
||||||
|
uint64_t N = params->N;
|
||||||
|
uint32_t r = params->r;
|
||||||
|
uint32_t p = params->p;
|
||||||
|
uint32_t t = params->t;
|
||||||
|
uint32_t g = params->g;
|
||||||
|
uint64_t NROM = params->NROM;
|
||||||
|
uint8_t dk[32];
|
||||||
|
|
||||||
|
/* Support for hash upgrades has been temporarily removed */
|
||||||
|
if (g) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & YESCRYPT_RW) &&
|
||||||
|
p >= 1 && N / p >= 0x100 && N / p * r >= 0x20000) {
|
||||||
|
/*
|
||||||
|
* This reference implementation's yescrypt_kdf_body()
|
||||||
|
* (de)allocates memory on each call, which defeats the purpose
|
||||||
|
* of this pre-hashing. The optimized implementations, which
|
||||||
|
* you should actually use, make the larger allocation first
|
||||||
|
* and then reuse it. Thus, this implementation doing things
|
||||||
|
* differently serves as a test that the computation result is
|
||||||
|
* unaffected by such differences.
|
||||||
|
*/
|
||||||
|
int retval = yescrypt_kdf_body(shared, local,
|
||||||
|
passwd, passwdlen, salt, saltlen,
|
||||||
|
flags | YESCRYPT_PREHASH, N >> 6, r, p, 0, NROM,
|
||||||
|
dk, sizeof(dk));
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
passwd = dk;
|
||||||
|
passwdlen = sizeof(dk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return yescrypt_kdf_body(shared, local,
|
||||||
|
passwd, passwdlen, salt, saltlen,
|
||||||
|
flags, N, r, p, t, NROM, buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int yescrypt_init_shared(yescrypt_shared_t *shared,
|
||||||
|
const uint8_t *seed, size_t seedlen,
|
||||||
|
const yescrypt_params_t *params)
|
||||||
|
{
|
||||||
|
yescrypt_flags_t flags = params->flags;
|
||||||
|
uint64_t N = params->NROM;
|
||||||
|
uint32_t r = params->r;
|
||||||
|
uint32_t p = params->p;
|
||||||
|
uint32_t t = params->t;
|
||||||
|
yescrypt_shared_t half1, half2;
|
||||||
|
uint8_t salt[32];
|
||||||
|
uint32_t *tag;
|
||||||
|
|
||||||
|
if (!(params->flags & YESCRYPT_RW) || params->N || params->g)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (flags & YESCRYPT_SHARED_PREALLOCATED) {
|
||||||
|
if (!shared->aligned || !shared->aligned_size)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Overwrite a possible old ROM tag before we overwrite the rest */
|
||||||
|
tag = (uint32_t *)
|
||||||
|
((uint8_t *)shared->aligned + shared->aligned_size - 48);
|
||||||
|
memset(tag, 0, 48);
|
||||||
|
} else {
|
||||||
|
shared->base = shared->aligned = NULL;
|
||||||
|
shared->base_size = shared->aligned_size = 0;
|
||||||
|
|
||||||
|
if (yescrypt_kdf_body(NULL, shared, NULL, 0, NULL, 0,
|
||||||
|
flags | YESCRYPT_INIT_SHARED | YESCRYPT_ALLOC_ONLY,
|
||||||
|
N, r, p, t, 0, NULL, 0) != -2 || !shared->aligned)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
half1 = half2 = *shared;
|
||||||
|
half1.aligned_size /= 2;
|
||||||
|
half2.aligned = (uint8_t *)half2.aligned + half1.aligned_size;
|
||||||
|
half2.aligned_size = half1.aligned_size;
|
||||||
|
N /= 2;
|
||||||
|
|
||||||
|
if (yescrypt_kdf_body(NULL, &half1,
|
||||||
|
seed, seedlen, (const uint8_t *)"yescrypt-ROMhash", 16,
|
||||||
|
flags | YESCRYPT_INIT_SHARED, N, r, p, t, 0,
|
||||||
|
salt, sizeof(salt)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (yescrypt_kdf_body(&half1, &half2,
|
||||||
|
seed, seedlen, salt, sizeof(salt),
|
||||||
|
flags | YESCRYPT_INIT_SHARED, N, r, p, t, N,
|
||||||
|
salt, sizeof(salt)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (yescrypt_kdf_body(&half2, &half1,
|
||||||
|
seed, seedlen, salt, sizeof(salt),
|
||||||
|
flags | YESCRYPT_INIT_SHARED, N, r, p, t, N,
|
||||||
|
salt, sizeof(salt)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
tag = (uint32_t *)
|
||||||
|
((uint8_t *)shared->aligned + shared->aligned_size - 48);
|
||||||
|
tag[0] = YESCRYPT_ROM_TAG1 & 0xffffffffU;
|
||||||
|
tag[1] = YESCRYPT_ROM_TAG1 >> 32;
|
||||||
|
tag[2] = YESCRYPT_ROM_TAG2 & 0xffffffffU;
|
||||||
|
tag[3] = YESCRYPT_ROM_TAG2 >> 32;
|
||||||
|
tag[4] = le32dec(salt);
|
||||||
|
tag[5] = le32dec(salt + 4);
|
||||||
|
tag[6] = le32dec(salt + 8);
|
||||||
|
tag[7] = le32dec(salt + 12);
|
||||||
|
tag[8] = le32dec(salt + 16);
|
||||||
|
tag[9] = le32dec(salt + 20);
|
||||||
|
tag[10] = le32dec(salt + 24);
|
||||||
|
tag[11] = le32dec(salt + 28);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (!(flags & YESCRYPT_SHARED_PREALLOCATED))
|
||||||
|
free(shared->base);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
yescrypt_binary_t *yescrypt_digest_shared(yescrypt_shared_t *shared)
|
||||||
|
{
|
||||||
|
static yescrypt_binary_t digest;
|
||||||
|
uint32_t *tag;
|
||||||
|
uint64_t tag1, tag2;
|
||||||
|
|
||||||
|
if (shared->aligned_size < 48)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
tag = (uint32_t *)
|
||||||
|
((uint8_t *)shared->aligned + shared->aligned_size - 48);
|
||||||
|
|
||||||
|
tag1 = ((uint64_t)tag[1] << 32) + tag[0];
|
||||||
|
tag2 = ((uint64_t)tag[3] << 32) + tag[2];
|
||||||
|
if (tag1 != YESCRYPT_ROM_TAG1 || tag2 != YESCRYPT_ROM_TAG2)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
le32enc(digest.uc, tag[4]);
|
||||||
|
le32enc(digest.uc + 4, tag[5]);
|
||||||
|
le32enc(digest.uc + 8, tag[6]);
|
||||||
|
le32enc(digest.uc + 12, tag[7]);
|
||||||
|
le32enc(digest.uc + 16, tag[8]);
|
||||||
|
le32enc(digest.uc + 20, tag[9]);
|
||||||
|
le32enc(digest.uc + 24, tag[10]);
|
||||||
|
le32enc(digest.uc + 28, tag[11]);
|
||||||
|
|
||||||
|
return &digest;
|
||||||
|
}
|
||||||
|
|
||||||
|
int yescrypt_free_shared(yescrypt_shared_t *shared)
|
||||||
|
{
|
||||||
|
free(shared->base);
|
||||||
|
shared->base = shared->aligned = NULL;
|
||||||
|
shared->base_size = shared->aligned_size = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int yescrypt_init_local(yescrypt_local_t *local)
|
||||||
|
{
|
||||||
|
/* The reference implementation doesn't use the local structure */
|
||||||
|
local->base = local->aligned = NULL;
|
||||||
|
local->base_size = local->aligned_size = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int yescrypt_free_local(yescrypt_local_t *local)
|
||||||
|
{
|
||||||
|
/* The reference implementation frees its memory in yescrypt_kdf() */
|
||||||
|
(void)local; /* unused */
|
||||||
|
return 0;
|
||||||
|
}
|
346
deps/yescrypt-master/yescrypt.h
vendored
Normal file
346
deps/yescrypt-master/yescrypt.h
vendored
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright 2009 Colin Percival
|
||||||
|
* Copyright 2013-2018 Alexander Peslyak
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file was originally written by Colin Percival as part of the Tarsnap
|
||||||
|
* online backup system.
|
||||||
|
*/
|
||||||
|
#ifndef _YESCRYPT_H_
|
||||||
|
#define _YESCRYPT_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h> /* for size_t */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
|
||||||
|
* Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
|
||||||
|
* p, buflen) and write the result into buf. The parameters r, p, and buflen
|
||||||
|
* must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
|
||||||
|
* must be a power of 2 greater than 1.
|
||||||
|
*
|
||||||
|
* Return 0 on success; or -1 on error.
|
||||||
|
*
|
||||||
|
* MT-safe as long as buf is local to the thread.
|
||||||
|
*/
|
||||||
|
extern int crypto_scrypt(const uint8_t *passwd, size_t passwdlen,
|
||||||
|
const uint8_t *salt, size_t saltlen,
|
||||||
|
uint64_t N, uint32_t r, uint32_t p, uint8_t *buf, size_t buflen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal type used by the memory allocator. Please do not use it directly.
|
||||||
|
* Use yescrypt_shared_t and yescrypt_local_t as appropriate instead, since
|
||||||
|
* they might differ from each other in a future version.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
void *base, *aligned;
|
||||||
|
size_t base_size, aligned_size;
|
||||||
|
} yescrypt_region_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types for shared (ROM) and thread-local (RAM) data structures.
|
||||||
|
*/
|
||||||
|
typedef yescrypt_region_t yescrypt_shared_t;
|
||||||
|
typedef yescrypt_region_t yescrypt_local_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Two 64-bit tags placed 48 bytes to the end of a ROM in host byte endianness
|
||||||
|
* (and followed by 32 bytes of the ROM digest).
|
||||||
|
*/
|
||||||
|
#define YESCRYPT_ROM_TAG1 0x7470797263736579ULL /* "yescrypt" */
|
||||||
|
#define YESCRYPT_ROM_TAG2 0x687361684d4f522dULL /* "-ROMhash" */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type and possible values for the flags argument of yescrypt_kdf(),
|
||||||
|
* yescrypt_encode_params_r(), yescrypt_encode_params(). Most of these may be
|
||||||
|
* OR'ed together, except that YESCRYPT_WORM stands on its own.
|
||||||
|
* Please refer to the description of yescrypt_kdf() below for the meaning of
|
||||||
|
* these flags.
|
||||||
|
*/
|
||||||
|
typedef uint32_t yescrypt_flags_t;
|
||||||
|
/* Public */
|
||||||
|
#define YESCRYPT_WORM 1
|
||||||
|
#define YESCRYPT_RW 0x002
|
||||||
|
#define YESCRYPT_ROUNDS_3 0x000
|
||||||
|
#define YESCRYPT_ROUNDS_6 0x004
|
||||||
|
#define YESCRYPT_GATHER_1 0x000
|
||||||
|
#define YESCRYPT_GATHER_2 0x008
|
||||||
|
#define YESCRYPT_GATHER_4 0x010
|
||||||
|
#define YESCRYPT_GATHER_8 0x018
|
||||||
|
#define YESCRYPT_SIMPLE_1 0x000
|
||||||
|
#define YESCRYPT_SIMPLE_2 0x020
|
||||||
|
#define YESCRYPT_SIMPLE_4 0x040
|
||||||
|
#define YESCRYPT_SIMPLE_8 0x060
|
||||||
|
#define YESCRYPT_SBOX_6K 0x000
|
||||||
|
#define YESCRYPT_SBOX_12K 0x080
|
||||||
|
#define YESCRYPT_SBOX_24K 0x100
|
||||||
|
#define YESCRYPT_SBOX_48K 0x180
|
||||||
|
#define YESCRYPT_SBOX_96K 0x200
|
||||||
|
#define YESCRYPT_SBOX_192K 0x280
|
||||||
|
#define YESCRYPT_SBOX_384K 0x300
|
||||||
|
#define YESCRYPT_SBOX_768K 0x380
|
||||||
|
/* Only valid for yescrypt_init_shared() */
|
||||||
|
#define YESCRYPT_SHARED_PREALLOCATED 0x10000
|
||||||
|
#ifdef YESCRYPT_INTERNAL
|
||||||
|
/* Private */
|
||||||
|
#define YESCRYPT_MODE_MASK 0x003
|
||||||
|
#define YESCRYPT_RW_FLAVOR_MASK 0x3fc
|
||||||
|
#define YESCRYPT_INIT_SHARED 0x01000000
|
||||||
|
#define YESCRYPT_ALLOC_ONLY 0x08000000
|
||||||
|
#define YESCRYPT_PREHASH 0x10000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define YESCRYPT_RW_DEFAULTS \
|
||||||
|
(YESCRYPT_RW | \
|
||||||
|
YESCRYPT_ROUNDS_6 | YESCRYPT_GATHER_4 | YESCRYPT_SIMPLE_2 | \
|
||||||
|
YESCRYPT_SBOX_12K)
|
||||||
|
|
||||||
|
#define YESCRYPT_DEFAULTS YESCRYPT_RW_DEFAULTS
|
||||||
|
|
||||||
|
#ifdef YESCRYPT_INTERNAL
|
||||||
|
#define YESCRYPT_KNOWN_FLAGS \
|
||||||
|
(YESCRYPT_MODE_MASK | YESCRYPT_RW_FLAVOR_MASK | \
|
||||||
|
YESCRYPT_SHARED_PREALLOCATED | \
|
||||||
|
YESCRYPT_INIT_SHARED | YESCRYPT_ALLOC_ONLY | YESCRYPT_PREHASH)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt parameters combined into one struct. N, r, p are the same as in
|
||||||
|
* classic scrypt, except that the meaning of p changes when YESCRYPT_RW is
|
||||||
|
* set. flags, t, g, NROM are special to yescrypt.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
yescrypt_flags_t flags;
|
||||||
|
uint64_t N;
|
||||||
|
uint32_t r, p, t, g;
|
||||||
|
uint64_t NROM;
|
||||||
|
} yescrypt_params_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 256-bit yescrypt hash, or a hash encryption key (which may itself have
|
||||||
|
* been derived as a yescrypt hash of a human-specified key string).
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
unsigned char uc[32];
|
||||||
|
uint64_t u64[4];
|
||||||
|
} yescrypt_binary_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_init_shared(shared, seed, seedlen, params):
|
||||||
|
* Optionally allocate memory for and initialize the shared (ROM) data
|
||||||
|
* structure. The parameters flags, NROM, r, p, and t specify how the ROM is
|
||||||
|
* to be initialized, and seed and seedlen specify the initial seed affecting
|
||||||
|
* the data with which the ROM is filled.
|
||||||
|
*
|
||||||
|
* Return 0 on success; or -1 on error.
|
||||||
|
*
|
||||||
|
* If bit YESCRYPT_SHARED_PREALLOCATED in flags is set, then memory for the
|
||||||
|
* ROM is assumed to have been preallocated by the caller, with shared->aligned
|
||||||
|
* being the start address of the ROM and shared->aligned_size being its size
|
||||||
|
* (which must be sufficient for NROM, r, p). This may be used e.g. when the
|
||||||
|
* ROM is to be placed in a SysV shared memory segment allocated by the caller.
|
||||||
|
*
|
||||||
|
* MT-safe as long as shared is local to the thread.
|
||||||
|
*/
|
||||||
|
extern int yescrypt_init_shared(yescrypt_shared_t *shared,
|
||||||
|
const uint8_t *seed, size_t seedlen, const yescrypt_params_t *params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_digest_shared(shared):
|
||||||
|
* Extract the previously stored message digest of the provided yescrypt ROM.
|
||||||
|
*
|
||||||
|
* Return pointer to the message digest on success; or NULL on error.
|
||||||
|
*
|
||||||
|
* MT-unsafe.
|
||||||
|
*/
|
||||||
|
extern yescrypt_binary_t *yescrypt_digest_shared(yescrypt_shared_t *shared);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_free_shared(shared):
|
||||||
|
* Free memory that had been allocated with yescrypt_init_shared().
|
||||||
|
*
|
||||||
|
* Return 0 on success; or -1 on error.
|
||||||
|
*
|
||||||
|
* MT-safe as long as shared is local to the thread.
|
||||||
|
*/
|
||||||
|
extern int yescrypt_free_shared(yescrypt_shared_t *shared);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_init_local(local):
|
||||||
|
* Initialize the thread-local (RAM) data structure. Actual memory allocation
|
||||||
|
* is currently fully postponed until a call to yescrypt_kdf() or yescrypt_r().
|
||||||
|
*
|
||||||
|
* Return 0 on success; or -1 on error.
|
||||||
|
*
|
||||||
|
* MT-safe as long as local is local to the thread.
|
||||||
|
*/
|
||||||
|
extern int yescrypt_init_local(yescrypt_local_t *local);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_free_local(local):
|
||||||
|
* Free memory that may have been allocated for an initialized thread-local
|
||||||
|
* (RAM) data structure.
|
||||||
|
*
|
||||||
|
* Return 0 on success; or -1 on error.
|
||||||
|
*
|
||||||
|
* MT-safe as long as local is local to the thread.
|
||||||
|
*/
|
||||||
|
extern int yescrypt_free_local(yescrypt_local_t *local);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, params,
|
||||||
|
* buf, buflen):
|
||||||
|
* Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
|
||||||
|
* p, buflen), or a revision of scrypt as requested by flags and shared, and
|
||||||
|
* write the result into buf. The parameters N, r, p, and buflen must satisfy
|
||||||
|
* the same conditions as with crypto_scrypt(). t controls computation time
|
||||||
|
* while not affecting peak memory usage (t = 0 is optimal unless higher N*r
|
||||||
|
* is not affordable while higher t is). g controls hash upgrades (g = 0 for
|
||||||
|
* no upgrades so far). shared and flags may request special modes. local is
|
||||||
|
* the thread-local data structure, allowing to preserve and reuse a memory
|
||||||
|
* allocation across calls, thereby reducing processing overhead.
|
||||||
|
*
|
||||||
|
* Return 0 on success; or -1 on error.
|
||||||
|
*
|
||||||
|
* Classic scrypt is available by setting shared = NULL, flags = 0, and t = 0.
|
||||||
|
*
|
||||||
|
* Setting YESCRYPT_WORM enables only minimal deviations from classic scrypt:
|
||||||
|
* support for the t parameter, and pre- and post-hashing.
|
||||||
|
*
|
||||||
|
* Setting YESCRYPT_RW fully enables yescrypt. As a side effect of differences
|
||||||
|
* between the algorithms, it also prevents p > 1 from growing the threads'
|
||||||
|
* combined processing time and memory allocation (like it did with classic
|
||||||
|
* scrypt and YESCRYPT_WORM), treating p as a divider rather than a multiplier.
|
||||||
|
*
|
||||||
|
* Passing a shared structure, with ROM contents previously computed by
|
||||||
|
* yescrypt_init_shared(), enables the use of ROM and requires YESCRYPT_RW.
|
||||||
|
*
|
||||||
|
* In order to allow for initialization of the ROM to be split into a separate
|
||||||
|
* program (or separate invocation of the same program), the shared->aligned
|
||||||
|
* and shared->aligned_size fields may optionally be set by the caller directly
|
||||||
|
* (e.g., to a mapped SysV shm segment), without using yescrypt_init_shared().
|
||||||
|
*
|
||||||
|
* local must be initialized with yescrypt_init_local().
|
||||||
|
*
|
||||||
|
* MT-safe as long as local and buf are local to the thread.
|
||||||
|
*/
|
||||||
|
extern int yescrypt_kdf(const yescrypt_shared_t *shared,
|
||||||
|
yescrypt_local_t *local,
|
||||||
|
const uint8_t *passwd, size_t passwdlen,
|
||||||
|
const uint8_t *salt, size_t saltlen,
|
||||||
|
const yescrypt_params_t *params,
|
||||||
|
uint8_t *buf, size_t buflen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_r(shared, local, passwd, passwdlen, setting, key, buf, buflen):
|
||||||
|
* Compute and encode an scrypt or enhanced scrypt hash of passwd given the
|
||||||
|
* parameters and salt value encoded in setting. If shared is not NULL, a ROM
|
||||||
|
* is used and YESCRYPT_RW is required. Otherwise, whether to compute classic
|
||||||
|
* scrypt, YESCRYPT_WORM (a slight deviation from classic scrypt), or
|
||||||
|
* YESCRYPT_RW (time-memory tradeoff discouraging modification) is determined
|
||||||
|
* by the setting string. shared (if not NULL) and local must be initialized
|
||||||
|
* as described above for yescrypt_kdf(). buf must be large enough (as
|
||||||
|
* indicated by buflen) to hold the encoded hash string.
|
||||||
|
*
|
||||||
|
* Return the encoded hash string on success; or NULL on error.
|
||||||
|
*
|
||||||
|
* MT-safe as long as local and buf are local to the thread.
|
||||||
|
*/
|
||||||
|
extern uint8_t *yescrypt_r(const yescrypt_shared_t *shared,
|
||||||
|
yescrypt_local_t *local,
|
||||||
|
const uint8_t *passwd, size_t passwdlen,
|
||||||
|
const uint8_t *setting,
|
||||||
|
const yescrypt_binary_t *key,
|
||||||
|
uint8_t *buf, size_t buflen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt(passwd, setting):
|
||||||
|
* Compute and encode an scrypt or enhanced scrypt hash of passwd given the
|
||||||
|
* parameters and salt value encoded in setting. Whether to compute classic
|
||||||
|
* scrypt, YESCRYPT_WORM (a slight deviation from classic scrypt), or
|
||||||
|
* YESCRYPT_RW (time-memory tradeoff discouraging modification) is determined
|
||||||
|
* by the setting string.
|
||||||
|
*
|
||||||
|
* Return the encoded hash string on success; or NULL on error.
|
||||||
|
*
|
||||||
|
* This is a crypt(3)-like interface, which is simpler to use than
|
||||||
|
* yescrypt_r(), but it is not MT-safe, it does not allow for the use of a ROM,
|
||||||
|
* and it is slower than yescrypt_r() for repeated calls because it allocates
|
||||||
|
* and frees memory on each call.
|
||||||
|
*
|
||||||
|
* MT-unsafe.
|
||||||
|
*/
|
||||||
|
extern uint8_t *yescrypt(const uint8_t *passwd, const uint8_t *setting);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_reencrypt(hash, from_key, to_key):
|
||||||
|
* Re-encrypt a yescrypt hash from one key to another. Either key may be NULL
|
||||||
|
* to indicate unencrypted hash. The encoded hash string is modified in-place.
|
||||||
|
*
|
||||||
|
* Return the hash pointer on success; or NULL on error (in which case the hash
|
||||||
|
* string is left unmodified).
|
||||||
|
*
|
||||||
|
* MT-safe as long as hash is local to the thread.
|
||||||
|
*/
|
||||||
|
extern uint8_t *yescrypt_reencrypt(uint8_t *hash,
|
||||||
|
const yescrypt_binary_t *from_key,
|
||||||
|
const yescrypt_binary_t *to_key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_encode_params_r(params, src, srclen, buf, buflen):
|
||||||
|
* Generate a setting string for use with yescrypt_r() and yescrypt() by
|
||||||
|
* encoding into it the parameters flags, N, r, p, t, g, and a salt given by
|
||||||
|
* src (of srclen bytes). buf must be large enough (as indicated by buflen)
|
||||||
|
* to hold the setting string.
|
||||||
|
*
|
||||||
|
* Return the setting string on success; or NULL on error.
|
||||||
|
*
|
||||||
|
* MT-safe as long as buf is local to the thread.
|
||||||
|
*/
|
||||||
|
extern uint8_t *yescrypt_encode_params_r(const yescrypt_params_t *params,
|
||||||
|
const uint8_t *src, size_t srclen,
|
||||||
|
uint8_t *buf, size_t buflen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yescrypt_encode_params(params, src, srclen):
|
||||||
|
* Generate a setting string for use with yescrypt_r() and yescrypt(). This
|
||||||
|
* function is the same as yescrypt_encode_params_r() except that it uses a
|
||||||
|
* static buffer and thus is not MT-safe.
|
||||||
|
*
|
||||||
|
* Return the setting string on success; or NULL on error.
|
||||||
|
*
|
||||||
|
* MT-unsafe.
|
||||||
|
*/
|
||||||
|
extern uint8_t *yescrypt_encode_params(const yescrypt_params_t *params,
|
||||||
|
const uint8_t *src, size_t srclen);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_YESCRYPT_H_ */
|
285
src/bridges/bridge_scrypt_yescrypt.c
Normal file
285
src/bridges/bridge_scrypt_yescrypt.c
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
/**
|
||||||
|
* Author......: See docs/credits.txt
|
||||||
|
* License.....: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "bridges.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
#include "yescrypt.h"
|
||||||
|
|
||||||
|
void smix(uint8_t *B, size_t r, uint32_t N, uint32_t p, uint32_t t,
|
||||||
|
yescrypt_flags_t flags,
|
||||||
|
void *V, uint32_t NROM, const void *VROM,
|
||||||
|
void *XY, uint8_t *S, uint8_t *passwd);
|
||||||
|
|
||||||
|
// good: we can use this multiplier do reduce copy overhead to increase the guessing speed,
|
||||||
|
// bad: but we also increase the password candidate batch size.
|
||||||
|
// slow hashes which make use of this bridge probably are used with smaller wordlists,
|
||||||
|
// and therefore it's easier for hashcat to parallelize if this multiplier is low.
|
||||||
|
// in the end, it's a trade-off.
|
||||||
|
|
||||||
|
#define N_ACCEL 8
|
||||||
|
|
||||||
|
#define SCRYPT_R_MAX 16
|
||||||
|
#define SCRYPT_P_MAX 16
|
||||||
|
|
||||||
|
#define SCRYPT_TMP_SIZE (128ULL * SCRYPT_R_MAX * SCRYPT_P_MAX)
|
||||||
|
#define SCRYPT_TMP_SIZE4 (SCRYPT_TMP_SIZE / 4)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 B[SCRYPT_TMP_SIZE4];
|
||||||
|
|
||||||
|
} scrypt_tmp_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 salt_buf[64];
|
||||||
|
u32 salt_len;
|
||||||
|
|
||||||
|
u32 digest_buf[64];
|
||||||
|
u32 digest_len;
|
||||||
|
|
||||||
|
u32 N;
|
||||||
|
u32 r;
|
||||||
|
u32 p;
|
||||||
|
|
||||||
|
} scrypt_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *V;
|
||||||
|
void *XY;
|
||||||
|
|
||||||
|
// implementation specific
|
||||||
|
|
||||||
|
char unit_info_buf[1024];
|
||||||
|
int unit_info_len;
|
||||||
|
|
||||||
|
u64 workitem_count;
|
||||||
|
size_t workitem_size;
|
||||||
|
|
||||||
|
} unit_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unit_t *units_buf;
|
||||||
|
int units_cnt;
|
||||||
|
|
||||||
|
} bridge_scrypt_yescrypt_t;
|
||||||
|
|
||||||
|
static bool units_init (bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt)
|
||||||
|
{
|
||||||
|
#if defined (_WIN)
|
||||||
|
|
||||||
|
SYSTEM_INFO sysinfo;
|
||||||
|
|
||||||
|
GetSystemInfo (&sysinfo);
|
||||||
|
|
||||||
|
int num_devices = sysinfo.dwNumberOfProcessors;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int num_devices = sysconf (_SC_NPROCESSORS_ONLN);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unit_t *units_buf = (unit_t *) hccalloc (num_devices, sizeof (unit_t));
|
||||||
|
|
||||||
|
int units_cnt = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_devices; i++)
|
||||||
|
{
|
||||||
|
unit_t *unit_buf = &units_buf[i];
|
||||||
|
|
||||||
|
unit_buf->unit_info_len = snprintf (unit_buf->unit_info_buf, sizeof (unit_buf->unit_info_buf) - 1,
|
||||||
|
"%s",
|
||||||
|
"Scrypt-Yescrypt");
|
||||||
|
|
||||||
|
unit_buf->unit_info_buf[unit_buf->unit_info_len] = 0;
|
||||||
|
|
||||||
|
unit_buf->workitem_count = N_ACCEL;
|
||||||
|
|
||||||
|
units_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge_scrypt_yescrypt->units_buf = units_buf;
|
||||||
|
bridge_scrypt_yescrypt->units_cnt = units_cnt;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void units_term (bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt)
|
||||||
|
{
|
||||||
|
if (bridge_scrypt_yescrypt)
|
||||||
|
{
|
||||||
|
hcfree (bridge_scrypt_yescrypt->units_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *platform_init ()
|
||||||
|
{
|
||||||
|
// bridge_scrypt_yescrypt_t will be our platform context
|
||||||
|
|
||||||
|
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = (bridge_scrypt_yescrypt_t *) hcmalloc (sizeof (bridge_scrypt_yescrypt_t));
|
||||||
|
|
||||||
|
if (units_init (bridge_scrypt_yescrypt) == false)
|
||||||
|
{
|
||||||
|
hcfree (bridge_scrypt_yescrypt);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bridge_scrypt_yescrypt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void platform_term (void *platform_context)
|
||||||
|
{
|
||||||
|
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = platform_context;
|
||||||
|
|
||||||
|
if (bridge_scrypt_yescrypt)
|
||||||
|
{
|
||||||
|
units_term (bridge_scrypt_yescrypt);
|
||||||
|
|
||||||
|
hcfree (bridge_scrypt_yescrypt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_unit_count (void *platform_context)
|
||||||
|
{
|
||||||
|
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = platform_context;
|
||||||
|
|
||||||
|
return bridge_scrypt_yescrypt->units_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we support units of mixed speed, that's why the workitem count is unit specific
|
||||||
|
|
||||||
|
int get_workitem_count (void *platform_context, const int unit_idx)
|
||||||
|
{
|
||||||
|
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = platform_context;
|
||||||
|
|
||||||
|
unit_t *unit_buf = &bridge_scrypt_yescrypt->units_buf[unit_idx];
|
||||||
|
|
||||||
|
return unit_buf->workitem_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *get_unit_info (void *platform_context, const int unit_idx)
|
||||||
|
{
|
||||||
|
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = platform_context;
|
||||||
|
|
||||||
|
unit_t *unit_buf = &bridge_scrypt_yescrypt->units_buf[unit_idx];
|
||||||
|
|
||||||
|
return unit_buf->unit_info_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool salt_prepare (void *platform_context, MAYBE_UNUSED hashconfig_t *hashconfig, MAYBE_UNUSED hashes_t *hashes)
|
||||||
|
{
|
||||||
|
// selftest hash
|
||||||
|
|
||||||
|
scrypt_t *scrypt_st = (scrypt_t *) hashes->st_esalts_buf;
|
||||||
|
|
||||||
|
size_t largest_V = 128 * scrypt_st->r * scrypt_st->N; // yescrypt: the temporary storage V must be 128rN bytes in length
|
||||||
|
size_t largest_XY = 256 * scrypt_st->r * scrypt_st->p; // yescrypt: the temporary storage XY must be 256r or 256rp bytes in length
|
||||||
|
|
||||||
|
// from here regular hashes
|
||||||
|
|
||||||
|
scrypt_t *scrypt = (scrypt_t *) hashes->esalts_buf;
|
||||||
|
|
||||||
|
for (u32 salt_idx = 0; salt_idx < hashes->salts_cnt; salt_idx++, scrypt++)
|
||||||
|
{
|
||||||
|
const size_t sz_V = 128 * scrypt->r * scrypt->N; // yescrypt: the temporary storage V must be 128rN bytes in length
|
||||||
|
const size_t sz_XY = 256 * scrypt->r * scrypt->p; // yescrypt: the temporary storage XY must be 256r or 256rp bytes in length
|
||||||
|
|
||||||
|
if (sz_V > largest_V) largest_V = sz_V;
|
||||||
|
if (sz_XY > largest_XY) largest_XY = sz_XY;
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = platform_context;
|
||||||
|
|
||||||
|
for (int unit_idx = 0; unit_idx < bridge_scrypt_yescrypt->units_cnt; unit_idx++)
|
||||||
|
{
|
||||||
|
unit_t *unit_buf = &bridge_scrypt_yescrypt->units_buf[unit_idx];
|
||||||
|
|
||||||
|
unit_buf->V = hcmalloc_aligned (largest_V, 64);
|
||||||
|
unit_buf->XY = hcmalloc_aligned (largest_XY, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void salt_destroy (void *platform_context, MAYBE_UNUSED hashconfig_t *hashconfig, MAYBE_UNUSED hashes_t *hashes)
|
||||||
|
{
|
||||||
|
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = platform_context;
|
||||||
|
|
||||||
|
for (int unit_idx = 0; unit_idx < bridge_scrypt_yescrypt->units_cnt; unit_idx++)
|
||||||
|
{
|
||||||
|
unit_t *unit_buf = &bridge_scrypt_yescrypt->units_buf[unit_idx];
|
||||||
|
|
||||||
|
hcfree_aligned (unit_buf->V);
|
||||||
|
hcfree_aligned (unit_buf->XY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool launch_loop (MAYBE_UNUSED void *platform_context, MAYBE_UNUSED hc_device_param_t *device_param, MAYBE_UNUSED hashconfig_t *hashconfig, MAYBE_UNUSED hashes_t *hashes, MAYBE_UNUSED const u32 salt_pos, MAYBE_UNUSED const u64 pws_cnt)
|
||||||
|
{
|
||||||
|
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = platform_context;
|
||||||
|
|
||||||
|
const int unit_idx = device_param->bridge_link_device;
|
||||||
|
|
||||||
|
unit_t *unit_buf = &bridge_scrypt_yescrypt->units_buf[unit_idx];
|
||||||
|
|
||||||
|
scrypt_t *esalts_buf = (scrypt_t *) hashes->esalts_buf;
|
||||||
|
|
||||||
|
scrypt_t *esalt_buf = &esalts_buf[salt_pos];
|
||||||
|
|
||||||
|
// hashcat guarantees h_tmps[] is 64 byte aligned, so is *B
|
||||||
|
|
||||||
|
scrypt_tmp_t *scrypt_tmp = (scrypt_tmp_t *) device_param->h_tmps;
|
||||||
|
|
||||||
|
for (u64 pw_cnt = 0; pw_cnt < pws_cnt; pw_cnt++)
|
||||||
|
{
|
||||||
|
u8 *B = (u8 *) scrypt_tmp->B;
|
||||||
|
|
||||||
|
// We could use p-based parallelization from yescrypt instead,
|
||||||
|
// but since we're already multi-threading, there's no need to run OpenMP.
|
||||||
|
// With that in mind, we can optimize by using a constant p=1,
|
||||||
|
// allowing the compiler to eliminate branches in smix().
|
||||||
|
|
||||||
|
for (u32 i = 0; i < esalt_buf->p; i++)
|
||||||
|
{
|
||||||
|
// Same here: using constants allows the compiler to optimize away branches in smix(),
|
||||||
|
// so there's no need to call smix1()/smix2() directly and unnecessarily complicate the code.
|
||||||
|
|
||||||
|
smix (B, esalt_buf->r, esalt_buf->N, 1, 0, 0, unit_buf->V, 0, NULL, unit_buf->XY, NULL, NULL);
|
||||||
|
|
||||||
|
B += 128 * esalt_buf->r;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrypt_tmp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bridge_init (bridge_ctx_t *bridge_ctx)
|
||||||
|
{
|
||||||
|
bridge_ctx->bridge_context_size = BRIDGE_CONTEXT_SIZE_CURRENT;
|
||||||
|
bridge_ctx->bridge_interface_version = BRIDGE_INTERFACE_VERSION_CURRENT;
|
||||||
|
|
||||||
|
bridge_ctx->platform_init = platform_init;
|
||||||
|
bridge_ctx->platform_term = platform_term;
|
||||||
|
bridge_ctx->get_unit_count = get_unit_count;
|
||||||
|
bridge_ctx->get_unit_info = get_unit_info;
|
||||||
|
bridge_ctx->get_workitem_count = get_workitem_count;
|
||||||
|
bridge_ctx->thread_init = BRIDGE_DEFAULT;
|
||||||
|
bridge_ctx->thread_term = BRIDGE_DEFAULT;
|
||||||
|
bridge_ctx->salt_prepare = salt_prepare;
|
||||||
|
bridge_ctx->salt_destroy = salt_destroy;
|
||||||
|
bridge_ctx->launch_loop = launch_loop;
|
||||||
|
bridge_ctx->launch_loop2 = BRIDGE_DEFAULT;
|
||||||
|
bridge_ctx->st_update_hash = BRIDGE_DEFAULT;
|
||||||
|
bridge_ctx->st_update_pass = BRIDGE_DEFAULT;
|
||||||
|
}
|
30
src/bridges/bridge_scrypt_yescrypt.mk
Normal file
30
src/bridges/bridge_scrypt_yescrypt.mk
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
SCRYPT_YESCRYPT := deps/yescrypt-master
|
||||||
|
SCRYPT_YESCRYPT_CFLAGS := -I$(SCRYPT_YESCRYPT)/ -DSKIP_MEMZERO -Wno-cpp -Wno-type-limits
|
||||||
|
|
||||||
|
ifeq ($(BUILD_MODE),cross)
|
||||||
|
SCRYPT_YESCRYPT_CFLAGS += -mavx2
|
||||||
|
else
|
||||||
|
ifeq ($(UNAME),Darwin)
|
||||||
|
ifeq ($(IS_APPLE_SILICON),0)
|
||||||
|
SCRYPT_YESCRYPT_CFLAGS += -mavx2
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
SCRYPT_YESCRYPT_CFLAGS += -march=native
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(BUILD_MODE),cross)
|
||||||
|
bridges/bridge_scrypt_yescrypt.so: src/bridges/bridge_scrypt_yescrypt.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.LINUX.a
|
||||||
|
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_YESCRYPT_CFLAGS)
|
||||||
|
bridges/bridge_scrypt_yescrypt.dll: src/bridges/bridge_scrypt_yescrypt.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.WIN.a
|
||||||
|
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_YESCRYPT_CFLAGS)
|
||||||
|
else
|
||||||
|
ifeq ($(SHARED),1)
|
||||||
|
bridges/bridge_scrypt_yescrypt.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_yescrypt.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c $(HASHCAT_LIBRARY)
|
||||||
|
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_YESCRYPT_CFLAGS)
|
||||||
|
else
|
||||||
|
bridges/bridge_scrypt_yescrypt.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_yescrypt.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.NATIVE.a
|
||||||
|
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_YESCRYPT_CFLAGS)
|
||||||
|
endif
|
||||||
|
endif
|
298
src/modules/module_70200.c
Normal file
298
src/modules/module_70200.c
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
/**
|
||||||
|
* Author......: See docs/credits.txt
|
||||||
|
* License.....: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "modules.h"
|
||||||
|
#include "bitops.h"
|
||||||
|
#include "convert.h"
|
||||||
|
#include "shared.h"
|
||||||
|
|
||||||
|
static const u32 ATTACK_EXEC = ATTACK_EXEC_OUTSIDE_KERNEL;
|
||||||
|
static const u32 DGST_POS0 = 0;
|
||||||
|
static const u32 DGST_POS1 = 1;
|
||||||
|
static const u32 DGST_POS2 = 2;
|
||||||
|
static const u32 DGST_POS3 = 3;
|
||||||
|
static const u32 DGST_SIZE = DGST_SIZE_4_4;
|
||||||
|
static const u32 HASH_CATEGORY = HASH_CATEGORY_GENERIC_KDF;
|
||||||
|
static const char *HASH_NAME = "scrypt [Bridged: Scrypt-Yescrypt]";
|
||||||
|
static const u64 KERN_TYPE = 70100;
|
||||||
|
static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE;
|
||||||
|
static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE
|
||||||
|
| OPTS_TYPE_PT_GENERATE_LE
|
||||||
|
| OPTS_TYPE_NATIVE_THREADS
|
||||||
|
| OPTS_TYPE_MP_MULTI_DISABLE;
|
||||||
|
static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED;
|
||||||
|
static const u64 BRIDGE_TYPE = BRIDGE_TYPE_MATCH_TUNINGS // optional - improves performance
|
||||||
|
| BRIDGE_TYPE_LAUNCH_LOOP;
|
||||||
|
static const char *BRIDGE_NAME = "scrypt_yescrypt";
|
||||||
|
static const char *ST_PASS = "hashcat";
|
||||||
|
static const char *ST_HASH = "SCRYPT:16384:8:2:ODEzMTA2Mw==:NuOcXzv+MOqXmwTXnH6bbUEjN/vjlDG28IM7WXaUkk0=";
|
||||||
|
|
||||||
|
u32 module_attack_exec (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ATTACK_EXEC; }
|
||||||
|
u32 module_dgst_pos0 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS0; }
|
||||||
|
u32 module_dgst_pos1 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS1; }
|
||||||
|
u32 module_dgst_pos2 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS2; }
|
||||||
|
u32 module_dgst_pos3 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS3; }
|
||||||
|
u32 module_dgst_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_SIZE; }
|
||||||
|
u32 module_hash_category (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_CATEGORY; }
|
||||||
|
const char *module_hash_name (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_NAME; }
|
||||||
|
u64 module_kern_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return KERN_TYPE; }
|
||||||
|
u32 module_opti_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTI_TYPE; }
|
||||||
|
u64 module_opts_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTS_TYPE; }
|
||||||
|
u32 module_salt_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return SALT_TYPE; }
|
||||||
|
const char *module_st_hash (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_HASH; }
|
||||||
|
const char *module_st_pass (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_PASS; }
|
||||||
|
const char *module_bridge_name (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return BRIDGE_NAME; }
|
||||||
|
u64 module_bridge_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return BRIDGE_TYPE; }
|
||||||
|
|
||||||
|
static const char *SIGNATURE_SCRYPT = "SCRYPT";
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 salt_buf[64];
|
||||||
|
u32 salt_len;
|
||||||
|
|
||||||
|
u32 digest_buf[64];
|
||||||
|
u32 digest_len;
|
||||||
|
|
||||||
|
u32 N;
|
||||||
|
u32 r;
|
||||||
|
u32 p;
|
||||||
|
|
||||||
|
} scrypt_t;
|
||||||
|
|
||||||
|
u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
|
||||||
|
{
|
||||||
|
// this overrides the reductions of PW_MAX in case optimized kernel is selected
|
||||||
|
// IOW, even in optimized kernel mode it support length 256
|
||||||
|
|
||||||
|
const u32 pw_max = PW_MAX;
|
||||||
|
|
||||||
|
return pw_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 module_esalt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
|
||||||
|
{
|
||||||
|
const u64 esalt_size = (const u64) sizeof (scrypt_t);
|
||||||
|
|
||||||
|
return esalt_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 module_tmp_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
|
||||||
|
{
|
||||||
|
#define SCRYPT_R_MAX 16
|
||||||
|
#define SCRYPT_P_MAX 16
|
||||||
|
|
||||||
|
const u64 tmp_size = 128ULL * SCRYPT_R_MAX * SCRYPT_P_MAX;
|
||||||
|
|
||||||
|
return tmp_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED void *digest_buf, MAYBE_UNUSED salt_t *salt, MAYBE_UNUSED void *esalt_buf, MAYBE_UNUSED void *hook_salt_buf, MAYBE_UNUSED hashinfo_t *hash_info, const char *line_buf, MAYBE_UNUSED const int line_len)
|
||||||
|
{
|
||||||
|
u32 *digest = (u32 *) digest_buf;
|
||||||
|
|
||||||
|
scrypt_t *scrypt = (scrypt_t *) esalt_buf;
|
||||||
|
|
||||||
|
hc_token_t token;
|
||||||
|
|
||||||
|
token.token_cnt = 6;
|
||||||
|
|
||||||
|
token.signatures_cnt = 1;
|
||||||
|
token.signatures_buf[0] = SIGNATURE_SCRYPT;
|
||||||
|
|
||||||
|
token.len_min[0] = 6;
|
||||||
|
token.len_max[0] = 6;
|
||||||
|
token.sep[0] = ':';
|
||||||
|
token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH
|
||||||
|
| TOKEN_ATTR_VERIFY_SIGNATURE;
|
||||||
|
|
||||||
|
token.len_min[1] = 1;
|
||||||
|
token.len_max[1] = 6;
|
||||||
|
token.sep[1] = ':';
|
||||||
|
token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH;
|
||||||
|
|
||||||
|
token.len_min[2] = 1;
|
||||||
|
token.len_max[2] = 6;
|
||||||
|
token.sep[2] = ':';
|
||||||
|
token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH;
|
||||||
|
|
||||||
|
token.len_min[3] = 1;
|
||||||
|
token.len_max[3] = 6;
|
||||||
|
token.sep[3] = ':';
|
||||||
|
token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH;
|
||||||
|
|
||||||
|
token.len_min[4] = 0;
|
||||||
|
token.len_max[4] = 45;
|
||||||
|
token.sep[4] = ':';
|
||||||
|
token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH
|
||||||
|
| TOKEN_ATTR_VERIFY_BASE64A;
|
||||||
|
|
||||||
|
token.len_min[5] = 44;
|
||||||
|
token.len_max[5] = 88;
|
||||||
|
token.sep[5] = ':';
|
||||||
|
token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH
|
||||||
|
| TOKEN_ATTR_VERIFY_BASE64A;
|
||||||
|
|
||||||
|
const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token);
|
||||||
|
|
||||||
|
if (rc_tokenizer != PARSER_OK) return (rc_tokenizer);
|
||||||
|
|
||||||
|
// scrypt settings
|
||||||
|
|
||||||
|
const u8 *N_pos = token.buf[1];
|
||||||
|
const u8 *r_pos = token.buf[2];
|
||||||
|
const u8 *p_pos = token.buf[3];
|
||||||
|
|
||||||
|
scrypt->N = hc_strtoul ((const char *) N_pos, NULL, 10);
|
||||||
|
scrypt->r = hc_strtoul ((const char *) r_pos, NULL, 10);
|
||||||
|
scrypt->p = hc_strtoul ((const char *) p_pos, NULL, 10);
|
||||||
|
|
||||||
|
if (scrypt->r > 16) return (PARSER_SALT_VALUE);
|
||||||
|
if (scrypt->p > 16) return (PARSER_SALT_VALUE);
|
||||||
|
|
||||||
|
// salt
|
||||||
|
|
||||||
|
const u8 *salt_pos = token.buf[4];
|
||||||
|
const int salt_len = token.len[4];
|
||||||
|
|
||||||
|
scrypt->salt_len = base64_decode (base64_to_int, (const u8 *) salt_pos, salt_len, (u8 *) scrypt->salt_buf);
|
||||||
|
|
||||||
|
// digest - base64 decode
|
||||||
|
|
||||||
|
const u8 *hash_pos = token.buf[5];
|
||||||
|
const int hash_len = token.len[5];
|
||||||
|
|
||||||
|
scrypt->digest_len = base64_decode (base64_to_int, (const u8 *) hash_pos, hash_len, (u8 *) scrypt->digest_buf);
|
||||||
|
|
||||||
|
// comparison digest
|
||||||
|
|
||||||
|
digest[0] = scrypt->digest_buf[0];
|
||||||
|
digest[1] = scrypt->digest_buf[1];
|
||||||
|
digest[2] = scrypt->digest_buf[2];
|
||||||
|
digest[3] = scrypt->digest_buf[3];
|
||||||
|
|
||||||
|
// fake salt, we just need to make this unique
|
||||||
|
|
||||||
|
salt->salt_buf[0] = digest[0];
|
||||||
|
salt->salt_buf[1] = digest[1];
|
||||||
|
salt->salt_buf[2] = digest[2];
|
||||||
|
salt->salt_buf[3] = digest[3];
|
||||||
|
salt->salt_buf[4] = scrypt->N;
|
||||||
|
salt->salt_buf[5] = scrypt->r;
|
||||||
|
salt->salt_buf[6] = scrypt->p;
|
||||||
|
salt->salt_buf[7] = 0;
|
||||||
|
|
||||||
|
salt->salt_len = 32;
|
||||||
|
salt->salt_iter = 1;
|
||||||
|
|
||||||
|
return (PARSER_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const void *digest_buf, MAYBE_UNUSED const salt_t *salt, MAYBE_UNUSED const void *esalt_buf, MAYBE_UNUSED const void *hook_salt_buf, MAYBE_UNUSED const hashinfo_t *hash_info, char *line_buf, MAYBE_UNUSED const int line_size)
|
||||||
|
{
|
||||||
|
const scrypt_t *scrypt = (const scrypt_t *) esalt_buf;
|
||||||
|
|
||||||
|
char base64_salt[64] = { 0 };
|
||||||
|
|
||||||
|
base64_encode (int_to_base64, (const u8 *) scrypt->salt_buf, scrypt->salt_len, (u8 *) base64_salt);
|
||||||
|
|
||||||
|
char base64_digest[128] = { 0 };
|
||||||
|
|
||||||
|
base64_encode (int_to_base64, (const u8 *) scrypt->digest_buf, scrypt->digest_len, (u8 *) base64_digest);
|
||||||
|
|
||||||
|
const int line_len = snprintf (line_buf, line_size, "%s:%u:%u:%u:%s:%s",
|
||||||
|
SIGNATURE_SCRYPT,
|
||||||
|
scrypt->N,
|
||||||
|
scrypt->r,
|
||||||
|
scrypt->p,
|
||||||
|
base64_salt,
|
||||||
|
base64_digest);
|
||||||
|
|
||||||
|
return line_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void module_init (module_ctx_t *module_ctx)
|
||||||
|
{
|
||||||
|
module_ctx->module_context_size = MODULE_CONTEXT_SIZE_CURRENT;
|
||||||
|
module_ctx->module_interface_version = MODULE_INTERFACE_VERSION_CURRENT;
|
||||||
|
|
||||||
|
module_ctx->module_attack_exec = module_attack_exec;
|
||||||
|
module_ctx->module_benchmark_esalt = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_benchmark_hook_salt = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_benchmark_mask = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_benchmark_charset = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_benchmark_salt = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_bridge_name = module_bridge_name;
|
||||||
|
module_ctx->module_bridge_type = module_bridge_type;
|
||||||
|
module_ctx->module_build_plain_postprocess = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_deep_comp_kernel = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_deprecated_notice = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_dgst_pos0 = module_dgst_pos0;
|
||||||
|
module_ctx->module_dgst_pos1 = module_dgst_pos1;
|
||||||
|
module_ctx->module_dgst_pos2 = module_dgst_pos2;
|
||||||
|
module_ctx->module_dgst_pos3 = module_dgst_pos3;
|
||||||
|
module_ctx->module_dgst_size = module_dgst_size;
|
||||||
|
module_ctx->module_dictstat_disable = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_esalt_size = module_esalt_size;
|
||||||
|
module_ctx->module_extra_buffer_size = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_extra_tmp_size = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_extra_tuningdb_block = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_forced_outfile_format = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_binary_count = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_binary_parse = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_binary_save = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_decode_postprocess = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_decode_potfile = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_decode_zero_hash = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_decode = module_hash_decode;
|
||||||
|
module_ctx->module_hash_encode_status = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_encode_potfile = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_encode = module_hash_encode;
|
||||||
|
module_ctx->module_hash_init_selftest = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_mode = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hash_category = module_hash_category;
|
||||||
|
module_ctx->module_hash_name = module_hash_name;
|
||||||
|
module_ctx->module_hashes_count_min = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hashes_count_max = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hlfmt_disable = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hook_extra_param_size = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hook_extra_param_init = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hook_extra_param_term = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hook12 = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hook23 = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hook_salt_size = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_hook_size = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_jit_build_options = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_jit_cache_disable = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_kernel_accel_max = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_kernel_accel_min = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_kernel_loops_max = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_kernel_loops_min = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_kernel_threads_max = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_kernel_threads_min = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_kern_type = module_kern_type;
|
||||||
|
module_ctx->module_kern_type_dynamic = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_opti_type = module_opti_type;
|
||||||
|
module_ctx->module_opts_type = module_opts_type;
|
||||||
|
module_ctx->module_outfile_check_disable = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_outfile_check_nocomp = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_potfile_custom_check = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_potfile_disable = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_potfile_keep_all_hashes = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_pwdump_column = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_pw_max = module_pw_max;
|
||||||
|
module_ctx->module_pw_min = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_salt_max = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_salt_min = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_salt_type = module_salt_type;
|
||||||
|
module_ctx->module_separator = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_st_hash = module_st_hash;
|
||||||
|
module_ctx->module_st_pass = module_st_pass;
|
||||||
|
module_ctx->module_tmp_size = module_tmp_size;
|
||||||
|
module_ctx->module_unstable_warning = MODULE_DEFAULT;
|
||||||
|
module_ctx->module_warmup_disable = MODULE_DEFAULT;
|
||||||
|
}
|
90
tools/test_modules/m70200.pm
Normal file
90
tools/test_modules/m70200.pm
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/env perl
|
||||||
|
|
||||||
|
##
|
||||||
|
## Author......: See docs/credits.txt
|
||||||
|
## License.....: MIT
|
||||||
|
##
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Crypt::ScryptKDF qw (scrypt_hash);
|
||||||
|
use MIME::Base64 qw (decode_base64);
|
||||||
|
|
||||||
|
sub module_constraints { [[0, 256], [1, 15], [-1, -1], [-1, -1], [-1, -1]] }
|
||||||
|
|
||||||
|
sub module_generate_hash
|
||||||
|
{
|
||||||
|
my $word = shift;
|
||||||
|
my $salt = shift;
|
||||||
|
my $N = shift // 16384;
|
||||||
|
my $r = shift // 8;
|
||||||
|
my $p = shift // 2;
|
||||||
|
|
||||||
|
my $hash_buf = scrypt_hash ($word, $salt, $N, $r, $p, 32);
|
||||||
|
|
||||||
|
my $hash = sprintf ('%s', $hash_buf);
|
||||||
|
|
||||||
|
return $hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub module_verify_hash
|
||||||
|
{
|
||||||
|
my $line = shift;
|
||||||
|
|
||||||
|
# scrypt
|
||||||
|
return unless (substr ($line, 0, 7) eq 'SCRYPT:');
|
||||||
|
|
||||||
|
# get hash
|
||||||
|
my $index1 = index ($line, ":", 7);
|
||||||
|
|
||||||
|
return if $index1 < 1;
|
||||||
|
|
||||||
|
# N
|
||||||
|
my $N = substr ($line, 7, $index1 - 7);
|
||||||
|
|
||||||
|
my $index2 = index ($line, ":", $index1 + 1);
|
||||||
|
|
||||||
|
return if $index2 < 1;
|
||||||
|
|
||||||
|
# r
|
||||||
|
my $r = substr ($line, $index1 + 1, $index2 - $index1 - 1);
|
||||||
|
|
||||||
|
$index1 = index ($line, ":", $index2 + 1);
|
||||||
|
|
||||||
|
return if $index1 < 1;
|
||||||
|
|
||||||
|
# p
|
||||||
|
my $p = substr ($line, $index2 + 1, $index1 - $index2 - 1);
|
||||||
|
|
||||||
|
$index2 = index ($line, ":", $index1 + 1);
|
||||||
|
|
||||||
|
return if $index2 < 1;
|
||||||
|
|
||||||
|
# salt
|
||||||
|
my $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
|
||||||
|
|
||||||
|
$salt = decode_base64 ($salt);
|
||||||
|
|
||||||
|
$index1 = index ($line, ":", $index2 + 1);
|
||||||
|
|
||||||
|
return if $index1 < 1;
|
||||||
|
|
||||||
|
# digest
|
||||||
|
|
||||||
|
my $word = substr ($line, $index1 + 1);
|
||||||
|
|
||||||
|
return unless defined $salt;
|
||||||
|
return unless defined $word;
|
||||||
|
return unless defined $N;
|
||||||
|
return unless defined $r;
|
||||||
|
return unless defined $p;
|
||||||
|
|
||||||
|
$word = pack_if_HEX_notation ($word);
|
||||||
|
|
||||||
|
my $new_hash = module_generate_hash ($word, $salt, $N, $r, $p);
|
||||||
|
|
||||||
|
return ($new_hash, $word);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
Loading…
Reference in New Issue
Block a user