diff options
author | Mattias Andrée <maandree@kth.se> | 2024-08-24 18:02:00 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2024-08-24 18:02:00 +0200 |
commit | 72111e7a53eaad7bea841ab8b09e70642bde00ae (patch) | |
tree | 016e0326b794f8a5b9cc03139b8a5ab094ed7411 /libhashsum_init_hasher_from_string.c | |
parent | Make it possible for libhashsum_state to grow in future versions (diff) | |
download | libhashsum-72111e7a53eaad7bea841ab8b09e70642bde00ae.tar.gz libhashsum-72111e7a53eaad7bea841ab8b09e70642bde00ae.tar.bz2 libhashsum-72111e7a53eaad7bea841ab8b09e70642bde00ae.tar.xz |
Add support for Keccak, SHA3, SHAKE, and RawSHAKE via libkeccak>=1.3 (this version introduced zerocopy)
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | libhashsum_init_hasher_from_string.c | 129 |
1 files changed, 127 insertions, 2 deletions
diff --git a/libhashsum_init_hasher_from_string.c b/libhashsum_init_hasher_from_string.c index e41c8b1..30526da 100644 --- a/libhashsum_init_hasher_from_string.c +++ b/libhashsum_init_hasher_from_string.c @@ -8,7 +8,7 @@ __attribute__((__pure__)) static int equiv(const char *a, const char *b) { - while (*a && *b) { + while (*a && *b && *b != '[') { if (tolower(*a) == tolower(*b)) { a++; b++; @@ -18,7 +18,102 @@ equiv(const char *a, const char *b) return 0; } } - return !*a && !*b; + return !*a && (!*b || *b == '['); +} + + +static int +with_n(int (*initfunc)(struct libhashsum_hasher *, size_t), struct libhashsum_hasher *this, const char *algorithm) +{ + const char *p; + size_t n = 0, digit; + + p = strchr(algorithm, '['); + if (!p || *++p == ']') + return initfunc(this, 0); + + if ((*p++ != 'n' && *p++ != 'N')) + goto einval; + if (*p++ != '=' || !('1' <= *p && *p <= '9')) + goto einval; + + while (isdigit(*p)) { + digit = (size_t)(*p++ & 15); + if (n > (SIZE_MAX - digit) / 10U) + goto einval; + n = n * 10U + digit; + } + + if (*p++ != ']' || *p) + goto einval; + + return initfunc(this, n); + +einval: + errno = EINVAL; + return -1; +} + + +static int +parse_value(size_t *valp, const char *p, const char **end_out) +{ + size_t digit; + if (*valp) + return -1; + p++; + if (*p++ != '=' || !('1' <= *p && *p <= '9')) + return -1; + while (isdigit(*p)) { + digit = (size_t)(*p++ & 15); + if (*valp > (SIZE_MAX - digit) / 10U) + return -1; + *valp = *valp * 10U + digit; + } + *end_out = p; + return 0; +} + + +static int +with_rcn(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t), + struct libhashsum_hasher *this, const char *algorithm) +{ + const char *p; + size_t r = 0, c = 0, n = 0; + + p = strchr(algorithm, '['); + if (!p || *++p == ']') + return initfunc(this, 0, 0, 0); + + for (;;) { + if (*p == 'r' || *p == 'R') { + if (parse_value(&r, p, &p)) + goto einval; + } else if (*p == 'c' || *p == 'C') { + if (parse_value(&c, p, &p)) + goto einval; + } else if (*p == 'n' || *p == 'N') { + if (parse_value(&n, p, &p)) + goto einval; + } else if (*p == ']') { + break; + } else { + goto einval; + } + if (*p == ']') + break; + if (*p++ != ',') + goto einval; + } + if (p[1]) + goto einval; + + return initfunc(this, r, c, n); + +einval: + errno = EINVAL; + return -1; } @@ -55,6 +150,36 @@ libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *a return libhashsum_init_sha_512_224_hasher(this); if (equiv(algorithm, "SHA-512/256") || !strcasecmp(algorithm, "SHA2-512/256")) return libhashsum_init_sha_512_256_hasher(this); + if (equiv(algorithm, "Keccak-224")) + return libhashsum_init_keccak_224_hasher(this); + if (equiv(algorithm, "Keccak-256")) + return libhashsum_init_keccak_256_hasher(this); + if (equiv(algorithm, "Keccak-384")) + return libhashsum_init_keccak_384_hasher(this); + if (equiv(algorithm, "Keccak-512")) + return libhashsum_init_keccak_512_hasher(this); + if (!strcasecmp(algorithm, "SHA3-224")) + return libhashsum_init_sha3_224_hasher(this); + if (!strcasecmp(algorithm, "SHA3-256")) + return libhashsum_init_sha3_256_hasher(this); + if (!strcasecmp(algorithm, "SHA3-384")) + return libhashsum_init_sha3_384_hasher(this); + if (!strcasecmp(algorithm, "SHA3-512")) + return libhashsum_init_sha3_512_hasher(this); + if (equiv(algorithm, "SHAKE-128[")) + return with_n(&libhashsum_init_shake128_hasher, this, algorithm); + if (equiv(algorithm, "SHAKE-256[")) + return with_n(&libhashsum_init_shake256_hasher, this, algorithm); + if (equiv(algorithm, "SHAKE-512[")) + return with_n(&libhashsum_init_shake512_hasher, this, algorithm); + if (equiv(algorithm, "RawSHAKE-128[")) + return with_n(&libhashsum_init_rawshake128_hasher, this, algorithm); + if (equiv(algorithm, "RawSHAKE-256[")) + return with_n(&libhashsum_init_rawshake256_hasher, this, algorithm); + if (equiv(algorithm, "RawSHAKE-512[")) + return with_n(&libhashsum_init_rawshake512_hasher, this, algorithm); + if (equiv(algorithm, "Keccak[")) + return with_rcn(&libhashsum_init_keccak_hasher, this, algorithm); errno = EINVAL; return -1; |