blob: 1665df1a86153c4cbcad8feaf5203d5d61988ed3 [file] [log] [blame]
Pankaj Gupta95c7eee2020-12-09 14:02:39 +05301/*
2 * Copyright 2021 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <errno.h>
9#include <stdbool.h>
10#include <stdint.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include <arch_helpers.h>
16#include "caam.h"
17#include <common/debug.h>
18#include <drivers/auth/crypto_mod.h>
19
20#include "hash.h"
21#include "jobdesc.h"
22#include "sec_hw_specific.h"
23
24/* Since no Allocator is available . Taking a global static ctx.
25 * This would mean that only one active ctx can be there at a time.
26 */
27
28static struct hash_ctx glbl_ctx;
29
30static void hash_done(uint32_t *desc, uint32_t status, void *arg,
31 void *job_ring)
32{
33 INFO("Hash Desc SUCCESS with status %x\n", status);
34}
35
36/***************************************************************************
37 * Function : hash_init
38 * Arguments : ctx - SHA context
39 * Return : init,
40 * Description : This function initializes the context for SHA calculation
41 ***************************************************************************/
42int hash_init(enum hash_algo algo, void **ctx)
43{
44 if (glbl_ctx.active == false) {
45 memset(&glbl_ctx, 0, sizeof(struct hash_ctx));
46 glbl_ctx.active = true;
47 glbl_ctx.algo = algo;
48 *ctx = &glbl_ctx;
49 return 0;
50 } else {
51 return -1;
52 }
53}
54
55/***************************************************************************
56 * Function : hash_update
57 * Arguments : ctx - SHA context
58 * buffer - Data
59 * length - Length
60 * Return : -1 on error
61 * 0 on SUCCESS
62 * Description : This function creates SG entry of the data provided
63 ***************************************************************************/
64int hash_update(enum hash_algo algo, void *context, void *data_ptr,
65 unsigned int data_len)
66{
67 struct hash_ctx *ctx = context;
68 /* MAX_SG would be MAX_SG_ENTRIES + key + hdr + sg table */
69 if (ctx->sg_num >= MAX_SG) {
70 ERROR("Reached limit for calling %s\n", __func__);
71 ctx->active = false;
72 return -EINVAL;
73
74 }
75
76 if (ctx->algo != algo) {
77 ERROR("ctx for algo not correct\n");
78 ctx->active = false;
79 return -EINVAL;
80 }
81
82#if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2)
83 flush_dcache_range((uintptr_t)data_ptr, data_len);
84 dmbsy();
85#endif
86
87#ifdef CONFIG_PHYS_64BIT
88 sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_hi,
89 (uint32_t) ((uintptr_t) data_ptr >> 32));
90#else
91 sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_hi, 0x0);
92#endif
93 sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_lo, (uintptr_t) data_ptr);
94
95 sec_out32(&ctx->sg_tbl[ctx->sg_num].len_flag,
96 (data_len & SG_ENTRY_LENGTH_MASK));
97
98 ctx->sg_num++;
99
100 ctx->len += data_len;
101
102 return 0;
103}
104
105/***************************************************************************
106 * Function : hash_final
107 * Arguments : ctx - SHA context
108 * Return : SUCCESS or FAILURE
109 * Description : This function sets the final bit and enqueues the decriptor
110 ***************************************************************************/
111int hash_final(enum hash_algo algo, void *context, void *hash_ptr,
112 unsigned int hash_len)
113{
114 int ret = 0;
115 struct hash_ctx *ctx = context;
116 uint32_t final = 0U;
117
118 struct job_descriptor jobdesc __aligned(CACHE_WRITEBACK_GRANULE);
119
120 jobdesc.arg = NULL;
121 jobdesc.callback = hash_done;
122
123 if (ctx->algo != algo) {
124 ERROR("ctx for algo not correct\n");
125 ctx->active = false;
126 return -EINVAL;
127 }
128
129 final = sec_in32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag) |
130 SG_ENTRY_FINAL_BIT;
131 sec_out32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag, final);
132
133 dsb();
134
135 /* create the hw_rng descriptor */
136 cnstr_hash_jobdesc(jobdesc.desc, (uint8_t *) ctx->sg_tbl,
137 ctx->len, hash_ptr);
138
139#if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2)
140 flush_dcache_range((uintptr_t)ctx->sg_tbl,
141 (sizeof(struct sg_entry) * MAX_SG));
142 inv_dcache_range((uintptr_t)hash_ptr, hash_len);
143
144 dmbsy();
145#endif
146
147 /* Finally, generate the requested random data bytes */
148 ret = run_descriptor_jr(&jobdesc);
149 if (ret != 0) {
150 ERROR("Error in running descriptor\n");
151 ret = -1;
152 }
153 ctx->active = false;
154 return ret;
155}