You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

66 lines
2.3 KiB

/* MIT (BSD) license - see LICENSE file for details */
/* HMAC code adapted from the Bitcoin project's C++:
*
* src/crypto/hmac_sha512.cpp f914f1a746d7f91951c1da262a4a749dd3ebfa71
* Copyright (c) 2014 The Bitcoin Core developers
* Distributed under the MIT software license, see the accompanying
* file COPYING or http://www.opensource.org/licenses/mit-license.php.
*
* https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
*/
static void SHA_PRE(_mix)(struct SHA_T *sha, const unsigned char *pad,
const unsigned char *data, size_t data_len)
{
struct SHA_PRE(_ctx) ctx;
SHA_PRE(_init)(&ctx);
SHA_PRE(_update)(&ctx, pad, sizeof(ctx.buf));
SHA_PRE(_update)(&ctx, data, data_len);
SHA_PRE(_done)(&ctx, sha);
clear(&ctx, sizeof(ctx));
}
void HMAC_FUNCTION(struct SHA_T *sha,
const unsigned char *key, size_t key_len,
const unsigned char *msg, size_t msg_len)
{
struct SHA_PRE(_ctx) ctx;
unsigned char ipad[sizeof(ctx.buf)];
unsigned char opad[sizeof(ctx.buf)];
size_t i;
clear(ctx.buf.u8, sizeof(ctx.buf));
if (key_len <= sizeof(ctx.buf))
memcpy(ctx.buf.u8, key, key_len);
else
SHA_T((struct SHA_T *)ctx.buf.SHA_CTX_MEMBER, key, key_len);
for (i = 0; i < sizeof(ctx.buf); ++i) {
opad[i] = ctx.buf.u8[i] ^ 0x5c;
ipad[i] = ctx.buf.u8[i] ^ 0x36;
}
SHA_PRE(_mix)((struct SHA_T *)ctx.buf.SHA_CTX_MEMBER, ipad, msg, msg_len);
SHA_PRE(_mix)(sha, opad, ctx.buf.u8, sizeof(*sha));
clear_n(3, &ctx, sizeof(ctx), ipad, sizeof(ipad), opad, sizeof(opad));
}
int WALLY_HMAC_FUNCTION(const unsigned char *key, size_t key_len,
const unsigned char *bytes_in, size_t len_in,
unsigned char *bytes_out, size_t len)
{
struct SHA_T sha;
bool aligned = alignment_ok(bytes_out, sizeof(sha.u.SHA_CTX_MEMBER));
struct SHA_T *sha_p = aligned ? (struct SHA_T *)bytes_out : &sha;
if (!key || !key_len || !bytes_in || !len_in ||
!bytes_out || len != sizeof(struct SHA_T))
return WALLY_EINVAL;
HMAC_FUNCTION(sha_p, key, key_len, bytes_in, len_in);
if (!aligned) {
memcpy(bytes_out, sha_p, sizeof(*sha_p));
clear(sha_p, sizeof(*sha_p));
}
return WALLY_OK;
}