aboutsummaryrefslogtreecommitdiffstats
path: root/argon2
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-07-01 21:37:09 +0200
committerMattias Andrée <m@maandree.se>2026-07-01 21:37:09 +0200
commit1323b81cd2679bb61a480524a0e4cd008d3d0bee (patch)
treed7fc0c3417b6ae7a1688cddd8ce3a9607ec53dd7 /argon2
parentAdd test and fix a bug (diff)
downloadlibrecrypt-master.tar.gz
librecrypt-master.tar.bz2
librecrypt-master.tar.xz
Add support for the reference implementation of Argon2HEAD1.1.1master
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--argon2/argon2.h62
-rw-r--r--argon2/hash.c172
-rw-r--r--argon2/make_settings.c31
-rw-r--r--argon2/suffix.mk13
-rw-r--r--argon2/test_supported.c13
5 files changed, 246 insertions, 45 deletions
diff --git a/argon2/argon2.h b/argon2/argon2.h
index a14e782..02afcc5 100644
--- a/argon2/argon2.h
+++ b/argon2/argon2.h
@@ -1,6 +1,47 @@
/* See LICENSE file for copyright and license details. */
/* included from "algorithms.h" */
+#if defined(SUPPORT_ARGON2I) || defined(SUPPORT_ARGON2D) || defined(SUPPORT_ARGON2ID) || defined(SUPPORT_ARGON2DS)
+# if !defined(ARGON2_VERSION)
+# include <libar2.h>
+# ifndef NO_LIBAR2SIMPLIFIED
+# include <libar2simplified.h>
+# else
+# define libar2simplified_init_context init_context
+# endif
+# else
+# include <argon2.h>
+# define LIBAR2_ARGON2D 0
+# define LIBAR2_ARGON2I 1
+# define LIBAR2_ARGON2ID 2
+# define LIBAR2_ARGON2DS 4
+# define LIBAR2_ARGON2_VERSION_10 0x10
+# define LIBAR2_ARGON2_VERSION_13 0x13
+# define LIBAR2_MIN_M_COST ARGON2_MIN_MEMORY
+# define LIBAR2_MAX_M_COST ARGON2_MAX_MEMORY
+# define LIBAR2_MIN_T_COST ARGON2_MIN_TIME
+# define LIBAR2_MAX_T_COST ARGON2_MAX_TIME
+# define LIBAR2_MIN_LANES ARGON2_MIN_LANES
+# define LIBAR2_MAX_LANES ARGON2_MAX_LANES
+# define LIBAR2_MIN_SALTLEN ARGON2_MIN_SALT_LENGTH
+# define LIBAR2_MAX_SALTLEN ARGON2_MAX_SALT_LENGTH
+# define LIBAR2_MIN_HASHLEN ARGON2_MIN_OUTLEN
+# define LIBAR2_MAX_HASHLEN ARGON2_MAX_OUTLEN
+# if ARGON2_VERSION < 20161029L
+# ifdef SUPPORT_ARGON2ID
+# undef SUPPORT_ARGON2ID
+# endif
+# endif
+# if ARGON2_VERSION < 20160406L
+# define NO_ARGON2_VERSION_13__
+# else
+# ifdef SUPPORT_ARGON2DS
+# undef SUPPORT_ARGON2DS
+# endif
+# endif
+# endif
+#endif
+
#define IF__argon2i__SUPPORTED(A)
#define IF__argon2d__SUPPORTED(A)
@@ -76,7 +117,17 @@ HIDDEN ssize_t librecrypt__argon2ds__make_settings(char *out_buffer, size_t size
ssize_t (*rng)(void *out, size_t n, void *user), void *user);
#endif
+#define IF__argon2_v1_0__SUPPORTED(A)
+#define IF__argon2_v1_3__SUPPORTED(A)
#if defined(SUPPORT_ARGON2I) || defined(SUPPORT_ARGON2D) || defined(SUPPORT_ARGON2ID) || defined(SUPPORT_ARGON2DS)
+# undef IF__argon2_v1_0__SUPPORTED
+# define IF__argon2_v1_0__SUPPORTED(A) A
+# define SUPPORT_ARGON2_V1_0
+# ifndef NO_ARGON2_VERSION_13__
+# undef IF__argon2_v1_3__SUPPORTED
+# define IF__argon2_v1_3__SUPPORTED(A) A
+# define SUPPORT_ARGON2_V1_3
+# endif
# define argon2__HASH_SIZE 32u
# define argon2__FLEXIBLE_HASH_SIZE 1
# define argon2__STRICT_PAD 0
@@ -89,3 +140,14 @@ HIDDEN PURE int librecrypt__argon2__test_supported(const char *phrase, size_t le
# define REQUIRES_COMMON_RFC4848S4
# endif
#endif
+
+
+#define IF__argon2i_v1_0__SUPPORTED(A) IF__argon2_v1_0__SUPPORTED(IF__argon2i__SUPPORTED(A))
+#define IF__argon2d_v1_0__SUPPORTED(A) IF__argon2_v1_0__SUPPORTED(IF__argon2d__SUPPORTED(A))
+#define IF__argon2id_v1_0__SUPPORTED(A) IF__argon2_v1_0__SUPPORTED(IF__argon2id__SUPPORTED(A))
+#define IF__argon2ds_v1_0__SUPPORTED(A) IF__argon2_v1_0__SUPPORTED(IF__argon2ds__SUPPORTED(A))
+
+#define IF__argon2i_v1_3__SUPPORTED(A) IF__argon2_v1_3__SUPPORTED(IF__argon2i__SUPPORTED(A))
+#define IF__argon2d_v1_3__SUPPORTED(A) IF__argon2_v1_3__SUPPORTED(IF__argon2d__SUPPORTED(A))
+#define IF__argon2id_v1_3__SUPPORTED(A) IF__argon2_v1_3__SUPPORTED(IF__argon2id__SUPPORTED(A))
+#define IF__argon2ds_v1_3__SUPPORTED(A) IF__argon2_v1_3__SUPPORTED(IF__argon2ds__SUPPORTED(A))
diff --git a/argon2/hash.c b/argon2/hash.c
index c964455..e6d6841 100644
--- a/argon2/hash.c
+++ b/argon2/hash.c
@@ -2,20 +2,13 @@
#include "../common.h"
#ifndef TEST
-#include <libar2.h>
-#ifndef NO_LIBAR2SIMPLIFIED
-# include <libar2simplified.h>
-#else
-# define libar2simplified_init_context init_context
-#endif
-
#define RANGE(MIN, MAX) (uintmax_t)(MIN), (uintmax_t)(MAX)
#define BASE64 librecrypt_common_rfc4848s4_decoding_lut_, argon2__PAD, argon2__STRICT_PAD
#define REMOVE_CONST(X) (*(void **)(void *)&(X))
-#ifdef NO_LIBAR2SIMPLIFIED
+#if !defined(ARGON2_VERSION) && defined(NO_LIBAR2SIMPLIFIED)
static void *
allocate(size_t num, size_t size, size_t alignment, struct libar2_context *ctx)
@@ -89,15 +82,105 @@ init_context(struct libar2_context *ctxp)
#endif
+#if defined(ARGON2_VERSION)
+struct type_and_version {
+ unsigned type;
+ unsigned version;
+};
+
+
+# define libar2_hash librecrypt__libar2_hash
+static int
+libar2_hash(void *out_buffer, void *phrase, size_t len, struct Argon2_Context *params, struct type_and_version *params2)
+{
+ int r;
+
+# if ARGON2_VERSION < 20160406L
+ if (params2->version != LIBAR2_ARGON2_VERSION_10) {
+ errno = ENOSYS;
+ return -1;
+ }
+# endif
+
+ params->out = out_buffer;
+ params->pwd = phrase;
+ params->pwdlen = (uint32_t)len;
+# if ARGON2_VERSION >= 20160406L
+ params->version = params2->version;
+# endif
+
+# if ARGON2_VERSION >= 20160406L
+ r = argon2_ctx(params, params2->type);
+# else
+ switch (params2->type) {
+# if defined(SUPPORT_ARGON2D)
+ case LIBAR2_ARGON2D:
+ r = argon2d_ctx(params);
+ break;
+# endif
+# if defined(SUPPORT_ARGON2I)
+ case LIBAR2_ARGON2I:
+ r = argon2i_ctx(params);
+ break;
+# endif
+# if defined(SUPPORT_ARGON2ID)
+ case LIBAR2_ARGON2ID:
+ r = argon2id_ctx(params);
+ break;
+# endif
+#if defined(SUPPORT_ARGON2DS)
+ case LIBAR2_ARGON2DS:
+ r = argon2ds_ctx(params);
+ break;
+# endif
+ default:
+ errno = ENOSYS;
+ return -1;
+ }
+# endif
+
+ switch (r) {
+ case ARGON2_OK:
+ return 0;
+ case ARGON2_MEMORY_ALLOCATION_ERROR:
+ errno = ENOMEM;
+ return -1;
+ case ARGON2_INCORRECT_TYPE:
+ errno = ENOSYS;
+ return -1;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+
+# define libar2_hash_buf_size librecrypt__libar2_hash_buf_size
+static size_t
+libar2_hash_buf_size(struct Argon2_Context *params)
+{
+ return params->outlen;
+}
+#endif
+
+
int
librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
const char *settings, size_t prefix, LIBRECRYPT_CONTEXT *ctx)
{
enum librecrypt_hash_algorithm algo_v10, algo_v13, algo;
+#if !defined(ARGON2_VERSION)
+# define params2 params
struct libar2_argon2_parameters params;
struct libar2_context ar2ctx;
+#else
+# define ar2ctx params2
+# define hashlen outlen
+ struct Argon2_Context params;
+ struct type_and_version params2;
+#endif
const char *type, *version, *salt_encoded;
- uintmax_t mcost, tcost, lanes, saltlen, hashlen;
+ uintmax_t mcost, tcost, lanes, saltlen, taglen;
void *salt = NULL, *scratch = NULL;
size_t scratch_size;
struct pepper *pepper = NULL;
@@ -116,7 +199,7 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
&tcost, RANGE(LIBAR2_MIN_T_COST, LIBAR2_MAX_T_COST),
&lanes, RANGE(LIBAR2_MIN_LANES, LIBAR2_MAX_LANES),
&salt_encoded, &saltlen, RANGE(LIBAR2_MIN_SALTLEN, LIBAR2_MAX_SALTLEN), BASE64,
- &hashlen, RANGE(LIBAR2_MIN_HASHLEN, LIBAR2_MAX_HASHLEN), BASE64);
+ &taglen, RANGE(LIBAR2_MIN_HASHLEN, LIBAR2_MAX_HASHLEN), BASE64);
if (!r) {
errno = EINVAL;
return -1;
@@ -140,6 +223,7 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
return 0;
}
+#if !defined(ARGON2_VERSION)
/* Gives us memory allocation and threading support;
* so we don't have to implement any of that ourselves */
libar2simplified_init_context(&ar2ctx);
@@ -150,6 +234,7 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
ar2ctx.autoerase_salt = 1; /* since we are decoding the salt, we do a memory allocation,
* and our testing always checks that allocated memory is earse;
* it doesn't really matter, but it's paranoid, and that's good */
+#endif
/* Decode salt */
if (!salt_encoded) /* this would be if asterisk-notation is used, but it is not */
@@ -176,16 +261,17 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
}
/* Apply `settings` */
- params.type = type[1u] == 'd' ? LIBAR2_ARGON2ID :
- type[1u] == 's' ? LIBAR2_ARGON2DS :
- type[0u] == 'i' ? LIBAR2_ARGON2I :
- LIBAR2_ARGON2D;
- params.version = !*version ? LIBAR2_ARGON2_VERSION_10 :
- version[3u] == '9' ? LIBAR2_ARGON2_VERSION_13 : /* 19 = 0x13 = 1.3 */
- LIBAR2_ARGON2_VERSION_10; /* 16 = 0x10 = 1.0 */
+ memset(&params, 0, sizeof(params));
+ params2.type = type[1u] == 'd' ? LIBAR2_ARGON2ID :
+ type[1u] == 's' ? LIBAR2_ARGON2DS :
+ type[0u] == 'i' ? LIBAR2_ARGON2I :
+ LIBAR2_ARGON2D;
+ params2.version = !*version ? LIBAR2_ARGON2_VERSION_10 :
+ version[3u] == '9' ? LIBAR2_ARGON2_VERSION_13 : /* 19 = 0x13 = 1.3 */
+ LIBAR2_ARGON2_VERSION_10; /* 16 = 0x10 = 1.0 */
if (!ctx)
goto no_pepper;
- switch (params.type) {
+ switch (params2.type) {
case LIBAR2_ARGON2I:
algo_v10 = LIBRECRYPT_ARGON2I_V1_0;
algo_v13 = LIBRECRYPT_ARGON2I_V1_3;
@@ -207,7 +293,7 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
abort();
/* $covered}$ */
}
- switch (params.version) {
+ switch (params2.version) {
case LIBAR2_ARGON2_VERSION_10:
algo = algo_v10;
break;
@@ -225,12 +311,25 @@ no_pepper:
params.m_cost = (uint_least32_t)mcost;
params.lanes = (uint_least32_t)lanes;
params.salt = salt;
+#if !defined(ARGON2_VERSION)
params.saltlen = (size_t)saltlen;
params.key = pepper ? REMOVE_CONST(pepper->data) : NULL;
params.keylen = pepper ? pepper->len : 0u;
+#else
+ params.saltlen = (uint32_t)saltlen;
+ params.secret = pepper ? REMOVE_CONST(pepper->data) : NULL;
+ params.secretlen = pepper ? (uint32_t)pepper->len : 0u;
+#endif
params.ad = NULL;
params.adlen = 0u;
- params.hashlen = hashlen ? (size_t)hashlen : argon2__HASH_SIZE;
+#if !defined(ARGON2_VERSION)
+ params.hashlen = taglen ? (size_t)taglen : argon2__HASH_SIZE;
+#else
+ params.outlen = taglen ? (uint32_t)taglen : argon2__HASH_SIZE;
+ params.threads = params.lanes;
+ params.allocate_cbk = NULL;
+ params.free_cbk = NULL;
+#endif
/* Argon2 may require a larger buffer to work with for the hash than it outputs */
scratch_size = libar2_hash_buf_size(&params);
@@ -371,6 +470,11 @@ check(const char *phrase, const char *settings, const char *hash, size_t hashlen
#endif
+#if defined(ARGON2_VERSION)
+# define IF_LIBAR2(...)
+#else
+# define IF_LIBAR2(...) __VA_ARGS__
+#endif
#define COMMON buf, 1u, NULL, 0u
#define CHECK_BAD(ALGO)\
do {\
@@ -399,10 +503,12 @@ check(const char *phrase, const char *settings, const char *hash, size_t hashlen
EXPECT(errno == ENOMEM);\
\
/* target `libar2_hash` */\
- libtest_set_alloc_failure_in(3u);\
- errno = 0;\
- EXPECT(librecrypt__argon2__hash(COMMON, S(ALGO"m=1024,t=10,p=1$CCCCDDDDAAAABBBB$"), ctx) == -1);\
- EXPECT(errno == ENOMEM);\
+ IF_LIBAR2(\
+ libtest_set_alloc_failure_in(3u);\
+ errno = 0;\
+ EXPECT(librecrypt__argon2__hash(COMMON, S(ALGO"m=1024,t=10,p=1$CCCCDDDDAAAABBBB$"), ctx) == -1);\
+ EXPECT(errno == ENOMEM);\
+ )\
\
assert(!libtest_get_alloc_failure_in());\
} while (0)
@@ -426,12 +532,13 @@ main(void)
start_over:
#if defined(SUPPORT_ARGON2I)
-# if SIZE_MAX > UINT32_MAX
+# if defined(SUPPORT_ARGON2_V1_0)
+# if SIZE_MAX > UINT32_MAX
errno = 0;
EXPECT(librecrypt__argon2__hash(NULL, 0u, phony, (size_t)UINT32_MAX + 1u, "$argon2i$m=256,t=2,p=1$c29tZXNhbHQ$",
sizeof("$argon2i$m=256,t=2,p=1$c29tZXNhbHQ$"), ctx) == -1);
EXPECT(errno == EINVAL);
-#else
+# else
if (libtest_have_custom_malloc()) {
char conf[256];
int r;
@@ -457,23 +564,32 @@ start_over:
libtest_set_alloc_failure_in(0u);
}
-# endif
+# endif
CHECK("password", "$argon2i$" "m=256,t=2,p=1$c29tZXNhbHQ$", 32, "/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY");
+# endif
+# if defined(SUPPORT_ARGON2_V1_3)
CHECK("password", "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$", 32, "iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8");
+# endif
CHECK_BAD("$argon2i$");
#endif
#if defined(SUPPORT_ARGON2ID)
+# if defined(SUPPORT_ARGON2_V1_3)
CHECK("password", "$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ$", 32, "nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4");
+# endif
CHECK_BAD("$argon2id$");
#endif
#if defined(SUPPORT_ARGON2DS)
+# if defined(SUPPORT_ARGON2_V1_0)
CHECK("", "$argon2ds$v=16$m=""8,t=1,p=1$ICAgICAgICA$", 32, "zgdykk9ZjN5VyrW0LxGw8LmrJ1Z6fqSC+3jPQtn4n0s");
+# endif
CHECK_BAD("$argon2ds$");
#endif
#if defined(SUPPORT_ARGON2D)
+# if defined(SUPPORT_ARGON2_V1_0)
CHECK("", "$argon2d$v=16$m=""8,t=1,p=1$ICAgICAgICA$", 100, "NjODMrWrS7zeivNNpHsuxD9c6uDmUQ6YqPRhb8H5DSNw9"
"n683FUCJZ3tyxgfJpYYANI+01WT/S5zp1UVs+qNRwnkdE"
"yLKZMg+DIOXVc9z1po9ZlZG8+Gp4g5brqfza3lvkR9vw");
+# endif
CHECK_BAD("$argon2d$");
#endif
@@ -485,7 +601,7 @@ start_over:
memset(nuls, 0, sizeof(nuls));
-#if defined(SUPPORT_ARGON2I)
+#if defined(SUPPORT_ARGON2I) && defined(SUPPORT_ARGON2_V1_3)
assert(sizeof(nuls) >= 4u);
assert(librecrypt_set_pepper(ctx, LIBRECRYPT_ARGON2I_V1_3, nuls, 4u) == 0);
CHECK(" ", "$argon2i$v=19$m=8,t=1,p=1$ICAgICAgICA$", 8, "Mhl4o3AkJuA");
diff --git a/argon2/make_settings.c b/argon2/make_settings.c
index bac49a4..c6d2128 100644
--- a/argon2/make_settings.c
+++ b/argon2/make_settings.c
@@ -1,6 +1,5 @@
/* See LICENSE file for copyright and license details. */
#include "../common.h"
-#include <libar2.h>
#ifndef TEST
@@ -8,7 +7,7 @@ static ssize_t
make_settings(char *out_buffer, size_t size, const char *algorithm, size_t memcost, uintmax_t timecost,
int gensalt, ssize_t (*rng)(void *out, size_t n, void *user), void *user)
{
- const char *p, *version = "19";
+ const char *p, *version;
size_t algolen, ret, min, len, i;
int r;
@@ -50,15 +49,21 @@ make_settings(char *out_buffer, size_t size, const char *algorithm, size_t memco
if (p && p[1u] == 'v') {
p = &p[2u];
if (!strncmp(p, "=16", 3u) && (!p[3u] || p[3u] == '$'))
- version = "16";
+ version = "$v=16";
else if (!strncmp(p, "=19", 3u) && (!p[3u] || p[3u] == '$'))
- version = "19";
+ version = "$v=19";
else
goto enosys;
+ } else {
+#if defined(SUPPORT_ARGON2_V1_3)
+ version = "$v=19";
+#else
+ version = "";
+#endif
}
/* Write algorithm and parameters */
- r = snprintf(out_buffer, size, "%.*s$v=%s$m=%zu,t=%ju,p=1$",
+ r = snprintf(out_buffer, size, "%.*s%s$m=%zu,t=%ju,p=1$",
(int)algolen, algorithm, version, memcost, timecost);
if (r < (int)sizeof("$argon2_$v=__$m=_,t=_,p=1$") - 1)
abort(); /* $covered$ (impossible) */
@@ -351,13 +356,19 @@ check_aborts(ssize_t (*gen)(char *, size_t, const char *, size_t, uintmax_t,
}
+#if defined(SUPPORT_ARGON2_V1_3)
+# define HIGHEST "v=19$"
+#else
+# define HIGHEST ""
+#endif
+
#define CHECK(FUNC, ALGO)\
do {\
- check(&(FUNC), "$"ALGO"$v=19$", NULL);\
- check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$");\
- check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO);\
- check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$m=100,t=10,p=2$xxxx$*32");\
- check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$m=100,t=10,p=2$*40$");\
+ check(&(FUNC), "$"ALGO"$"HIGHEST, NULL);\
+ check(&(FUNC), "$"ALGO"$"HIGHEST, "$"ALGO"$");\
+ check(&(FUNC), "$"ALGO"$"HIGHEST, "$"ALGO);\
+ check(&(FUNC), "$"ALGO"$"HIGHEST, "$"ALGO"$m=100,t=10,p=2$xxxx$*32");\
+ check(&(FUNC), "$"ALGO"$"HIGHEST, "$"ALGO"$m=100,t=10,p=2$*40$");\
check(&(FUNC), "$"ALGO"$v=16$", "$"ALGO"$v=16");\
check(&(FUNC), "$"ALGO"$v=16$", "$"ALGO"$v=16$");\
check(&(FUNC), "$"ALGO"$v=16$", "$"ALGO"$v=16$m=100,t=10,p=2$xxxx$*32");\
diff --git a/argon2/suffix.mk b/argon2/suffix.mk
index 5ca2ceb..f71b040 100644
--- a/argon2/suffix.mk
+++ b/argon2/suffix.mk
@@ -34,16 +34,23 @@ CPPFLAGS_ARGON2 !=\
;fi;\
if ! $(WITH_LIBAR2SIMPLIFIED); then echo\
-DNO_LIBAR2SIMPLIFIED\
+ ;fi;\
+ if test -n "$(ARGON2_VERSION)"; then echo\
+ -DARGON2_VERSION="$(ARGON2_VERSION)L"\
;fi
CFLAGS_ARGON2 !=\
- if $(SUPPORT_ANY_ARGON2) && $(WITH_LIBAR2SIMPLIFIED); then echo\
- -pthread\
+ if $(SUPPORT_ANY_ARGON2) && $(WITH_LIBAR2SIMPLIFIED); then\
+ if test -n "$(ARGON2_VERSION)" || test -n "$(ARGON2_NO_THREADS)"; then echo\
+ -pthread\
+ ;fi\
;fi
LDFLAGS_ARGON2 !=\
if $(SUPPORT_ANY_ARGON2); then\
- if $(WITH_LIBAR2SIMPLIFIED); then echo\
+ if test -n "$(ARGON2_VERSION)"; then echo\
+ -largon2\
+ ;elif $(WITH_LIBAR2SIMPLIFIED); then echo\
-lar2simplified\
-lar2\
-lblake\
diff --git a/argon2/test_supported.c b/argon2/test_supported.c
index cad7794..32aa5fd 100644
--- a/argon2/test_supported.c
+++ b/argon2/test_supported.c
@@ -2,8 +2,6 @@
#include "../common.h"
#ifndef TEST
-#include <libar2.h>
-
#define RANGE(MIN, MAX) (uintmax_t)(MIN), (uintmax_t)(MAX)
#define BASE64 librecrypt_common_rfc4848s4_decoding_lut_, argon2__PAD, argon2__STRICT_PAD
@@ -12,6 +10,7 @@
int
librecrypt__argon2__test_supported(const char *phrase, size_t len, int text, const char *settings, size_t prefix, size_t *len_out)
{
+ const char *version;
uintmax_t hashlen;
int r;
@@ -21,8 +20,8 @@ librecrypt__argon2__test_supported(const char *phrase, size_t len, int text, con
/* Validate string format and parameters */
r = librecrypt_scan_settings(settings, prefix,
- "$%*$%sm=%p,t=%p,p=%p$%b$%^h",
- "v=16$", "v=19$", "", NULL,
+ "$%*$%^sm=%p,t=%p,p=%p$%b$%^h",
+ &version, "v=16$", "v=19$", "", NULL,
RANGE(LIBAR2_MIN_M_COST, LIBAR2_MAX_M_COST),
RANGE(LIBAR2_MIN_T_COST, LIBAR2_MAX_T_COST),
RANGE(LIBAR2_MIN_LANES, LIBAR2_MAX_LANES),
@@ -31,6 +30,12 @@ librecrypt__argon2__test_supported(const char *phrase, size_t len, int text, con
if (!r)
return 0;
+ /* Check compatibility with library support */
+#if !defined(SUPPORT_ARGON2_V1_3)
+ if (!strcmp(version, "v=19$"))
+ return 0;
+#endif
+
/* Return hash size */
if (!hashlen)
hashlen = argon2__HASH_SIZE;