aboutsummaryrefslogtreecommitdiff
path: root/libbb/hash_md5_sha.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libbb/hash_md5_sha.c146
1 files changed, 133 insertions, 13 deletions
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c
index 75a61c32c..fd56d831b 100644
--- a/libbb/hash_md5_sha.c
+++ b/libbb/hash_md5_sha.c
@@ -11,7 +11,93 @@
11#define STR1(s) #s 11#define STR1(s) #s
12#define STR(s) STR1(s) 12#define STR(s) STR1(s)
13 13
14#define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA) 14#define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_SHA384SUM || ENABLE_USE_BB_CRYPT_SHA)
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_SHA384_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000051)
25# define BCRYPT_SHA512_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000061)
26
27/* Initialize structure containing state of computation.
28 * (RFC 1321, 3.3: Step 3)
29 */
30
31static void generic_init(struct bcrypt_hash_ctx_t *ctx, BCRYPT_ALG_HANDLE alg_handle) {
32 DWORD hash_object_length = 0;
33 ULONG _unused;
34 NTSTATUS status;
35
36 status = BCryptGetProperty(alg_handle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hash_object_length, sizeof(DWORD), &_unused, 0);
37 mingw_die_if_error(status, "BCryptGetProperty");
38 status = BCryptGetProperty(alg_handle, BCRYPT_HASH_LENGTH, (PUCHAR)&ctx->output_size, sizeof(DWORD), &_unused, 0);
39 mingw_die_if_error(status, "BCryptGetProperty");
40
41
42 ctx->hash_obj = xmalloc(hash_object_length);
43
44 status = BCryptCreateHash(alg_handle, &ctx->handle, ctx->hash_obj, hash_object_length, NULL, 0, 0);
45 mingw_die_if_error(status, "BCryptCreateHash");
46}
47
48void FAST_FUNC md5_begin(md5_ctx_t *ctx)
49{
50 generic_init(ctx, BCRYPT_MD5_ALG_HANDLE);
51}
52
53void FAST_FUNC sha1_begin(sha1_ctx_t *ctx)
54{
55 generic_init(ctx, BCRYPT_SHA1_ALG_HANDLE);
56}
57
58/* Initialize structure containing state of computation.
59 (FIPS 180-2:5.3.2) */
60void FAST_FUNC sha256_begin(sha256_ctx_t *ctx)
61{
62 generic_init(ctx, BCRYPT_SHA256_ALG_HANDLE);
63}
64
65#if ENABLE_SHA384SUM
66/* Initialize structure containing state of computation.
67 (FIPS 180-2:5.3.3) */
68void FAST_FUNC sha384_begin(sha384_ctx_t *ctx)
69{
70 generic_init(ctx, BCRYPT_SHA384_ALG_HANDLE);
71}
72#endif /* ENABLE_SHA384SUM */
73
74#if NEED_SHA512
75/* Initialize structure containing state of computation.
76 (FIPS 180-2:5.3.4) */
77void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
78{
79 generic_init(ctx, BCRYPT_SHA512_ALG_HANDLE);
80}
81#endif /* NEED_SHA512 */
82
83void FAST_FUNC generic_hash(struct bcrypt_hash_ctx_t *ctx, const void *buffer, size_t len)
84{
85 /*
86 for perf, no error checking here
87 */
88 /*NTSTATUS status = */ BCryptHashData(ctx->handle, (const PUCHAR)buffer, len, 0);
89 // mingw_die_if_error(status, "BCryptHashData");
90}
91
92unsigned FAST_FUNC generic_end(struct bcrypt_hash_ctx_t *ctx, void *resbuf)
93{
94 NTSTATUS status = BCryptFinishHash(ctx->handle, resbuf, ctx->output_size, 0);
95 mingw_die_if_error(status, "BCryptFinishHash");
96 BCryptDestroyHash(ctx->handle);
97 free(ctx->hash_obj);
98 return ctx->output_size;
99}
100#endif /* !ENABLE_FEATURE_USE_CNG_API */
15 101
16#if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL 102#if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL
17# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) 103# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
@@ -80,6 +166,7 @@ static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n)
80 return (x << n) | (x >> (64 - n)); 166 return (x << n) | (x >> (64 - n));
81} 167}
82 168
169#if !ENABLE_FEATURE_USE_CNG_API
83/* Process the remaining bytes in the buffer */ 170/* Process the remaining bytes in the buffer */
84static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) 171static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed)
85{ 172{
@@ -1032,7 +1119,7 @@ static const sha_K_int sha_K[] ALIGN8 = {
1032 K(0x84c87814a1f0ab72ULL), K(0x8cc702081a6439ecULL), 1119 K(0x84c87814a1f0ab72ULL), K(0x8cc702081a6439ecULL),
1033 K(0x90befffa23631e28ULL), K(0xa4506cebde82bde9ULL), 1120 K(0x90befffa23631e28ULL), K(0xa4506cebde82bde9ULL),
1034 K(0xbef9a3f7b2c67915ULL), K(0xc67178f2e372532bULL), 1121 K(0xbef9a3f7b2c67915ULL), K(0xc67178f2e372532bULL),
1035#if NEED_SHA512 /* [64]+ are used for sha512 only */ 1122#if NEED_SHA512 /* [64]+ are used for sha384 and sha512 only */
1036 K(0xca273eceea26619cULL), K(0xd186b8c721c0c207ULL), 1123 K(0xca273eceea26619cULL), K(0xd186b8c721c0c207ULL),
1037 K(0xeada7dd6cde0eb1eULL), K(0xf57d4f7fee6ed178ULL), 1124 K(0xeada7dd6cde0eb1eULL), K(0xf57d4f7fee6ed178ULL),
1038 K(0x06f067aa72176fbaULL), K(0x0a637dc5a2c898a6ULL), 1125 K(0x06f067aa72176fbaULL), K(0x0a637dc5a2c898a6ULL),
@@ -1229,11 +1316,20 @@ static const uint32_t init512_lo[] ALIGN4 = {
1229 0x137e2179, 1316 0x137e2179,
1230}; 1317};
1231#endif /* NEED_SHA512 */ 1318#endif /* NEED_SHA512 */
1232 1319#if ENABLE_SHA384SUM
1233// Note: SHA-384 is identical to SHA-512, except that initial hash values are 1320static const uint64_t init384[] ALIGN8 = {
1234// 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, 1321 0,
1235// 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4, 1322 0,
1236// and the output is constructed by omitting last two 64-bit words of it. 1323 0xcbbb9d5dc1059ed8,
1324 0x629a292a367cd507,
1325 0x9159015a3070dd17,
1326 0x152fecd8f70e5939,
1327 0x67332667ffc00b31,
1328 0x8eb44a8768581511,
1329 0xdb0c2e0d64f98fa7,
1330 0x47b5481dbefa4fa4,
1331};
1332#endif
1237 1333
1238/* Initialize structure containing state of computation. 1334/* Initialize structure containing state of computation.
1239 (FIPS 180-2:5.3.2) */ 1335 (FIPS 180-2:5.3.2) */
@@ -1255,9 +1351,19 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx)
1255#endif 1351#endif
1256} 1352}
1257 1353
1258#if NEED_SHA512 1354#if ENABLE_SHA384SUM
1259/* Initialize structure containing state of computation. 1355/* Initialize structure containing state of computation.
1260 (FIPS 180-2:5.3.3) */ 1356 (FIPS 180-2:5.3.3) */
1357void FAST_FUNC sha384_begin(sha512_ctx_t *ctx)
1358{
1359 memcpy(&ctx->total64, init384, sizeof(init384));
1360 /*ctx->total64[0] = ctx->total64[1] = 0; - already done */
1361}
1362#endif
1363
1364#if NEED_SHA512
1365/* Initialize structure containing state of computation.
1366 (FIPS 180-2:5.3.4) */
1261void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) 1367void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
1262{ 1368{
1263 int i; 1369 int i;
@@ -1332,7 +1438,7 @@ unsigned FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
1332} 1438}
1333 1439
1334#if NEED_SHA512 1440#if NEED_SHA512
1335unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) 1441static unsigned FAST_FUNC sha512384_end(sha512_ctx_t *ctx, void *resbuf, unsigned outsize)
1336{ 1442{
1337 unsigned bufpos = ctx->total64[0] & 127; 1443 unsigned bufpos = ctx->total64[0] & 127;
1338 1444
@@ -1363,11 +1469,22 @@ unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
1363 for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) 1469 for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
1364 ctx->hash[i] = SWAP_BE64(ctx->hash[i]); 1470 ctx->hash[i] = SWAP_BE64(ctx->hash[i]);
1365 } 1471 }
1366 memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); 1472 memcpy(resbuf, ctx->hash, outsize);
1367 return sizeof(ctx->hash); 1473 return outsize;
1474}
1475unsigned FAST_FUNC sha512_end(sha384_ctx_t *ctx, void *resbuf)
1476{
1477 return sha512384_end(ctx, resbuf, SHA512_OUTSIZE);
1368} 1478}
1369#endif /* NEED_SHA512 */ 1479#endif /* NEED_SHA512 */
1370 1480
1481#if ENABLE_SHA384SUM
1482unsigned FAST_FUNC sha384_end(sha384_ctx_t *ctx, void *resbuf)
1483{
1484 return sha512384_end(ctx, resbuf, SHA384_OUTSIZE);
1485}
1486#endif
1487#endif /* !ENABLE_FEATURE_USE_CNG_API */
1371 1488
1372/* 1489/*
1373 * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, 1490 * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
@@ -1904,6 +2021,8 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len)
1904 2021
1905unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) 2022unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
1906{ 2023{
2024 unsigned hash_len;
2025
1907 /* Padding */ 2026 /* Padding */
1908 uint8_t *buf = (uint8_t*)ctx->state; 2027 uint8_t *buf = (uint8_t*)ctx->state;
1909 /* 2028 /*
@@ -1926,6 +2045,7 @@ unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
1926 sha3_process_block72(ctx->state); 2045 sha3_process_block72(ctx->state);
1927 2046
1928 /* Output */ 2047 /* Output */
1929 memcpy(resbuf, ctx->state, 64); 2048 hash_len = (1600/8 - ctx->input_block_bytes) / 2;
1930 return 64; 2049 memcpy(resbuf, ctx->state, hash_len);
2050 return hash_len;
1931} 2051}