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