aboutsummaryrefslogtreecommitdiffstats
path: root/argon2
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-05-01 17:45:39 +0200
committerMattias Andrée <m@maandree.se>2026-05-01 17:45:39 +0200
commitadfa8e1265f6155d1a582baa9929af198bb5d4de (patch)
treee3cee62aa5a8768621cd294295f787b8cc54141b /argon2
parentAdd librecrypt.7 and README (diff)
downloadlibrecrypt-adfa8e1265f6155d1a582baa9929af198bb5d4de.tar.gz
librecrypt-adfa8e1265f6155d1a582baa9929af198bb5d4de.tar.bz2
librecrypt-adfa8e1265f6155d1a582baa9929af198bb5d4de.tar.xz
Misc
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'argon2')
-rw-r--r--argon2/argon2.h91
-rw-r--r--argon2/hash.c36
-rw-r--r--argon2/is_algorithm.c81
-rw-r--r--argon2/make_settings.c66
-rw-r--r--argon2/prefix.mk6
-rw-r--r--argon2/suffix.mk52
-rw-r--r--argon2/test_supported.c59
7 files changed, 391 insertions, 0 deletions
diff --git a/argon2/argon2.h b/argon2/argon2.h
new file mode 100644
index 0000000..cd149da
--- /dev/null
+++ b/argon2/argon2.h
@@ -0,0 +1,91 @@
+/* See LICENSE file for copyright and license details. */
+/* included from "algorithms.h" */
+
+
+#define IF__argon2i__SUPPORTED(A)
+#define IF__argon2d__SUPPORTED(A)
+#define IF__argon2id__SUPPORTED(A)
+#define IF__argon2ds__SUPPORTED(A)
+
+
+#if defined(SUPPORT_ARGON2I)
+# undef IF__argon2i__SUPPORTED
+# define IF__argon2i__SUPPORTED(A) A
+# define argon2i__HASH_SIZE argon2__HASH_SIZE
+# define argon2i__FLEXIBLE_HASH_SIZE argon2__FLEXIBLE_HASH_SIZE
+# define argon2i__STRICT_PAD argon2__STRICT_PAD
+# define argon2i__PAD argon2__PAD
+# define librecrypt__argon2i__hash librecrypt__argon2__hash
+# define librecrypt__argon2i__test_supported librecrypt__argon2__test_supported
+# define librecrypt__argon2i__encoding_lut librecrypt_common_rfc4848s4_encoding_lut_
+# define librecrypt__argon2i__decoding_lut librecrypt_common_rfc4848s4_decoding_lut_
+HIDDEN PURE unsigned librecrypt__argon2i__is_algorithm(const char *settings, size_t len);
+HIDDEN ssize_t librecrypt__argon2i__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);
+#endif
+
+#if defined(SUPPORT_ARGON2D)
+# undef IF__argon2d__SUPPORTED
+# define IF__argon2d__SUPPORTED(A) A
+# define argon2d__HASH_SIZE argon2__HASH_SIZE
+# define argon2d__FLEXIBLE_HASH_SIZE argon2__FLEXIBLE_HASH_SIZE
+# define argon2d__STRICT_PAD argon2__STRICT_PAD
+# define argon2d__PAD argon2__PAD
+# define librecrypt__argon2d__hash librecrypt__argon2__hash
+# define librecrypt__argon2d__test_supported librecrypt__argon2__test_supported
+# define librecrypt__argon2d__encoding_lut librecrypt_common_rfc4848s4_encoding_lut_
+# define librecrypt__argon2d__decoding_lut librecrypt_common_rfc4848s4_decoding_lut_
+HIDDEN PURE unsigned librecrypt__argon2d__is_algorithm(const char *settings, size_t len);
+HIDDEN ssize_t librecrypt__argon2d__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);
+#endif
+
+#if defined(SUPPORT_ARGON2ID)
+# undef IF__argon2id__SUPPORTED
+# define IF__argon2id__SUPPORTED(A) A
+# define argon2id__HASH_SIZE argon2__HASH_SIZE
+# define argon2id__FLEXIBLE_HASH_SIZE argon2__FLEXIBLE_HASH_SIZE
+# define argon2id__STRICT_PAD argon2__STRICT_PAD
+# define argon2id__PAD argon2__PAD
+# define librecrypt__argon2id__hash librecrypt__argon2__hash
+# define librecrypt__argon2id__test_supported librecrypt__argon2__test_supported
+# define librecrypt__argon2id__encoding_lut librecrypt_common_rfc4848s4_encoding_lut_
+# define librecrypt__argon2id__decoding_lut librecrypt_common_rfc4848s4_decoding_lut_
+HIDDEN PURE unsigned librecrypt__argon2id__is_algorithm(const char *settings, size_t len);
+HIDDEN ssize_t librecrypt__argon2id__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);
+#endif
+
+#if defined(SUPPORT_ARGON2DS)
+# undef IF__argon2ds__SUPPORTED
+# define IF__argon2ds__SUPPORTED(A) A
+# define argon2ds__HASH_SIZE argon2__HASH_SIZE
+# define argon2ds__FLEXIBLE_HASH_SIZE argon2__FLEXIBLE_HASH_SIZE
+# define argon2ds__STRICT_PAD argon2__STRICT_PAD
+# define argon2ds__PAD argon2__PAD
+# define librecrypt__argon2ds__hash librecrypt__argon2__hash
+# define librecrypt__argon2ds__test_supported librecrypt__argon2__test_supported
+# define librecrypt__argon2ds__encoding_lut librecrypt_common_rfc4848s4_encoding_lut_
+# define librecrypt__argon2ds__decoding_lut librecrypt_common_rfc4848s4_decoding_lut_
+HIDDEN PURE unsigned librecrypt__argon2ds__is_algorithm(const char *settings, size_t len);
+HIDDEN ssize_t librecrypt__argon2ds__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);
+#endif
+
+#if defined(SUPPORT_ARGON2I) || defined(SUPPORT_ARGON2D) || defined(SUPPORT_ARGON2ID) || defined(SUPPORT_ARGON2DS)
+# define argon2__HASH_SIZE 32u
+# define argon2__FLEXIBLE_HASH_SIZE 1
+# define argon2__STRICT_PAD 0
+# define argon2__PAD '='
+HIDDEN int librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
+ const char *settings, size_t prefix, void *reserved);
+HIDDEN PURE int librecrypt__argon2__test_supported(const char *phrase, size_t len, int text,
+ const char *settings, size_t prefix, size_t *len_out);
+# ifndef REQUIRES_COMMON_RFC4848S4
+# define REQUIRES_COMMON_RFC4848S4
+# endif
+#endif
diff --git a/argon2/hash.c b/argon2/hash.c
new file mode 100644
index 0000000..ff4a4f8
--- /dev/null
+++ b/argon2/hash.c
@@ -0,0 +1,36 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+#ifndef TEST
+
+#include <libar2.h>
+#include <libar2simplified.h>
+
+
+int
+librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
+ const char *settings, size_t prefix, void *reserved)
+{
+ /* TODO implement */
+ (void) out_buffer;
+ (void) size;
+ (void) phrase;
+ (void) len;
+ (void) settings;
+ (void) prefix;
+ (void) reserved;
+ return 0;
+}
+
+
+#else
+
+
+CONST int
+main(void)
+{
+ return 0;
+}
+
+
+#endif
+/* TODO test */
diff --git a/argon2/is_algorithm.c b/argon2/is_algorithm.c
new file mode 100644
index 0000000..96a889a
--- /dev/null
+++ b/argon2/is_algorithm.c
@@ -0,0 +1,81 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+#ifndef TEST
+
+
+#define DECLARE_IS_ALGORITHM(ALGO)\
+ unsigned\
+ librecrypt__##ALGO##__is_algorithm(const char *settings, size_t len)\
+ {\
+ return len >= sizeof("$"#ALGO"$") - 1u && !strncmp(settings, "$"#ALGO"$", sizeof("$"#ALGO"$") - 1u);\
+ }
+
+IF__argon2i__SUPPORTED(DECLARE_IS_ALGORITHM(argon2i))
+IF__argon2d__SUPPORTED(DECLARE_IS_ALGORITHM(argon2d))
+IF__argon2id__SUPPORTED(DECLARE_IS_ALGORITHM(argon2id))
+IF__argon2ds__SUPPORTED(DECLARE_IS_ALGORITHM(argon2ds))
+
+
+#else
+
+
+#define CHECK(ALGO, PREFIX, SUFFIX, RET)\
+ EXPECT(librecrypt__##ALGO##__is_algorithm(PREFIX SUFFIX, sizeof(PREFIX) - 1u) == (RET))
+
+
+int
+main(void)
+{
+#if defined(SUPPORT_ARGON2I)
+ CHECK(argon2i, "", "", 0u);
+ CHECK(argon2i, "$argon2$", "", 0u);
+ CHECK(argon2i, "$argon2i", "$", 0u);
+ CHECK(argon2i, "$argon2i$", "", 1u);
+ CHECK(argon2i, "$ARGON2I$", "", 0u);
+ CHECK(argon2i, "$argon2i$x", "", 1u);
+ CHECK(argon2i, "$argon2d$", "", 0u);
+ CHECK(argon2i, "$argon2id$", "", 0u);
+ CHECK(argon2i, "$argon2ds$", "", 0u);
+#endif
+
+#if defined(SUPPORT_ARGON2D)
+ CHECK(argon2d, "", "", 0u);
+ CHECK(argon2d, "$argon2$", "", 0u);
+ CHECK(argon2d, "$argon2d", "$", 0u);
+ CHECK(argon2d, "$argon2d$", "", 1u);
+ CHECK(argon2d, "$ARGON2D$", "", 0u);
+ CHECK(argon2d, "$argon2d$x", "", 1u);
+ CHECK(argon2d, "$argon2i$", "", 0u);
+ CHECK(argon2d, "$argon2id$", "", 0u);
+ CHECK(argon2d, "$argon2ds$", "", 0u);
+#endif
+
+#if defined(SUPPORT_ARGON2ID)
+ CHECK(argon2id, "", "", 0u);
+ CHECK(argon2id, "$argon2$", "", 0u);
+ CHECK(argon2id, "$argon2id", "$", 0u);
+ CHECK(argon2id, "$argon2id$", "", 1u);
+ CHECK(argon2id, "$ARGON2ID$", "", 0u);
+ CHECK(argon2id, "$argon2id$x", "", 1u);
+ CHECK(argon2id, "$argon2i$", "", 0u);
+ CHECK(argon2id, "$argon2d$", "", 0u);
+ CHECK(argon2id, "$argon2ds$", "", 0u);
+#endif
+
+#if defined(SUPPORT_ARGON2DS)
+ CHECK(argon2ds, "", "", 0u);
+ CHECK(argon2ds, "$argon2$", "", 0u);
+ CHECK(argon2ds, "$argon2ds", "$", 0u);
+ CHECK(argon2ds, "$argon2ds$", "", 1u);
+ CHECK(argon2ds, "$ARGON2DS$", "", 0u);
+ CHECK(argon2ds, "$argon2ds$x", "", 1u);
+ CHECK(argon2ds, "$argon2i$", "", 0u);
+ CHECK(argon2ds, "$argon2d$", "", 0u);
+ CHECK(argon2ds, "$argon2id$", "", 0u);
+#endif
+
+ return 0;
+}
+
+
+#endif
diff --git a/argon2/make_settings.c b/argon2/make_settings.c
new file mode 100644
index 0000000..33c13a4
--- /dev/null
+++ b/argon2/make_settings.c
@@ -0,0 +1,66 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+#ifndef TEST
+
+
+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)
+{
+ /* Use default RNG if NULL is specified */
+ if (!rng)
+ rng = &librecrypt_rng_;
+
+ /* Adjust `memcost` for algorithm */
+ if (!memcost) {
+ /* Use default memcost if 0 was specified */
+ memcost = (size_t)4096u; /* 4 MiB */
+ } else {
+ /* Function takes bytes as memcost, algorithm takes kilobytes */
+ int memcost_round_up = memcost % 1024u >= 512u;
+ memcost >>= 10;
+ memcost += memcost_round_up ? 1u : 0u;
+ memcost = memcost ? memcost : 1u;
+ }
+
+ /* TODO implement */
+ (void) out_buffer;
+ (void) size;
+ (void) algorithm;
+ (void) memcost;
+ (void) timecost;
+ (void) gensalt;
+ (void) rng;
+ (void) user;
+ return 0;
+}
+
+
+#define DECLARE_MAKE_SETTINGS(ALGO)\
+ ssize_t\
+ librecrypt__##ALGO##__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)\
+ {\
+ algorithm = algorithm ? algorithm : "$"#ALGO"$";\
+ return make_settings(out_buffer, size, algorithm, memcost, timecost, gensalt, rng, user);\
+ }
+
+IF__argon2i__SUPPORTED(DECLARE_MAKE_SETTINGS(argon2i))
+IF__argon2d__SUPPORTED(DECLARE_MAKE_SETTINGS(argon2d))
+IF__argon2id__SUPPORTED(DECLARE_MAKE_SETTINGS(argon2id))
+IF__argon2ds__SUPPORTED(DECLARE_MAKE_SETTINGS(argon2ds))
+
+
+#else
+
+
+CONST int
+main(void)
+{
+ return 0;
+}
+
+
+#endif
+/* TODO test */
diff --git a/argon2/prefix.mk b/argon2/prefix.mk
new file mode 100644
index 0000000..ff5c01d
--- /dev/null
+++ b/argon2/prefix.mk
@@ -0,0 +1,6 @@
+SUPPORT_ARGON2 = true
+
+SUPPORT_ARGON2I = $(SUPPORT_ARGON2)
+SUPPORT_ARGON2D = $(SUPPORT_ARGON2)
+SUPPORT_ARGON2ID = $(SUPPORT_ARGON2)
+SUPPORT_ARGON2DS = $(SUPPORT_ARGON2)
diff --git a/argon2/suffix.mk b/argon2/suffix.mk
new file mode 100644
index 0000000..01be2df
--- /dev/null
+++ b/argon2/suffix.mk
@@ -0,0 +1,52 @@
+SUPPORT_ANY_ARGON2 = ($(SUPPORT_ARGON2I) || $(SUPPORT_ARGON2D) || $(SUPPORT_ARGON2ID) || $(SUPPORT_ARGON2DS))
+
+HDR += argon2/argon2.h
+
+OBJ_ARGON2 !=\
+ if $(SUPPORT_ANY_ARGON2); then echo\
+ argon2/hash.o\
+ argon2/test_supported.o\
+ argon2/is_algorithm.o\
+ argon2/make_settings.o\
+ ;fi
+
+OBJ_PRIVATE += $(OBJ_ARGON2)
+
+OBJ_COMMON_RFC4848S4 = $(USE_OBJ_COMMON_RFC4848S4)
+
+CPPFLAGS_ARGON2 !=\
+ if $(SUPPORT_ARGON2I); then echo\
+ -DSUPPORT_ARGON2I\
+ ;fi;\
+ if $(SUPPORT_ARGON2D); then echo\
+ -DSUPPORT_ARGON2D\
+ ;fi;\
+ if $(SUPPORT_ARGON2ID); then echo\
+ -DSUPPORT_ARGON2ID\
+ ;fi;\
+ if $(SUPPORT_ARGON2DS); then echo\
+ -DSUPPORT_ARGON2DS\
+ ;fi
+
+CFLAGS_ARGON2 !=\
+ if $(SUPPORT_ANY_ARGON2); then echo\
+ -pthread\
+ ;fi
+
+LDFLAGS_ARGON2 !=\
+ if $(SUPPORT_ANY_ARGON2); then echo\
+ -lar2simplified\
+ -lar2\
+ -lblake\
+ -pthread\
+ ;fi
+
+CPPFLAGS_MODULES += $(CPPFLAGS_ARGON2)
+CFLAGS_MODULES += $(CFLAGS_ARGON2)
+LDFLAGS_MODULES += $(LDFLAGS_ARGON2)
+
+
+clean: clean-argon2
+clean-argon2:
+ -rm -f -- argon2/*.o argon2/*.lo argon2/*.su argon2/*.to argon2/*.t
+ -rm -f -- argon2/*.gch argon2/*.gcov argon2/*.gcno argon2/*.gcda
diff --git a/argon2/test_supported.c b/argon2/test_supported.c
new file mode 100644
index 0000000..1589191
--- /dev/null
+++ b/argon2/test_supported.c
@@ -0,0 +1,59 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+#ifndef TEST
+
+#include <libar2.h>
+
+
+int
+librecrypt__argon2__test_supported(const char *phrase, size_t len, int text, const char *settings, size_t prefix, size_t *len_out)
+{
+ uintmax_t hashsize;
+ int r;
+
+ /* We don't care about password content, arbitrary binary is supported */
+ (void) phrase;
+ (void) text;
+
+#define RANGE(MIN, MAX) (uintmax_t)(MIN), (uintmax_t)(MAX)
+#define BASE64 librecrypt_common_rfc4848s4_decoding_lut_, argon2__PAD, argon2__STRICT_PAD
+
+ /* Validate string format and parameters */
+ r = librecrypt_check_settings_(settings, prefix,
+ "$%*$%sm=%p,t=%p,p=%p$%b$%^h",
+ "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),
+ RANGE(LIBAR2_MIN_SALTLEN, LIBAR2_MAX_SALTLEN), BASE64,
+ &hashsize, RANGE(LIBAR2_MIN_HASHLEN, LIBAR2_MAX_HASHLEN), BASE64);
+ if (!r)
+ return 0;
+
+ /* Return hash size */
+ if (!hashsize)
+ hashsize = argon2__HASH_SIZE;
+ *len_out = (size_t)hashsize;
+
+ /* Check password size */
+#if SIZE_MAX > UINT32_MAX
+ return len <= UINT32_MAX;
+#else
+ (void) len;
+ return 1;
+#endif
+}
+
+
+#else
+
+
+CONST int
+main(void)
+{
+ return 0;
+}
+
+
+#endif
+/* TODO test */