Merge tag 'xilinx-for-v2025.01-rc3-v2' of https://source.denx.de/u-boot/custodians...
[u-boot.git] / cmd / optee_rpmb.c
blobb155278ee2ad2972e141a079f533ac2f4a64aeb8
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright 2020 NXP
4 */
6 #include <command.h>
7 #include <env.h>
8 #include <errno.h>
9 #include <image.h>
10 #include <malloc.h>
11 #include <mmc.h>
12 #include <tee.h>
13 #include <tee/optee_ta_avb.h>
15 static struct udevice *tee;
16 static u32 session;
18 static int avb_ta_open_session(void)
20 const struct tee_optee_ta_uuid uuid = TA_AVB_UUID;
21 struct tee_open_session_arg arg;
22 int rc;
24 tee = tee_find_device(tee, NULL, NULL, NULL);
25 if (!tee)
26 return -ENODEV;
28 memset(&arg, 0, sizeof(arg));
29 tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
30 rc = tee_open_session(tee, &arg, 0, NULL);
31 if (!rc)
32 session = arg.session;
34 return 0;
37 static int invoke_func(u32 func, ulong num_param, struct tee_param *param)
39 struct tee_invoke_arg arg;
41 if (!tee)
42 if (avb_ta_open_session())
43 return -ENODEV;
45 memset(&arg, 0, sizeof(arg));
46 arg.func = func;
47 arg.session = session;
49 if (tee_invoke_func(tee, &arg, num_param, param))
50 return -EFAULT;
51 switch (arg.ret) {
52 case TEE_SUCCESS:
53 return 0;
54 case TEE_ERROR_OUT_OF_MEMORY:
55 case TEE_ERROR_STORAGE_NO_SPACE:
56 return -ENOSPC;
57 case TEE_ERROR_ITEM_NOT_FOUND:
58 return -EIO;
59 case TEE_ERROR_TARGET_DEAD:
61 * The TA has paniced, close the session to reload the TA
62 * for the next request.
64 tee_close_session(tee, session);
65 tee = NULL;
66 return -EIO;
67 default:
68 return -EIO;
72 static int read_persistent_value(const char *name,
73 size_t buffer_size,
74 u8 *out_buffer,
75 size_t *out_num_bytes_read)
77 int rc = 0;
78 struct tee_shm *shm_name;
79 struct tee_shm *shm_buf;
80 struct tee_param param[2];
81 size_t name_size = strlen(name) + 1;
83 if (!tee)
84 if (avb_ta_open_session())
85 return -ENODEV;
87 rc = tee_shm_alloc(tee, name_size,
88 TEE_SHM_ALLOC, &shm_name);
89 if (rc) {
90 rc = -ENOMEM;
91 goto close_session;
94 rc = tee_shm_alloc(tee, buffer_size,
95 TEE_SHM_ALLOC, &shm_buf);
96 if (rc) {
97 rc = -ENOMEM;
98 goto free_name;
101 memcpy(shm_name->addr, name, name_size);
103 memset(param, 0, sizeof(param));
104 param[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
105 param[0].u.memref.shm = shm_name;
106 param[0].u.memref.size = name_size;
107 param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
108 param[1].u.memref.shm = shm_buf;
109 param[1].u.memref.size = buffer_size;
111 rc = invoke_func(TA_AVB_CMD_READ_PERSIST_VALUE,
112 2, param);
113 if (rc)
114 goto out;
116 if (param[1].u.memref.size > buffer_size) {
117 rc = -EINVAL;
118 goto out;
121 *out_num_bytes_read = param[1].u.memref.size;
123 memcpy(out_buffer, shm_buf->addr, *out_num_bytes_read);
125 out:
126 tee_shm_free(shm_buf);
127 free_name:
128 tee_shm_free(shm_name);
129 close_session:
130 tee_close_session(tee, session);
131 tee = NULL;
133 return rc;
136 static int write_persistent_value(const char *name,
137 size_t value_size,
138 const u8 *value)
140 int rc = 0;
141 struct tee_shm *shm_name;
142 struct tee_shm *shm_buf;
143 struct tee_param param[2];
144 size_t name_size = strlen(name) + 1;
146 if (!value_size)
147 return -EINVAL;
149 if (!tee) {
150 if (avb_ta_open_session())
151 return -ENODEV;
154 rc = tee_shm_alloc(tee, name_size,
155 TEE_SHM_ALLOC, &shm_name);
156 if (rc) {
157 rc = -ENOMEM;
158 goto close_session;
161 rc = tee_shm_alloc(tee, value_size,
162 TEE_SHM_ALLOC, &shm_buf);
163 if (rc) {
164 rc = -ENOMEM;
165 goto free_name;
168 memcpy(shm_name->addr, name, name_size);
169 memcpy(shm_buf->addr, value, value_size);
171 memset(param, 0, sizeof(param));
172 param[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
173 param[0].u.memref.shm = shm_name;
174 param[0].u.memref.size = name_size;
175 param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
176 param[1].u.memref.shm = shm_buf;
177 param[1].u.memref.size = value_size;
179 rc = invoke_func(TA_AVB_CMD_WRITE_PERSIST_VALUE,
180 2, param);
181 if (rc)
182 goto out;
184 out:
185 tee_shm_free(shm_buf);
186 free_name:
187 tee_shm_free(shm_name);
188 close_session:
189 tee_close_session(tee, session);
190 tee = NULL;
192 return rc;
195 int do_optee_rpmb_read(struct cmd_tbl *cmdtp, int flag, int argc,
196 char * const argv[])
198 const char *name;
199 size_t bytes;
200 size_t bytes_read;
201 void *buffer;
202 char *endp;
204 if (argc != 3)
205 return CMD_RET_USAGE;
207 name = argv[1];
208 bytes = dectoul(argv[2], &endp);
209 if (*endp && *endp != '\n')
210 return CMD_RET_USAGE;
212 buffer = malloc(bytes);
213 if (!buffer)
214 return CMD_RET_FAILURE;
216 if (read_persistent_value(name, bytes, buffer, &bytes_read) == 0) {
217 printf("Read %zu bytes, value = %s\n", bytes_read,
218 (char *)buffer);
219 free(buffer);
220 return CMD_RET_SUCCESS;
223 printf("Failed to read persistent value\n");
225 free(buffer);
227 return CMD_RET_FAILURE;
230 int do_optee_rpmb_write(struct cmd_tbl *cmdtp, int flag, int argc,
231 char * const argv[])
233 const char *name;
234 const char *value;
236 if (argc != 3)
237 return CMD_RET_USAGE;
239 name = argv[1];
240 value = argv[2];
242 if (write_persistent_value(name, strlen(value) + 1,
243 (const uint8_t *)value) == 0) {
244 printf("Wrote %zu bytes\n", strlen(value) + 1);
245 return CMD_RET_SUCCESS;
248 printf("Failed to write persistent value\n");
250 return CMD_RET_FAILURE;
253 static struct cmd_tbl cmd_optee_rpmb[] = {
254 U_BOOT_CMD_MKENT(read_pvalue, 3, 0, do_optee_rpmb_read, "", ""),
255 U_BOOT_CMD_MKENT(write_pvalue, 3, 0, do_optee_rpmb_write, "", ""),
258 static int do_optee_rpmb(struct cmd_tbl *cmdtp, int flag, int argc,
259 char * const argv[])
261 struct cmd_tbl *cp;
263 cp = find_cmd_tbl(argv[1], cmd_optee_rpmb, ARRAY_SIZE(cmd_optee_rpmb));
265 argc--;
266 argv++;
268 if (!cp || argc > cp->maxargs)
269 return CMD_RET_USAGE;
271 if (flag == CMD_FLAG_REPEAT)
272 return CMD_RET_FAILURE;
274 return cp->cmd(cmdtp, flag, argc, argv);
277 U_BOOT_CMD (
278 optee_rpmb, 29, 0, do_optee_rpmb,
279 "Provides commands for testing secure storage on RPMB on OPTEE",
280 "read_pvalue <name> <bytes> - read a persistent value <name>\n"
281 "optee_rpmb write_pvalue <name> <value> - write a persistent value <name>\n"