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