1 /* Copyright 2016 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include "2hmac.h"
7 #include "2sha.h"
8 #include "2sysincludes.h"
9
vb2_hmac_calculate(bool allow_hwcrypto,enum vb2_hash_algorithm alg,const void * key,uint32_t key_size,const void * msg,uint32_t msg_size,struct vb2_hash * mac)10 int vb2_hmac_calculate(bool allow_hwcrypto, enum vb2_hash_algorithm alg, const void *key,
11 uint32_t key_size, const void *msg, uint32_t msg_size,
12 struct vb2_hash *mac)
13 {
14 uint32_t block_size;
15 uint32_t digest_size;
16 uint8_t k[VB2_MAX_BLOCK_SIZE];
17 uint8_t o_pad[VB2_MAX_BLOCK_SIZE];
18 uint8_t i_pad[VB2_MAX_BLOCK_SIZE];
19 uint8_t b[VB2_MAX_DIGEST_SIZE];
20 struct vb2_digest_context dc;
21 int i;
22
23 if (!key | !msg | !mac)
24 return -1;
25
26 digest_size = vb2_digest_size(alg);
27 block_size = vb2_hash_block_size(alg);
28 if (!digest_size || !block_size)
29 return -1;
30
31 if (key_size > block_size) {
32 vb2_digest_init(&dc, allow_hwcrypto, alg, 0);
33 vb2_digest_extend(&dc, (uint8_t *)key, key_size);
34 vb2_digest_finalize(&dc, k, block_size);
35 key_size = digest_size;
36 } else {
37 memcpy(k, key, key_size);
38 }
39 if (key_size < block_size)
40 memset(k + key_size, 0, block_size - key_size);
41
42 for (i = 0; i < block_size; i++) {
43 o_pad[i] = 0x5c ^ k[i];
44 i_pad[i] = 0x36 ^ k[i];
45 }
46
47 vb2_digest_init(&dc, allow_hwcrypto, alg, 0);
48 vb2_digest_extend(&dc, i_pad, block_size);
49 vb2_digest_extend(&dc, msg, msg_size);
50 vb2_digest_finalize(&dc, b, digest_size);
51
52 vb2_digest_init(&dc, allow_hwcrypto, alg, 0);
53 vb2_digest_extend(&dc, o_pad, block_size);
54 vb2_digest_extend(&dc, b, digest_size);
55 vb2_digest_finalize(&dc, mac->raw, digest_size);
56 mac->algo = alg;
57
58 return 0;
59 }
60