diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index 3a30526c..bd31a3b0 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -511,6 +511,9 @@ struct get_char { void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz); void password_free(struct password *pw, const struct password_ctx *ctx); +/* Case-insensitive ASCII compare that ignores ' ', '-' and '_'. Returns 1 on match, 0 otherwise. */ +int ltc_algname_match(const char *left, const char *right); + int ltc_compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); int ltc_do_compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); diff --git a/src/misc/algname_match.c b/src/misc/algname_match.c new file mode 100644 index 00000000..d46fb8b8 --- /dev/null +++ b/src/misc/algname_match.c @@ -0,0 +1,40 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file algname_match.c + Shared relaxed name-matching helper for algorithm lookup tables. +*/ + +/** + Compare two algorithm-name strings. + + Matching is case-insensitive (ASCII) and ignores ' ', '-' and '_' on both sides + e.g. "SECP256R1", "secp_256_r1", "secp-256-r1" and "secp 256 r1" all match + @param left First NUL-terminated string + @param right Second NUL-terminated string + @return 1 if the strings match under the relaxed rules, 0 otherwise +*/ +int ltc_algname_match(const char *left, const char *right) +{ + char lc_r, lc_l; + + if (left == NULL || right == NULL) return 0; + + while ((*left != '\0') && (*right != '\0')) { + while ((*left == ' ') || (*left == '-') || (*left == '_')) left++; + while ((*right == ' ') || (*right == '-') || (*right == '_')) right++; + if (*left == '\0' || *right == '\0') break; + lc_r = *right; + lc_l = *left; + if ((lc_r >= 'A') && (lc_r <= 'Z')) lc_r += 32; + if ((lc_l >= 'A') && (lc_l <= 'Z')) lc_l += 32; + if (lc_l != lc_r) return 0; + left++; + right++; + } + + if ((*left == '\0') && (*right == '\0')) return 1; + return 0; +} diff --git a/src/pk/ecc/ecc_find_curve.c b/src/pk/ecc/ecc_find_curve.c index 96a61bdc..cfcb5dd0 100644 --- a/src/pk/ecc/ecc_find_curve.c +++ b/src/pk/ecc/ecc_find_curve.c @@ -189,28 +189,6 @@ static const struct { } }; -/* case-insensitive match + ignore '-', '_', ' ' */ -static int s_name_match(const char *left, const char *right) -{ - char lc_r, lc_l; - - while ((*left != '\0') && (*right != '\0')) { - while ((*left == ' ') || (*left == '-') || (*left == '_')) left++; - while ((*right == ' ') || (*right == '-') || (*right == '_')) right++; - if (*left == '\0' || *right == '\0') break; - lc_r = *right; - lc_l = *left; - if ((lc_r >= 'A') && (lc_r <= 'Z')) lc_r += 32; - if ((lc_l >= 'A') && (lc_l <= 'Z')) lc_l += 32; - if (lc_l != lc_r) return 0; - left++; - right++; - } - - if ((*left == '\0') && (*right == '\0')) return 1; - return 0; -} - int ecc_get_curve_names(const char *oid, const char * const **names) { unsigned long i; @@ -241,7 +219,7 @@ int ecc_find_curve(const char *name_or_oid, const ltc_ecc_curve **cu) OID = s_curve_names[i].OID; } for (j = 0; s_curve_names[i].names[j] != NULL && !OID; j++) { - if (s_name_match(s_curve_names[i].names[j], name_or_oid)) { + if (ltc_algname_match(s_curve_names[i].names[j], name_or_oid)) { OID = s_curve_names[i].OID; } }