boot_secure.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* Copyright (C) 2017 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further rom_api_testing or modification.
  11. */
  12. #define OSI_LOCAL_LOG_LEVEL OSI_LOG_LEVEL_DEBUG
  13. #include "boot_secure.h"
  14. #include "hal_efuse.h"
  15. #include "osi_log.h"
  16. #include "calclib/sha256.h"
  17. #include "calclib/simage.h"
  18. #include "calclib/sm3.h"
  19. #include "8850/hal_rom_api.h"
  20. #include "string.h"
  21. #include "hal_chip.h"
  22. #include "osi_api.h"
  23. typedef struct
  24. {
  25. bool secure_enable;
  26. bool integrity_valid;
  27. bool lock_bit_valid;
  28. unsigned min_secure_version;
  29. osiBits256_t rotpk;
  30. osiBits64_t soc_raw_id;
  31. } bootEfuseContent_t;
  32. static bootEfuseContent_t gEfuse;
  33. /**
  34. * \brief efuse content
  35. *
  36. * This is not the raw data of efuse. Rather, fields inside are
  37. * interpreted value.
  38. */
  39. typedef struct
  40. {
  41. bool secure_boot_enable; ///< whether secure is enabled
  42. bool develcert_enable; ///< whether develcert is enabled for secure debug
  43. bool download_enable; ///< whether download is enabled, for disable download
  44. bool keypad_entermode_enable; ///< whether to enable download mode check by keypad
  45. bool uart1_boot_enable; ///< whether uart1 will be polled during download
  46. bool uart4_boot_enable; ///< whether uart4 will be polled during download
  47. bool usb_boot_enable; ///< whether usb will be polled during download
  48. bool sdcard_boot_enable; ///< whether sdcard boot is enabled, for disable sdcard boot
  49. bool boot_med_encrypt; ///< whether bootloader is MED encrypted
  50. bool enable_faster_flash; ///< whether enable faster flash configuration
  51. bool sm_certify_mode; ///< whether iSM certification mode
  52. bool rma_med; ///< whether rma_med is set
  53. bool rma_all; ///< whether all rma bits are set
  54. uint32_t second_boot_offset; ///< second bootloader offset for dual bootloader, in bytes
  55. unsigned min_secure_version; ///< minimal valid security version
  56. osiBits64_t soc_raw_id; ///< raw SOC ID
  57. osiBits256_t rotpk; ///< root trusted public key hash
  58. osiBits256_t data_hash; ///< data hash for sm certify
  59. } romEfuseContent_t;
  60. void bootGetEfuseCtx(void)
  61. {
  62. romEfuseContent_t *Ctx = (romEfuseContent_t *)getEfuseContent();
  63. gEfuse.secure_enable = Ctx->secure_boot_enable;
  64. gEfuse.min_secure_version = Ctx->min_secure_version;
  65. memcpy(&gEfuse.rotpk, &Ctx->rotpk, sizeof(osiBits256_t));
  66. memcpy(&gEfuse.soc_raw_id, &Ctx->soc_raw_id, sizeof(osiBits64_t));
  67. }
  68. unsigned sha256ContextSize(void)
  69. {
  70. return halRomSha256ContextSize();
  71. }
  72. void sha256Init(sha256Context_t *ctx)
  73. {
  74. halRomSha256Init((halRomSha256Context_t *)ctx);
  75. }
  76. bool sha256Update(sha256Context_t *ctx, const void *input, size_t ilen)
  77. {
  78. halRomSha256Update((halRomSha256Context_t *)ctx, input, ilen);
  79. return true;
  80. }
  81. bool sha256Final(sha256Context_t *ctx, void *output)
  82. {
  83. halRomSha256Final((halRomSha256Context_t *)ctx, output);
  84. return true;
  85. }
  86. bool sha256Calc(const void *input, size_t ilen, void *output)
  87. {
  88. halRomSha256Calc(input, ilen, output);
  89. return true;
  90. }
  91. bool sm3Calc(const void *input, size_t ilen, void *output)
  92. {
  93. halRomSm3Calc(input, ilen, output);
  94. return true;
  95. }
  96. bool rsaVerify(unsigned pubkey_n_bytes, unsigned pubkey_e,
  97. const void *pubkey_n, unsigned pubkey_padding,
  98. const void *sig_data, unsigned sig_bytes,
  99. const void *hash, unsigned hash_bytes)
  100. {
  101. return halRomRsaVerify(pubkey_n_bytes, pubkey_e,
  102. pubkey_n, pubkey_padding,
  103. sig_data, sig_bytes,
  104. hash, hash_bytes);
  105. }
  106. bool eccVerify(unsigned curve, const void *ecp_x, unsigned xbytes,
  107. const void *ecp_y, unsigned ybytes,
  108. const void *sig_r, unsigned rbytes,
  109. const void *sig_s, unsigned sbytes,
  110. const void *hash, unsigned hash_bytes)
  111. {
  112. return halRomEccVerify(curve, ecp_x, xbytes,
  113. ecp_y, ybytes,
  114. sig_r, rbytes,
  115. sig_s, sbytes,
  116. hash, hash_bytes);
  117. }
  118. bool sm2Verify(const void *ecp_x, const void *ecp_y,
  119. const void *sig_r, const void *sig_s,
  120. const void *hash, unsigned hashbytes)
  121. {
  122. return halRomSm2Verify(ecp_x, ecp_y,
  123. sig_r, sig_s,
  124. hash, hashbytes);
  125. }
  126. bool bootSimageCheckSign(const simageHeader_t *header)
  127. {
  128. if (!gEfuse.secure_enable)
  129. return true;
  130. return halRomSimageSignVerify(header, &gEfuse.rotpk, &gEfuse.soc_raw_id,
  131. gEfuse.min_secure_version);
  132. }
  133. bool bootSecureBootEnable(void)
  134. {
  135. return gEfuse.secure_enable;
  136. }
  137. bool bootUpdateVersion(void)
  138. {
  139. if (!gEfuse.secure_enable)
  140. return true;
  141. simageHeader_t *header = (simageHeader_t *)(CONFIG_NOR_PHY_ADDRESS);
  142. const simageKeyCert_t *keycert = simageGetKeyCert(header);
  143. if (keycert == NULL)
  144. return false;
  145. if (keycert->security_version == gEfuse.min_secure_version)
  146. return true;
  147. if (keycert->security_version < gEfuse.min_secure_version)
  148. {
  149. OSI_LOGI(0x10009106, "bootloader secure version too small, %d/%d",
  150. keycert->security_version, gEfuse.min_secure_version);
  151. return false;
  152. }
  153. // Calculate anti-rollback efuse value
  154. uint32_t verbits[2];
  155. if (!halToEfuseAntiRollback64(keycert->security_version, verbits))
  156. return false;
  157. // Secure boot enable is NOT power failure safe. It will be safer to
  158. // disable interrupt for the whole, though it flash operation will
  159. // take time.
  160. unsigned critical = osiEnterCritical();
  161. halEfuseReadWriteOp_t efuse_ops2[] = {
  162. {HAL_EFUSE_OP_DOUBLE_WRITE, HAL_EFUSE_DOUBLE_BLOCK_SECURE_COUNTER1_0, {.wval = verbits[0]}},
  163. {HAL_EFUSE_OP_DOUBLE_WRITE, HAL_EFUSE_DOUBLE_BLOCK_SECURE_COUNTER1_1, {.wval = verbits[1]}},
  164. };
  165. if (!halEfuseReadWrite(efuse_ops2, OSI_ARRAY_SIZE(efuse_ops2)))
  166. {
  167. osiExitCritical(critical);
  168. return false;
  169. }
  170. osiExitCritical(critical);
  171. return true;
  172. }
  173. bool firmwareCheckSign(const simageKeyCert_t *cert,
  174. const void *sign_data, unsigned sign_size)
  175. {
  176. if (cert == NULL || sign_data == NULL)
  177. return false;
  178. if (sign_size == 0)
  179. return false;
  180. osiBits256_t efusepubhash;
  181. //prvGetEfusePkHash(&efusepubhash);
  182. memcpy(&efusepubhash, &gEfuse.rotpk, sizeof(osiBits256_t));
  183. const simageCertHeader_t *cert_header = NULL;
  184. const simagePubkey_t *pubkey = NULL;
  185. cert_header = &cert->header;
  186. pubkey = &cert_header->pubkey;
  187. unsigned pka_type = SIMAGE_CERT_PKA_TYPE(cert_header->pk_type);
  188. unsigned hash_type = SIMAGE_CERT_HASH_TYPE(cert_header->pk_type);
  189. const void *cert_data = (const char *)cert_header + SIMAGE_SIGN_DATA_OFFSET;
  190. unsigned cert_data_size = cert_header->cert_size - SIMAGE_SIGN_DATA_OFFSET;
  191. osiBits256_t hash;
  192. osiBits256_t certhash;
  193. if (hash_type == SIMAGE_HASHTYPE_SHA256)
  194. {
  195. sha256Calc(sign_data, sign_size, &hash);
  196. sha256Calc(cert_data, cert_data_size, &certhash);
  197. }
  198. else if (hash_type == SIMAGE_HASHTYPE_SM3)
  199. {
  200. sm3Calc(sign_data, sign_size, &hash);
  201. sm3Calc(cert_data, cert_data_size, &certhash);
  202. }
  203. else
  204. {
  205. OSI_LOGE(0x1000905d, "hash type incorrect %d", hash_type);
  206. return false;
  207. }
  208. if (memcmp(&cert->hash_data, &hash, sizeof(osiBits256_t)) != 0)
  209. {
  210. OSI_LOGE(0x1000905e, "firmware hash mismatch");
  211. return false;
  212. }
  213. unsigned keylen;
  214. if (pka_type == SIMAGE_PKATYPE_SM2)
  215. {
  216. keylen = sizeof(simageSm2Pubkey_t);
  217. if (!sm3Check(pubkey, keylen, &efusepubhash))
  218. {
  219. OSI_LOGE(0x1000905f, "keycert public key not match efuse");
  220. return false;
  221. }
  222. return sm2Verify(&pubkey->ecc.x, &pubkey->ecc.y,
  223. &cert_header->sig.ecc.r, &cert_header->sig.ecc.s,
  224. &certhash, sizeof(certhash));
  225. }
  226. else if (pka_type == SIMAGE_PKATYPE_RSA ||
  227. pka_type == SIMAGE_PKATYPE_RSA_PSS)
  228. {
  229. keylen = sizeof(simageRsaPubkey_t);
  230. if (!sha256Check(pubkey, keylen, &efusepubhash))
  231. {
  232. OSI_LOGE(0x1000905f, "keycert public key not match efuse");
  233. return false;
  234. }
  235. return rsaVerify(pubkey->rsa.n_bytes, pubkey->rsa.e,
  236. &pubkey->rsa.n, cert_header->pk_type,
  237. &cert_header->sig.rsa.sig, cert_header->sig.rsa.bytes,
  238. &certhash, sizeof(certhash));
  239. }
  240. else if (pka_type == SIMAGE_PKATYPE_ECC)
  241. {
  242. keylen = sizeof(simageEccPubkey_t);
  243. if (!sha256Check(pubkey, keylen, &efusepubhash))
  244. {
  245. OSI_LOGE(0x1000905f, "keycert public key not match efuse");
  246. return false;
  247. }
  248. return eccVerify(pubkey->ecc.curve,
  249. &pubkey->ecc.x, sizeof(pubkey->ecc.x),
  250. &pubkey->ecc.y, sizeof(pubkey->ecc.y),
  251. &cert_header->sig.ecc.r, sizeof(cert_header->sig.ecc.r),
  252. &cert_header->sig.ecc.s, sizeof(cert_header->sig.ecc.s),
  253. &certhash, sizeof(certhash));
  254. }
  255. else
  256. {
  257. OSI_LOGE(0x10009060, "pka type incorrect %d", pka_type);
  258. return false;
  259. }
  260. }