1 /*
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
28 static struct hash_ctx glbl_ctx;
29
hash_done(uint32_t * desc,uint32_t status,void * arg,void * job_ring)30 static 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 ***************************************************************************/
hash_init(enum hash_algo algo,void ** ctx)42 int 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 ***************************************************************************/
hash_update(enum hash_algo algo,void * context,void * data_ptr,unsigned int data_len)64 int 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 ***************************************************************************/
hash_final(enum hash_algo algo,void * context,void * hash_ptr,unsigned int hash_len)111 int 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 }
156