aboutsummaryrefslogtreecommitdiffstats
path: root/argon2/make_settings.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-05-08 22:29:35 +0200
committerMattias Andrée <m@maandree.se>2026-05-08 22:29:35 +0200
commit2d3a573977417d917c16742d8d9d8ead047d0ebc (patch)
treecaeac52856a9df0478e2bee53e5dda1f84422461 /argon2/make_settings.c
parentAdd DEFAULT_SUPPORT option and improve DEPENDENCIES (diff)
downloadlibrecrypt-2d3a573977417d917c16742d8d9d8ead047d0ebc.tar.gz
librecrypt-2d3a573977417d917c16742d8d9d8ead047d0ebc.tar.bz2
librecrypt-2d3a573977417d917c16742d8d9d8ead047d0ebc.tar.xz
Misc
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--argon2/make_settings.c102
1 files changed, 89 insertions, 13 deletions
diff --git a/argon2/make_settings.c b/argon2/make_settings.c
index 94ee5ae..66ac3d6 100644
--- a/argon2/make_settings.c
+++ b/argon2/make_settings.c
@@ -2,11 +2,17 @@
#include "../common.h"
#ifndef TEST
+#include <libar2.h>
+
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";
+ size_t algolen, ret, min, len, i;
+ int r;
+
/* Use default RNG if NULL is specified */
if (!rng)
rng = &librecrypt_rng_;
@@ -17,22 +23,90 @@ make_settings(char *out_buffer, size_t size, const char *algorithm, size_t memco
memcost = (size_t)4096u; /* 4 MiB */
} else {
/* Function takes bytes as memcost, algorithm takes kilobytes */
- int memcost_round_up = memcost % 1024u >= 512u;
+ size_t memcost_round_up = (memcost >> 9) & 1u;
memcost >>= 10;
- memcost += memcost_round_up ? 1u : 0u;
- memcost = memcost ? memcost : 1u;
+ memcost += memcost_round_up;
}
+ memcost = memcost < LIBAR2_MIN_M_COST ? LIBAR2_MIN_M_COST : memcost;
+ memcost = memcost > LIBAR2_MAX_M_COST ? LIBAR2_MAX_M_COST : memcost;
- /* TODO implement */
- (void) out_buffer;
- (void) size;
- (void) algorithm;
- (void) memcost;
- (void) timecost;
- (void) gensalt;
- (void) rng;
- (void) user;
- return 0;
+ /* Adjust `timecost` for algorithm */
+ if (!timecost) {
+ /* Use default timecost if 0 was specified:
+ * default m_cost (4096) multiple by default t_cost (10) */
+ timecost = 40960u;
+ }
+ timecost /= memcost;
+ timecost = timecost < LIBAR2_MIN_T_COST ? LIBAR2_MIN_T_COST : timecost;
+ timecost = timecost > LIBAR2_MAX_T_COST ? LIBAR2_MAX_T_COST : timecost;
+
+ /* Get version */
+ p = algorithm;
+ if (*p++ != '$')
+ abort();
+ p = strchr(p, '$');
+ algolen = p ? (size_t)(p - algorithm) : strlen(algorithm);
+ if (algolen > 64) /* just some small value absolute will fit all variants */
+ abort();
+ if (p++ && *p++ == 'v') {
+ if (!strncmp(p, "=16", 3u) && (!p[3u] || p[3u] == '$'))
+ version = "16";
+ else if (!strncmp(p, "=19", 3u) && (!p[3u] || p[3u] == '$'))
+ version = "19";
+ else
+ goto enosys;
+ }
+
+ /* Write algorithm and parameters */
+ r = snprintf(out_buffer, size, "%.*s$v=%s$m=%zu,t=%llu,p=1$",
+ (int)algolen, algorithm, version,
+ memcost, (unsigned long long int)timecost);
+ if (r < (int)sizeof("$argon2_$v=__$m=_,t=_,p=1$") - 1)
+ abort();
+ ret = (size_t)r;
+ min = size ? ret < size - 1u ? ret : size - 1u : 0u;
+ out_buffer = &out_buffer[min];
+ size -= min;
+
+ /* Add 16 bytes of salt */
+ if (gensalt) {
+ /* 16 bytes is 128 bits, and 128 = 21*6+2, so that is
+ * 21 full base-64 characeters and 1 that only use 2 bits */
+ ret += len = 22u;
+ min = size ? len < size - 1u ? len : size - 1u : 0u;
+ if (librecrypt_fill_with_random_(out_buffer, min, rng, user))
+ return -1;
+ if (min == len)
+ out_buffer[len - 1u] = (char)((unsigned char)out_buffer[len - 1u] & ~15u);
+ for (i = 0u; i < min; i++)
+ out_buffer[i] = librecrypt_common_rfc4848s4_encoding_lut_[((unsigned char *)out_buffer)[i]];
+ } else {
+ ret += len = sizeof("*16") - 1u;
+ min = size ? len < size - 1u ? len : size - 1u : 0u;
+ memcpy(out_buffer, "*16", min);
+ }
+ out_buffer = &out_buffer[min];
+ size -= min;
+
+ /* Add tag size (size of hash result) */
+ ret += len = sizeof("$*32") - 1u;
+ min = size ? len < size - 1u ? len : size - 1u : 0u;
+ memcpy(out_buffer, "$*32", min);
+ out_buffer = &out_buffer[min];
+ size -= min;
+
+ /* NUL terminate */
+ if (size) {
+ /* We were careful to make sure size is positive at
+ * the end if it was when the function was called */
+ *out_buffer = '\0';
+ }
+
+ return (ssize_t)ret;
+
+enosys:
+ errno = ENOSYS;
+ return -1;
}
@@ -59,7 +133,9 @@ CONST int
main(void)
{
SET_UP_ALARM();
+ INIT_RESOURCE_TEST();
+ STOP_RESOURCE_TEST();
return 0;
}