ds_ll.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include <stdint.h>
  8. #include <stdbool.h>
  9. #include <string.h>
  10. #include "soc/hwcrypto_reg.h"
  11. #include "soc/soc_caps.h"
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. static inline void ds_ll_start(void)
  16. {
  17. REG_WRITE(DS_SET_START_REG, 1);
  18. }
  19. /**
  20. * @brief Wait until DS peripheral has finished any outstanding operation.
  21. */
  22. static inline bool ds_ll_busy(void)
  23. {
  24. return (REG_READ(DS_QUERY_BUSY_REG) > 0) ? true : false;
  25. }
  26. /**
  27. * @brief Busy wait until the hardware is ready.
  28. */
  29. static inline void ds_ll_wait_busy(void)
  30. {
  31. while (ds_ll_busy());
  32. }
  33. /**
  34. * @brief In case of a key error, check what caused it.
  35. */
  36. static inline ds_key_check_t ds_ll_key_error_source(void)
  37. {
  38. uint32_t key_error = REG_READ(DS_QUERY_KEY_WRONG_REG);
  39. if (key_error == 0) {
  40. return DS_NO_KEY_INPUT;
  41. } else {
  42. return DS_OTHER_WRONG;
  43. }
  44. }
  45. /**
  46. * @brief Write the initialization vector to the corresponding register field.
  47. */
  48. static inline void ds_ll_configure_iv(const uint32_t *iv)
  49. {
  50. for (size_t i = 0; i < (SOC_DS_KEY_PARAM_MD_IV_LENGTH / sizeof(uint32_t)); i++) {
  51. REG_WRITE(DS_IV_BASE + (i * 4), iv[i]);
  52. }
  53. }
  54. /**
  55. * @brief Write the message which should be signed.
  56. *
  57. * @param msg Pointer to the message.
  58. * @param size Length of msg in bytes. It is the RSA signature length in bytes.
  59. */
  60. static inline void ds_ll_write_message(const uint8_t *msg, size_t size)
  61. {
  62. memcpy((uint8_t *) DS_X_BASE, msg, size);
  63. }
  64. /**
  65. * @brief Write the encrypted private key parameters.
  66. */
  67. static inline void ds_ll_write_private_key_params(const uint8_t *encrypted_key_params)
  68. {
  69. /* Note: as the internal peripheral still has RSA 4096 structure,
  70. but C is encrypted based on the actual max RSA length (ETS_DS_MAX_BITS), need to fragment it
  71. when copying to hardware...
  72. (note if ETS_DS_MAX_BITS == 4096, this should be the same as copying data->c to hardware in one fragment)
  73. */
  74. typedef struct {
  75. uint32_t addr;
  76. size_t len;
  77. } frag_t;
  78. const frag_t frags[] = {
  79. {DS_C_Y_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
  80. {DS_C_M_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
  81. {DS_C_RB_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
  82. {DS_C_BOX_BASE, DS_IV_BASE - DS_C_BOX_BASE},
  83. };
  84. const size_t NUM_FRAGS = sizeof(frags) / sizeof(frag_t);
  85. const uint8_t *from = encrypted_key_params;
  86. for (int i = 0; i < NUM_FRAGS; i++) {
  87. memcpy((uint8_t *)frags[i].addr, from, frags[i].len);
  88. from += frags[i].len;
  89. }
  90. }
  91. /**
  92. * @brief Begin signing procedure.
  93. */
  94. static inline void ds_ll_start_sign(void)
  95. {
  96. REG_WRITE(DS_SET_ME_REG, 1);
  97. }
  98. /**
  99. * @brief check the calculated signature.
  100. *
  101. * @return
  102. * - DS_SIGNATURE_OK if no issue is detected with the signature.
  103. * - DS_SIGNATURE_PADDING_FAIL if the padding of the private key parameters is wrong.
  104. * - DS_SIGNATURE_MD_FAIL if the message digest check failed. This means that the message digest calculated using
  105. * the private key parameters fails, i.e., the integrity of the private key parameters is not protected.
  106. * - DS_SIGNATURE_PADDING_AND_MD_FAIL if both padding and message digest check fail.
  107. */
  108. static inline ds_signature_check_t ds_ll_check_signature(void)
  109. {
  110. uint32_t result = REG_READ(DS_QUERY_CHECK_REG);
  111. switch (result) {
  112. case 0:
  113. return DS_SIGNATURE_OK;
  114. case 1:
  115. return DS_SIGNATURE_MD_FAIL;
  116. case 2:
  117. return DS_SIGNATURE_PADDING_FAIL;
  118. default:
  119. return DS_SIGNATURE_PADDING_AND_MD_FAIL;
  120. }
  121. }
  122. /**
  123. * @brief Read the signature from the hardware.
  124. *
  125. * @param result The signature result.
  126. * @param size Length of signature result in bytes. It is the RSA signature length in bytes.
  127. */
  128. static inline void ds_ll_read_result(uint8_t *result, size_t size)
  129. {
  130. memcpy(result, (uint8_t *) DS_Z_BASE, size);
  131. }
  132. /**
  133. * @brief Exit the signature operation.
  134. *
  135. * @note This does not deactivate the module. Corresponding clock/reset bits have to be triggered for deactivation.
  136. */
  137. static inline void ds_ll_finish(void)
  138. {
  139. REG_WRITE(DS_SET_FINISH_REG, 1);
  140. ds_ll_wait_busy();
  141. }
  142. #ifdef __cplusplus
  143. }
  144. #endif