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