Sandboxie/SandboxieTools/ImBox/dc/crypto_fast/sha512_hmac.c

85 lines
2.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*
* Copyright (c) 2013
* ntldr <ntldr@diskcryptor.net> PGP key ID - 0x1B6A24550F33E44A
*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <intrin.h>
#include "sha512_hmac.h"
void _stdcall sha512_hmac_init(sha512_hmac_ctx* ctx, const void* key, size_t keylen)
{
unsigned long i;
// zero-fill initial key state
memset(ctx->padded_key, 0, sizeof(ctx->padded_key));
// compress HMAC key if needed, or copy source key
if (keylen > SHA512_BLOCK_SIZE) {
sha512_init(&ctx->hash);
sha512_hash(&ctx->hash, (const unsigned char*)key, keylen);
sha512_done(&ctx->hash, ctx->padded_key);
} else {
memcpy(ctx->padded_key, key, keylen);
}
// start "inner" hash
for (i = 0; i < (SHA512_BLOCK_SIZE / 4); i++) {
((unsigned long*)ctx->padded_key)[i] ^= 0x36363636;
}
sha512_init(&ctx->hash);
sha512_hash(&ctx->hash, ctx->padded_key, SHA512_BLOCK_SIZE);
}
void _stdcall sha512_hmac_hash(sha512_hmac_ctx* ctx, const void* ptr, size_t length)
{
sha512_hash(&ctx->hash, (const unsigned char*)ptr, length);
}
void _stdcall sha512_hmac_done(sha512_hmac_ctx* ctx, unsigned char* out)
{
unsigned char inner_hash[SHA512_DIGEST_SIZE];
unsigned long i;
// finalize "inner" hash
sha512_done(&ctx->hash, inner_hash);
// calculate "outer" hash
for (i = 0; i < (SHA512_BLOCK_SIZE / 4); i++) {
((unsigned long*)ctx->padded_key)[i] ^= 0x6A6A6A6A; // 0x36 ^ 0x64 = 0x5С
}
sha512_init(&ctx->hash);
sha512_hash(&ctx->hash, ctx->padded_key, SHA512_BLOCK_SIZE);
sha512_hash(&ctx->hash, inner_hash, SHA512_DIGEST_SIZE);
sha512_done(&ctx->hash, out);
// prevent leaks
static_assert( !(sizeof(inner_hash) % sizeof(unsigned long)), "sizeof must be 4 byte aligned");
__stosd((unsigned long*)&inner_hash, 0, (sizeof(inner_hash) / sizeof(unsigned long)));
}
void _stdcall sha512_hmac(const void *k, size_t k_len, const void *d, size_t d_len, unsigned char *out)
{
sha512_hmac_ctx ctx;
sha512_hmac_init(&ctx, k, k_len);
sha512_hmac_hash(&ctx, d, d_len);
sha512_hmac_done(&ctx, out);
// prevent leaks
static_assert( !(sizeof(ctx) % sizeof(unsigned long)), "sizeof must be 4 byte aligned");
__stosd((unsigned long*)&ctx, 0, (sizeof(ctx) / sizeof(unsigned long)));
}