1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) Foundries Ltd. 2022
4 * Author: Jorge Ramirez <jorge@foundries.io>
5 */
6
7 #include <arm.h>
8 #include <initcall.h>
9 #include <ipi.h>
10 #include <kernel/panic.h>
11 #include <mm/core_memprot.h>
12 #include <string.h>
13 #include <tee/cache.h>
14 #include <util.h>
15
16 #define SEC_MODULE_SHIFT 8
17 #define SEC_MODULE_ID 5
18
19 #define CRYPTO_API_ID(__x) ((SEC_MODULE_ID << SEC_MODULE_SHIFT) | (__x))
20
versal_sha3_request(enum versal_crypto_api id,struct versal_cmd_args * arg)21 static TEE_Result versal_sha3_request(enum versal_crypto_api id,
22 struct versal_cmd_args *arg)
23 {
24 struct versal_ipi_cmd cmd = { };
25 uint32_t a = 0;
26 uint32_t b = 0;
27
28 cmd.data[0] = CRYPTO_API_ID(id);
29
30 if (arg->data[0]) {
31 /* write */
32 reg_pair_from_64(virt_to_phys(arg->ibuf[0].mem.buf), &b, &a);
33 cmd.data[1] = a;
34 cmd.data[2] = b;
35 cmd.data[3] = arg->data[0];
36
37 cmd.ibuf[0].mem = arg->ibuf[0].mem;
38 } else {
39 /* read */
40 reg_pair_from_64(virt_to_phys(arg->ibuf[0].mem.buf), &b, &a);
41 cmd.data[4] = a;
42 cmd.data[5] = b;
43
44 cmd.ibuf[0].mem = arg->ibuf[0].mem;
45 }
46
47 return versal_mbox_notify(&cmd, NULL, NULL);
48 }
49
versal_aes_update_aad_request(enum versal_crypto_api id,struct versal_cmd_args * arg)50 static TEE_Result versal_aes_update_aad_request(enum versal_crypto_api id,
51 struct versal_cmd_args *arg)
52 {
53 struct versal_ipi_cmd cmd = { };
54 uint32_t a = 0;
55 uint32_t b = 0;
56
57 reg_pair_from_64(virt_to_phys(arg->ibuf[0].mem.buf), &b, &a);
58
59 cmd.data[0] = CRYPTO_API_ID(id);
60 cmd.data[1] = a;
61 cmd.data[2] = b;
62 cmd.data[3] = arg->data[0];
63
64 cmd.ibuf[0].mem = arg->ibuf[0].mem;
65
66 return versal_mbox_notify(&cmd, NULL, NULL);
67 }
68
versal_crypto_request(enum versal_crypto_api id,struct versal_cmd_args * arg,uint32_t * err)69 TEE_Result versal_crypto_request(enum versal_crypto_api id,
70 struct versal_cmd_args *arg, uint32_t *err)
71 {
72 struct versal_ipi_cmd cmd = { };
73 uint32_t a = 0;
74 uint32_t b = 0;
75 size_t i = 0;
76
77 if (id == VERSAL_SHA3_UPDATE)
78 return versal_sha3_request(id, arg);
79
80 if (id == VERSAL_AES_UPDATE_AAD)
81 return versal_aes_update_aad_request(id, arg);
82
83 cmd.data[0] = CRYPTO_API_ID(id);
84 for (i = 1; i < arg->dlen + 1; i++)
85 cmd.data[i] = arg->data[i - 1];
86
87 /* src */
88 if (!arg->ibuf[0].mem.buf)
89 goto notify;
90
91 reg_pair_from_64(virt_to_phys(arg->ibuf[0].mem.buf), &b, &a);
92 cmd.data[i++] = a;
93 cmd.data[i++] = b;
94
95 /* dst */
96 if (!arg->ibuf[1].mem.buf)
97 goto cache;
98
99 if (arg->ibuf[1].only_cache)
100 goto cache;
101
102 reg_pair_from_64(virt_to_phys(arg->ibuf[1].mem.buf), &b, &a);
103 cmd.data[i++] = a;
104 cmd.data[i++] = b;
105 cache:
106 for (i = 0; i < VERSAL_MAX_IPI_BUF; i++)
107 cmd.ibuf[i].mem = arg->ibuf[i].mem;
108 notify:
109 return versal_mbox_notify(&cmd, NULL, err);
110 }
111