rmmd_attest.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  3. * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include <errno.h>
  8. #include <stdint.h>
  9. #include <string.h>
  10. #include <common/debug.h>
  11. #include <lib/spinlock.h>
  12. #include <lib/xlat_tables/xlat_tables_v2.h>
  13. #include <plat/common/platform.h>
  14. #include "rmmd_private.h"
  15. #include <services/rmm_el3_token_sign.h>
  16. #include <smccc_helpers.h>
  17. static spinlock_t lock;
  18. /* For printing Realm attestation token hash */
  19. #define DIGITS_PER_BYTE 2UL
  20. #define LENGTH_OF_TERMINATING_ZERO_IN_BYTES 1UL
  21. #define BYTES_PER_LINE_BASE 4UL
  22. static void print_challenge(uint8_t *hash, size_t hash_size)
  23. {
  24. size_t leftover;
  25. /*
  26. * bytes_per_line is always a power of two, so it can be used to
  27. * construct mask with it when it is necessary to count remainder.
  28. *
  29. */
  30. const size_t bytes_per_line = 1 << BYTES_PER_LINE_BASE;
  31. char hash_text[(1 << BYTES_PER_LINE_BASE) * DIGITS_PER_BYTE +
  32. LENGTH_OF_TERMINATING_ZERO_IN_BYTES];
  33. const char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
  34. '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  35. unsigned int i;
  36. for (i = 0U; i < hash_size; ++i) {
  37. hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE] =
  38. hex_chars[hash[i] >> 4];
  39. hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE + 1] =
  40. hex_chars[hash[i] & 0x0f];
  41. if (((i + 1) & (bytes_per_line - 1)) == 0U) {
  42. hash_text[bytes_per_line * DIGITS_PER_BYTE] = '\0';
  43. VERBOSE("hash part %u = %s\n",
  44. (i >> BYTES_PER_LINE_BASE) + 1, hash_text);
  45. }
  46. }
  47. leftover = (size_t)i & (bytes_per_line - 1);
  48. if (leftover != 0UL) {
  49. hash_text[leftover * DIGITS_PER_BYTE] = '\0';
  50. VERBOSE("hash part %u = %s\n", (i >> BYTES_PER_LINE_BASE) + 1,
  51. hash_text);
  52. }
  53. }
  54. /*
  55. * Helper function to validate that the buffer base and length are
  56. * within range.
  57. */
  58. static int validate_buffer_params(uint64_t buf_pa, uint64_t buf_len)
  59. {
  60. unsigned long shared_buf_page;
  61. uintptr_t shared_buf_base;
  62. (void)plat_rmmd_get_el3_rmm_shared_mem(&shared_buf_base);
  63. shared_buf_page = shared_buf_base & ~PAGE_SIZE_MASK;
  64. /* Validate the buffer pointer */
  65. if ((buf_pa & ~PAGE_SIZE_MASK) != shared_buf_page) {
  66. ERROR("Buffer PA out of range\n");
  67. return E_RMM_BAD_ADDR;
  68. }
  69. /* Validate the size of the shared area */
  70. if (((buf_pa + buf_len - 1UL) & ~PAGE_SIZE_MASK) != shared_buf_page) {
  71. ERROR("Invalid buffer length\n");
  72. return E_RMM_INVAL;
  73. }
  74. return 0; /* No error */
  75. }
  76. int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
  77. uint64_t c_size,
  78. uint64_t *remaining_len)
  79. {
  80. int err;
  81. uint8_t temp_buf[SHA512_DIGEST_SIZE];
  82. err = validate_buffer_params(buf_pa, *buf_size);
  83. if (err != 0) {
  84. return err;
  85. }
  86. if ((c_size != SHA256_DIGEST_SIZE) &&
  87. (c_size != SHA384_DIGEST_SIZE) &&
  88. (c_size != SHA512_DIGEST_SIZE)) {
  89. ERROR("Invalid hash size: %lu\n", c_size);
  90. return E_RMM_INVAL;
  91. }
  92. spin_lock(&lock);
  93. (void)memcpy(temp_buf, (void *)buf_pa, c_size);
  94. print_challenge((uint8_t *)temp_buf, c_size);
  95. /* Get the platform token. */
  96. err = plat_rmmd_get_cca_attest_token((uintptr_t)buf_pa,
  97. buf_size, (uintptr_t)temp_buf, c_size, remaining_len);
  98. switch (err) {
  99. case 0:
  100. err = E_RMM_OK;
  101. break;
  102. case -EAGAIN:
  103. err = E_RMM_AGAIN;
  104. break;
  105. case -EINVAL:
  106. err = E_RMM_INVAL;
  107. break;
  108. default:
  109. ERROR("Failed to get platform token: %d.\n", err);
  110. err = E_RMM_UNK;
  111. }
  112. spin_unlock(&lock);
  113. return err;
  114. }
  115. int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
  116. uint64_t ecc_curve)
  117. {
  118. int err;
  119. err = validate_buffer_params(buf_pa, *buf_size);
  120. if (err != 0) {
  121. return err;
  122. }
  123. if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
  124. ERROR("Invalid ECC curve specified\n");
  125. return E_RMM_INVAL;
  126. }
  127. spin_lock(&lock);
  128. /* Get the Realm attestation key. */
  129. err = plat_rmmd_get_cca_realm_attest_key((uintptr_t)buf_pa, buf_size,
  130. (unsigned int)ecc_curve);
  131. if (err != 0) {
  132. ERROR("Failed to get attestation key: %d.\n", err);
  133. err = E_RMM_UNK;
  134. }
  135. spin_unlock(&lock);
  136. return err;
  137. }
  138. static int rmmd_el3_token_sign_push_req(uint64_t buf_pa, uint64_t buf_size)
  139. {
  140. int err;
  141. err = validate_buffer_params(buf_pa, buf_size);
  142. if (err != 0) {
  143. return err;
  144. }
  145. if (buf_size < sizeof(struct el3_token_sign_request)) {
  146. return E_RMM_INVAL;
  147. }
  148. spin_lock(&lock);
  149. /* Call platform port to handle attestation toekn signing request. */
  150. err = plat_rmmd_el3_token_sign_push_req((struct el3_token_sign_request *)buf_pa);
  151. spin_unlock(&lock);
  152. return err;
  153. }
  154. static int rmmd_el3_token_sign_pull_resp(uint64_t buf_pa, uint64_t buf_size)
  155. {
  156. int err;
  157. err = validate_buffer_params(buf_pa, buf_size);
  158. if (err != 0) {
  159. return err;
  160. }
  161. if (buf_size < sizeof(struct el3_token_sign_response)) {
  162. return E_RMM_INVAL;
  163. }
  164. spin_lock(&lock);
  165. /* Pull attestation signing response from HES. */
  166. err = plat_rmmd_el3_token_sign_pull_resp(
  167. (struct el3_token_sign_response *)buf_pa);
  168. spin_unlock(&lock);
  169. return err;
  170. }
  171. static int rmmd_attest_get_attest_pub_key(uint64_t buf_pa, uint64_t *buf_size,
  172. uint64_t ecc_curve)
  173. {
  174. int err;
  175. err = validate_buffer_params(buf_pa, *buf_size);
  176. if (err != 0) {
  177. return err;
  178. }
  179. if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
  180. ERROR("Invalid ECC curve specified\n");
  181. return E_RMM_INVAL;
  182. }
  183. spin_lock(&lock);
  184. /* Get the Realm attestation public key from platform port. */
  185. err = plat_rmmd_el3_token_sign_get_rak_pub(
  186. (uintptr_t)buf_pa, buf_size, (unsigned int)ecc_curve);
  187. spin_unlock(&lock);
  188. if (err != 0) {
  189. ERROR("Failed to get attestation public key from HES: %d.\n",
  190. err);
  191. err = E_RMM_UNK;
  192. }
  193. return err;
  194. }
  195. uint64_t rmmd_el3_token_sign(void *handle, uint64_t opcode, uint64_t x2,
  196. uint64_t x3, uint64_t x4)
  197. {
  198. int ret;
  199. switch (opcode) {
  200. case RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP:
  201. ret = rmmd_el3_token_sign_push_req(x2, x3);
  202. SMC_RET1(handle, ret);
  203. case RMM_EL3_TOKEN_SIGN_PULL_RESP_OP:
  204. ret = rmmd_el3_token_sign_pull_resp(x2, x3);
  205. SMC_RET1(handle, ret);
  206. case RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP:
  207. ret = rmmd_attest_get_attest_pub_key(x2, &x3, x4);
  208. SMC_RET2(handle, ret, x3);
  209. default:
  210. SMC_RET1(handle, SMC_UNK);
  211. }
  212. }