From 989189890b25fa7d8691d9416eabf5b07f2b2eb5 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 27 Jun 2017 15:43:40 +0200 Subject: [PATCH] More argon2id bits --- .../crypto_pwhash/argon2/argon2-encoding.c | 4 +- .../argon2/argon2-fill-block-ref.c | 2 +- src/libsodium/crypto_pwhash/argon2/argon2.c | 29 ++++++++++- src/libsodium/crypto_pwhash/argon2/argon2.h | 49 +++++++++++++++++++ .../crypto_pwhash/argon2/pwhash_argon2i.c | 39 ++++++++++----- src/libsodium/crypto_pwhash/crypto_pwhash.c | 15 ++++-- src/libsodium/include/sodium/crypto_pwhash.h | 4 ++ .../include/sodium/crypto_pwhash_argon2i.h | 4 ++ 8 files changed, 129 insertions(+), 17 deletions(-) diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-encoding.c b/src/libsodium/crypto_pwhash/argon2/argon2-encoding.c index 961e96b0..f817fd3c 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-encoding.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-encoding.c @@ -318,7 +318,9 @@ decode_string(argon2_context *ctx, const char *str, argon2_type type) ctx->saltlen = 0; ctx->outlen = 0; - if (type == Argon2_i) { + if (type == Argon2_id) { + CC("$argon2id"); + } else if (type == Argon2_i) { CC("$argon2i"); } else { return ARGON2_INCORRECT_TYPE; diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c index 84fe5abf..98ad50c9 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c @@ -150,7 +150,7 @@ fill_segment_ref(const argon2_instance_t *instance, argon2_position_t position) uint32_t prev_offset, curr_offset; uint32_t starting_index; uint32_t i; - int data_independent_addressing = 1; /* instance->type == Argon2_i */ + int data_independent_addressing = 1; if (instance == NULL) { return ARGON2_OK; diff --git a/src/libsodium/crypto_pwhash/argon2/argon2.c b/src/libsodium/crypto_pwhash/argon2/argon2.c index f10b57b0..f52381db 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2.c @@ -35,7 +35,7 @@ argon2_ctx(argon2_context *context, argon2_type type) return result; } - if (Argon2_i != type) { + if (type != Argon2_id && type != Argon2_i) { return ARGON2_INCORRECT_TYPE; } @@ -176,6 +176,27 @@ argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, hash, hashlen, NULL, 0, Argon2_i); } +int +argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, char *encoded, + const size_t encodedlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_id); +} + +int +argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_id); +} + int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, argon2_type type) @@ -248,3 +269,9 @@ argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) { return argon2_verify(encoded, pwd, pwdlen, Argon2_i); } + +int +argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) +{ + return argon2_verify(encoded, pwd, pwdlen, Argon2_id); +} diff --git a/src/libsodium/crypto_pwhash/argon2/argon2.h b/src/libsodium/crypto_pwhash/argon2/argon2.h index 9fdc4076..ab2b01ec 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2.h +++ b/src/libsodium/crypto_pwhash/argon2/argon2.h @@ -215,6 +215,27 @@ int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, const size_t saltlen, const size_t hashlen, char *encoded, const size_t encodedlen); +/** + * Hashes a password with Argon2id, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen); + /** * Hashes a password with Argon2i, producing a raw hash * @param t_cost Number of iterations @@ -234,6 +255,25 @@ int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, const size_t pwdlen, const void *salt, const size_t saltlen, void *hash, const size_t hashlen); +/** + * Hashes a password with Argon2id, producing a raw hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen); + /* generic function underlying the above ones */ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, @@ -250,6 +290,15 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, */ int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen); +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen); + /* generic function underlying the above ones */ int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, argon2_type type); diff --git a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c index abf4ef90..b786da19 100644 --- a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c +++ b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c @@ -19,6 +19,12 @@ crypto_pwhash_argon2i_alg_argon2i13(void) return crypto_pwhash_argon2i_ALG_ARGON2I13; } +int +crypto_pwhash_argon2i_alg_argon2id13(void) +{ + return crypto_pwhash_argon2i_ALG_ARGON2ID13; +} + size_t crypto_pwhash_argon2i_bytes_min(void) { @@ -128,9 +134,6 @@ crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen, unsigned long long opslimit, size_t memlimit, int alg) { memset(out, 0, outlen); - if (alg != crypto_pwhash_argon2i_ALG_ARGON2I13) { - return -1; - } memlimit /= 1024U; if (outlen > ARGON2_MAX_OUTLEN || passwdlen > ARGON2_MAX_PWD_LENGTH || opslimit > ARGON2_MAX_TIME || memlimit > ARGON2_MAX_MEMORY) { @@ -142,13 +145,27 @@ crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen, 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; /* LCOV_EXCL_LINE */ + 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, + (size_t) crypto_pwhash_argon2i_SALTBYTES, out, + (size_t) outlen) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; + default: + errno = EINVAL; + return -1; } - return 0; } int @@ -201,10 +218,10 @@ crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], verify_ret = argon2i_verify(str, passwd, (size_t) passwdlen); if (verify_ret == ARGON2_OK) { - return 0; + return 0; } if (verify_ret == ARGON2_VERIFY_MISMATCH) { - errno = EINVAL; + errno = EINVAL; } return -1; } diff --git a/src/libsodium/crypto_pwhash/crypto_pwhash.c b/src/libsodium/crypto_pwhash/crypto_pwhash.c index ab0f4cc5..5bc2db21 100644 --- a/src/libsodium/crypto_pwhash/crypto_pwhash.c +++ b/src/libsodium/crypto_pwhash/crypto_pwhash.c @@ -9,6 +9,12 @@ crypto_pwhash_alg_argon2i13(void) return crypto_pwhash_ALG_ARGON2I13; } +int +crypto_pwhash_alg_argon2id13(void) +{ + return crypto_pwhash_ALG_ARGON2ID13; +} + int crypto_pwhash_alg_default(void) { @@ -123,12 +129,15 @@ crypto_pwhash(unsigned char * const out, unsigned long long outlen, const unsigned char * const salt, unsigned long long opslimit, size_t memlimit, int alg) { - if (alg != crypto_pwhash_ALG_ARGON2I13) { + switch (alg) { + case crypto_pwhash_ALG_ARGON2ID13: + case crypto_pwhash_ALG_ARGON2I13: + return crypto_pwhash_argon2i(out, outlen, passwd, passwdlen, salt, + opslimit, memlimit, alg); + default: errno = EINVAL; return -1; } - return crypto_pwhash_argon2i(out, outlen, passwd, passwdlen, salt, - opslimit, memlimit, alg); } int diff --git a/src/libsodium/include/sodium/crypto_pwhash.h b/src/libsodium/include/sodium/crypto_pwhash.h index 9e45d7ea..9183763b 100644 --- a/src/libsodium/include/sodium/crypto_pwhash.h +++ b/src/libsodium/include/sodium/crypto_pwhash.h @@ -17,6 +17,10 @@ extern "C" { SODIUM_EXPORT int crypto_pwhash_alg_argon2i13(void); +#define crypto_pwhash_ALG_ARGON2ID13 crypto_pwhash_argon2i_ALG_ARGON2ID13 +SODIUM_EXPORT +int crypto_pwhash_alg_argon2id13(void); + #define crypto_pwhash_ALG_DEFAULT crypto_pwhash_ALG_ARGON2I13 SODIUM_EXPORT int crypto_pwhash_alg_default(void); diff --git a/src/libsodium/include/sodium/crypto_pwhash_argon2i.h b/src/libsodium/include/sodium/crypto_pwhash_argon2i.h index 71b9af6c..e70cde2f 100644 --- a/src/libsodium/include/sodium/crypto_pwhash_argon2i.h +++ b/src/libsodium/include/sodium/crypto_pwhash_argon2i.h @@ -18,6 +18,10 @@ extern "C" { SODIUM_EXPORT int crypto_pwhash_argon2i_alg_argon2i13(void); +#define crypto_pwhash_argon2i_ALG_ARGON2ID13 2 +SODIUM_EXPORT +int crypto_pwhash_argon2i_alg_argon2id13(void); + #define crypto_pwhash_argon2i_BYTES_MIN 16U SODIUM_EXPORT size_t crypto_pwhash_argon2i_bytes_min(void);