sandbox.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2018 Linaro Limited
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <sandboxtee.h>
  8. #include <tee.h>
  9. #include <tee/optee_ta_avb.h>
  10. /*
  11. * The sandbox tee driver tries to emulate a generic Trusted Exectution
  12. * Environment (TEE) with the Trusted Application (TA) OPTEE_TA_AVB
  13. * available.
  14. */
  15. static const u32 pstorage_max = 16;
  16. /**
  17. * struct ta_entry - TA entries
  18. * @uuid: UUID of an emulated TA
  19. * @open_session Called when a session is openened to the TA
  20. * @invoke_func Called when a function in the TA is to be invoked
  21. *
  22. * This struct is used to register TAs in this sandbox emulation of a TEE.
  23. */
  24. struct ta_entry {
  25. struct tee_optee_ta_uuid uuid;
  26. u32 (*open_session)(struct udevice *dev, uint num_params,
  27. struct tee_param *params);
  28. u32 (*invoke_func)(struct udevice *dev,
  29. u32 func, uint num_params,
  30. struct tee_param *params);
  31. };
  32. #ifdef CONFIG_OPTEE_TA_AVB
  33. static u32 get_attr(uint n, uint num_params, struct tee_param *params)
  34. {
  35. if (n >= num_params)
  36. return TEE_PARAM_ATTR_TYPE_NONE;
  37. return params[n].attr;
  38. }
  39. static u32 check_params(u8 p0, u8 p1, u8 p2, u8 p3, uint num_params,
  40. struct tee_param *params)
  41. {
  42. u8 p[] = { p0, p1, p2, p3};
  43. uint n;
  44. for (n = 0; n < ARRAY_SIZE(p); n++)
  45. if (p[n] != get_attr(n, num_params, params))
  46. goto bad_params;
  47. for (; n < num_params; n++)
  48. if (get_attr(n, num_params, params))
  49. goto bad_params;
  50. return TEE_SUCCESS;
  51. bad_params:
  52. printf("Bad param attrs\n");
  53. return TEE_ERROR_BAD_PARAMETERS;
  54. }
  55. static u32 ta_avb_open_session(struct udevice *dev, uint num_params,
  56. struct tee_param *params)
  57. {
  58. /*
  59. * We don't expect additional parameters when opening a session to
  60. * this TA.
  61. */
  62. return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
  63. TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
  64. num_params, params);
  65. }
  66. static u32 ta_avb_invoke_func(struct udevice *dev, u32 func, uint num_params,
  67. struct tee_param *params)
  68. {
  69. struct sandbox_tee_state *state = dev_get_priv(dev);
  70. ENTRY e, *ep;
  71. char *name;
  72. u32 res;
  73. uint slot;
  74. u64 val;
  75. char *value;
  76. u32 value_sz;
  77. switch (func) {
  78. case TA_AVB_CMD_READ_ROLLBACK_INDEX:
  79. res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
  80. TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT,
  81. TEE_PARAM_ATTR_TYPE_NONE,
  82. TEE_PARAM_ATTR_TYPE_NONE,
  83. num_params, params);
  84. if (res)
  85. return res;
  86. slot = params[0].u.value.a;
  87. if (slot >= ARRAY_SIZE(state->ta_avb_rollback_indexes)) {
  88. printf("Rollback index slot out of bounds %u\n", slot);
  89. return TEE_ERROR_BAD_PARAMETERS;
  90. }
  91. val = state->ta_avb_rollback_indexes[slot];
  92. params[1].u.value.a = val >> 32;
  93. params[1].u.value.b = val;
  94. return TEE_SUCCESS;
  95. case TA_AVB_CMD_WRITE_ROLLBACK_INDEX:
  96. res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
  97. TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
  98. TEE_PARAM_ATTR_TYPE_NONE,
  99. TEE_PARAM_ATTR_TYPE_NONE,
  100. num_params, params);
  101. if (res)
  102. return res;
  103. slot = params[0].u.value.a;
  104. if (slot >= ARRAY_SIZE(state->ta_avb_rollback_indexes)) {
  105. printf("Rollback index slot out of bounds %u\n", slot);
  106. return TEE_ERROR_BAD_PARAMETERS;
  107. }
  108. val = (u64)params[1].u.value.a << 32 | params[1].u.value.b;
  109. if (val < state->ta_avb_rollback_indexes[slot])
  110. return TEE_ERROR_SECURITY;
  111. state->ta_avb_rollback_indexes[slot] = val;
  112. return TEE_SUCCESS;
  113. case TA_AVB_CMD_READ_LOCK_STATE:
  114. res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT,
  115. TEE_PARAM_ATTR_TYPE_NONE,
  116. TEE_PARAM_ATTR_TYPE_NONE,
  117. TEE_PARAM_ATTR_TYPE_NONE,
  118. num_params, params);
  119. if (res)
  120. return res;
  121. params[0].u.value.a = state->ta_avb_lock_state;
  122. return TEE_SUCCESS;
  123. case TA_AVB_CMD_WRITE_LOCK_STATE:
  124. res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
  125. TEE_PARAM_ATTR_TYPE_NONE,
  126. TEE_PARAM_ATTR_TYPE_NONE,
  127. TEE_PARAM_ATTR_TYPE_NONE,
  128. num_params, params);
  129. if (res)
  130. return res;
  131. if (state->ta_avb_lock_state != params[0].u.value.a) {
  132. state->ta_avb_lock_state = params[0].u.value.a;
  133. memset(state->ta_avb_rollback_indexes, 0,
  134. sizeof(state->ta_avb_rollback_indexes));
  135. }
  136. return TEE_SUCCESS;
  137. case TA_AVB_CMD_READ_PERSIST_VALUE:
  138. res = check_params(TEE_PARAM_ATTR_TYPE_MEMREF_INPUT,
  139. TEE_PARAM_ATTR_TYPE_MEMREF_INOUT,
  140. TEE_PARAM_ATTR_TYPE_NONE,
  141. TEE_PARAM_ATTR_TYPE_NONE,
  142. num_params, params);
  143. if (res)
  144. return res;
  145. name = params[0].u.memref.shm->addr;
  146. value = params[1].u.memref.shm->addr;
  147. value_sz = params[1].u.memref.size;
  148. e.key = name;
  149. e.data = NULL;
  150. hsearch_r(e, FIND, &ep, &state->pstorage_htab, 0);
  151. if (!ep)
  152. return TEE_ERROR_ITEM_NOT_FOUND;
  153. value_sz = strlen(ep->data);
  154. memcpy(value, ep->data, value_sz);
  155. return TEE_SUCCESS;
  156. case TA_AVB_CMD_WRITE_PERSIST_VALUE:
  157. res = check_params(TEE_PARAM_ATTR_TYPE_MEMREF_INPUT,
  158. TEE_PARAM_ATTR_TYPE_MEMREF_INPUT,
  159. TEE_PARAM_ATTR_TYPE_NONE,
  160. TEE_PARAM_ATTR_TYPE_NONE,
  161. num_params, params);
  162. if (res)
  163. return res;
  164. name = params[0].u.memref.shm->addr;
  165. value = params[1].u.memref.shm->addr;
  166. value_sz = params[1].u.memref.size;
  167. e.key = name;
  168. e.data = NULL;
  169. hsearch_r(e, FIND, &ep, &state->pstorage_htab, 0);
  170. if (ep)
  171. hdelete_r(e.key, &state->pstorage_htab, 0);
  172. e.key = name;
  173. e.data = value;
  174. hsearch_r(e, ENTER, &ep, &state->pstorage_htab, 0);
  175. if (!ep)
  176. return TEE_ERROR_OUT_OF_MEMORY;
  177. return TEE_SUCCESS;
  178. default:
  179. return TEE_ERROR_NOT_SUPPORTED;
  180. }
  181. }
  182. #endif /*OPTEE_TA_AVB*/
  183. static const struct ta_entry ta_entries[] = {
  184. #ifdef CONFIG_OPTEE_TA_AVB
  185. { .uuid = TA_AVB_UUID,
  186. .open_session = ta_avb_open_session,
  187. .invoke_func = ta_avb_invoke_func,
  188. },
  189. #endif
  190. };
  191. static void sandbox_tee_get_version(struct udevice *dev,
  192. struct tee_version_data *vers)
  193. {
  194. struct tee_version_data v = {
  195. .gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM,
  196. };
  197. *vers = v;
  198. }
  199. static int sandbox_tee_close_session(struct udevice *dev, u32 session)
  200. {
  201. struct sandbox_tee_state *state = dev_get_priv(dev);
  202. if (!state->ta || state->session != session)
  203. return -EINVAL;
  204. state->session = 0;
  205. state->ta = NULL;
  206. return 0;
  207. }
  208. static const struct ta_entry *find_ta_entry(u8 uuid[TEE_UUID_LEN])
  209. {
  210. struct tee_optee_ta_uuid u;
  211. uint n;
  212. tee_optee_ta_uuid_from_octets(&u, uuid);
  213. for (n = 0; n < ARRAY_SIZE(ta_entries); n++)
  214. if (!memcmp(&u, &ta_entries[n].uuid, sizeof(u)))
  215. return ta_entries + n;
  216. return NULL;
  217. }
  218. static int sandbox_tee_open_session(struct udevice *dev,
  219. struct tee_open_session_arg *arg,
  220. uint num_params, struct tee_param *params)
  221. {
  222. struct sandbox_tee_state *state = dev_get_priv(dev);
  223. const struct ta_entry *ta;
  224. if (state->ta) {
  225. printf("A session is already open\n");
  226. return -EBUSY;
  227. }
  228. ta = find_ta_entry(arg->uuid);
  229. if (!ta) {
  230. printf("Cannot find TA\n");
  231. arg->ret = TEE_ERROR_ITEM_NOT_FOUND;
  232. arg->ret_origin = TEE_ORIGIN_TEE;
  233. return 0;
  234. }
  235. arg->ret = ta->open_session(dev, num_params, params);
  236. arg->ret_origin = TEE_ORIGIN_TRUSTED_APP;
  237. if (!arg->ret) {
  238. state->ta = (void *)ta;
  239. state->session = 1;
  240. arg->session = state->session;
  241. } else {
  242. printf("Cannot open session, TA returns error\n");
  243. }
  244. return 0;
  245. }
  246. static int sandbox_tee_invoke_func(struct udevice *dev,
  247. struct tee_invoke_arg *arg,
  248. uint num_params, struct tee_param *params)
  249. {
  250. struct sandbox_tee_state *state = dev_get_priv(dev);
  251. struct ta_entry *ta = state->ta;
  252. if (!arg->session) {
  253. printf("Missing session\n");
  254. return -EINVAL;
  255. }
  256. if (!ta) {
  257. printf("TA session not available\n");
  258. return -EINVAL;
  259. }
  260. if (arg->session != state->session) {
  261. printf("Session mismatch\n");
  262. return -EINVAL;
  263. }
  264. arg->ret = ta->invoke_func(dev, arg->func, num_params, params);
  265. arg->ret_origin = TEE_ORIGIN_TRUSTED_APP;
  266. return 0;
  267. }
  268. static int sandbox_tee_shm_register(struct udevice *dev, struct tee_shm *shm)
  269. {
  270. struct sandbox_tee_state *state = dev_get_priv(dev);
  271. state->num_shms++;
  272. return 0;
  273. }
  274. static int sandbox_tee_shm_unregister(struct udevice *dev, struct tee_shm *shm)
  275. {
  276. struct sandbox_tee_state *state = dev_get_priv(dev);
  277. state->num_shms--;
  278. return 0;
  279. }
  280. static int sandbox_tee_remove(struct udevice *dev)
  281. {
  282. struct sandbox_tee_state *state = dev_get_priv(dev);
  283. hdestroy_r(&state->pstorage_htab);
  284. return 0;
  285. }
  286. static int sandbox_tee_probe(struct udevice *dev)
  287. {
  288. struct sandbox_tee_state *state = dev_get_priv(dev);
  289. /*
  290. * With this hastable we emulate persistent storage,
  291. * which should contain persistent values
  292. * between different sessions/command invocations.
  293. */
  294. if (!hcreate_r(pstorage_max, &state->pstorage_htab))
  295. return TEE_ERROR_OUT_OF_MEMORY;
  296. return 0;
  297. }
  298. static const struct tee_driver_ops sandbox_tee_ops = {
  299. .get_version = sandbox_tee_get_version,
  300. .open_session = sandbox_tee_open_session,
  301. .close_session = sandbox_tee_close_session,
  302. .invoke_func = sandbox_tee_invoke_func,
  303. .shm_register = sandbox_tee_shm_register,
  304. .shm_unregister = sandbox_tee_shm_unregister,
  305. };
  306. static const struct udevice_id sandbox_tee_match[] = {
  307. { .compatible = "sandbox,tee" },
  308. {},
  309. };
  310. U_BOOT_DRIVER(sandbox_tee) = {
  311. .name = "sandbox_tee",
  312. .id = UCLASS_TEE,
  313. .of_match = sandbox_tee_match,
  314. .ops = &sandbox_tee_ops,
  315. .priv_auto_alloc_size = sizeof(struct sandbox_tee_state),
  316. .probe = sandbox_tee_probe,
  317. .remove = sandbox_tee_remove,
  318. };