tee.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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 <log.h>
  8. #include <malloc.h>
  9. #include <dm/test.h>
  10. #include <sandboxtee.h>
  11. #include <tee.h>
  12. #include <test/test.h>
  13. #include <test/ut.h>
  14. #include <tee/optee_ta_avb.h>
  15. #include <tee/optee_ta_rpc_test.h>
  16. static int open_session(struct udevice *dev, u32 *session,
  17. struct tee_optee_ta_uuid *uuid)
  18. {
  19. struct tee_open_session_arg arg;
  20. int rc;
  21. memset(&arg, 0, sizeof(arg));
  22. tee_optee_ta_uuid_to_octets(arg.uuid, uuid);
  23. rc = tee_open_session(dev, &arg, 0, NULL);
  24. if (rc)
  25. return rc;
  26. if (arg.ret)
  27. return -EIO;
  28. *session = arg.session;
  29. return 0;
  30. }
  31. static int invoke_func_avb(struct udevice *dev, u32 session)
  32. {
  33. struct tee_param param = { .attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT };
  34. struct tee_invoke_arg arg;
  35. memset(&arg, 0, sizeof(arg));
  36. arg.session = session;
  37. arg.func = TA_AVB_CMD_READ_LOCK_STATE;
  38. if (tee_invoke_func(dev, &arg, 1, &param) || arg.ret)
  39. return -1;
  40. return 0;
  41. }
  42. static int invoke_func_rpc_test(struct udevice *dev, u32 session,
  43. u64 op, u64 busnum, u64 chip_addr,
  44. u64 xfer_flags, u8 *buf, size_t buf_size)
  45. {
  46. struct tee_param param[2];
  47. struct tee_invoke_arg arg;
  48. struct tee_shm *shm_buf;
  49. int rc;
  50. memset(&arg, 0, sizeof(arg));
  51. arg.session = session;
  52. arg.func = op;
  53. rc = tee_shm_alloc(dev, buf_size,
  54. TEE_SHM_ALLOC, &shm_buf);
  55. if (rc)
  56. return rc;
  57. if (op == TA_RPC_TEST_CMD_I2C_WRITE)
  58. memcpy(shm_buf->addr, buf, buf_size);
  59. memset(param, 0, sizeof(param));
  60. param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
  61. param[0].u.value.a = busnum;
  62. param[0].u.value.b = chip_addr;
  63. param[0].u.value.c = xfer_flags;
  64. param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
  65. param[1].u.memref.shm = shm_buf;
  66. param[1].u.memref.size = buf_size;
  67. if (tee_invoke_func(dev, &arg, 2, param) || arg.ret) {
  68. rc = -1;
  69. goto out;
  70. }
  71. if (op == TA_RPC_TEST_CMD_I2C_READ)
  72. memcpy(buf, shm_buf->addr, buf_size);
  73. out:
  74. tee_shm_free(shm_buf);
  75. return rc;
  76. }
  77. static int match(struct tee_version_data *vers, const void *data)
  78. {
  79. return vers->gen_caps & TEE_GEN_CAP_GP;
  80. }
  81. struct test_tee_vars {
  82. struct tee_shm *reg_shm;
  83. struct tee_shm *alloc_shm;
  84. };
  85. static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
  86. {
  87. struct tee_version_data vers;
  88. struct udevice *dev;
  89. struct sandbox_tee_state *state;
  90. struct tee_optee_ta_uuid avb_uuid = TA_AVB_UUID;
  91. u32 session = 0;
  92. int rc;
  93. u8 data[128];
  94. dev = tee_find_device(NULL, match, NULL, &vers);
  95. ut_assert(dev);
  96. state = dev_get_priv(dev);
  97. ut_assert(!state->session);
  98. rc = open_session(dev, &session, &avb_uuid);
  99. ut_assert(!rc);
  100. ut_assert(session == state->session);
  101. rc = invoke_func_avb(dev, session);
  102. ut_assert(!rc);
  103. rc = tee_close_session(dev, session);
  104. ut_assert(!rc);
  105. ut_assert(!state->session);
  106. ut_assert(!state->num_shms);
  107. rc = tee_shm_register(dev, data, sizeof(data), 0, &vars->reg_shm);
  108. ut_assert(!rc);
  109. ut_assert(state->num_shms == 1);
  110. rc = tee_shm_alloc(dev, 256, 0, &vars->alloc_shm);
  111. ut_assert(!rc);
  112. ut_assert(state->num_shms == 2);
  113. ut_assert(tee_shm_is_registered(vars->reg_shm, dev));
  114. ut_assert(tee_shm_is_registered(vars->alloc_shm, dev));
  115. tee_shm_free(vars->reg_shm);
  116. vars->reg_shm = NULL;
  117. tee_shm_free(vars->alloc_shm);
  118. vars->alloc_shm = NULL;
  119. ut_assert(!state->num_shms);
  120. return rc;
  121. }
  122. #define I2C_BUF_SIZE 64
  123. static int test_tee_rpc(struct unit_test_state *uts)
  124. {
  125. struct tee_version_data vers;
  126. struct udevice *dev;
  127. struct sandbox_tee_state *state;
  128. struct tee_optee_ta_uuid rpc_test_uuid = TA_RPC_TEST_UUID;
  129. u32 session = 0;
  130. int rc;
  131. char *test_str = "Test string";
  132. u8 data[I2C_BUF_SIZE] = {0};
  133. u8 data_from_eeprom[I2C_BUF_SIZE] = {0};
  134. /* Use sandbox I2C EEPROM emulation; bus: 0, chip: 0x2c */
  135. u64 bus = 0;
  136. u64 chip = 0x2c;
  137. u64 xfer_flags = 0;
  138. dev = tee_find_device(NULL, match, NULL, &vers);
  139. ut_assert(dev);
  140. state = dev_get_priv(dev);
  141. ut_assert(!state->session);
  142. /* Test RPC call asking for I2C service */
  143. rc = open_session(dev, &session, &rpc_test_uuid);
  144. ut_assert(!rc);
  145. ut_assert(session == state->session);
  146. /* Write buffer */
  147. strncpy((char *)data, test_str, strlen(test_str));
  148. rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_WRITE,
  149. bus, chip, xfer_flags, data, sizeof(data));
  150. ut_assert(!rc);
  151. /* Read buffer */
  152. rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_READ,
  153. bus, chip, xfer_flags, data_from_eeprom,
  154. sizeof(data_from_eeprom));
  155. ut_assert(!rc);
  156. /* Compare */
  157. ut_assert(!memcmp(data, data_from_eeprom, sizeof(data)));
  158. rc = tee_close_session(dev, session);
  159. ut_assert(!rc);
  160. ut_assert(!state->session);
  161. return rc;
  162. }
  163. static int dm_test_tee(struct unit_test_state *uts)
  164. {
  165. struct test_tee_vars vars = { NULL, NULL };
  166. int rc = test_tee(uts, &vars);
  167. if (rc)
  168. goto out;
  169. if (IS_ENABLED(CONFIG_OPTEE_TA_RPC_TEST))
  170. rc = test_tee_rpc(uts);
  171. out:
  172. /* In case test_tee() asserts these may still remain allocated */
  173. tee_shm_free(vars.reg_shm);
  174. tee_shm_free(vars.alloc_shm);
  175. return rc;
  176. }
  177. DM_TEST(dm_test_tee, UT_TESTF_SCAN_FDT);