diff --git a/src/libsodium/crypto_pwhash/argon2/argon2.h b/src/libsodium/crypto_pwhash/argon2/argon2.h index ab2b01ec..4bd7f82e 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2.h +++ b/src/libsodium/crypto_pwhash/argon2/argon2.h @@ -47,7 +47,7 @@ ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) /* Minimum and maximum number of passes */ -#define ARGON2_MIN_TIME UINT32_C(3) +#define ARGON2_MIN_TIME UINT32_C(1) #define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) /* Minimum and maximum password length in bytes */ diff --git a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c index 7acdab03..0515bd61 100644 --- a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c +++ b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c @@ -12,6 +12,7 @@ #include "crypto_pwhash.h" #include "crypto_pwhash_argon2i.h" #include "crypto_pwhash_argon2id.h" +#include "private/common.h" #include "randombytes.h" #include "utils.h" @@ -26,30 +27,36 @@ crypto_pwhash_argon2i_alg_argon2i13(void) size_t crypto_pwhash_argon2i_bytes_min(void) { + COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MIN >= ARGON2_MIN_OUTLEN); return crypto_pwhash_argon2i_BYTES_MIN; } size_t crypto_pwhash_argon2i_bytes_max(void) { + COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MAX <= ARGON2_MAX_OUTLEN); return crypto_pwhash_argon2i_BYTES_MAX; } size_t crypto_pwhash_argon2i_passwd_min(void) { + COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH); return crypto_pwhash_argon2i_PASSWD_MIN; } size_t crypto_pwhash_argon2i_passwd_max(void) { + COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH); return crypto_pwhash_argon2i_PASSWD_MAX; } size_t crypto_pwhash_argon2i_saltbytes(void) { + COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES >= ARGON2_MIN_SALT_LENGTH); + COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES <= ARGON2_MAX_SALT_LENGTH); return crypto_pwhash_argon2i_SALTBYTES; } @@ -68,24 +75,28 @@ crypto_pwhash_argon2i_strprefix(void) size_t crypto_pwhash_argon2i_opslimit_min(void) { + COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MIN >= ARGON2_MIN_TIME); return crypto_pwhash_argon2i_OPSLIMIT_MIN; } size_t crypto_pwhash_argon2i_opslimit_max(void) { + COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MAX <= ARGON2_MAX_TIME); return crypto_pwhash_argon2i_OPSLIMIT_MAX; } size_t crypto_pwhash_argon2i_memlimit_min(void) { + COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY); return crypto_pwhash_argon2i_MEMLIMIT_MIN; } size_t crypto_pwhash_argon2i_memlimit_max(void) { + COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY); return crypto_pwhash_argon2i_MEMLIMIT_MAX; } @@ -132,20 +143,29 @@ crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen, 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) { + if (outlen > crypto_pwhash_argon2i_BYTES_MAX) { errno = EFBIG; return -1; } - if (outlen < ARGON2_MIN_OUTLEN || passwdlen < ARGON2_MIN_PWD_LENGTH || - opslimit < ARGON2_MIN_TIME || memlimit < ARGON2_MIN_MEMORY) { + if (outlen < crypto_pwhash_argon2i_BYTES_MIN) { + errno = EINVAL; + return -1; + } + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX || + opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN || + opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) { errno = EINVAL; return -1; } switch (alg) { case crypto_pwhash_argon2i_ALG_ARGON2I13: - if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) memlimit, + if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), (uint32_t) 1U, passwd, (size_t) passwdlen, salt, (size_t) crypto_pwhash_argon2i_SALTBYTES, out, (size_t) outlen) != ARGON2_OK) { @@ -167,19 +187,20 @@ crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], unsigned char salt[crypto_pwhash_argon2i_SALTBYTES]; memset(out, 0, crypto_pwhash_argon2i_STRBYTES); - memlimit /= 1024U; - if (passwdlen > ARGON2_MAX_PWD_LENGTH || opslimit > ARGON2_MAX_TIME || - memlimit > ARGON2_MAX_MEMORY) { + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX || + opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) { errno = EFBIG; return -1; } - if (passwdlen < ARGON2_MIN_PWD_LENGTH || opslimit < ARGON2_MIN_TIME || - memlimit < ARGON2_MIN_MEMORY) { + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN || + opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) { errno = EINVAL; return -1; } randombytes_buf(salt, sizeof salt); - if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) memlimit, + if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), (uint32_t) 1U, passwd, (size_t) passwdlen, salt, sizeof salt, STR_HASHBYTES, out, crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) { @@ -195,12 +216,12 @@ crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], { int verify_ret; - if (passwdlen > ARGON2_MAX_PWD_LENGTH) { + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX) { errno = EFBIG; return -1; } /* LCOV_EXCL_START */ - if (passwdlen < ARGON2_MIN_PWD_LENGTH) { + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN) { errno = EINVAL; return -1; } diff --git a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c index aec0707c..99d3e219 100644 --- a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c +++ b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c @@ -8,6 +8,7 @@ #include "argon2-core.h" #include "argon2.h" #include "crypto_pwhash_argon2id.h" +#include "private/common.h" #include "randombytes.h" #include "utils.h" @@ -22,30 +23,36 @@ crypto_pwhash_argon2id_alg_argon2id13(void) size_t crypto_pwhash_argon2id_bytes_min(void) { + COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MIN >= ARGON2_MIN_OUTLEN); return crypto_pwhash_argon2id_BYTES_MIN; } size_t crypto_pwhash_argon2id_bytes_max(void) { + COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MAX <= ARGON2_MAX_OUTLEN); return crypto_pwhash_argon2id_BYTES_MAX; } size_t crypto_pwhash_argon2id_passwd_min(void) { + COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH); return crypto_pwhash_argon2id_PASSWD_MIN; } size_t crypto_pwhash_argon2id_passwd_max(void) { + COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH); return crypto_pwhash_argon2id_PASSWD_MAX; } size_t crypto_pwhash_argon2id_saltbytes(void) { + COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES >= ARGON2_MIN_SALT_LENGTH); + COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES <= ARGON2_MAX_SALT_LENGTH); return crypto_pwhash_argon2id_SALTBYTES; } @@ -64,24 +71,28 @@ crypto_pwhash_argon2id_strprefix(void) size_t crypto_pwhash_argon2id_opslimit_min(void) { + COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MIN >= ARGON2_MIN_TIME); return crypto_pwhash_argon2id_OPSLIMIT_MIN; } size_t crypto_pwhash_argon2id_opslimit_max(void) { + COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MAX <= ARGON2_MAX_TIME); return crypto_pwhash_argon2id_OPSLIMIT_MAX; } size_t crypto_pwhash_argon2id_memlimit_min(void) { + COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY); return crypto_pwhash_argon2id_MEMLIMIT_MIN; } size_t crypto_pwhash_argon2id_memlimit_max(void) { + COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY); return crypto_pwhash_argon2id_MEMLIMIT_MAX; } @@ -128,20 +139,29 @@ crypto_pwhash_argon2id(unsigned char *const out, unsigned long long outlen, 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) { + if (outlen > crypto_pwhash_argon2id_BYTES_MAX) { errno = EFBIG; return -1; } - if (outlen < ARGON2_MIN_OUTLEN || passwdlen < ARGON2_MIN_PWD_LENGTH || - opslimit < ARGON2_MIN_TIME || memlimit < ARGON2_MIN_MEMORY) { + if (outlen < crypto_pwhash_argon2id_BYTES_MIN) { + errno = EINVAL; + return -1; + } + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX || + opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN || + opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) { errno = EINVAL; return -1; } switch (alg) { case crypto_pwhash_argon2id_ALG_ARGON2ID13: - if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) memlimit, + if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), (uint32_t) 1U, passwd, (size_t) passwdlen, salt, (size_t) crypto_pwhash_argon2id_SALTBYTES, out, (size_t) outlen) != ARGON2_OK) { @@ -163,19 +183,20 @@ crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], 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) { + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX || + opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) { errno = EFBIG; return -1; } - if (passwdlen < ARGON2_MIN_PWD_LENGTH || opslimit < ARGON2_MIN_TIME || - memlimit < ARGON2_MIN_MEMORY) { + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN || + opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) { errno = EINVAL; return -1; } randombytes_buf(salt, sizeof salt); - if (argon2id_hash_encoded((uint32_t) opslimit, (uint32_t) memlimit, + if (argon2id_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), (uint32_t) 1U, passwd, (size_t) passwdlen, salt, sizeof salt, STR_HASHBYTES, out, crypto_pwhash_argon2id_STRBYTES) != ARGON2_OK) { @@ -191,12 +212,12 @@ crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES { int verify_ret; - if (passwdlen > ARGON2_MAX_PWD_LENGTH) { + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX) { errno = EFBIG; return -1; } /* LCOV_EXCL_START */ - if (passwdlen < ARGON2_MIN_PWD_LENGTH) { + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN) { errno = EINVAL; return -1; } diff --git a/test/default/pwhash.exp b/test/default/pwhash.exp index abe87325..f3425bc4 100644 --- a/test/default/pwhash.exp +++ b/test/default/pwhash.exp @@ -8,5 +8,4 @@ c121209f0ba70aed93d49200e5dc82cce013cef25ea31e160bf8db3cf448a59d1a56f6c19259e18e e942951dfbc2d508294b10f9e97b47d0cd04e668a043cb95679cc1139df7c27cd54367688725be9d069f5704c12223e7e4ca181fbd0bed18bb4634795e545a6c04a7306933a41a794baedbb628d41bc285e0b9084055ae136f6b63624c874f5a1e1d8be7b0b7227a171d2d7ed578d88bfdcf18323198962d0dcad4126fd3f21adeb1e11d66252ea0c58c91696e91031bfdcc2a9dc0e028d17b9705ba2d7bcdcd1e3ba75b4b1fea 9fbbc02a420b00614a49a8e8d89834df368fa54dbef5dce7f9928f4d09f45ce22766598c0c979a707b1df130ab8d63802447923f6e8b89b3c183d71d694161569b1937d8b58f0091fcb8b1f48f2e3f43067bb2498b727fb62cc776ed39219613aa2083619385ec64dfb38f3cda7fddce9cec708a1aa5e9b09d6a5f063cda6c644c5e4a6c1bba9362b27f050984ee3a91bbed69160c95d63c04724f 28645e1a4f5bc2a58786c87f0d88c2c68047b874b122e2c3936fb6adf26d7ca8fbcb872a8aef282ff202526a91b8ca1d0926c4ae0f5429c342bfd4987916b147ccaa1624bbb2d3f197e56601a541939a1a867ee659515d379d252c8b53aa2297b6008f97bc4a246040b0fb4f46754482884ff04bdade7ffc74989c68ec085de660ef2071db22bacc227d43af282a2336049d78fe0b8ff543628dc8 -[tv3] pwhash_str failure (maybe intentional): [0] OK diff --git a/test/default/pwhash_argon2id.c b/test/default/pwhash_argon2id.c index b54daaa2..9afe7021 100644 --- a/test/default/pwhash_argon2id.c +++ b/test/default/pwhash_argon2id.c @@ -293,8 +293,13 @@ main(void) return 1; } if (crypto_pwhash_argon2id_str(str_out2, passwd, strlen(passwd), 1, MEMLIMIT) != + 0) { + printf("pwhash_argon2id_str() with a small opslimit should not have failed\n"); + return 1; + } + if (crypto_pwhash_argon2id_str(str_out2, passwd, strlen(passwd), 0, MEMLIMIT) != -1) { - printf("pwhash_argon2id_str() with a small opslimit should have failed\n"); + printf("pwhash_argon2id_str() with a null opslimit should have failed\n"); return 1; } if (crypto_pwhash_argon2id_str_verify("$argon2id$m=65536,t=2,p=1c29tZXNhbHQ" diff --git a/test/default/pwhash_argon2id.exp b/test/default/pwhash_argon2id.exp index abea0611..5d05ce48 100644 --- a/test/default/pwhash_argon2id.exp +++ b/test/default/pwhash_argon2id.exp @@ -4,7 +4,7 @@ [tv] pwhash failure (maybe intentional): [3] 08d8cd330c57e1b4643241d05bb468ba4ee4e932cd0858816be9ef15360b27bbd06a87130ee92222be267a29b81f5ae8fe8613324cfc4832dc49387fd0602f1c57b4d0f3855db94fb7e12eb05f9a484aed4a4307abf586cd3d55c809bc081541e00b682772fb2066504ff935b8ebc551a2083882f874bc0fae68e56848ae34c91097c3bf0cca8e75c0797eef3efde3f75e005815018db3cf7c109a812264c4de69dcb22322dbbcfa447f5b00ecd1b04a7be1569c8e556adb7bba48adf81d d6e9d6cabd42fb9ba7162fe9b8e41d59d3c7034756cb460c9affe393308bd0225ce0371f2e6c3ca32aca2002bf2d3909c6b6e7dfc4a00e850ff4f570f8f749d4bb6f0091e554be67a9095ae1eefaa1a933316cbec3c2fd4a14a5b6941bda9b7eabd821d79abde2475a53af1a8571c7ee46460be415882e0b393f48c12f740a6a72cba9773000602e13b40d3dfa6ac1d4ec43a838b7e3e165fecad4b2498389e60a3ff9f0f8f4b9fca1126e64f49501e38690 -[tv] pwhash failure (maybe intentional): [6] +7fb72409b0987f8190c3729710e98c3f80c5a8727d425fdcde7f3644d467fe973f5b5fee683bd3fce812cb9ae5e9921a2d06c2f1905e4e839692f2b934b682f11a2fe2b90482ea5dd234863516dba6f52dc0702d324ec77d860c2e181f84472bd7104fedce071ffa93c5309494ad51623d214447a7b2b1462dc7d5d55a1f6fd5b54ce024118d86f0c6489d16545aaa87b6689dad9f2fb47fda9894f8e12b87d978b483ccd4cc5fd9595cdc7a818452f915ce2f7df95ec12b1c72e3788d473441d884f9748eb14703c21b45d82fd667b85f5b2d98c13303b3fe76285531a826b6fc0fe8e3dddecf 4e702bc5f891df884c6ddaa243aa846ce3c087fe930fef0f36b3c2be34164ccc295db509254743f18f947159c813bcd5dd8d94a3aec93bbe57605d1fad1aef1112687c3d4ef1cb329d21f1632f626818d766915d886e8d819e4b0b9c9307f4b6afc081e13b0cf31db382ff1bf05a16aac7af696336d75e99f82163e0f371e1d25c4add808e215697ad3f779a51a462f8bf52610af21fc69dba6b072606f2dabca7d4ae1d91d919 2d232f9dc4de96628b2a4c2b39ceb6a813011fb74a3ba1da096761fabe08f563bd91366aba5c5e35aecd98643cabc16ce560dca261a963230a1fa2af52f2413a57a827c6ee13bcec0c123d195914a55700ccb5756196a86fb9cb4aeacccc0e6dd850f4386b705aaae147ea347543b7fbe24553d9da41f1b335b6e9980cdb966cf7b48520eb42a7269380c885dbefbccf447851fcacbe1753a5b9e1 34b207147fb7ef83e1ca1a97e30aa6e08ea9b6b1048c59c9c13050dff33e76ce3c440d7f018f817e6b8593e78f339ba633b9d7ec3519b5eafbcc4bc2d20b5136bbc7e5b7e92ff37d024bbbecf5738f718ab22c8adcdb82ceffc233b8ad61f91850abdfe8bb119775d9c4243ec1ac761dfbd132489228dfeab5268c7f0ddc29f56b957d1b76c874cdd77e16139e0df9b847248fd782c9a1147b8480