1 /* Copyright 2023 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 * SHA256 implementation using the hardware crypto accelerator.
6 */
7
8 #include "2common.h"
9 #include "2sha.h"
10 #include "2sha_private.h"
11 #include "2api.h"
12
13 struct vb2_sha256_context vb2_sha_ctx;
14
vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,uint32_t data_size)15 vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
16 uint32_t data_size)
17 {
18 int i;
19
20 if (hash_alg != VB2_HASH_SHA256)
21 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
22
23 for (i = 0; i < ARRAY_SIZE(vb2_hash_seq); i++) {
24 VB2_ASSERT(vb2_hash_seq[i] < ARRAY_SIZE(vb2_sha_ctx.h));
25 vb2_sha_ctx.h[vb2_hash_seq[i]] = vb2_sha256_h0[i];
26 }
27
28 vb2_sha_ctx.size = 0;
29 vb2_sha_ctx.total_size = 0;
30 memset(vb2_sha_ctx.block, 0, sizeof(vb2_sha_ctx.block));
31
32 return VB2_SUCCESS;
33 }
34
vb2ex_hwcrypto_digest_extend(const uint8_t * buf,uint32_t size)35 vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
36 {
37 unsigned int remaining_blocks;
38 unsigned int new_size, rem_size, tmp_size;
39 const uint8_t *shifted_data;
40
41 tmp_size = VB2_SHA256_BLOCK_SIZE - vb2_sha_ctx.size;
42 rem_size = size < tmp_size ? size : tmp_size;
43
44 memcpy(&vb2_sha_ctx.block[vb2_sha_ctx.size], buf, rem_size);
45
46 if (vb2_sha_ctx.size + size < VB2_SHA256_BLOCK_SIZE) {
47 vb2_sha_ctx.size += size;
48 return VB2_SUCCESS;
49 }
50
51 new_size = size - rem_size;
52 remaining_blocks = new_size / VB2_SHA256_BLOCK_SIZE;
53
54 shifted_data = buf + rem_size;
55
56 vb2_sha256_transform_hwcrypto(vb2_sha_ctx.block, 1);
57 if (remaining_blocks)
58 vb2_sha256_transform_hwcrypto(shifted_data, remaining_blocks);
59
60 rem_size = new_size % VB2_SHA256_BLOCK_SIZE;
61
62 memcpy(vb2_sha_ctx.block,
63 &shifted_data[remaining_blocks * VB2_SHA256_BLOCK_SIZE],
64 rem_size);
65
66 vb2_sha_ctx.size = rem_size;
67 vb2_sha_ctx.total_size += (remaining_blocks + 1) * VB2_SHA256_BLOCK_SIZE;
68 return VB2_SUCCESS;
69 }
70
vb2ex_hwcrypto_digest_finalize(uint8_t * digest,uint32_t digest_size)71 vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
72 uint32_t digest_size)
73 {
74 unsigned int block_nb;
75 unsigned int pm_size;
76 unsigned int size_b;
77 int i;
78
79 if (digest_size != VB2_SHA256_DIGEST_SIZE) {
80 VB2_DEBUG("ERROR: Digest size does not match expected length.\n");
81 return VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE;
82 }
83
84 block_nb = (1 + ((VB2_SHA256_BLOCK_SIZE - SHA256_MIN_PAD_LEN)
85 < (vb2_sha_ctx.size % VB2_SHA256_BLOCK_SIZE)));
86
87 size_b = (vb2_sha_ctx.total_size + vb2_sha_ctx.size) * 8;
88 pm_size = block_nb * VB2_SHA256_BLOCK_SIZE;
89
90 memset(vb2_sha_ctx.block + vb2_sha_ctx.size, 0,
91 pm_size - vb2_sha_ctx.size);
92 vb2_sha_ctx.block[vb2_sha_ctx.size] = SHA256_PAD_BEGIN;
93 UNPACK32(size_b, vb2_sha_ctx.block + pm_size - 4);
94
95 vb2_sha256_transform_hwcrypto(vb2_sha_ctx.block, block_nb);
96
97 for (i = 0; i < ARRAY_SIZE(vb2_hash_seq); i++) {
98 VB2_ASSERT(vb2_hash_seq[i] < ARRAY_SIZE(vb2_sha_ctx.h));
99 UNPACK32(vb2_sha_ctx.h[vb2_hash_seq[i]], &digest[i * 4]);
100 }
101 return VB2_SUCCESS;
102 }
103