diff --git a/client.c b/client.c index 9e64c6d..f418c73 100644 --- a/client.c +++ b/client.c @@ -2990,7 +2990,7 @@ process_cmd_keygen(char *line) cmac_length = 0; #endif - if (HSH_GetHashId(type) >= 0) { + if (HSH_GetHashId(UTI_HashNameToAlgorithm(type)) >= 0) { length = (bits + 7) / 8; } else if (cmac_length > 0) { length = cmac_length; diff --git a/hash.h b/hash.h index 185da66..12167bc 100644 --- a/hash.h +++ b/hash.h @@ -31,7 +31,22 @@ /* length of hash values produced by SHA512 */ #define MAX_HASH_LENGTH 64 -extern int HSH_GetHashId(const char *name); +typedef enum { + HSH_INVALID = 0, + HSH_MD5 = 1, + HSH_SHA1 = 2, + HSH_SHA256 = 3, + HSH_SHA384 = 4, + HSH_SHA512 = 5, + HSH_SHA3_224 = 6, + HSH_SHA3_256 = 7, + HSH_SHA3_384 = 8, + HSH_SHA3_512 = 9, + HSH_TIGER = 10, + HSH_WHIRLPOOL = 11, +} HSH_Algorithm; + +extern int HSH_GetHashId(HSH_Algorithm algorithm); extern unsigned int HSH_Hash(int id, const unsigned char *in1, unsigned int in1_len, diff --git a/hash_intmd5.c b/hash_intmd5.c index 49da1cf..5a0debf 100644 --- a/hash_intmd5.c +++ b/hash_intmd5.c @@ -36,10 +36,10 @@ static MD5_CTX ctx; int -HSH_GetHashId(const char *name) +HSH_GetHashId(HSH_Algorithm algorithm) { /* only MD5 is supported */ - if (strcmp(name, "MD5")) + if (algorithm != HSH_MD5) return -1; return 0; diff --git a/hash_nettle.c b/hash_nettle.c index 2622f76..66fbe75 100644 --- a/hash_nettle.c +++ b/hash_nettle.c @@ -35,36 +35,36 @@ #include "memory.h" struct hash { - const char *name; + const HSH_Algorithm algorithm; const char *int_name; const struct nettle_hash *nettle_hash; void *context; }; static struct hash hashes[] = { - { "MD5", "md5", NULL, NULL }, - { "SHA1", "sha1", NULL, NULL }, - { "SHA256", "sha256", NULL, NULL }, - { "SHA384", "sha384", NULL, NULL }, - { "SHA512", "sha512", NULL, NULL }, - { "SHA3-224", "sha3_224", NULL, NULL }, - { "SHA3-256", "sha3_256", NULL, NULL }, - { "SHA3-384", "sha3_384", NULL, NULL }, - { "SHA3-512", "sha3_512", NULL, NULL }, - { NULL, NULL, NULL, NULL } + { HSH_MD5, "md5", NULL, NULL }, + { HSH_SHA1, "sha1", NULL, NULL }, + { HSH_SHA256, "sha256", NULL, NULL }, + { HSH_SHA384, "sha384", NULL, NULL }, + { HSH_SHA512, "sha512", NULL, NULL }, + { HSH_SHA3_224, "sha3_224", NULL, NULL }, + { HSH_SHA3_256, "sha3_256", NULL, NULL }, + { HSH_SHA3_384, "sha3_384", NULL, NULL }, + { HSH_SHA3_512, "sha3_512", NULL, NULL }, + { 0, NULL, NULL, NULL } }; int -HSH_GetHashId(const char *name) +HSH_GetHashId(HSH_Algorithm algorithm) { int id, nid; - for (id = 0; hashes[id].name; id++) { - if (!strcmp(name, hashes[id].name)) + for (id = 0; hashes[id].algorithm != 0; id++) { + if (hashes[id].algorithm == algorithm) break; } - if (!hashes[id].name) + if (hashes[id].algorithm == 0) return -1; if (hashes[id].context) @@ -112,7 +112,7 @@ HSH_Finalise(void) { int i; - for (i = 0; hashes[i].name; i++) { + for (i = 0; hashes[i].algorithm != 0; i++) { if (hashes[i].context) Free(hashes[i].context); } diff --git a/hash_nss.c b/hash_nss.c index 9967bf8..81345c2 100644 --- a/hash_nss.c +++ b/hash_nss.c @@ -38,30 +38,30 @@ static NSSLOWInitContext *ictx; struct hash { HASH_HashType type; - const char *name; + HSH_Algorithm algorithm; NSSLOWHASHContext *context; }; static struct hash hashes[] = { - { HASH_AlgMD5, "MD5", NULL }, - { HASH_AlgSHA1, "SHA1", NULL }, - { HASH_AlgSHA256, "SHA256", NULL }, - { HASH_AlgSHA384, "SHA384", NULL }, - { HASH_AlgSHA512, "SHA512", NULL }, - { 0, NULL, NULL } + { HASH_AlgMD5, HSH_MD5, NULL }, + { HASH_AlgSHA1, HSH_SHA1, NULL }, + { HASH_AlgSHA256, HSH_SHA256, NULL }, + { HASH_AlgSHA384, HSH_SHA384, NULL }, + { HASH_AlgSHA512, HSH_SHA512, NULL }, + { 0, 0, NULL } }; int -HSH_GetHashId(const char *name) +HSH_GetHashId(HSH_Algorithm algorithm) { int i; - for (i = 0; hashes[i].name; i++) { - if (!strcmp(name, hashes[i].name)) + for (i = 0; hashes[i].algorithm != 0; i++) { + if (hashes[i].algorithm == algorithm) break; } - if (!hashes[i].name) + if (hashes[i].algorithm == 0) return -1; /* not found */ if (!ictx && !(ictx = NSSLOW_Init())) @@ -99,7 +99,7 @@ HSH_Finalise(void) { int i; - for (i = 0; hashes[i].name; i++) { + for (i = 0; hashes[i].algorithm != 0; i++) { if (hashes[i].context) NSSLOWHASH_Destroy(hashes[i].context); } diff --git a/hash_tomcrypt.c b/hash_tomcrypt.c index 8ee0490..5da09b2 100644 --- a/hash_tomcrypt.c +++ b/hash_tomcrypt.c @@ -32,51 +32,51 @@ #include "util.h" struct hash { - const char *name; + HSH_Algorithm algorithm; const char *int_name; const struct ltc_hash_descriptor *desc; }; static const struct hash hashes[] = { - { "MD5", "md5", &md5_desc }, + { HSH_MD5, "md5", &md5_desc }, #ifdef LTC_SHA1 - { "SHA1", "sha1", &sha1_desc }, + { HSH_SHA1, "sha1", &sha1_desc }, #endif #ifdef LTC_SHA256 - { "SHA256", "sha256", &sha256_desc }, + { HSH_SHA256, "sha256", &sha256_desc }, #endif #ifdef LTC_SHA384 - { "SHA384", "sha384", &sha384_desc }, + { HSH_SHA384, "sha384", &sha384_desc }, #endif #ifdef LTC_SHA512 - { "SHA512", "sha512", &sha512_desc }, + { HSH_SHA512, "sha512", &sha512_desc }, #endif #ifdef LTC_SHA3 - { "SHA3-224", "sha3-224", &sha3_224_desc }, - { "SHA3-256", "sha3-256", &sha3_256_desc }, - { "SHA3-384", "sha3-384", &sha3_384_desc }, - { "SHA3-512", "sha3-512", &sha3_512_desc }, + { HSH_SHA3_224, "sha3-224", &sha3_224_desc }, + { HSH_SHA3_256, "sha3-256", &sha3_256_desc }, + { HSH_SHA3_384, "sha3-384", &sha3_384_desc }, + { HSH_SHA3_512, "sha3-512", &sha3_512_desc }, #endif #ifdef LTC_TIGER - { "TIGER", "tiger", &tiger_desc }, + { HSH_TIGER, "tiger", &tiger_desc }, #endif #ifdef LTC_WHIRLPOOL - { "WHIRLPOOL", "whirlpool", &whirlpool_desc }, + { HSH_WHIRLPOOL, "whirlpool", &whirlpool_desc }, #endif - { NULL, NULL, NULL } + { 0, NULL, NULL } }; int -HSH_GetHashId(const char *name) +HSH_GetHashId(HSH_Algorithm algorithm) { int i, h; - for (i = 0; hashes[i].name; i++) { - if (!strcmp(name, hashes[i].name)) + for (i = 0; hashes[i].algorithm != 0; i++) { + if (hashes[i].algorithm == algorithm) break; } - if (!hashes[i].name) + if (hashes[i].algorithm == 0) return -1; /* not found */ h = find_hash(hashes[i].int_name); diff --git a/keys.c b/keys.c index 1fa2215..749ca38 100644 --- a/keys.c +++ b/keys.c @@ -201,6 +201,7 @@ KEY_Reload(void) FILE *in; char line[2048], *key_file, *key_value; const char *key_type; + HSH_Algorithm hash_algorithm; int hash_id; Key key; @@ -238,10 +239,15 @@ KEY_Reload(void) continue; } - hash_id = HSH_GetHashId(key_type); cmac_key_length = CMC_GetKeyLength(key_type); + hash_algorithm = UTI_HashNameToAlgorithm(key_type); - if (hash_id >= 0) { + if (hash_algorithm != 0) { + hash_id = HSH_GetHashId(hash_algorithm); + if (hash_id < 0) { + LOG(LOGS_WARN, "Unsupported %s in key %"PRIu32, "hash function", key.id); + continue; + } key.class = NTP_MAC; key.data.ntp_mac.value = MallocArray(unsigned char, key_length); memcpy(key.data.ntp_mac.value, key_value, key_length); diff --git a/test/unit/hash.c b/test/unit/hash.c index f1e44bc..331dcac 100644 --- a/test/unit/hash.c +++ b/test/unit/hash.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "test.h" struct hash_test { @@ -69,18 +70,23 @@ test_unit(void) { "", "", 0 } }; + HSH_Algorithm algorithm; unsigned int length; int i, j, hash_id; + TEST_CHECK(HSH_INVALID == 0); + for (i = 0; tests[i].name[0] != '\0'; i++) { - hash_id = HSH_GetHashId(tests[i].name); + algorithm = UTI_HashNameToAlgorithm(tests[i].name); + TEST_CHECK(algorithm != 0); + hash_id = HSH_GetHashId(algorithm); if (hash_id < 0) { - TEST_CHECK(strcmp(tests[i].name, "MD5")); + TEST_CHECK(algorithm != HSH_MD5); #ifdef FEAT_SECHASH - TEST_CHECK(strcmp(tests[i].name, "SHA1")); - TEST_CHECK(strcmp(tests[i].name, "SHA256")); - TEST_CHECK(strcmp(tests[i].name, "SHA384")); - TEST_CHECK(strcmp(tests[i].name, "SHA512")); + TEST_CHECK(algorithm != HSH_SHA1); + TEST_CHECK(algorithm != HSH_SHA256); + TEST_CHECK(algorithm != HSH_SHA384); + TEST_CHECK(algorithm != HSH_SHA512); #endif continue; } @@ -88,8 +94,8 @@ test_unit(void) DEBUG_LOG("testing %s", tests[i].name); for (j = 0; j <= sizeof (out); j++) { - TEST_CHECK(HSH_GetHashId(tests[i].name) == hash_id); - TEST_CHECK(HSH_GetHashId("nosuchhash") < 0); + TEST_CHECK(HSH_GetHashId(algorithm) == hash_id); + TEST_CHECK(HSH_GetHashId(0) < 0); memset(out, 0, sizeof (out)); length = HSH_Hash(hash_id, data1, sizeof (data1) - 1, data2, sizeof (data2) - 1, diff --git a/util.c b/util.c index 8f18a21..a71b8fc 100644 --- a/util.c +++ b/util.c @@ -399,7 +399,7 @@ UTI_IPToRefid(const IPAddr *ip) return ip->addr.in4; case IPADDR_INET6: if (MD5_hash < 0) - MD5_hash = HSH_GetHashId("MD5"); + MD5_hash = HSH_GetHashId(HSH_MD5); if (MD5_hash < 0 || HSH_Hash(MD5_hash, (const unsigned char *)ip->addr.in6, sizeof (ip->addr.in6), @@ -927,6 +927,36 @@ UTI_FloatHostToNetwork(double x) /* ================================================== */ +HSH_Algorithm +UTI_HashNameToAlgorithm(const char *name) +{ + if (strcmp(name, "MD5") == 0) + return HSH_MD5; + else if (strcmp(name, "SHA1") == 0) + return HSH_SHA1; + else if (strcmp(name, "SHA256") == 0) + return HSH_SHA256; + else if (strcmp(name, "SHA384") == 0) + return HSH_SHA384; + else if (strcmp(name, "SHA512") == 0) + return HSH_SHA512; + else if (strcmp(name, "SHA3-224") == 0) + return HSH_SHA3_224; + else if (strcmp(name, "SHA3-256") == 0) + return HSH_SHA3_256; + else if (strcmp(name, "SHA3-384") == 0) + return HSH_SHA3_384; + else if (strcmp(name, "SHA3-512") == 0) + return HSH_SHA3_512; + else if (strcmp(name, "TIGER") == 0) + return HSH_TIGER; + else if (strcmp(name, "WHIRLPOOL") == 0) + return HSH_WHIRLPOOL; + return HSH_INVALID; +} + +/* ================================================== */ + int UTI_FdSetCloexec(int fd) { diff --git a/util.h b/util.h index 1e28b26..f3cb99f 100644 --- a/util.h +++ b/util.h @@ -165,6 +165,8 @@ extern void UTI_TimespecHostToNetwork(const struct timespec *src, Timespec *dest extern double UTI_FloatNetworkToHost(Float x); extern Float UTI_FloatHostToNetwork(double x); +extern HSH_Algorithm UTI_HashNameToAlgorithm(const char *name); + /* Set FD_CLOEXEC on descriptor */ extern int UTI_FdSetCloexec(int fd);