blob: aa78e8a743954d2b7fcdc1c8f1d39d693953e9f9 [file] [log] [blame]
/* Software-based Trusted Platform Module (TPM) Emulator
* Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This module 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.
*
* $Id: hmac.c 364 2010-02-11 10:24:45Z mast $
*/
#include "hmac.h"
#include <string.h>
void tpm_hmac_init(tpm_hmac_ctx_t *ctx, const uint8_t *key, size_t key_len)
{
uint8_t tk[SHA1_DIGEST_LENGTH];
uint8_t k_ipad[HMAC_PAD_LENGTH];
int i;
/* if the key is longer than 64 bytes reset it to key := hash(key) */
if (key_len > HMAC_PAD_LENGTH) {
tpm_sha1_init(&ctx->ctx);
tpm_sha1_update(&ctx->ctx, key, key_len);
tpm_sha1_final(&ctx->ctx, tk);
key = tk;
key_len = SHA1_DIGEST_LENGTH;
}
/* start out by storing key in pads */
memset(k_ipad, 0, HMAC_PAD_LENGTH);
memset(ctx->k_opad, 0, HMAC_PAD_LENGTH);
memcpy(k_ipad, key, key_len);
memcpy(ctx->k_opad, key, key_len);
/* xor key with ipad and opad values */
for (i = 0; i < HMAC_PAD_LENGTH; i++) {
k_ipad[i] ^= 0x36;
ctx->k_opad[i] ^= 0x5C;
}
/* start inner hash */
tpm_sha1_init(&ctx->ctx);
tpm_sha1_update(&ctx->ctx, k_ipad, HMAC_PAD_LENGTH);
}
void tpm_hmac_update(tpm_hmac_ctx_t *ctx, const uint8_t *data, size_t length)
{
/* update inner hash */
tpm_sha1_update(&ctx->ctx, data, length);
}
void tpm_hmac_final(tpm_hmac_ctx_t *ctx, uint8_t *digest)
{
/* complete inner hash */
tpm_sha1_final(&ctx->ctx, digest);
/* perform outer hash */
tpm_sha1_init(&ctx->ctx);
tpm_sha1_update(&ctx->ctx, ctx->k_opad, HMAC_PAD_LENGTH);
tpm_sha1_update(&ctx->ctx, digest, SHA1_DIGEST_LENGTH);
tpm_sha1_final(&ctx->ctx, digest);
}