mirror of
https://github.com/libtom/libtomcrypt
synced 2026-08-25 20:26:07 -04:00
Merge pull request #719 from libtom/pr/scrypt-rfc7914
The scrypt Password-Based Key Derivation Function (RFC 7914)
This commit is contained in:
commit
e5bfb94f63
15 changed files with 390 additions and 32 deletions
|
|
@ -7629,6 +7629,33 @@ The output tag of length \textit{outlen} (minimum 4 bytes) is written to \textit
|
|||
The function returns \texttt{CRYPT\_OK} on success, \texttt{CRYPT\_MEM} if memory allocation fails, or \texttt{CRYPT\_INVALID\_ARG} if any parameter is out of range.
|
||||
|
||||
|
||||
\subsection{scrypt}
|
||||
\index{scrypt}
|
||||
\label{scrypt}
|
||||
|
||||
scrypt is a memory-hard password-based key derivation function defined in \href{https://datatracker.ietf.org/doc/html/rfc7914}{\texttt{RFC 7914}}.
|
||||
It is designed so that a large amount of memory is required for evaluation, making hardware brute-force attacks more costly.
|
||||
Internally it uses PBKDF2-HMAC-SHA-256 and a reduced-round Salsa20 core.
|
||||
|
||||
To enable scrypt, define \texttt{LTC\_SCRYPT} in \textit{tomcrypt\_custom.h} (it also requires \texttt{LTC\_PKCS\_5} and \texttt{LTC\_SHA256}).
|
||||
|
||||
\index{scrypt\_pbkdf()}
|
||||
\begin{alltt}
|
||||
int scrypt_pbkdf(const unsigned char *password, unsigned long password_len,
|
||||
const unsigned char *salt, unsigned long salt_len,
|
||||
unsigned long N, unsigned long r, unsigned long p,
|
||||
unsigned char *out, unsigned long outlen);
|
||||
\end{alltt}
|
||||
|
||||
The \textit{password} parameter is the password of length \textit{password\_len}.
|
||||
The \textit{salt} parameter is a random salt of length \textit{salt\_len}.
|
||||
The \textit{N} parameter is the CPU/memory cost; it must be greater than 1 and a power of 2.
|
||||
The \textit{r} parameter is the block size (minimum 1; a typical value is 8).
|
||||
The \textit{p} parameter is the parallelisation factor (minimum 1); this implementation is single-threaded, so increasing \textit{p} raises the computational cost without improving performance.
|
||||
The derived key of length \textit{outlen} is written to \textit{out}.
|
||||
The function returns \texttt{CRYPT\_OK} on success or an error code on failure.
|
||||
|
||||
|
||||
\mysection{PKCS \#8}
|
||||
\index{PKCS \#8}
|
||||
\label{pkcs8}
|
||||
|
|
|
|||
|
|
@ -1675,6 +1675,14 @@
|
|||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="scrypt"
|
||||
>
|
||||
<File
|
||||
RelativePath="src\misc\scrypt\scrypt.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ssh"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -116,13 +116,14 @@ src/misc/padding/padding_pad.o src/misc/password_free.o src/misc/pbes/pbes.o src
|
|||
src/misc/pbes/pbes2.o src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o \
|
||||
src/misc/pem/pem_ssh.o src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o \
|
||||
src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o \
|
||||
src/misc/ssh/ssh_decode_sequence_multi.o src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o \
|
||||
src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \
|
||||
src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \
|
||||
src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \
|
||||
src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \
|
||||
src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \
|
||||
src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
|
||||
src/misc/scrypt/scrypt.o src/misc/ssh/ssh_decode_sequence_multi.o \
|
||||
src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
|
||||
src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \
|
||||
src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \
|
||||
src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \
|
||||
src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o \
|
||||
src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o \
|
||||
src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
|
||||
src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
|
||||
src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \
|
||||
src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \
|
||||
|
|
@ -242,7 +243,7 @@ tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o \
|
|||
tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o tests/pem_test.o \
|
||||
tests/pk_oid_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o \
|
||||
tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o tests/rotate_test.o tests/rsa_test.o \
|
||||
tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
|
||||
tests/scrypt_test.o tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
|
||||
|
||||
#The following headers will be installed by "make install"
|
||||
HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \
|
||||
|
|
|
|||
|
|
@ -109,13 +109,14 @@ src/misc/padding/padding_pad.obj src/misc/password_free.obj src/misc/pbes/pbes.o
|
|||
src/misc/pbes/pbes2.obj src/misc/pem/pem.obj src/misc/pem/pem_pkcs.obj src/misc/pem/pem_read.obj \
|
||||
src/misc/pem/pem_ssh.obj src/misc/pkcs12/pkcs12_kdf.obj src/misc/pkcs12/pkcs12_utf8_to_utf16.obj \
|
||||
src/misc/pkcs5/pkcs_5_1.obj src/misc/pkcs5/pkcs_5_2.obj src/misc/pkcs5/pkcs_5_test.obj \
|
||||
src/misc/ssh/ssh_decode_sequence_multi.obj src/misc/ssh/ssh_encode_sequence_multi.obj src/misc/zeromem.obj \
|
||||
src/modes/cbc/cbc_decrypt.obj src/modes/cbc/cbc_done.obj src/modes/cbc/cbc_encrypt.obj \
|
||||
src/modes/cbc/cbc_getiv.obj src/modes/cbc/cbc_setiv.obj src/modes/cbc/cbc_start.obj \
|
||||
src/modes/cfb/cfb_decrypt.obj src/modes/cfb/cfb_done.obj src/modes/cfb/cfb_encrypt.obj \
|
||||
src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj src/modes/cfb/cfb_start.obj \
|
||||
src/modes/ctr/ctr_decrypt.obj src/modes/ctr/ctr_done.obj src/modes/ctr/ctr_encrypt.obj \
|
||||
src/modes/ctr/ctr_getiv.obj src/modes/ctr/ctr_setiv.obj src/modes/ctr/ctr_start.obj src/modes/ctr/ctr_test.obj \
|
||||
src/misc/scrypt/scrypt.obj src/misc/ssh/ssh_decode_sequence_multi.obj \
|
||||
src/misc/ssh/ssh_encode_sequence_multi.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj \
|
||||
src/modes/cbc/cbc_done.obj src/modes/cbc/cbc_encrypt.obj src/modes/cbc/cbc_getiv.obj \
|
||||
src/modes/cbc/cbc_setiv.obj src/modes/cbc/cbc_start.obj src/modes/cfb/cfb_decrypt.obj \
|
||||
src/modes/cfb/cfb_done.obj src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj \
|
||||
src/modes/cfb/cfb_setiv.obj src/modes/cfb/cfb_start.obj src/modes/ctr/ctr_decrypt.obj \
|
||||
src/modes/ctr/ctr_done.obj src/modes/ctr/ctr_encrypt.obj src/modes/ctr/ctr_getiv.obj \
|
||||
src/modes/ctr/ctr_setiv.obj src/modes/ctr/ctr_start.obj src/modes/ctr/ctr_test.obj \
|
||||
src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj src/modes/ecb/ecb_encrypt.obj \
|
||||
src/modes/ecb/ecb_start.obj src/modes/f8/f8_decrypt.obj src/modes/f8/f8_done.obj src/modes/f8/f8_encrypt.obj \
|
||||
src/modes/f8/f8_getiv.obj src/modes/f8/f8_setiv.obj src/modes/f8/f8_start.obj src/modes/f8/f8_test_mode.obj \
|
||||
|
|
@ -235,7 +236,7 @@ tests/misc_test.obj tests/modes_test.obj tests/mpi_test.obj tests/multi_test.obj
|
|||
tests/no_null_termination_check_test.obj tests/no_prng.obj tests/padding_test.obj tests/pem_test.obj \
|
||||
tests/pk_oid_test.obj tests/pkcs_1_eme_test.obj tests/pkcs_1_emsa_test.obj tests/pkcs_1_oaep_test.obj \
|
||||
tests/pkcs_1_pss_test.obj tests/pkcs_1_test.obj tests/prng_test.obj tests/rotate_test.obj tests/rsa_test.obj \
|
||||
tests/ssh_test.obj tests/store_test.obj tests/test.obj tests/x25519_test.obj
|
||||
tests/scrypt_test.obj tests/ssh_test.obj tests/store_test.obj tests/test.obj tests/x25519_test.obj
|
||||
|
||||
#The following headers will be installed by "make install"
|
||||
HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \
|
||||
|
|
|
|||
|
|
@ -130,13 +130,14 @@ src/misc/padding/padding_pad.o src/misc/password_free.o src/misc/pbes/pbes.o src
|
|||
src/misc/pbes/pbes2.o src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o \
|
||||
src/misc/pem/pem_ssh.o src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o \
|
||||
src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o \
|
||||
src/misc/ssh/ssh_decode_sequence_multi.o src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o \
|
||||
src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \
|
||||
src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \
|
||||
src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \
|
||||
src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \
|
||||
src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \
|
||||
src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
|
||||
src/misc/scrypt/scrypt.o src/misc/ssh/ssh_decode_sequence_multi.o \
|
||||
src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
|
||||
src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \
|
||||
src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \
|
||||
src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \
|
||||
src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o \
|
||||
src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o \
|
||||
src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
|
||||
src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
|
||||
src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \
|
||||
src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \
|
||||
|
|
@ -256,7 +257,7 @@ tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o \
|
|||
tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o tests/pem_test.o \
|
||||
tests/pk_oid_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o \
|
||||
tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o tests/rotate_test.o tests/rsa_test.o \
|
||||
tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
|
||||
tests/scrypt_test.o tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
|
||||
|
||||
#The following headers will be installed by "make install"
|
||||
HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \
|
||||
|
|
|
|||
|
|
@ -301,13 +301,14 @@ src/misc/padding/padding_pad.o src/misc/password_free.o src/misc/pbes/pbes.o src
|
|||
src/misc/pbes/pbes2.o src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o \
|
||||
src/misc/pem/pem_ssh.o src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o \
|
||||
src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o \
|
||||
src/misc/ssh/ssh_decode_sequence_multi.o src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o \
|
||||
src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \
|
||||
src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \
|
||||
src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \
|
||||
src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \
|
||||
src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \
|
||||
src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
|
||||
src/misc/scrypt/scrypt.o src/misc/ssh/ssh_decode_sequence_multi.o \
|
||||
src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
|
||||
src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \
|
||||
src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \
|
||||
src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \
|
||||
src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o \
|
||||
src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o \
|
||||
src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
|
||||
src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
|
||||
src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \
|
||||
src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \
|
||||
|
|
@ -432,7 +433,7 @@ tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o \
|
|||
tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o tests/pem_test.o \
|
||||
tests/pk_oid_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o \
|
||||
tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o tests/rotate_test.o tests/rsa_test.o \
|
||||
tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
|
||||
tests/scrypt_test.o tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o
|
||||
|
||||
# The following headers will be installed by "make install"
|
||||
HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \
|
||||
|
|
|
|||
|
|
@ -253,6 +253,7 @@ src/misc/pkcs12/pkcs12_utf8_to_utf16.c
|
|||
src/misc/pkcs5/pkcs_5_1.c
|
||||
src/misc/pkcs5/pkcs_5_2.c
|
||||
src/misc/pkcs5/pkcs_5_test.c
|
||||
src/misc/scrypt/scrypt.c
|
||||
src/misc/ssh/ssh_decode_sequence_multi.c
|
||||
src/misc/ssh/ssh_encode_sequence_multi.c
|
||||
src/misc/zeromem.c
|
||||
|
|
|
|||
|
|
@ -516,6 +516,8 @@
|
|||
|
||||
#define LTC_ARGON2
|
||||
|
||||
#define LTC_SCRYPT
|
||||
|
||||
/* Keep LTC_NO_HKDF for compatibility reasons
|
||||
* superseeded by LTC_NO_MISC*/
|
||||
#ifndef LTC_NO_HKDF
|
||||
|
|
@ -687,6 +689,10 @@
|
|||
#error LTC_ARGON2 requires LTC_BLAKE2B
|
||||
#endif
|
||||
|
||||
#if defined(LTC_SCRYPT) && (!defined(LTC_PKCS_5) || !defined(LTC_SHA256))
|
||||
#error LTC_SCRYPT requires LTC_PKCS_5 and LTC_SHA256
|
||||
#endif
|
||||
|
||||
#if defined(LTC_CHACHA20POLY1305_MODE) && (!defined(LTC_CHACHA) || !defined(LTC_POLY1305))
|
||||
#error LTC_CHACHA20POLY1305_MODE requires LTC_CHACHA + LTC_POLY1305
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -71,6 +71,14 @@ int argon2_hash(const unsigned char *pwd, unsigned long pwdlen,
|
|||
unsigned char *out, unsigned long outlen);
|
||||
#endif /* LTC_ARGON2 */
|
||||
|
||||
/* ---- scrypt password-based KDF (RFC 7914) ---- */
|
||||
#ifdef LTC_SCRYPT
|
||||
int scrypt_pbkdf(const unsigned char *password, unsigned long password_len,
|
||||
const unsigned char *salt, unsigned long salt_len,
|
||||
unsigned long N, unsigned long r, unsigned long p,
|
||||
unsigned char *out, unsigned long outlen);
|
||||
#endif /* LTC_SCRYPT */
|
||||
|
||||
#ifdef LTC_BCRYPT
|
||||
int bcrypt_pbkdf_openbsd(const void *secret, unsigned long secret_len,
|
||||
const unsigned char *salt, unsigned long salt_len,
|
||||
|
|
|
|||
|
|
@ -458,6 +458,9 @@ const char *crypt_build_settings =
|
|||
" BCRYPT "
|
||||
" " NAME_VALUE(LTC_BCRYPT_DEFAULT_ROUNDS) " "
|
||||
#endif
|
||||
#if defined(LTC_SCRYPT)
|
||||
" SCRYPT "
|
||||
#endif
|
||||
#if defined(LTC_CRC32)
|
||||
" CRC32 "
|
||||
#endif
|
||||
|
|
|
|||
190
src/misc/scrypt/scrypt.c
Normal file
190
src/misc/scrypt/scrypt.c
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file scrypt.c
|
||||
scrypt password-based key derivation function (RFC 7914)
|
||||
*/
|
||||
#ifdef LTC_SCRYPT
|
||||
|
||||
/* Salsa20/8 Core (RFC 7914 Section 3) */
|
||||
#define SCRYPT_QR(a,b,c,d) \
|
||||
x[b] ^= ROL(x[a] + x[d], 7); \
|
||||
x[c] ^= ROL(x[b] + x[a], 9); \
|
||||
x[d] ^= ROL(x[c] + x[b], 13); \
|
||||
x[a] ^= ROL(x[d] + x[c], 18);
|
||||
|
||||
static void s_salsa20_8(unsigned char B[64])
|
||||
{
|
||||
ulong32 x[16], b32[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
LOAD32L(b32[i], B + i * 4);
|
||||
}
|
||||
XMEMCPY(x, b32, sizeof(x));
|
||||
for (i = 8; i > 0; i -= 2) {
|
||||
SCRYPT_QR( 0, 4, 8,12)
|
||||
SCRYPT_QR( 5, 9,13, 1)
|
||||
SCRYPT_QR(10,14, 2, 6)
|
||||
SCRYPT_QR(15, 3, 7,11)
|
||||
SCRYPT_QR( 0, 1, 2, 3)
|
||||
SCRYPT_QR( 5, 6, 7, 4)
|
||||
SCRYPT_QR(10,11, 8, 9)
|
||||
SCRYPT_QR(15,12,13,14)
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
STORE32L(x[i] + b32[i], B + i * 4);
|
||||
}
|
||||
}
|
||||
|
||||
/* scryptBlockMix (RFC 7914 Section 4) */
|
||||
static void s_blockmix(unsigned char *B, unsigned char *Y, unsigned long r)
|
||||
{
|
||||
unsigned char X[64];
|
||||
unsigned long i;
|
||||
unsigned long blen = 128 * r;
|
||||
|
||||
/* 1: X = B[2r - 1] */
|
||||
XMEMCPY(X, B + blen - 64, 64);
|
||||
/* 2: for i = 0 to 2r-1 */
|
||||
for (i = 0; i < 2 * r; ++i) {
|
||||
unsigned long j;
|
||||
for (j = 0; j < 64; ++j) X[j] ^= B[i * 64 + j];
|
||||
s_salsa20_8(X);
|
||||
XMEMCPY(Y + i * 64, X, 64);
|
||||
}
|
||||
/* 3: B' = (Y[0], Y[2], ..., Y[2r-2], Y[1], Y[3], ..., Y[2r-1]) */
|
||||
for (i = 0; i < r; ++i) {
|
||||
XMEMCPY(B + i * 64, Y + (2 * i) * 64, 64);
|
||||
}
|
||||
for (i = 0; i < r; ++i) {
|
||||
XMEMCPY(B + (i + r) * 64, Y + (2 * i + 1) * 64, 64);
|
||||
}
|
||||
}
|
||||
|
||||
/* Integerify: interpret last 64-byte block as little-endian and return low 64 bits */
|
||||
static LTC_INLINE ulong64 s_integerify(const unsigned char *B, unsigned long r)
|
||||
{
|
||||
const unsigned char *X = B + (2 * r - 1) * 64;
|
||||
ulong64 v;
|
||||
|
||||
LOAD64L(v, X);
|
||||
return v;
|
||||
}
|
||||
|
||||
/* scryptROMix (RFC 7914 Section 5) */
|
||||
static void s_romix(unsigned char *B, unsigned long r, ulong64 N, unsigned char *V, unsigned char *XY)
|
||||
{
|
||||
unsigned char *X = XY;
|
||||
unsigned char *Y = XY + 128 * r;
|
||||
unsigned long blen = 128 * r;
|
||||
ulong64 i, j;
|
||||
|
||||
/* 1: X = B */
|
||||
XMEMCPY(X, B, blen);
|
||||
/* 2: for i = 0 to N-1: V[i] = X; X = BlockMix(X) */
|
||||
for (i = 0; i < N; ++i) {
|
||||
XMEMCPY(V + i * blen, X, blen);
|
||||
s_blockmix(X, Y, r);
|
||||
}
|
||||
/* 3: for i = 0 to N-1 */
|
||||
for (i = 0; i < N; ++i) {
|
||||
j = s_integerify(X, r) & (N - 1);
|
||||
{
|
||||
unsigned long k;
|
||||
unsigned char *Vj = V + j * blen;
|
||||
for (k = 0; k < blen; ++k) X[k] ^= Vj[k];
|
||||
}
|
||||
s_blockmix(X, Y, r);
|
||||
}
|
||||
/* 4: B' = X */
|
||||
XMEMCPY(B, X, blen);
|
||||
}
|
||||
|
||||
/**
|
||||
Derive a key using scrypt (RFC 7914)
|
||||
|
||||
@param password Password
|
||||
@param password_len Length of password
|
||||
@param salt Salt
|
||||
@param salt_len Length of salt
|
||||
@param N CPU/memory cost parameter (must be > 1 and a power of 2)
|
||||
@param r Block size parameter (minimum 1)
|
||||
@param p Parallelisation parameter (minimum 1)
|
||||
@param out [out] Derived key
|
||||
@param outlen Desired output length
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int scrypt_pbkdf(const unsigned char *password, unsigned long password_len,
|
||||
const unsigned char *salt, unsigned long salt_len,
|
||||
unsigned long N, unsigned long r, unsigned long p,
|
||||
unsigned char *out, unsigned long outlen)
|
||||
{
|
||||
unsigned char *B = NULL, *V = NULL, *XY = NULL;
|
||||
const unsigned char *pwd;
|
||||
unsigned long pwd_len, Blen, Vlen, XYlen, i;
|
||||
unsigned char zero_byte = 0;
|
||||
int err, hash_idx;
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
LTC_ARGCHK(password != NULL || password_len == 0);
|
||||
LTC_ARGCHK(salt != NULL || salt_len == 0);
|
||||
LTC_ARGCHK(N >= 2 && (N & (N - 1)) == 0); /* must be > 1 and power of 2 */
|
||||
LTC_ARGCHK(r >= 1);
|
||||
LTC_ARGCHK(p >= 1);
|
||||
LTC_ARGCHK(outlen >= 1);
|
||||
LTC_ARGCHK(r <= ULONG_MAX / 128 / p);
|
||||
LTC_ARGCHK(r <= ULONG_MAX / 256);
|
||||
LTC_ARGCHK(N <= ULONG_MAX / 128 / r);
|
||||
|
||||
hash_idx = find_hash("sha256");
|
||||
if (hash_idx == -1) return CRYPT_INVALID_HASH;
|
||||
|
||||
/* WORKAROUND: HMAC rejects zero-length keys; a single zero byte
|
||||
* produces the same zero-padded key block as an empty key. */
|
||||
pwd = password;
|
||||
pwd_len = password_len;
|
||||
if (pwd_len == 0) {
|
||||
pwd = &zero_byte;
|
||||
pwd_len = 1;
|
||||
}
|
||||
|
||||
Blen = 128 * r * p;
|
||||
Vlen = 128 * r * N;
|
||||
XYlen = 256 * r;
|
||||
|
||||
B = (unsigned char *)XMALLOC(Blen);
|
||||
V = (unsigned char *)XMALLOC(Vlen);
|
||||
XY = (unsigned char *)XMALLOC(XYlen);
|
||||
if (B == NULL || V == NULL || XY == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* 1: B = PBKDF2-HMAC-SHA256(password, salt, 1, p * 128 * r) */
|
||||
{
|
||||
unsigned long blen_out = Blen;
|
||||
err = pkcs_5_alg2(pwd, pwd_len, salt, salt_len, 1, hash_idx, B, &blen_out);
|
||||
if (err != CRYPT_OK) goto cleanup;
|
||||
}
|
||||
/* 2: for i = 0 to p-1: B[i] = ROMix(r, B[i], N) */
|
||||
for (i = 0; i < p; ++i) {
|
||||
s_romix(B + i * 128 * r, r, (ulong64)N, V, XY);
|
||||
}
|
||||
/* 3: DK = PBKDF2-HMAC-SHA256(password, B, 1, dkLen) */
|
||||
{
|
||||
unsigned long outlen_out = outlen;
|
||||
err = pkcs_5_alg2(pwd, pwd_len, B, Blen, 1, hash_idx, out, &outlen_out);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (XY != NULL) { zeromem(XY, XYlen); XFREE(XY); }
|
||||
if (V != NULL) { zeromem(V, Vlen); XFREE(V); }
|
||||
if (B != NULL) { zeromem(B, Blen); XFREE(B); }
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_SCRYPT */
|
||||
|
|
@ -10,6 +10,9 @@ int misc_test(void)
|
|||
#ifdef LTC_BCRYPT
|
||||
DO(bcrypt_test());
|
||||
#endif
|
||||
#ifdef LTC_SCRYPT
|
||||
DO(scrypt_test());
|
||||
#endif
|
||||
#ifdef LTC_HKDF
|
||||
DO(hkdf_test());
|
||||
#endif
|
||||
|
|
|
|||
106
tests/scrypt_test.c
Normal file
106
tests/scrypt_test.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include <tomcrypt_test.h>
|
||||
|
||||
#ifdef LTC_SCRYPT
|
||||
|
||||
/* RFC 7914 test vectors */
|
||||
|
||||
typedef struct {
|
||||
const char *password;
|
||||
unsigned long password_len;
|
||||
const char *salt;
|
||||
unsigned long salt_len;
|
||||
unsigned long N, r, p;
|
||||
const unsigned char expected[64];
|
||||
const char *name;
|
||||
} scrypt_testcase;
|
||||
|
||||
static const scrypt_testcase cases[] = {
|
||||
{
|
||||
"", 0, "", 0, 16, 1, 1,
|
||||
{
|
||||
0x77, 0xd6, 0x57, 0x62, 0x38, 0x65, 0x7b, 0x20,
|
||||
0x3b, 0x19, 0xca, 0x42, 0xc1, 0x8a, 0x04, 0x97,
|
||||
0xf1, 0x6b, 0x48, 0x44, 0xe3, 0x07, 0x4a, 0xe8,
|
||||
0xdf, 0xdf, 0xfa, 0x3f, 0xed, 0xe2, 0x14, 0x42,
|
||||
0xfc, 0xd0, 0x06, 0x9d, 0xed, 0x09, 0x48, 0xf8,
|
||||
0x32, 0x6a, 0x75, 0x3a, 0x0f, 0xc8, 0x1f, 0x17,
|
||||
0xe8, 0xd3, 0xe0, 0xfb, 0x2e, 0x0d, 0x36, 0x28,
|
||||
0xcf, 0x35, 0xe2, 0x0c, 0x38, 0xd1, 0x89, 0x06
|
||||
},
|
||||
"scrypt(\"\", \"\", 16, 1, 1)"
|
||||
},
|
||||
{
|
||||
"password", 8, "NaCl", 4, 1024, 8, 16,
|
||||
{
|
||||
0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00,
|
||||
0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe,
|
||||
0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30,
|
||||
0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62,
|
||||
0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88,
|
||||
0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda,
|
||||
0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d,
|
||||
0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40
|
||||
},
|
||||
"scrypt(\"password\", \"NaCl\", 1024, 8, 16)"
|
||||
},
|
||||
{
|
||||
"pleaseletmein", 13, "SodiumChloride", 14, 16384, 8, 1,
|
||||
{
|
||||
0x70, 0x23, 0xbd, 0xcb, 0x3a, 0xfd, 0x73, 0x48,
|
||||
0x46, 0x1c, 0x06, 0xcd, 0x81, 0xfd, 0x38, 0xeb,
|
||||
0xfd, 0xa8, 0xfb, 0xba, 0x90, 0x4f, 0x8e, 0x3e,
|
||||
0xa9, 0xb5, 0x43, 0xf6, 0x54, 0x5d, 0xa1, 0xf2,
|
||||
0xd5, 0x43, 0x29, 0x55, 0x61, 0x3f, 0x0f, 0xcf,
|
||||
0x62, 0xd4, 0x97, 0x05, 0x24, 0x2a, 0x9a, 0xf9,
|
||||
0xe6, 0x1e, 0x85, 0xdc, 0x0d, 0x65, 0x1e, 0x40,
|
||||
0xdf, 0xcf, 0x01, 0x7b, 0x45, 0x57, 0x58, 0x87
|
||||
},
|
||||
"scrypt(\"pleaseletmein\", \"SodiumChloride\", 16384, 8, 1)"
|
||||
},
|
||||
#ifdef LTC_SCRYPT_TEST_1GB
|
||||
/* Define LTC_SCRYPT_TEST_1GB via CFLAGS to enable this test vector
|
||||
* which allocates ~1 GiB of memory and takes a long time to run. */
|
||||
{
|
||||
"pleaseletmein", 13, "SodiumChloride", 14, 1048576, 8, 1,
|
||||
{
|
||||
0x21, 0x01, 0xcb, 0x9b, 0x6a, 0x51, 0x1a, 0xae,
|
||||
0xad, 0xdb, 0xbe, 0x09, 0xcf, 0x70, 0xf8, 0x81,
|
||||
0xec, 0x56, 0x8d, 0x57, 0x4a, 0x2f, 0xfd, 0x4d,
|
||||
0xab, 0xe5, 0xee, 0x98, 0x20, 0xad, 0xaa, 0x47,
|
||||
0x8e, 0x56, 0xfd, 0x8f, 0x4b, 0xa5, 0xd0, 0x9f,
|
||||
0xfa, 0x1c, 0x6d, 0x92, 0x7c, 0x40, 0xf4, 0xc3,
|
||||
0x37, 0x30, 0x40, 0x49, 0xe8, 0xa9, 0x52, 0xfb,
|
||||
0xcb, 0xf4, 0x5c, 0x6f, 0xa7, 0x7a, 0x41, 0xa4
|
||||
},
|
||||
"scrypt(\"pleaseletmein\", \"SodiumChloride\", 1048576, 8, 1)"
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
int scrypt_test(void)
|
||||
{
|
||||
unsigned char dk[64];
|
||||
unsigned int n;
|
||||
|
||||
for (n = 0; n < LTC_ARRAY_SIZE(cases); ++n) {
|
||||
DO(scrypt_pbkdf((const unsigned char *)cases[n].password, cases[n].password_len,
|
||||
(const unsigned char *)cases[n].salt, cases[n].salt_len,
|
||||
cases[n].N, cases[n].r, cases[n].p,
|
||||
dk, sizeof(dk)));
|
||||
COMPARE_TESTVECTOR(dk, sizeof(dk), cases[n].expected, sizeof(cases[n].expected), cases[n].name, n);
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int scrypt_test(void)
|
||||
{
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -31,6 +31,7 @@ pkcs_1_test.c
|
|||
prng_test.c
|
||||
rotate_test.c
|
||||
rsa_test.c
|
||||
scrypt_test.c
|
||||
ssh_test.c
|
||||
store_test.c
|
||||
test.c
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ int ed25519_test(void);
|
|||
int ssh_test(void);
|
||||
int argon2_test(void);
|
||||
int bcrypt_test(void);
|
||||
int scrypt_test(void);
|
||||
int no_null_termination_check_test(void);
|
||||
int pk_oid_test(void);
|
||||
int deprecated_test(void);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue