diff options
Diffstat (limited to 'libbb/hash_md5_sha.c')
-rw-r--r-- | libbb/hash_md5_sha.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 75a61c32c..abdacf939 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -13,6 +13,90 @@ | |||
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_FEATURE_USE_CNG_API | ||
17 | # include <windows.h> | ||
18 | # include <bcrypt.h> | ||
19 | |||
20 | // these work on Windows >= 10 | ||
21 | # define BCRYPT_MD5_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000021) | ||
22 | # define BCRYPT_SHA1_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000031) | ||
23 | # define BCRYPT_SHA256_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000041) | ||
24 | # define BCRYPT_SHA512_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000061) | ||
25 | |||
26 | # define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) | ||
27 | |||
28 | static void die_if_error(NTSTATUS status, const char *function_name) { | ||
29 | if (!NT_SUCCESS(status)) { | ||
30 | bb_error_msg_and_die("call to %s failed: 0x%08lX", | ||
31 | function_name, (unsigned long)status); | ||
32 | } | ||
33 | } | ||
34 | |||
35 | /* Initialize structure containing state of computation. | ||
36 | * (RFC 1321, 3.3: Step 3) | ||
37 | */ | ||
38 | |||
39 | static void generic_init(struct bcrypt_hash_ctx_t *ctx, BCRYPT_ALG_HANDLE *alg_handle) { | ||
40 | DWORD hash_object_length = 0; | ||
41 | ULONG _unused; | ||
42 | NTSTATUS status; | ||
43 | |||
44 | status = BCryptGetProperty(alg_handle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hash_object_length, sizeof(DWORD), &_unused, 0); | ||
45 | die_if_error(status, "BCryptGetProperty"); | ||
46 | status = BCryptGetProperty(alg_handle, BCRYPT_HASH_LENGTH, (PUCHAR)&ctx->output_size, sizeof(DWORD), &_unused, 0); | ||
47 | die_if_error(status, "BCryptGetProperty"); | ||
48 | |||
49 | |||
50 | ctx->hash_obj = xmalloc(hash_object_length); | ||
51 | |||
52 | status = BCryptCreateHash(alg_handle, &ctx->handle, ctx->hash_obj, hash_object_length, NULL, 0, 0); | ||
53 | die_if_error(status, "BCryptCreateHash"); | ||
54 | } | ||
55 | |||
56 | void FAST_FUNC md5_begin(md5_ctx_t *ctx) | ||
57 | { | ||
58 | generic_init(ctx, BCRYPT_MD5_ALG_HANDLE); | ||
59 | } | ||
60 | |||
61 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | ||
62 | { | ||
63 | generic_init(ctx, BCRYPT_SHA1_ALG_HANDLE); | ||
64 | } | ||
65 | |||
66 | /* Initialize structure containing state of computation. | ||
67 | (FIPS 180-2:5.3.2) */ | ||
68 | void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | ||
69 | { | ||
70 | generic_init(ctx, BCRYPT_SHA256_ALG_HANDLE); | ||
71 | } | ||
72 | |||
73 | #if NEED_SHA512 | ||
74 | /* Initialize structure containing state of computation. | ||
75 | (FIPS 180-2:5.3.3) */ | ||
76 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | ||
77 | { | ||
78 | generic_init(ctx, BCRYPT_SHA512_ALG_HANDLE); | ||
79 | } | ||
80 | #endif /* NEED_SHA512 */ | ||
81 | |||
82 | void FAST_FUNC generic_hash(struct bcrypt_hash_ctx_t *ctx, const void *buffer, size_t len) | ||
83 | { | ||
84 | /* | ||
85 | for perf, no error checking here | ||
86 | */ | ||
87 | /*NTSTATUS status = */ BCryptHashData(ctx->handle, (const PUCHAR)buffer, len, 0); | ||
88 | // die_if_error(status, "BCryptHashData"); | ||
89 | } | ||
90 | |||
91 | unsigned FAST_FUNC generic_end(struct bcrypt_hash_ctx_t *ctx, void *resbuf) | ||
92 | { | ||
93 | NTSTATUS status = BCryptFinishHash(ctx->handle, resbuf, ctx->output_size, 0); | ||
94 | die_if_error(status, "BCryptFinishHash"); | ||
95 | free(ctx->hash_obj); | ||
96 | return ctx->output_size; | ||
97 | } | ||
98 | #endif /* !ENABLE_FEATURE_USE_CNG_API */ | ||
99 | |||
16 | #if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL | 100 | #if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL |
17 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | 101 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) |
18 | static void cpuid_eax_ebx_ecx(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) | 102 | static void cpuid_eax_ebx_ecx(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) |
@@ -80,6 +164,7 @@ static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n) | |||
80 | return (x << n) | (x >> (64 - n)); | 164 | return (x << n) | (x >> (64 - n)); |
81 | } | 165 | } |
82 | 166 | ||
167 | #if !ENABLE_FEATURE_USE_CNG_API | ||
83 | /* Process the remaining bytes in the buffer */ | 168 | /* Process the remaining bytes in the buffer */ |
84 | static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) | 169 | static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) |
85 | { | 170 | { |
@@ -1367,6 +1452,7 @@ unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
1367 | return sizeof(ctx->hash); | 1452 | return sizeof(ctx->hash); |
1368 | } | 1453 | } |
1369 | #endif /* NEED_SHA512 */ | 1454 | #endif /* NEED_SHA512 */ |
1455 | #endif /* !ENABLE_FEATURE_USE_CNG_API */ | ||
1370 | 1456 | ||
1371 | 1457 | ||
1372 | /* | 1458 | /* |