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 a23db5152..880ffab01 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -13,6 +13,27 @@ | |||
13 | 13 | ||
14 | #define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA) | 14 | #define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA) |
15 | 15 | ||
16 | #if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL | ||
17 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | ||
18 | static void cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) | ||
19 | { | ||
20 | asm ("cpuid" | ||
21 | : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) | ||
22 | : "0"(*eax), "1"(*ebx), "2"(*ecx), "3"(*edx) | ||
23 | ); | ||
24 | } | ||
25 | static smallint shaNI; | ||
26 | void FAST_FUNC sha1_process_block64_shaNI(sha1_ctx_t *ctx); | ||
27 | void FAST_FUNC sha256_process_block64_shaNI(sha256_ctx_t *ctx); | ||
28 | # if defined(__i386__) | ||
29 | struct ASM_expects_76_shaNI { char t[1 - 2*(offsetof(sha256_ctx_t, hash) != 76)]; }; | ||
30 | # endif | ||
31 | # if defined(__x86_64__) | ||
32 | struct ASM_expects_80_shaNI { char t[1 - 2*(offsetof(sha256_ctx_t, hash) != 80)]; }; | ||
33 | # endif | ||
34 | # endif | ||
35 | #endif | ||
36 | |||
16 | /* gcc 4.2.1 optimizes rotr64 better with inline than with macro | 37 | /* gcc 4.2.1 optimizes rotr64 better with inline than with macro |
17 | * (for rotX32, there is no difference). Why? My guess is that | 38 | * (for rotX32, there is no difference). Why? My guess is that |
18 | * macro requires clever common subexpression elimination heuristics | 39 | * macro requires clever common subexpression elimination heuristics |
@@ -1142,25 +1163,6 @@ static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx) | |||
1142 | } | 1163 | } |
1143 | #endif /* NEED_SHA512 */ | 1164 | #endif /* NEED_SHA512 */ |
1144 | 1165 | ||
1145 | #if ENABLE_SHA1_HWACCEL | ||
1146 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | ||
1147 | static void cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) | ||
1148 | { | ||
1149 | asm ("cpuid" | ||
1150 | : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) | ||
1151 | : "0"(*eax), "1"(*ebx), "2"(*ecx), "3"(*edx) | ||
1152 | ); | ||
1153 | } | ||
1154 | void FAST_FUNC sha1_process_block64_shaNI(sha1_ctx_t *ctx); | ||
1155 | # if defined(__i386__) | ||
1156 | struct ASM_expects_76_shaNI { char t[1 - 2*(offsetof(sha1_ctx_t, hash) != 76)]; }; | ||
1157 | # endif | ||
1158 | # if defined(__x86_64__) | ||
1159 | struct ASM_expects_80_shaNI { char t[1 - 2*(offsetof(sha1_ctx_t, hash) != 80)]; }; | ||
1160 | # endif | ||
1161 | # endif | ||
1162 | #endif | ||
1163 | |||
1164 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | 1166 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) |
1165 | { | 1167 | { |
1166 | ctx->hash[0] = 0x67452301; | 1168 | ctx->hash[0] = 0x67452301; |
@@ -1173,7 +1175,6 @@ void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | |||
1173 | #if ENABLE_SHA1_HWACCEL | 1175 | #if ENABLE_SHA1_HWACCEL |
1174 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | 1176 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) |
1175 | { | 1177 | { |
1176 | static smallint shaNI; | ||
1177 | if (!shaNI) { | 1178 | if (!shaNI) { |
1178 | unsigned eax = 7, ebx = ebx, ecx = 0, edx = edx; | 1179 | unsigned eax = 7, ebx = ebx, ecx = 0, edx = edx; |
1179 | cpuid(&eax, &ebx, &ecx, &edx); | 1180 | cpuid(&eax, &ebx, &ecx, &edx); |
@@ -1225,6 +1226,19 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | |||
1225 | memcpy(&ctx->total64, init256, sizeof(init256)); | 1226 | memcpy(&ctx->total64, init256, sizeof(init256)); |
1226 | /*ctx->total64 = 0; - done by prepending two 32-bit zeros to init256 */ | 1227 | /*ctx->total64 = 0; - done by prepending two 32-bit zeros to init256 */ |
1227 | ctx->process_block = sha256_process_block64; | 1228 | ctx->process_block = sha256_process_block64; |
1229 | #if ENABLE_SHA256_HWACCEL | ||
1230 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | ||
1231 | { | ||
1232 | if (!shaNI) { | ||
1233 | unsigned eax = 7, ebx = ebx, ecx = 0, edx = edx; | ||
1234 | cpuid(&eax, &ebx, &ecx, &edx); | ||
1235 | shaNI = ((ebx >> 29) << 1) - 1; | ||
1236 | } | ||
1237 | if (shaNI > 0) | ||
1238 | ctx->process_block = sha256_process_block64_shaNI; | ||
1239 | } | ||
1240 | # endif | ||
1241 | #endif | ||
1228 | } | 1242 | } |
1229 | 1243 | ||
1230 | #if NEED_SHA512 | 1244 | #if NEED_SHA512 |