aboutsummaryrefslogtreecommitdiff
path: root/libbb/hash_hmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/hash_hmac.c')
-rw-r--r--libbb/hash_hmac.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/libbb/hash_hmac.c b/libbb/hash_hmac.c
index 9e48e0f51..b3138029f 100644
--- a/libbb/hash_hmac.c
+++ b/libbb/hash_hmac.c
@@ -18,6 +18,7 @@
18// if we often need HMAC hmac with the same key. 18// if we often need HMAC hmac with the same key.
19// 19//
20// text is often given in disjoint pieces. 20// text is often given in disjoint pieces.
21#if !ENABLE_FEATURE_USE_CNG_API
21void FAST_FUNC hmac_begin(hmac_ctx_t *ctx, const uint8_t *key, unsigned key_size, md5sha_begin_func *begin) 22void FAST_FUNC hmac_begin(hmac_ctx_t *ctx, const uint8_t *key, unsigned key_size, md5sha_begin_func *begin)
22{ 23{
23#if HMAC_ONLY_SHA256 24#if HMAC_ONLY_SHA256
@@ -89,12 +90,58 @@ void FAST_FUNC hmac_hash_v(
89 md5sha_hash(&ctx->hashed_key_xor_ipad, in, size); 90 md5sha_hash(&ctx->hashed_key_xor_ipad, in, size);
90 } 91 }
91} 92}
93#else
94void _hmac_begin(hmac_ctx_t *ctx, uint8_t *key, unsigned key_size,
95 BCRYPT_ALG_HANDLE alg_handle) {
96 DWORD hash_object_length = 0;
97 ULONG _unused;
98 NTSTATUS status;
99
100 status = BCryptGetProperty(alg_handle, BCRYPT_OBJECT_LENGTH,
101 (PUCHAR)&hash_object_length, sizeof(DWORD), &_unused, 0);
102 mingw_die_if_error(status, "BCryptGetProperty");
103 status = BCryptGetProperty(alg_handle, BCRYPT_HASH_LENGTH,
104 (PUCHAR)&ctx->output_size, sizeof(DWORD), &_unused, 0);
105 mingw_die_if_error(status, "BCryptGetProperty");
106
107 ctx->hash_obj = xmalloc(hash_object_length);
108
109 status = BCryptCreateHash(alg_handle, &ctx->handle, ctx->hash_obj,
110 hash_object_length, key, key_size, BCRYPT_HASH_REUSABLE_FLAG);
111 mingw_die_if_error(status, "BCryptCreateHash");
112}
113
114unsigned FAST_FUNC hmac_end(hmac_ctx_t *ctx, uint8_t *out)
115{
116 NTSTATUS status;
117
118 status = BCryptFinishHash(ctx->handle, out, ctx->output_size, 0);
119 mingw_die_if_error(status, "BCryptFinishHash");
120
121 return ctx->output_size;
122}
123
124void FAST_FUNC hmac_hash_v(hmac_ctx_t *ctx, va_list va)
125{
126 uint8_t *in;
127
128 while ((in = va_arg(va, uint8_t*)) != NULL) {
129 unsigned size = va_arg(va, unsigned);
130 BCryptHashData(ctx->handle, in, size, 0);
131 }
132}
133
134void hmac_uninit(hmac_ctx_t *ctx) {
135 BCryptDestroyHash(ctx->handle);
136 free(ctx->hash_obj);
137}
138#endif
92 139
93/* Using HMAC state, make a copy of it (IOW: without affecting this state!) 140/* Using HMAC state, make a copy of it (IOW: without affecting this state!)
94 * hash in the list of (ptr,size) blocks, and finish the HMAC to out[] buffer. 141 * hash in the list of (ptr,size) blocks, and finish the HMAC to out[] buffer.
95 * This function is useful for TLS PRF. 142 * This function is useful for TLS PRF.
96 */ 143 */
97unsigned FAST_FUNC hmac_peek_hash(hmac_ctx_t *ctx, uint8_t *out, ...) 144unsigned hmac_peek_hash(hmac_ctx_t *ctx, uint8_t *out, ...)
98{ 145{
99 hmac_ctx_t tmpctx = *ctx; /* struct copy */ 146 hmac_ctx_t tmpctx = *ctx; /* struct copy */
100 va_list va; 147 va_list va;