diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index 1f4312c2..7ad9f780 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -62,6 +62,7 @@ libsodium_la_SOURCES = \ crypto_pwhash/argon2/blake2b-long.c \ crypto_pwhash/argon2/blake2b-long.h \ crypto_pwhash/argon2/blamka-round-ref.h \ + crypto_pwhash/argon2/pwhash_argon2i.c \ crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c \ crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h \ crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c \ diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-core.c b/src/libsodium/crypto_pwhash/argon2/argon2-core.c index ae3d1627..1d9065a6 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-core.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-core.c @@ -496,11 +496,11 @@ int argon2_pick_best_implementation(void) #if (defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)) || \ (defined(_MSC_VER) && (defined(_M_X64) || defined(_M_AMD64))) if (sodium_runtime_has_ssse3()) { - fill_segment_fn fill_segment = fill_segment_ssse3; + fill_segment = fill_segment_ssse3; return 0; } #endif - fill_segment_fn fill_segment = fill_segment_ref; + fill_segment = fill_segment_ref; return 0; } diff --git a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c new file mode 100644 index 00000000..ab43c98d --- /dev/null +++ b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c @@ -0,0 +1,141 @@ + +#include +#include +#include +#include +#include + +#include "argon2.h" +#include "argon2-core.h" +#include "crypto_pwhash_argon2i.h" +#include "randombytes.h" +#include "utils.h" + +#define STR_HASHBYTES 32U + +size_t +crypto_pwhash_argon2i_saltbytes(void) +{ + return crypto_pwhash_argon2i_SALTBYTES; +} + +size_t +crypto_pwhash_argon2i_strbytes(void) +{ + return crypto_pwhash_argon2i_STRBYTES; +} + +const char * +crypto_pwhash_argon2i_strprefix(void) +{ + return crypto_pwhash_argon2i_STRPREFIX; +} + +size_t +crypto_pwhash_argon2i_opslimit_interactive(void) +{ + return crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2i_memlimit_interactive(void) +{ + return crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2i_opslimit_sensitive(void) +{ + return crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_argon2i_memlimit_sensitive(void) +{ + return crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash_argon2i(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, + size_t memlimit) +{ + memlimit /= 1024U; + if (outlen > ARGON2_MAX_OUTLEN || passwdlen > ARGON2_MAX_PWD_LENGTH || + opslimit > ARGON2_MAX_TIME || memlimit > ARGON2_MAX_MEMORY) { + errno = EFBIG; + return -1; + } + if (outlen < ARGON2_MIN_OUTLEN || passwdlen < ARGON2_MIN_PWD_LENGTH || + opslimit < ARGON2_MIN_TIME || memlimit < ARGON2_MIN_MEMORY) { + errno = EINVAL; + return -1; + } + if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) memlimit, + (uint32_t) 1U, passwd, (size_t) passwdlen, + salt, (size_t) crypto_pwhash_argon2i_SALTBYTES, + out, (size_t) outlen) != ARGON2_OK) { + return -1; + } + return 0; +} + +int +crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, + size_t memlimit) +{ + unsigned char salt[crypto_pwhash_argon2i_SALTBYTES]; + + memlimit /= 1024U; + if (passwdlen > ARGON2_MAX_PWD_LENGTH || + opslimit > ARGON2_MAX_TIME || memlimit > ARGON2_MAX_MEMORY) { + errno = EFBIG; + return -1; + } + if (passwdlen < ARGON2_MIN_PWD_LENGTH || + opslimit < ARGON2_MIN_TIME || memlimit < ARGON2_MIN_MEMORY) { + errno = EINVAL; + return -1; + } + randombytes_buf(salt, sizeof salt); + memset(out, 0, crypto_pwhash_argon2i_STRBYTES); + if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) memlimit, + (uint32_t) 1U, passwd, (size_t) passwdlen, + salt, sizeof salt, STR_HASHBYTES, + out, crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) { + return -1; + } + return 0; +} + +int +crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) +{ + if (passwdlen > ARGON2_MAX_PWD_LENGTH) { + errno = EFBIG; + return -1; + } + if (passwdlen < ARGON2_MIN_PWD_LENGTH) { + errno = EINVAL; + return -1; + } + if (argon2i_verify(str, passwd, (size_t) passwdlen) != ARGON2_OK) { + return -1; + } + return 0; +} + +int +_crypto_pwhash_argon2i_pick_best_implementation(void) +{ + return argon2_pick_best_implementation(); +} diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am index 31d2c1c8..eef27a8e 100644 --- a/src/libsodium/include/Makefile.am +++ b/src/libsodium/include/Makefile.am @@ -21,6 +21,7 @@ SODIUM_EXPORT = \ sodium/crypto_hash_sha512.h \ sodium/crypto_onetimeauth.h \ sodium/crypto_onetimeauth_poly1305.h \ + sodium/crypto_pwhash_argon2i.h \ sodium/crypto_pwhash_scryptsalsa208sha256.h \ sodium/crypto_scalarmult.h \ sodium/crypto_scalarmult_curve25519.h \ diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h index b9a44ca3..9d2b9d6b 100644 --- a/src/libsodium/include/sodium.h +++ b/src/libsodium/include/sodium.h @@ -22,6 +22,7 @@ #include "sodium/crypto_hash_sha512.h" #include "sodium/crypto_onetimeauth.h" #include "sodium/crypto_onetimeauth_poly1305.h" +#include "sodium/crypto_pwhash_argon2i.h" #include "sodium/crypto_pwhash_scryptsalsa208sha256.h" #include "sodium/crypto_scalarmult.h" #include "sodium/crypto_scalarmult_curve25519.h" diff --git a/src/libsodium/sodium/core.c b/src/libsodium/sodium/core.c index b2f149e9..f8de5ab1 100644 --- a/src/libsodium/sodium/core.c +++ b/src/libsodium/sodium/core.c @@ -28,6 +28,7 @@ sodium_init(void) _sodium_runtime_get_cpu_features(); randombytes_stir(); _sodium_alloc_init(); + _crypto_pwhash_argon2i_pick_best_implementation(); _crypto_generichash_blake2b_pick_best_implementation(); _crypto_onetimeauth_poly1305_pick_best_implementation(); _crypto_scalarmult_curve25519_pick_best_implementation();