summaryrefslogtreecommitdiff
path: root/firmware/2lib/2hwcrypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/2lib/2hwcrypto.c')
-rw-r--r--firmware/2lib/2hwcrypto.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/firmware/2lib/2hwcrypto.c b/firmware/2lib/2hwcrypto.c
new file mode 100644
index 00000000..f6cc5241
--- /dev/null
+++ b/firmware/2lib/2hwcrypto.c
@@ -0,0 +1,101 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * SHA256 implementation using the hardware crypto accelerator.
+ */
+
+#include "2common.h"
+#include "2sha.h"
+#include "2sha_private.h"
+#include "2api.h"
+
+struct vb2_sha256_context vb2_sha_ctx;
+
+vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+ uint32_t data_size)
+{
+ int i;
+
+ if (hash_alg != VB2_HASH_SHA256)
+ return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+
+ for (i = 0; i < ARRAY_SIZE(vb2_hash_seq); i++) {
+ VB2_ASSERT(vb2_hash_seq[i] < ARRAY_SIZE(vb2_sha_ctx.h));
+ vb2_sha_ctx.h[vb2_hash_seq[i]] = vb2_sha256_h0[i];
+ }
+
+ vb2_sha_ctx.size = 0;
+ vb2_sha_ctx.total_size = 0;
+ memset(vb2_sha_ctx.block, 0, sizeof(vb2_sha_ctx.block));
+
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
+{
+ unsigned int remaining_blocks;
+ unsigned int new_size, rem_size, tmp_size;
+ const uint8_t *shifted_data;
+
+ tmp_size = VB2_SHA256_BLOCK_SIZE - vb2_sha_ctx.size;
+ rem_size = size < tmp_size ? size : tmp_size;
+
+ memcpy(&vb2_sha_ctx.block[vb2_sha_ctx.size], buf, rem_size);
+
+ if (vb2_sha_ctx.size + size < VB2_SHA256_BLOCK_SIZE) {
+ vb2_sha_ctx.size += size;
+ return VB2_SUCCESS;
+ }
+
+ new_size = size - rem_size;
+ remaining_blocks = new_size / VB2_SHA256_BLOCK_SIZE;
+
+ shifted_data = buf + rem_size;
+
+ vb2_sha256_transform_hwcrypto(vb2_sha_ctx.block, 1);
+ vb2_sha256_transform_hwcrypto(shifted_data, remaining_blocks);
+
+ rem_size = new_size % VB2_SHA256_BLOCK_SIZE;
+
+ memcpy(vb2_sha_ctx.block,
+ &shifted_data[remaining_blocks * VB2_SHA256_BLOCK_SIZE],
+ rem_size);
+
+ vb2_sha_ctx.size = rem_size;
+ vb2_sha_ctx.total_size += (remaining_blocks + 1) * VB2_SHA256_BLOCK_SIZE;
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
+ uint32_t digest_size)
+{
+ unsigned int block_nb;
+ unsigned int pm_size;
+ unsigned int size_b;
+ int i;
+
+ if (digest_size != VB2_SHA256_DIGEST_SIZE) {
+ VB2_DEBUG("ERROR: Digest size does not match expected length.\n");
+ return VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE;
+ }
+
+ block_nb = (1 + ((VB2_SHA256_BLOCK_SIZE - SHA256_MIN_PAD_LEN)
+ < (vb2_sha_ctx.size % VB2_SHA256_BLOCK_SIZE)));
+
+ size_b = (vb2_sha_ctx.total_size + vb2_sha_ctx.size) * 8;
+ pm_size = block_nb * VB2_SHA256_BLOCK_SIZE;
+
+ memset(vb2_sha_ctx.block + vb2_sha_ctx.size, 0,
+ pm_size - vb2_sha_ctx.size);
+ vb2_sha_ctx.block[vb2_sha_ctx.size] = SHA256_PAD_BEGIN;
+ UNPACK32(size_b, vb2_sha_ctx.block + pm_size - 4);
+
+ vb2_sha256_transform_hwcrypto(vb2_sha_ctx.block, block_nb);
+
+ for (i = 0; i < ARRAY_SIZE(vb2_hash_seq); i++) {
+ VB2_ASSERT(vb2_hash_seq[i] < ARRAY_SIZE(vb2_sha_ctx.h));
+ UNPACK32(vb2_sha_ctx.h[vb2_hash_seq[i]], &digest[i * 4]);
+ }
+ return VB2_SUCCESS;
+}