From efc640d7c8d4018f6d0ed8f02ec4ff7c61ff401a Mon Sep 17 00:00:00 2001 From: Daniel Zagaynov Date: Sun, 9 Nov 2025 18:28:28 +0300 Subject: [PATCH 1/2] lib/crypt.h: provide list of supported hash algorithms --- build-aux/scripts/gen-crypt-hashes-h | 10 ++++++++++ lib/crypt.c | 6 ++++++ lib/crypt.h.in | 5 +++++ lib/libcrypt.map.in | 3 ++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/build-aux/scripts/gen-crypt-hashes-h b/build-aux/scripts/gen-crypt-hashes-h index ee72b86c..474f5321 100644 --- a/build-aux/scripts/gen-crypt-hashes-h +++ b/build-aux/scripts/gen-crypt-hashes-h @@ -110,6 +110,16 @@ EOT #define HASH_ALGORITHM_DEFAULT "$default_prefix" EOT + + # List of supported hash methods + my @provided_hashes = (); + while (my ($e, $v) = each %{$hconf->hashes}){ + if ($enabled{$e}) { + push @provided_hashes, "$e:@{[$v->prefix]}"; + } + } + print "\n#define SUPPORTED_HASH_METHODS \\\n"; + print ' "' . (join ";\" \\\n \"", sort @provided_hashes) . '"'; print <<'EOT'; #endif /* crypt-hashes.h */ diff --git a/lib/crypt.c b/lib/crypt.c index 20178422..43c369f9 100644 --- a/lib/crypt.c +++ b/lib/crypt.c @@ -419,3 +419,9 @@ crypt_preferred_method (void) } SYMVER_crypt_preferred_method; #endif + +const char *crypt_get_supported_hash_methods(void) +{ + return SUPPORTED_HASH_METHODS; +} +SYMVER_crypt_get_supported_hash_methods; diff --git a/lib/crypt.h.in b/lib/crypt.h.in index f7040bbc..5ab0e6e0 100644 --- a/lib/crypt.h.in +++ b/lib/crypt.h.in @@ -244,6 +244,11 @@ extern const char *crypt_preferred_method (void); /* Version number as a string constant. */ #define XCRYPT_VERSION_STR "@XCRYPT_VERSION_STR@" +/* List of provided by the current build hash algorithms*/ + +#define CRYPT_GET_SUPPORTED_HASH_METHODS_AVAILABLE 1 +extern const char *crypt_get_supported_hash_methods(void); + @END_DECLS@ #endif /* crypt.h */ diff --git a/lib/libcrypt.map.in b/lib/libcrypt.map.in index 3f8bb18c..a942b03a 100644 --- a/lib/libcrypt.map.in +++ b/lib/libcrypt.map.in @@ -19,6 +19,7 @@ crypt_gensalt_ra XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.2:alt OW_CRYPT_1.0: # Actively supported interfaces from libxcrypt. crypt_checksalt XCRYPT_4.3 crypt_preferred_method XCRYPT_4.4 +crypt_get_supported_hash_methods XCRYPT_4.5 # Interfaces for code compatibility with libxcrypt v3.1.1 and earlier. # No longer available to new binaries. Include in version-script, only @@ -45,4 +46,4 @@ fcrypt - GLIBC_2.0 %chain GLIBC_2.3 GLIBC_2.4 GLIBC_2.12 GLIBC_2.16 GLIBC_2.17 GLIBC_2.18 %chain GLIBC_2.21 GLIBC_2.27 GLIBC_2.29 GLIBC_2.32 GLIBC_2.33 GLIBC_2.35 %chain GLIBC_2.36 GLIBC_2.38 -%chain OW_CRYPT_1.0 XCRYPT_2.0 XCRYPT_4.3 XCRYPT_4.4 +%chain OW_CRYPT_1.0 XCRYPT_2.0 XCRYPT_4.3 XCRYPT_4.4 XCRYPT_4.5 From 16da43926bbf634374f7996d29c383d949911da9 Mon Sep 17 00:00:00 2001 From: Daniel Zagaynov Date: Thu, 20 Nov 2025 21:20:17 +0300 Subject: [PATCH 2/2] Add tests for crypt_get_supported_hash_methods --- Makefile.am | 2 + test/crypt-get-supported-hash-methods.c | 76 +++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 test/crypt-get-supported-hash-methods.c diff --git a/Makefile.am b/Makefile.am index 548d44a6..acc84747 100644 --- a/Makefile.am +++ b/Makefile.am @@ -384,6 +384,7 @@ check_PROGRAMS = \ test/checksalt \ test/compile-strong-alias \ test/crypt-badargs \ + test/crypt-get-supported-hash-methods \ test/crypt-gost-yescrypt \ test/crypt-nested-call \ test/crypt-sm3-yescrypt \ @@ -509,6 +510,7 @@ test_checksalt_LDADD = $(COMMON_TEST_OBJECTS) test_des_obsolete_LDADD = $(COMMON_TEST_OBJECTS) test_des_obsolete_r_LDADD = $(COMMON_TEST_OBJECTS) test_crypt_badargs_LDADD = $(COMMON_TEST_OBJECTS) +test_crypt_get_supported_hash_methods_LDADD = $(COMMON_TEST_OBJECTS) test_crypt_nested_call_LDADD = $(COMMON_TEST_OBJECTS) test_crypt_too_long_phrase_LDADD = $(COMMON_TEST_OBJECTS) test_preferred_method_LDADD = $(COMMON_TEST_OBJECTS) diff --git a/test/crypt-get-supported-hash-methods.c b/test/crypt-get-supported-hash-methods.c new file mode 100644 index 00000000..66d7d60e --- /dev/null +++ b/test/crypt-get-supported-hash-methods.c @@ -0,0 +1,76 @@ +#include +#include + +#include "crypt-port.h" + +const char defined_hash_methods[] = +#if INCLUDE_bcrypt + "bcrypt:$2b$;" +#endif +#if INCLUDE_bcrypt_a + "bcrypt_a:$2a$;" +#endif +#if INCLUDE_bcrypt_x + "bcrypt_x:$2x$;" +#endif +#if INCLUDE_bcrypt_y + "bcrypt_y:$2y$;" +#endif +#if INCLUDE_bigcrypt + "bigcrypt:;" +#endif +#if INCLUDE_bsdicrypt + "bsdicrypt:_;" +#endif +#if INCLUDE_descrypt + "descrypt:;" +#endif +#if INCLUDE_gost_yescrypt + "gost_yescrypt:$gy$;" +#endif +#if INCLUDE_md5crypt + "md5crypt:$1$;" +#endif +#if INCLUDE_nt + "nt:$3$;" +#endif +#if INCLUDE_scrypt + "scrypt:$7$;" +#endif +#if INCLUDE_sha1crypt + "sha1crypt:$sha1;" +#endif +#if INCLUDE_sha256crypt + "sha256crypt:$5$;" +#endif +#if INCLUDE_sha512crypt + "sha512crypt:$6$;" +#endif +#if INCLUDE_sm3_yescrypt + "sm3_yescrypt:$sm3y$;" +#endif +#if INCLUDE_sm3crypt + "sm3crypt:$sm3$;" +#endif +#if INCLUDE_sunmd5 + "sunmd5:$md5;" +#endif +#if INCLUDE_yescrypt + "yescrypt:$y$;" +#endif +""; + +int main(void) +{ + const char *expected = defined_hash_methods; + const char *reported = crypt_get_supported_hash_methods(); + size_t len1 = strlen(expected) - 1, len2 = strlen(reported); + int res = (len1 != len2 || strncmp(expected, reported, len2)); + + // Assume there is ";" in the end of defined_hash_methods + fprintf(stderr, "Compiled and reported by" + " crypt_get_supported_hash_methods() lists of supported" + " hash methods are %sequal:\n\"%s\" %s=\n\"%s;\"\n", + (res ? "NOT " : ""), expected, (res ? "!" : "="), reported); + return res; +}