summaryrefslogtreecommitdiffstats
path: root/drivers/nxp/crypto/caam/src/auth/hash.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--drivers/nxp/crypto/caam/src/auth/hash.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/drivers/nxp/crypto/caam/src/auth/hash.c b/drivers/nxp/crypto/caam/src/auth/hash.c
new file mode 100644
index 0000000..1665df1
--- /dev/null
+++ b/drivers/nxp/crypto/caam/src/auth/hash.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include "caam.h"
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+
+#include "hash.h"
+#include "jobdesc.h"
+#include "sec_hw_specific.h"
+
+/* Since no Allocator is available . Taking a global static ctx.
+ * This would mean that only one active ctx can be there at a time.
+ */
+
+static struct hash_ctx glbl_ctx;
+
+static void hash_done(uint32_t *desc, uint32_t status, void *arg,
+ void *job_ring)
+{
+ INFO("Hash Desc SUCCESS with status %x\n", status);
+}
+
+/***************************************************************************
+ * Function : hash_init
+ * Arguments : ctx - SHA context
+ * Return : init,
+ * Description : This function initializes the context for SHA calculation
+ ***************************************************************************/
+int hash_init(enum hash_algo algo, void **ctx)
+{
+ if (glbl_ctx.active == false) {
+ memset(&glbl_ctx, 0, sizeof(struct hash_ctx));
+ glbl_ctx.active = true;
+ glbl_ctx.algo = algo;
+ *ctx = &glbl_ctx;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/***************************************************************************
+ * Function : hash_update
+ * Arguments : ctx - SHA context
+ * buffer - Data
+ * length - Length
+ * Return : -1 on error
+ * 0 on SUCCESS
+ * Description : This function creates SG entry of the data provided
+ ***************************************************************************/
+int hash_update(enum hash_algo algo, void *context, void *data_ptr,
+ unsigned int data_len)
+{
+ struct hash_ctx *ctx = context;
+ /* MAX_SG would be MAX_SG_ENTRIES + key + hdr + sg table */
+ if (ctx->sg_num >= MAX_SG) {
+ ERROR("Reached limit for calling %s\n", __func__);
+ ctx->active = false;
+ return -EINVAL;
+
+ }
+
+ if (ctx->algo != algo) {
+ ERROR("ctx for algo not correct\n");
+ ctx->active = false;
+ return -EINVAL;
+ }
+
+#if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2)
+ flush_dcache_range((uintptr_t)data_ptr, data_len);
+ dmbsy();
+#endif
+
+#ifdef CONFIG_PHYS_64BIT
+ sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_hi,
+ (uint32_t) ((uintptr_t) data_ptr >> 32));
+#else
+ sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_hi, 0x0);
+#endif
+ sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_lo, (uintptr_t) data_ptr);
+
+ sec_out32(&ctx->sg_tbl[ctx->sg_num].len_flag,
+ (data_len & SG_ENTRY_LENGTH_MASK));
+
+ ctx->sg_num++;
+
+ ctx->len += data_len;
+
+ return 0;
+}
+
+/***************************************************************************
+ * Function : hash_final
+ * Arguments : ctx - SHA context
+ * Return : SUCCESS or FAILURE
+ * Description : This function sets the final bit and enqueues the decriptor
+ ***************************************************************************/
+int hash_final(enum hash_algo algo, void *context, void *hash_ptr,
+ unsigned int hash_len)
+{
+ int ret = 0;
+ struct hash_ctx *ctx = context;
+ uint32_t final = 0U;
+
+ struct job_descriptor jobdesc __aligned(CACHE_WRITEBACK_GRANULE);
+
+ jobdesc.arg = NULL;
+ jobdesc.callback = hash_done;
+
+ if (ctx->algo != algo) {
+ ERROR("ctx for algo not correct\n");
+ ctx->active = false;
+ return -EINVAL;
+ }
+
+ final = sec_in32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag) |
+ SG_ENTRY_FINAL_BIT;
+ sec_out32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag, final);
+
+ dsb();
+
+ /* create the hw_rng descriptor */
+ cnstr_hash_jobdesc(jobdesc.desc, (uint8_t *) ctx->sg_tbl,
+ ctx->len, hash_ptr);
+
+#if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2)
+ flush_dcache_range((uintptr_t)ctx->sg_tbl,
+ (sizeof(struct sg_entry) * MAX_SG));
+ inv_dcache_range((uintptr_t)hash_ptr, hash_len);
+
+ dmbsy();
+#endif
+
+ /* Finally, generate the requested random data bytes */
+ ret = run_descriptor_jr(&jobdesc);
+ if (ret != 0) {
+ ERROR("Error in running descriptor\n");
+ ret = -1;
+ }
+ ctx->active = false;
+ return ret;
+}