aboutsummaryrefslogtreecommitdiffstats
path: root/libhashsum_init_hasher_from_string.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libhashsum_init_hasher_from_string.c73
1 files changed, 64 insertions, 9 deletions
diff --git a/libhashsum_init_hasher_from_string.c b/libhashsum_init_hasher_from_string.c
index 9a53864..1bdc70d 100644
--- a/libhashsum_init_hasher_from_string.c
+++ b/libhashsum_init_hasher_from_string.c
@@ -32,7 +32,7 @@ with_n(int (*initfunc)(struct libhashsum_hasher *, size_t), struct libhashsum_ha
if (!p || *++p == ']')
return initfunc(this, 0);
- if ((*p++ != 'n' && *p++ != 'N'))
+ if (*p++ != 'n' && *p++ != 'N')
goto einval;
if (*p++ != '=' || !('1' <= *p && *p <= '9'))
goto einval;
@@ -117,6 +117,61 @@ einval:
}
+static int
+with_salt(int (*initfunc)(struct libhashsum_hasher *, const void *),
+ struct libhashsum_hasher *this, const char *algorithm, size_t saltbytes)
+{
+ const char *p;
+ uint8_t a, b, salt[32];
+ size_t salti = 0;
+
+ p = strchr(algorithm, '[');
+ if (!p || *++p == ']')
+ return initfunc(this, NULL);
+
+ if (*p++ != 's' && *p++ != 'S')
+ goto einval;
+ if (*p++ != 'a' && *p++ != 'A')
+ goto einval;
+ if (*p++ != 'l' && *p++ != 'L')
+ goto einval;
+ if (*p++ != 't' && *p++ != 'T')
+ goto einval;
+ if (*p++ != '=')
+ goto einval;
+
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
+ p = &p[2];
+
+ for (;;) {
+ if (isxdigit(p[0]) && isxdigit(p[1])) {
+ if (!saltbytes)
+ goto einval;
+ saltbytes--;
+ } else if (isxdigit(p[0])) {
+ goto einval;
+ } else if (saltbytes) {
+ goto einval;
+ } else {
+ break;
+ }
+
+ a = (uint8_t)(((*p & 15) + (*p > '9' ? 9 : 0)) << 4);
+ b = (uint8_t)(((*p & 15) + (*p > '9' ? 9 : 0)) << 0);
+ salt[salti++] = (uint8_t)(a | b);
+ }
+
+ if (*p++ != ']' || *p)
+ goto einval;
+
+ return initfunc(this, salt);
+
+einval:
+ errno = EINVAL;
+ return -1;
+}
+
+
int
libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *algorithm)
{
@@ -180,14 +235,14 @@ libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *a
return with_n(&libhashsum_init_rawshake512_hasher, this, algorithm);
if (equiv(algorithm, "Keccak["))
return with_rcn(&libhashsum_init_keccak_hasher, this, algorithm);
- if (equiv(algorithm, "BLAKE-224"))
- return libhashsum_init_blake224_hasher(this);
- if (equiv(algorithm, "BLAKE-256"))
- return libhashsum_init_blake256_hasher(this);
- if (equiv(algorithm, "BLAKE-384"))
- return libhashsum_init_blake384_hasher(this);
- if (equiv(algorithm, "BLAKE-512"))
- return libhashsum_init_blake512_hasher(this);
+ if (equiv(algorithm, "BLAKE-224["))
+ return with_salt(&libhashsum_init_blake224_hasher, this, algorithm, 16U);
+ if (equiv(algorithm, "BLAKE-256["))
+ return with_salt(&libhashsum_init_blake256_hasher, this, algorithm, 16U);
+ if (equiv(algorithm, "BLAKE-384["))
+ return with_salt(&libhashsum_init_blake384_hasher, this, algorithm, 32U);
+ if (equiv(algorithm, "BLAKE-512["))
+ return with_salt(&libhashsum_init_blake512_hasher, this, algorithm, 32U);
errno = EINVAL;
return -1;