From 2cb841539e0d8f2b328f7bc546877fb01df54c1e Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 27 Jun 2017 16:06:43 +0200 Subject: [PATCH] Public Argon2id API --- src/libsodium/Makefile.am | 2 + .../crypto_pwhash/argon2/argon2-core.c | 6 + .../crypto_pwhash/argon2/pwhash_argon2i.c | 14 -- .../crypto_pwhash/argon2/pwhash_argon2id.c | 219 ++++++++++++++++++ src/libsodium/include/Makefile.am | 1 + src/libsodium/include/sodium/crypto_pwhash.h | 1 + .../include/sodium/crypto_pwhash_argon2i.h | 4 - .../include/sodium/crypto_pwhash_argon2id.h | 120 ++++++++++ .../include/sodium/private/implementations.h | 19 ++ src/libsodium/sodium/core.c | 4 +- 10 files changed, 370 insertions(+), 20 deletions(-) create mode 100644 src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c create mode 100644 src/libsodium/include/sodium/crypto_pwhash_argon2id.h create mode 100644 src/libsodium/include/sodium/private/implementations.h diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index 34e6f72f..04256461 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -54,6 +54,7 @@ libsodium_la_SOURCES = \ crypto_pwhash/argon2/blake2b-long.h \ crypto_pwhash/argon2/blamka-round-ref.h \ crypto_pwhash/argon2/pwhash_argon2i.c \ + crypto_pwhash/argon2/pwhash_argon2id.c \ crypto_pwhash/crypto_pwhash.c \ crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c \ crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h \ @@ -89,6 +90,7 @@ libsodium_la_SOURCES = \ crypto_verify/sodium/verify.c \ include/sodium/private/common.h \ include/sodium/private/curve25519_ref10.h \ + include/sodium/private/implementations.h \ include/sodium/private/mutex.h \ include/sodium/private/sse2_64_32.h \ randombytes/randombytes.c \ diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-core.c b/src/libsodium/crypto_pwhash/argon2/argon2-core.c index 61204552..091ce33f 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-core.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-core.c @@ -609,3 +609,9 @@ argon2_pick_best_implementation(void) return 0; /* LCOV_EXCL_STOP */ } + +int +_crypto_pwhash_argon2_pick_best_implementation(void) +{ + return argon2_pick_best_implementation(); +} diff --git a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c index b786da19..2e0805ae 100644 --- a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c +++ b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c @@ -146,14 +146,6 @@ crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen, return -1; } switch (alg) { - case crypto_pwhash_argon2i_ALG_ARGON2ID13: - if (argon2id_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; /* LCOV_EXCL_LINE */ - } - return 0; case crypto_pwhash_argon2i_ALG_ARGON2I13: if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) memlimit, (uint32_t) 1U, passwd, (size_t) passwdlen, salt, @@ -225,9 +217,3 @@ crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], } return -1; } - -int -_crypto_pwhash_argon2i_pick_best_implementation(void) -{ - return argon2_pick_best_implementation(); -} diff --git a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c new file mode 100644 index 00000000..916da9b1 --- /dev/null +++ b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c @@ -0,0 +1,219 @@ + +#include +#include +#include +#include +#include + +#include "argon2-core.h" +#include "argon2.h" +#include "crypto_pwhash_argon2id.h" +#include "randombytes.h" +#include "utils.h" + +#define STR_HASHBYTES 32U + +int +crypto_pwhash_argon2id_alg_argon2i13(void) +{ + return crypto_pwhash_argon2id_ALG_ARGON2I13; +} + +int +crypto_pwhash_argon2id_alg_argon2id13(void) +{ + return crypto_pwhash_argon2id_ALG_ARGON2ID13; +} + +size_t +crypto_pwhash_argon2id_bytes_min(void) +{ + return crypto_pwhash_argon2id_BYTES_MIN; +} + +size_t +crypto_pwhash_argon2id_bytes_max(void) +{ + return crypto_pwhash_argon2id_BYTES_MAX; +} + +size_t +crypto_pwhash_argon2id_passwd_min(void) +{ + return crypto_pwhash_argon2id_PASSWD_MIN; +} + +size_t +crypto_pwhash_argon2id_passwd_max(void) +{ + return crypto_pwhash_argon2id_PASSWD_MAX; +} + +size_t +crypto_pwhash_argon2id_saltbytes(void) +{ + return crypto_pwhash_argon2id_SALTBYTES; +} + +size_t +crypto_pwhash_argon2id_strbytes(void) +{ + return crypto_pwhash_argon2id_STRBYTES; +} + +const char* +crypto_pwhash_argon2id_strprefix(void) +{ + return crypto_pwhash_argon2id_STRPREFIX; +} + +size_t +crypto_pwhash_argon2id_opslimit_min(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2id_opslimit_max(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2id_memlimit_min(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2id_memlimit_max(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2id_opslimit_interactive(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2id_memlimit_interactive(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2id_opslimit_moderate(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2id_memlimit_moderate(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2id_opslimit_sensitive(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_argon2id_memlimit_sensitive(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash_argon2id(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, int alg) +{ + memset(out, 0, outlen); + 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; + } + switch (alg) { + case crypto_pwhash_argon2id_ALG_ARGON2ID13: + if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) memlimit, + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + (size_t) crypto_pwhash_argon2id_SALTBYTES, out, + (size_t) outlen) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; + default: + errno = EINVAL; + return -1; + } +} + +int +crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], + const char *const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + unsigned char salt[crypto_pwhash_argon2id_SALTBYTES]; + + memset(out, 0, crypto_pwhash_argon2id_STRBYTES); + 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); + if (argon2id_hash_encoded((uint32_t) opslimit, (uint32_t) memlimit, + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + sizeof salt, STR_HASHBYTES, out, + crypto_pwhash_argon2id_STRBYTES) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES], + const char *const passwd, + unsigned long long passwdlen) +{ + int verify_ret; + + if (passwdlen > ARGON2_MAX_PWD_LENGTH) { + errno = EFBIG; + return -1; + } + /* LCOV_EXCL_START */ + if (passwdlen < ARGON2_MIN_PWD_LENGTH) { + errno = EINVAL; + return -1; + } + /* LCOV_EXCL_STOP */ + + verify_ret = argon2id_verify(str, passwd, (size_t) passwdlen); + if (verify_ret == ARGON2_OK) { + return 0; + } + if (verify_ret == ARGON2_VERIFY_MISMATCH) { + errno = EINVAL; + } + return -1; +} diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am index eb75f15d..a63d127a 100644 --- a/src/libsodium/include/Makefile.am +++ b/src/libsodium/include/Makefile.am @@ -29,6 +29,7 @@ SODIUM_EXPORT = \ sodium/crypto_onetimeauth_poly1305.h \ sodium/crypto_pwhash.h \ sodium/crypto_pwhash_argon2i.h \ + sodium/crypto_pwhash_argon2id.h \ sodium/crypto_pwhash_scryptsalsa208sha256.h \ sodium/crypto_scalarmult.h \ sodium/crypto_scalarmult_curve25519.h \ diff --git a/src/libsodium/include/sodium/crypto_pwhash.h b/src/libsodium/include/sodium/crypto_pwhash.h index 9183763b..41664aa0 100644 --- a/src/libsodium/include/sodium/crypto_pwhash.h +++ b/src/libsodium/include/sodium/crypto_pwhash.h @@ -4,6 +4,7 @@ #include #include "crypto_pwhash_argon2i.h" +#include "crypto_pwhash_argon2id.h" #include "export.h" #ifdef __cplusplus diff --git a/src/libsodium/include/sodium/crypto_pwhash_argon2i.h b/src/libsodium/include/sodium/crypto_pwhash_argon2i.h index e70cde2f..0f895805 100644 --- a/src/libsodium/include/sodium/crypto_pwhash_argon2i.h +++ b/src/libsodium/include/sodium/crypto_pwhash_argon2i.h @@ -113,10 +113,6 @@ int crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYT unsigned long long passwdlen) __attribute__ ((warn_unused_result)); -/* ------------------------------------------------------------------------- */ - -int _crypto_pwhash_argon2i_pick_best_implementation(void); - #ifdef __cplusplus } #endif diff --git a/src/libsodium/include/sodium/crypto_pwhash_argon2id.h b/src/libsodium/include/sodium/crypto_pwhash_argon2id.h new file mode 100644 index 00000000..72e69ff3 --- /dev/null +++ b/src/libsodium/include/sodium/crypto_pwhash_argon2id.h @@ -0,0 +1,120 @@ +#ifndef crypto_pwhash_argon2id_H +#define crypto_pwhash_argon2id_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_argon2id_ALG_ARGON2I13 1 +SODIUM_EXPORT +int crypto_pwhash_argon2id_alg_argon2i13(void); + +#define crypto_pwhash_argon2id_ALG_ARGON2ID13 2 +SODIUM_EXPORT +int crypto_pwhash_argon2id_alg_argon2id13(void); + +#define crypto_pwhash_argon2id_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_bytes_min(void); + +#define crypto_pwhash_argon2id_BYTES_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_bytes_max(void); + +#define crypto_pwhash_argon2id_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_passwd_min(void); + +#define crypto_pwhash_argon2id_PASSWD_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_passwd_max(void); + +#define crypto_pwhash_argon2id_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_saltbytes(void); + +#define crypto_pwhash_argon2id_STRBYTES 128U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_strbytes(void); + +#define crypto_pwhash_argon2id_STRPREFIX "$argon2id$" +SODIUM_EXPORT +const char *crypto_pwhash_argon2id_strprefix(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MIN 3U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_min(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_max(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MIN 8192U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_min(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MAX ((SIZE_MAX >= 4398046510080U) ? 4398046510080U : (SIZE_MAX >= 2147483648U) ? 2147483648U : 32768U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_max(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE 4U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_interactive(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE 33554432U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_interactive(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MODERATE 6U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_moderate(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MODERATE 134217728U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_moderate(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE 8U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_sensitive(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE 536870912U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_argon2id(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, + int alg) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libsodium/include/sodium/private/implementations.h b/src/libsodium/include/sodium/private/implementations.h new file mode 100644 index 00000000..85c52d7c --- /dev/null +++ b/src/libsodium/include/sodium/private/implementations.h @@ -0,0 +1,19 @@ +#ifndef implementations_H +#define implementations_H + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +int _crypto_pwhash_argon2_pick_best_implementation(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libsodium/sodium/core.c b/src/libsodium/sodium/core.c index 9fdd09ec..9e8cfa8d 100644 --- a/src/libsodium/sodium/core.c +++ b/src/libsodium/sodium/core.c @@ -10,13 +10,13 @@ #include "core.h" #include "crypto_generichash.h" #include "crypto_onetimeauth.h" -#include "crypto_pwhash_argon2i.h" #include "crypto_scalarmult.h" #include "crypto_stream_chacha20.h" #include "crypto_stream_salsa20.h" #include "randombytes.h" #include "runtime.h" #include "utils.h" +#include "private/implementations.h" #include "private/mutex.h" #if !defined(_MSC_VER) && 0 @@ -51,7 +51,7 @@ sodium_init(void) _sodium_runtime_get_cpu_features(); randombytes_stir(); _sodium_alloc_init(); - _crypto_pwhash_argon2i_pick_best_implementation(); + _crypto_pwhash_argon2_pick_best_implementation(); _crypto_generichash_blake2b_pick_best_implementation(); _crypto_onetimeauth_poly1305_pick_best_implementation(); _crypto_scalarmult_curve25519_pick_best_implementation();