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
60
61
62
63
|
/* 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"
#include "cryptoc/util.h"
/* TODO(sukhomlinov): add support for hardware hmac. */
static void hmac_sha256_init(LITE_HMAC_CTX *ctx, const void *key,
unsigned int len)
{
unsigned int i;
BUILD_ASSERT(sizeof(ctx->opad) >= SHA256_BLOCK_SIZE);
memset(&ctx->opad[0], 0, SHA256_BLOCK_SIZE);
if (len > SHA256_BLOCK_SIZE) {
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 < SHA256_BLOCK_SIZE; ++i)
ctx->opad[i] ^= 0x36;
DCRYPTO_SHA256_init(&ctx->hash, 0);
/* hash ipad */
HASH_update(&ctx->hash, ctx->opad, SHA256_BLOCK_SIZE);
for (i = 0; i < SHA256_BLOCK_SIZE; ++i)
ctx->opad[i] ^= (0x36 ^ 0x5c);
}
void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
unsigned int len)
{
hmac_sha256_init(ctx, key, len);
}
const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_CTX *ctx)
{
uint8_t digest[SHA256_DIGEST_SIZE]; /* up to SHA256 */
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, SHA256_BLOCK_SIZE);
HASH_update(&ctx->hash, digest, HASH_size(&ctx->hash));
always_memset(&ctx->opad[0], 0, SHA256_BLOCK_SIZE); /* wipe key */
return HASH_final(&ctx->hash);
}
|