summaryrefslogtreecommitdiff
path: root/chip/g/dcrypto/hmac.c
blob: 1c34ddfd966a149f8189495474a310af67f39284 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/* Copyright 2015 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "internal.h"
#include "dcrypto.h"

#include <stdint.h>

#include "cryptoc/sha256.h"

/* TODO(ngm): add support for hardware hmac. */
static void HMAC_init(LITE_HMAC_CTX *ctx, const void *key, unsigned int len)
{
	unsigned int i;

	memset(&ctx->opad[0], 0, sizeof(ctx->opad));

	if (len > sizeof(ctx->opad)) {
		DCRYPTO_SHA256_init(&ctx->hash, 0);
		HASH_update(&ctx->hash, key, len);
		memcpy(&ctx->opad[0], HASH_final(&ctx->hash),
			HASH_size(&ctx->hash));
	} else {
		memcpy(&ctx->opad[0], key, len);
	}

	for (i = 0; i < sizeof(ctx->opad); ++i)
		ctx->opad[i] ^= 0x36;

	DCRYPTO_SHA256_init(&ctx->hash, 0);
	/* hash ipad */
	HASH_update(&ctx->hash, ctx->opad, sizeof(ctx->opad));

	for (i = 0; i < sizeof(ctx->opad); ++i)
		ctx->opad[i] ^= (0x36 ^ 0x5c);
}

void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
			unsigned int len)
{
	DCRYPTO_SHA256_init(&ctx->hash, 0);
	HMAC_init(ctx, key, len);
}

const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_CTX *ctx)
{
	uint8_t digest[SHA_DIGEST_MAX_BYTES];  /* upto SHA2 */

	memcpy(digest, HASH_final(&ctx->hash),
		(HASH_size(&ctx->hash) <= sizeof(digest) ?
			HASH_size(&ctx->hash) : sizeof(digest)));
	DCRYPTO_SHA256_init(&ctx->hash, 0);
	HASH_update(&ctx->hash, ctx->opad, sizeof(ctx->opad));
	HASH_update(&ctx->hash, digest, HASH_size(&ctx->hash));
	memset(&ctx->opad[0], 0, sizeof(ctx->opad));  /* wipe key */
	return HASH_final(&ctx->hash);
}