1
0
mirror of https://github.com/hashcat/hashcat.git synced 2025-07-04 13:52:40 +00:00

The Assimilation Bridge (Scrypt-Yescrypt GPU-CPU hybrid plugin -m 70200)

This commit is contained in:
Jens Steube 2025-06-01 07:10:00 +02:00
parent 22c25b3ea1
commit ed71e41ae1
26 changed files with 7621 additions and 0 deletions

200
deps/yescrypt-master/CHANGES vendored Normal file
View 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
View 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
View 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
View 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
View 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

View File

@ -0,0 +1 @@
05ad49b9d9fb9eb65df78c919c3a778b7952e2e63f2e8ddb6b2b3f4b645e3cd0 PHC-TEST-OUT

197
deps/yescrypt-master/README vendored Normal file
View 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
View 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
View 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(&params,
(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
View 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
View 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
View 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, &params,
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
View 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
View 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
View 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
View 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), &params, 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(&params,
(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(&params,
(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(&params,
(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(&params,
(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
View 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(&params,
(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, &param))
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
View 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(&params.r, 30, src);
if (!src)
return NULL;
src = decode64_uint32_fixed(&params.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(&params.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(&params.p, src, 2);
if (!src)
return NULL;
}
if (have & 2) {
src = decode64_uint32(&params.t, src, 1);
if (!src)
return NULL;
}
if (have & 4) {
src = decode64_uint32(&params.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,
&params, 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, &params, buf, buflen);
if (yescrypt_free_local(&local))
return -1;
return retval;
}

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
View 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
View 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
View 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_ */

View 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;
}

View 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
View 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;
}

View 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;