stm32mp_trusted_boot.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <endian.h>
  7. #include <errno.h>
  8. #include <limits.h>
  9. #include <common/debug.h>
  10. #include <common/tbbr/cot_def.h>
  11. #include <drivers/clk.h>
  12. #include <drivers/st/stm32_hash.h>
  13. #include <lib/fconf/fconf.h>
  14. #include <lib/fconf/fconf_dyn_cfg_getter.h>
  15. #include <lib/fconf/fconf_tbbr_getter.h>
  16. #include <lib/mmio.h>
  17. #include <lib/xlat_tables/xlat_tables_v2.h>
  18. #include <plat/common/platform.h>
  19. #include <boot_api.h>
  20. #include <platform_def.h>
  21. #define HEADER_AND_EXT_TOTAL_SIZE 512
  22. static uint8_t der_sha256_header[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
  23. 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
  24. static uint8_t root_pk_hash[HASH_DER_LEN];
  25. static int copy_hash_from_otp(const char *otp_name, uint8_t *hash, size_t len)
  26. {
  27. uint32_t otp_idx;
  28. uint32_t otp_len;
  29. size_t i;
  30. bool valid = false;
  31. assert(len % sizeof(uint32_t) == 0);
  32. if (stm32_get_otp_index(otp_name, &otp_idx, &otp_len) != 0) {
  33. VERBOSE("%s: get %s index error\n", __func__, otp_name);
  34. return -EINVAL;
  35. }
  36. if (otp_len != (len * CHAR_BIT)) {
  37. VERBOSE("%s: length Error\n", __func__);
  38. return -EINVAL;
  39. }
  40. for (i = 0U; i < len / sizeof(uint32_t); i++) {
  41. uint32_t tmp;
  42. uint32_t otp_val;
  43. uint32_t first;
  44. if (stm32_get_otp_value_from_idx(otp_idx + i, &otp_val) != 0) {
  45. VERBOSE("%s: unable to read from otp\n", __func__);
  46. return -EINVAL;
  47. }
  48. tmp = bswap32(otp_val);
  49. memcpy(hash + i * sizeof(uint32_t), &tmp, sizeof(tmp));
  50. if (i == 0U) {
  51. first = tmp;
  52. }
  53. /*
  54. * Check if key hash values in OTP are 0 or 0xFFFFFFFFF
  55. * programmed : Invalid Key
  56. */
  57. if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) && !valid) {
  58. if ((tmp != 0U) && (tmp != 0xFFFFFFFFU) && (tmp != first)) {
  59. valid = true;
  60. }
  61. }
  62. }
  63. if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) && !valid) {
  64. return 0;
  65. }
  66. return len;
  67. }
  68. #if STM32_HEADER_VERSION_MAJOR == 1
  69. static int get_rotpk_hash(void *cookie, uint8_t *hash, size_t len)
  70. {
  71. if (cookie != NULL) {
  72. return -EINVAL;
  73. }
  74. return copy_hash_from_otp(PKH_OTP, hash, len);
  75. }
  76. #else
  77. static int get_rotpk_hash(void *cookie, uint8_t *hash, size_t len)
  78. {
  79. int ret;
  80. uint32_t pk_idx = 0U;
  81. uint8_t calc_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
  82. uint8_t otp_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
  83. boot_api_image_header_t *hdr = (boot_api_image_header_t *)(SRAM3_BASE + SRAM3_SIZE -
  84. HEADER_AND_EXT_TOTAL_SIZE);
  85. boot_extension_header_t *ext_header = (boot_extension_header_t *)hdr->ext_header;
  86. boot_ext_header_params_authentication_t *param;
  87. if (cookie != NULL) {
  88. return -EINVAL;
  89. }
  90. if (hdr->header_version != BOOT_API_HEADER_VERSION) {
  91. VERBOSE("%s: unexpected header_version\n", __func__);
  92. return -EINVAL;
  93. }
  94. param = (boot_ext_header_params_authentication_t *)ext_header->params;
  95. pk_idx = param->pk_idx;
  96. stm32_hash_init(HASH_SHA256);
  97. ret = stm32_hash_final_update((uint8_t *)param->pk_hashes,
  98. param->nb_pk * sizeof(boot_api_sha256_t), calc_hash);
  99. if (ret != 0) {
  100. VERBOSE("%s: hash failed\n", __func__);
  101. return -EINVAL;
  102. }
  103. ret = copy_hash_from_otp(PKH_OTP, otp_hash, len);
  104. if (ret < 0) {
  105. return -EINVAL;
  106. }
  107. if (ret != 0) {
  108. ret = memcmp(calc_hash, otp_hash, sizeof(calc_hash));
  109. if (ret != 0) {
  110. VERBOSE("%s: not expected digest\n", __func__);
  111. return -EINVAL;
  112. }
  113. ret = sizeof(otp_hash);
  114. }
  115. memcpy(hash, param->pk_hashes[pk_idx], sizeof(otp_hash));
  116. return ret;
  117. }
  118. #endif
  119. int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
  120. unsigned int *flags)
  121. {
  122. size_t start_copy_idx = 0U;
  123. int res;
  124. memcpy(root_pk_hash, der_sha256_header, sizeof(der_sha256_header));
  125. start_copy_idx = sizeof(der_sha256_header);
  126. res = get_rotpk_hash(cookie, root_pk_hash + start_copy_idx,
  127. BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES);
  128. if (res < 0) {
  129. return -EINVAL;
  130. }
  131. *key_len = HASH_DER_LEN;
  132. *key_ptr = &root_pk_hash;
  133. *flags = ROTPK_IS_HASH;
  134. if ((res == 0) && (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN)) {
  135. *flags |= ROTPK_NOT_DEPLOYED;
  136. }
  137. return 0;
  138. }
  139. int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
  140. {
  141. clk_enable(TAMP_BKP_REG_CLK);
  142. *nv_ctr = mmio_read_32(TAMP_BASE + TAMP_COUNTR);
  143. clk_disable(TAMP_BKP_REG_CLK);
  144. return 0;
  145. }
  146. int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
  147. {
  148. clk_enable(TAMP_BKP_REG_CLK);
  149. while (mmio_read_32(TAMP_BASE + TAMP_COUNTR) != nv_ctr) {
  150. mmio_write_32(TAMP_BASE + TAMP_COUNTR, 1U);
  151. }
  152. clk_disable(TAMP_BKP_REG_CLK);
  153. return 0;
  154. }
  155. int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
  156. {
  157. assert(heap_addr != NULL);
  158. assert(heap_size != NULL);
  159. #if STM32MP_USE_EXTERNAL_HEAP
  160. /* Retrieve the already allocated heap's info from DTB */
  161. *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr);
  162. *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size);
  163. /* We expect heap already statically mapped */
  164. return 0;
  165. #else
  166. return get_mbedtls_heap_helper(heap_addr, heap_size);
  167. #endif
  168. }