xref: /optee_os/core/drivers/versal_sha3_384.c (revision 4502832d4a4766aa5219a31a4c7983cbbbb59231)
1*4502832dSJorge Ramirez-Ortiz // SPDX-License-Identifier: BSD-2-Clause
2*4502832dSJorge Ramirez-Ortiz /*
3*4502832dSJorge Ramirez-Ortiz  * Copyright (C) Foundries Ltd. 2022
4*4502832dSJorge Ramirez-Ortiz  * Author: Jorge Ramirez <jorge@foundries.io>
5*4502832dSJorge Ramirez-Ortiz  */
6*4502832dSJorge Ramirez-Ortiz 
7*4502832dSJorge Ramirez-Ortiz #include <drivers/versal_sha3_384.h>
8*4502832dSJorge Ramirez-Ortiz #include <initcall.h>
9*4502832dSJorge Ramirez-Ortiz #include <ipi.h>
10*4502832dSJorge Ramirez-Ortiz #include <mm/core_memprot.h>
11*4502832dSJorge Ramirez-Ortiz #include <string.h>
12*4502832dSJorge Ramirez-Ortiz 
13*4502832dSJorge Ramirez-Ortiz #define VERSAL_SHA3_384_FIRST_PACKET		BIT(30)
14*4502832dSJorge Ramirez-Ortiz #define VERSAL_SHA3_384_NEXT_PACKET		BIT(31)
15*4502832dSJorge Ramirez-Ortiz 
16*4502832dSJorge Ramirez-Ortiz static struct mutex lock = MUTEX_INITIALIZER;
17*4502832dSJorge Ramirez-Ortiz static bool engine_ready;
18*4502832dSJorge Ramirez-Ortiz 
input_plaintext(const uint8_t * src,size_t src_len)19*4502832dSJorge Ramirez-Ortiz static TEE_Result input_plaintext(const uint8_t *src, size_t src_len)
20*4502832dSJorge Ramirez-Ortiz {
21*4502832dSJorge Ramirez-Ortiz 	uint32_t first = VERSAL_SHA3_384_FIRST_PACKET;
22*4502832dSJorge Ramirez-Ortiz 	struct versal_cmd_args arg = { .dlen = 1, };
23*4502832dSJorge Ramirez-Ortiz 	struct versal_mbox_mem p = { };
24*4502832dSJorge Ramirez-Ortiz 	TEE_Result ret = TEE_SUCCESS;
25*4502832dSJorge Ramirez-Ortiz 	size_t len = 0;
26*4502832dSJorge Ramirez-Ortiz 	size_t i = 0;
27*4502832dSJorge Ramirez-Ortiz 
28*4502832dSJorge Ramirez-Ortiz 	while (src_len && !ret) {
29*4502832dSJorge Ramirez-Ortiz 		len = MIN(src_len, SMALL_PAGE_SIZE);
30*4502832dSJorge Ramirez-Ortiz 		src_len -= len;
31*4502832dSJorge Ramirez-Ortiz 		versal_mbox_alloc(len, src + i * SMALL_PAGE_SIZE, &p);
32*4502832dSJorge Ramirez-Ortiz 
33*4502832dSJorge Ramirez-Ortiz 		arg.data[0] = first | VERSAL_SHA3_384_NEXT_PACKET | len;
34*4502832dSJorge Ramirez-Ortiz 		arg.ibuf[0].mem = p;
35*4502832dSJorge Ramirez-Ortiz 		ret = versal_crypto_request(VERSAL_SHA3_UPDATE, &arg, NULL);
36*4502832dSJorge Ramirez-Ortiz 		if (ret)
37*4502832dSJorge Ramirez-Ortiz 			EMSG("VERSAL_SHA3_UPDATE [%ld, len = %zu]", i, len);
38*4502832dSJorge Ramirez-Ortiz 
39*4502832dSJorge Ramirez-Ortiz 		free(p.buf);
40*4502832dSJorge Ramirez-Ortiz 		first = 0;
41*4502832dSJorge Ramirez-Ortiz 		i++;
42*4502832dSJorge Ramirez-Ortiz 	}
43*4502832dSJorge Ramirez-Ortiz 
44*4502832dSJorge Ramirez-Ortiz 	return ret;
45*4502832dSJorge Ramirez-Ortiz }
46*4502832dSJorge Ramirez-Ortiz 
get_ciphertext(uint8_t * dst,size_t dst_len)47*4502832dSJorge Ramirez-Ortiz static TEE_Result get_ciphertext(uint8_t *dst, size_t dst_len)
48*4502832dSJorge Ramirez-Ortiz {
49*4502832dSJorge Ramirez-Ortiz 	struct versal_cmd_args arg = { };
50*4502832dSJorge Ramirez-Ortiz 	struct versal_mbox_mem p = { };
51*4502832dSJorge Ramirez-Ortiz 	TEE_Result ret = TEE_SUCCESS;
52*4502832dSJorge Ramirez-Ortiz 
53*4502832dSJorge Ramirez-Ortiz 	versal_mbox_alloc(TEE_SHA384_HASH_SIZE, NULL, &p);
54*4502832dSJorge Ramirez-Ortiz 
55*4502832dSJorge Ramirez-Ortiz 	arg.ibuf[0].mem = p;
56*4502832dSJorge Ramirez-Ortiz 	ret = versal_crypto_request(VERSAL_SHA3_UPDATE, &arg, NULL);
57*4502832dSJorge Ramirez-Ortiz 	if (!ret)
58*4502832dSJorge Ramirez-Ortiz 		memcpy(dst, p.buf, MIN(dst_len, (size_t)TEE_SHA384_HASH_SIZE));
59*4502832dSJorge Ramirez-Ortiz 	else
60*4502832dSJorge Ramirez-Ortiz 		EMSG("VERSAL_SHA3_UPDATE final");
61*4502832dSJorge Ramirez-Ortiz 
62*4502832dSJorge Ramirez-Ortiz 	free(p.buf);
63*4502832dSJorge Ramirez-Ortiz 
64*4502832dSJorge Ramirez-Ortiz 	return ret;
65*4502832dSJorge Ramirez-Ortiz }
66*4502832dSJorge Ramirez-Ortiz 
versal_sha3_384(const uint8_t * src,size_t src_len,uint8_t * dst,size_t dst_len)67*4502832dSJorge Ramirez-Ortiz TEE_Result versal_sha3_384(const uint8_t *src, size_t src_len,
68*4502832dSJorge Ramirez-Ortiz 			   uint8_t *dst, size_t dst_len)
69*4502832dSJorge Ramirez-Ortiz {
70*4502832dSJorge Ramirez-Ortiz 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
71*4502832dSJorge Ramirez-Ortiz 
72*4502832dSJorge Ramirez-Ortiz 	if (!src_len || !dst_len || !src || !dst)
73*4502832dSJorge Ramirez-Ortiz 		return ret;
74*4502832dSJorge Ramirez-Ortiz 
75*4502832dSJorge Ramirez-Ortiz 	if (!engine_ready)
76*4502832dSJorge Ramirez-Ortiz 		return TEE_ERROR_BAD_STATE;
77*4502832dSJorge Ramirez-Ortiz 
78*4502832dSJorge Ramirez-Ortiz 	mutex_lock(&lock);
79*4502832dSJorge Ramirez-Ortiz 
80*4502832dSJorge Ramirez-Ortiz 	ret = input_plaintext(src, src_len);
81*4502832dSJorge Ramirez-Ortiz 	if (!ret)
82*4502832dSJorge Ramirez-Ortiz 		ret = get_ciphertext(dst, dst_len);
83*4502832dSJorge Ramirez-Ortiz 
84*4502832dSJorge Ramirez-Ortiz 	mutex_unlock(&lock);
85*4502832dSJorge Ramirez-Ortiz 
86*4502832dSJorge Ramirez-Ortiz 	return ret;
87*4502832dSJorge Ramirez-Ortiz }
88*4502832dSJorge Ramirez-Ortiz 
versal_sha3_384_init(void)89*4502832dSJorge Ramirez-Ortiz static TEE_Result versal_sha3_384_init(void)
90*4502832dSJorge Ramirez-Ortiz {
91*4502832dSJorge Ramirez-Ortiz 	struct versal_cmd_args arg = { };
92*4502832dSJorge Ramirez-Ortiz 	TEE_Result ret = TEE_SUCCESS;
93*4502832dSJorge Ramirez-Ortiz 
94*4502832dSJorge Ramirez-Ortiz 	ret = versal_crypto_request(VERSAL_SHA3_KAT, &arg, NULL);
95*4502832dSJorge Ramirez-Ortiz 	if (!ret)
96*4502832dSJorge Ramirez-Ortiz 		engine_ready = true;
97*4502832dSJorge Ramirez-Ortiz 
98*4502832dSJorge Ramirez-Ortiz 	return ret;
99*4502832dSJorge Ramirez-Ortiz }
100*4502832dSJorge Ramirez-Ortiz 
101*4502832dSJorge Ramirez-Ortiz /* Be available for the HUK */
102*4502832dSJorge Ramirez-Ortiz service_init(versal_sha3_384_init);
103