diff options
Diffstat (limited to 'libbb/hash_md5_sha.c')
-rw-r--r-- | libbb/hash_md5_sha.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index a23db51..880ffab 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c @@ -13,6 +13,27 @@ #define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA) +#if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL +# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +static void cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) +{ + asm ("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "0"(*eax), "1"(*ebx), "2"(*ecx), "3"(*edx) + ); +} +static smallint shaNI; +void FAST_FUNC sha1_process_block64_shaNI(sha1_ctx_t *ctx); +void FAST_FUNC sha256_process_block64_shaNI(sha256_ctx_t *ctx); +# if defined(__i386__) +struct ASM_expects_76_shaNI { char t[1 - 2*(offsetof(sha256_ctx_t, hash) != 76)]; }; +# endif +# if defined(__x86_64__) +struct ASM_expects_80_shaNI { char t[1 - 2*(offsetof(sha256_ctx_t, hash) != 80)]; }; +# endif +# endif +#endif + /* gcc 4.2.1 optimizes rotr64 better with inline than with macro * (for rotX32, there is no difference). Why? My guess is that * macro requires clever common subexpression elimination heuristics @@ -1142,25 +1163,6 @@ static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx) } #endif /* NEED_SHA512 */ -#if ENABLE_SHA1_HWACCEL -# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -static void cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) -{ - asm ("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "0"(*eax), "1"(*ebx), "2"(*ecx), "3"(*edx) - ); -} -void FAST_FUNC sha1_process_block64_shaNI(sha1_ctx_t *ctx); -# if defined(__i386__) -struct ASM_expects_76_shaNI { char t[1 - 2*(offsetof(sha1_ctx_t, hash) != 76)]; }; -# endif -# if defined(__x86_64__) -struct ASM_expects_80_shaNI { char t[1 - 2*(offsetof(sha1_ctx_t, hash) != 80)]; }; -# endif -# endif -#endif - void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) { ctx->hash[0] = 0x67452301; @@ -1173,7 +1175,6 @@ void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) #if ENABLE_SHA1_HWACCEL # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) { - static smallint shaNI; if (!shaNI) { unsigned eax = 7, ebx = ebx, ecx = 0, edx = edx; cpuid(&eax, &ebx, &ecx, &edx); @@ -1225,6 +1226,19 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) memcpy(&ctx->total64, init256, sizeof(init256)); /*ctx->total64 = 0; - done by prepending two 32-bit zeros to init256 */ ctx->process_block = sha256_process_block64; +#if ENABLE_SHA256_HWACCEL +# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + { + if (!shaNI) { + unsigned eax = 7, ebx = ebx, ecx = 0, edx = edx; + cpuid(&eax, &ebx, &ecx, &edx); + shaNI = ((ebx >> 29) << 1) - 1; + } + if (shaNI > 0) + ctx->process_block = sha256_process_block64_shaNI; + } +# endif +#endif } #if NEED_SHA512 |