aboutsummaryrefslogtreecommitdiffstats
path: root/librecrypt_realise_salts.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-05-11 23:15:33 +0200
committerMattias Andrée <m@maandree.se>2026-05-11 23:15:33 +0200
commit86087e5f9cf4a0512ba36b4d01086b905574a47d (patch)
tree03ce90743ef4d9e3da6ba45b70f11494e12b667c /librecrypt_realise_salts.c
parentMisc (diff)
downloadlibrecrypt-86087e5f9cf4a0512ba36b4d01086b905574a47d.tar.gz
librecrypt-86087e5f9cf4a0512ba36b4d01086b905574a47d.tar.bz2
librecrypt-86087e5f9cf4a0512ba36b4d01086b905574a47d.tar.xz
Misc
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--librecrypt_realise_salts.c143
1 files changed, 139 insertions, 4 deletions
diff --git a/librecrypt_realise_salts.c b/librecrypt_realise_salts.c
index a21c4df..58ba6d3 100644
--- a/librecrypt_realise_salts.c
+++ b/librecrypt_realise_salts.c
@@ -51,6 +51,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set
for (i = 0u; settings[i] != '*'; i++);
min = i < size ? i : size;
memcpy(out_buffer, settings, min);
+ out_buffer = &out_buffer[min];
size -= min;
settings = &settings[i];
ret += i;
@@ -60,7 +61,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set
/* If the '*' is not followed by an unsigned,
* decimal integer include it literally */
- if ('0' > settings[1u] || settings[1u] > '9') {
+ if ('0' > settings[0u] || settings[0u] > '9') {
if (size) {
*out_buffer++ = '*';
size -= 1u;
@@ -95,7 +96,9 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set
* r==2: 3 base-64 characters, so 1 padding characters */
right = (r && pad) ? 3u - r : 0u;
/* Get total length */
- if (q > ((size_t)SSIZE_MAX - right) / 4u)
+ if (q > ((size_t)SSIZE_MAX - (r + mid + right)) / 4u)
+ goto erange;
+ if (ret > (size_t)SSIZE_MAX - (left + mid + right))
goto erange;
ret += left + mid + right;
@@ -104,7 +107,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set
* one variable for all random characters */
left += mid;
if (left > size) {
- left = 0u;
+ left = size;
mid = 0u;
}
@@ -134,6 +137,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set
break;
min = i < size ? i : size;
memcpy(out_buffer, settings, min);
+ out_buffer = &out_buffer[min];
size -= min;
settings = &settings[i];
ret += i;
@@ -160,16 +164,147 @@ erange:
#else
+# define LARGE "99999999999999999999999999999999999999999999999999999999999999"
+# define A10 "AAAAAAAAAA"
+# define A40 A10 A10 A10 A10
+
+
+static unsigned char saltbyte = 0u;
+
+
+static ssize_t
+saltgen(void *out, size_t n, void *user)
+{
+ (void) user;
+ if (n > (size_t)SSIZE_MAX)
+ n = (size_t)SSIZE_MAX;
+ memset(out, *(unsigned char *)user, n);
+ return (ssize_t)n;
+}
+
+
+static ssize_t
+saltfail(void *out, size_t n, void *user)
+{
+ (void) out;
+ (void) n;
+ (void) user;
+ errno = EDOM;
+ return -1;
+}
+
+
int
main(void)
{
+ char buf[1024], buf2[1024], conf[128];
+ size_t i;
+ int r;
+
SET_UP_ALARM();
INIT_RESOURCE_TEST();
+ errno = 0;
+ EXPECT(librecrypt_realise_salts(NULL, 0u, "$~no~such~algorithm~$", NULL, NULL) == -1);
+ EXPECT(errno == ENOSYS);
+
+ EXPECT(librecrypt_realise_salts(NULL, 0u, "", NULL, NULL) == 0);
+
+#if defined(SUPPORT_ARGON2ID)
+# define ALGO "$argon2id$"
+#elif defined(SUPPORT_ARGON2I)
+# define ALGO "$argon2i$"
+#elif defined(SUPPORT_ARGON2D)
+# define ALGO "$argon2d$"
+#elif defined(SUPPORT_ARGON2DS)
+# define ALGO "$argon2ds$"
+#endif
+
+#if defined(ALGO)
+# define CHECK(IN, OUT)\
+ do {\
+ EXPECT(librecrypt_realise_salts(NULL, 0u, (IN), NULL, NULL) == (ssize_t)sizeof(OUT) - 1);\
+ EXPECT(librecrypt_realise_salts(buf, 0u, (IN), NULL, NULL) == (ssize_t)sizeof(OUT) - 1);\
+ memset(buf, 99, sizeof(buf));\
+ EXPECT(librecrypt_realise_salts(buf, sizeof(buf), (IN), &saltgen, &saltbyte) == (ssize_t)sizeof(OUT) - 1);\
+ EXPECT(!strcmp(buf, (OUT)));\
+ for (i = 0u; i < sizeof(OUT); i++) {\
+ memset(buf, 99, sizeof(buf));\
+ EXPECT(librecrypt_realise_salts(buf, i + 1u, (IN), &saltgen, &saltbyte) == (ssize_t)sizeof(OUT) - 1);\
+ EXPECT(!memcmp(buf, (OUT), i));\
+ EXPECT(!buf[i]);\
+ }\
+ } while (0)
+
+ CHECK(ALGO, ALGO);
+ CHECK(ALGO"*100", ALGO "*100");
+ CHECK(ALGO"*30$", ALGO A40 "$");
+ CHECK(ALGO"*30$*100", ALGO A40 "$*100");
+ CHECK(ALGO"*31$*100", ALGO A40 "AA$*100");
+ CHECK(ALGO"*32$*100", ALGO A40 "AAA$*100");
+ CHECK(ALGO"*33$*100", ALGO A40 "AAAA$*100");
+ CHECK(ALGO"*1$*100", ALGO "AA$*100");
+ CHECK(ALGO"*2$*100", ALGO "AAA$*100");
+ CHECK(ALGO"*3$*100", ALGO "AAAA$*100");
+ CHECK(ALGO"*033$*100", ALGO A40 "AAAA$*100");
+ CHECK(ALGO"*0$*100", ALGO "$*100");
+ CHECK(ALGO"*30*30$*100", ALGO A40 A40"$*100");
+ CHECK(ALGO"*30*3$*100", ALGO A40 "AAAA$*100");
+ CHECK(ALGO"*30$*30$*100", ALGO A40 "$" A40"$*100");
+ CHECK(ALGO"*30$*3$*100", ALGO A40 "$AAAA$*100");
+ CHECK(ALGO"*$*100", ALGO "*$*100");
+ CHECK(ALGO"*x$*100", ALGO "*x$*100");
+ CHECK(ALGO">"ALGO, ALGO">"ALGO);
+ CHECK(ALGO"*30$*100>"ALGO"*30$*10", ALGO A40 "$*100>" ALGO A40 "$*10");
+ CHECK(ALGO"*30$>"ALGO"*30$", ALGO A40 "$>" ALGO A40 "$");
+
+# undef CHECK
+
+ errno = 0;
+ EXPECT(librecrypt_realise_salts(NULL, 0u, ALGO">$~no~such~algorithm~$", &saltgen, &saltbyte) == -1);
+ EXPECT(errno == ENOSYS);
+ errno = 0;
+ EXPECT(librecrypt_realise_salts(NULL, 0u, "$~no~such~algorithm~$>"ALGO, &saltgen, &saltbyte) == -1);
+ EXPECT(errno == ENOSYS);
+ errno = 0;
+ EXPECT(librecrypt_realise_salts(NULL, 0u, ALGO"*"LARGE"$", &saltgen, &saltbyte) == -1);
+ EXPECT(errno == ERANGE);
+
+ EXPECT(librecrypt_realise_salts(buf, sizeof(ALGO) - 1u, ALGO"*3$", &saltfail, NULL) == (ssize_t)sizeof(ALGO"$") - 1 + 4);
+ errno = 0;
+ EXPECT(librecrypt_realise_salts(buf, sizeof(buf), ALGO"*3$", &saltfail, NULL) == -1);
+ EXPECT(errno == EDOM);
+
+ r = snprintf(conf, sizeof(conf), "%s*%zu$", ALGO, (size_t)SSIZE_MAX / 4u * 3u + 3u);
+ assert(r > 0 && (size_t)r < sizeof(conf));
+ errno = 0;
+ EXPECT(librecrypt_realise_salts(NULL, 0u, conf, &saltgen, &saltbyte) == -1);
+ EXPECT(errno == ERANGE);
+
+ r = snprintf(conf, sizeof(conf), "%s*%zu$", ALGO, (size_t)SSIZE_MAX / 4u * 3u);
+ assert(r > 0 && (size_t)r < sizeof(conf));
+ errno = 0;
+ EXPECT(librecrypt_realise_salts(NULL, 0u, conf, &saltgen, &saltbyte) == -1);
+ EXPECT(errno == ERANGE);
+
+ r = snprintf(conf, sizeof(conf), "%s*%zu$abcdef", ALGO, ((size_t)SSIZE_MAX - (sizeof(ALGO) - 1u)) / 4u * 3u);
+ assert(r > 0 && (size_t)r < sizeof(conf));
+ errno = 0;
+ EXPECT(librecrypt_realise_salts(NULL, 0u, conf, &saltgen, &saltbyte) == -1);
+ EXPECT(errno == ERANGE);
+
+ memset(buf, 99, sizeof(buf));
+ memset(buf2, 99, sizeof(buf2));
+ EXPECT(librecrypt_realise_salts(buf, sizeof(buf), ALGO"*30$", NULL, NULL) == (ssize_t)sizeof(ALGO"$") - 1 + 40);
+ EXPECT(librecrypt_realise_salts(buf2, sizeof(buf2), ALGO"*30$", NULL, NULL) == (ssize_t)sizeof(ALGO"$") - 1 + 40);
+ EXPECT(!buf[sizeof(ALGO"$") - 1u + 40u]);
+ EXPECT(!buf2[sizeof(ALGO"$") - 1u + 40u]);
+ EXPECT(memcmp(buf, buf2, sizeof(ALGO"$") - 1u + 40u));
+#endif
+
STOP_RESOURCE_TEST();
return 0;
}
#endif
-/* TODO test */