diff options
Diffstat (limited to '')
-rw-r--r-- | libhashsum_init_hasher_from_string.c | 73 |
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; |