From f51a5c9235bbf9a8c3670278a6d8bbf2147e43b8 Mon Sep 17 00:00:00 2001 From: "Pavel I. Kryukov" Date: Mon, 19 Feb 2018 00:06:14 +0300 Subject: [PATCH] Add supports_sha_ni(void) function It executes CPUID instruction to check whether SHA extensions are supported by hosting CPU. --- ssh.h | 2 ++ sshsha.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/ssh.h b/ssh.h index 2f946e83..013f4eb2 100644 --- a/ssh.h +++ b/ssh.h @@ -258,6 +258,8 @@ void hmacmd5_key(void *handle, void const *key, int len); void hmacmd5_do_hmac(void *handle, unsigned char const *blk, int len, unsigned char *hmac); +int supports_sha_ni(void); + typedef struct SHA_State { uint32 h[5]; unsigned char block[64]; diff --git a/sshsha.c b/sshsha.c index 711b08a6..5c0f69b4 100644 --- a/sshsha.c +++ b/sshsha.c @@ -461,3 +461,52 @@ const struct ssh_mac ssh_hmac_sha1_96_buggy = { 12, 16, "bug-compatible HMAC-SHA1-96" }; + +#ifdef COMPILER_SUPPORTS_SHA_NI + +/* + * Set target architecture for Clang and GCC + */ +#if !defined(__clang__) && defined(__GNUC__) +# pragma GCC target("sha") +# pragma GCC target("sse4.1") +#endif + +#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5)) +# define FUNC_ISA __attribute__ ((target("sse4.1,sha"))) +#else +# define FUNC_ISA +#endif + +/* + * Determinators of CPU type + */ +#if defined(__clang__) || defined(__GNUC__) + +#include +int supports_sha_ni(void) +{ + unsigned int CPUInfo[4]; + __cpuid_count(7, 0, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]); + return CPUInfo[1] & (1 << 29); /* SHA */ +} + +#else /* defined(__clang__) || defined(__GNUC__) */ + +int supports_sha_ni(void) +{ + unsigned int CPUInfo[4]; + __cpuidex(CPUInfo, 7, 0); + return CPUInfo[1] & (1 << 29); /* Check SHA */ +} + +#endif /* defined(__clang__) || defined(__GNUC__) */ + +#else /* COMPILER_SUPPORTS_AES_NI */ + +int supports_sha_ni(void) +{ + return 0; +} + +#endif /* COMPILER_SUPPORTS_AES_NI */