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