diff --git a/ChangeLog b/ChangeLog index 2ccfc117..ce502497 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,8 @@ AVX* when temperature/power consumption is a concern. - `crypto_kx_*()` now aborts if called with no non-NULL pointers to store keys to. - SSE2 implementations of `crypto_verify_*()` have been added. + - Passwords can be hashed using a specific algorithm with the new +`crypto_pwhash_str_alg()` function. * Version 1.0.13 - Javascript: the sumo builds now include all symbols. They were diff --git a/THANKS b/THANKS index b8b69be3..26cf3709 100644 --- a/THANKS +++ b/THANKS @@ -1,3 +1,6 @@ +Special thanks to people, companies and organizations having written +libsodium bindings for their favorite programming languages: + @alethia7 @artemisc @carblue @@ -70,12 +73,17 @@ Tony Garnock-Jones (@tonyg) Y. T. Chung (@zonyitoo) Bytecurry Software -Cisco -Coverity, Inc. Cryptotronix +Facebook FSF France MaidSafe -OVH Paragonie Initiative Enterprises Python Cryptographic Authority +(this list may not be complete, if you don't see your name, please +submit a pull request!) + +Also thanks to: + +- Coverity, Inc. to provide static analysis. +- FSF France for providing access to their compilation servers. diff --git a/src/libsodium/crypto_pwhash/crypto_pwhash.c b/src/libsodium/crypto_pwhash/crypto_pwhash.c index 3bccfe2b..bd4b14bf 100644 --- a/src/libsodium/crypto_pwhash/crypto_pwhash.c +++ b/src/libsodium/crypto_pwhash/crypto_pwhash.c @@ -2,6 +2,7 @@ #include #include +#include "core.h" #include "crypto_pwhash.h" int @@ -150,6 +151,23 @@ crypto_pwhash_str(char out[crypto_pwhash_STRBYTES], opslimit, memlimit); } +int +crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit, int alg) +{ + switch (alg) { + case crypto_pwhash_ALG_ARGON2I13: + return crypto_pwhash_argon2i_str(out, passwd, passwdlen, + opslimit, memlimit); + case crypto_pwhash_ALG_ARGON2ID13: + return crypto_pwhash_argon2id_str(out, passwd, passwdlen, + opslimit, memlimit); + default: + sodium_misuse(); + } +} + int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], const char * const passwd, diff --git a/src/libsodium/include/sodium/crypto_aead_aes256gcm.h b/src/libsodium/include/sodium/crypto_aead_aes256gcm.h index 30bb7315..46a3800f 100644 --- a/src/libsodium/include/sodium/crypto_aead_aes256gcm.h +++ b/src/libsodium/include/sodium/crypto_aead_aes256gcm.h @@ -1,6 +1,26 @@ #ifndef crypto_aead_aes256gcm_H #define crypto_aead_aes256gcm_H +/* + * WARNING: Despite being the most popular AEAD construction due to its + * use in TLS, safely using AES-GCM in a different context is tricky. + * + * No more than ~ 350 GB of input data should be encrypted with a given key. + * This is for ~ 16 KB messages -- Actual figures vary according to + * message sizes. + * + * In addition, nonces are short and repeated nonces would totally destroy + * the security of this scheme. + * + * Nonces should thus come from atomic counters, which can be difficult to + * set up in a distributed environment. + * + * Unless you absolutely need AES-GCM, use crypto_aead_xchacha20poly1305_ietf_*() + * instead. It doesn't have any of these limitations. + * Or, if you don't need to authenticate additional data, just stick to + * crypto_secretbox(). + */ + #include #include "export.h" diff --git a/src/libsodium/include/sodium/crypto_pwhash.h b/src/libsodium/include/sodium/crypto_pwhash.h index 4a5309c4..d0b8bba7 100644 --- a/src/libsodium/include/sodium/crypto_pwhash.h +++ b/src/libsodium/include/sodium/crypto_pwhash.h @@ -94,6 +94,10 @@ size_t crypto_pwhash_opslimit_sensitive(void); SODIUM_EXPORT size_t crypto_pwhash_memlimit_sensitive(void); +/* + * With this function, do not forget to store all parameters, including the + * algorithm identifier in order to produce deterministic output. + */ SODIUM_EXPORT int crypto_pwhash(unsigned char * const out, unsigned long long outlen, const char * const passwd, unsigned long long passwdlen, @@ -101,12 +105,23 @@ int crypto_pwhash(unsigned char * const out, unsigned long long outlen, unsigned long long opslimit, size_t memlimit, int alg) __attribute__ ((warn_unused_result)); +/* + * The output string already includes all the required parameters, including + * the algorithm identifier. The string is all that has to be stored in + * order to verify a password. + */ SODIUM_EXPORT int crypto_pwhash_str(char out[crypto_pwhash_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_str_alg(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit, int alg) + __attribute__ ((warn_unused_result)); + SODIUM_EXPORT int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], const char * const passwd, diff --git a/test/default/pwhash.c b/test/default/pwhash.c index 2a6fef79..dd4de052 100644 --- a/test/default/pwhash.c +++ b/test/default/pwhash.c @@ -349,6 +349,14 @@ main(void) "password", strlen("password")) != -1 || errno != EINVAL) { printf("pwhash_str_verify(invalid(11)) failure\n"); } + + assert(crypto_pwhash_str_alg(str_out, "test", 4, OPSLIMIT, MEMLIMIT, + crypto_pwhash_ALG_ARGON2I13) == 0); + assert(crypto_pwhash_argon2i_str_verify(str_out, "test", 4) == 0); + assert(crypto_pwhash_str_alg(str_out, "test", 4, OPSLIMIT, MEMLIMIT, + crypto_pwhash_ALG_ARGON2ID13) == 0); + assert(crypto_pwhash_argon2id_str_verify(str_out, "test", 4) == 0); + assert(crypto_pwhash_bytes_min() > 0U); assert(crypto_pwhash_bytes_max() > crypto_pwhash_bytes_min()); assert(crypto_pwhash_passwd_max() > crypto_pwhash_passwd_min());