esp_ds.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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 "esp_hmac.h"
  8. #include "esp_err.h"
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12. #define ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
  13. #define ESP_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
  14. HMAC peripheral problem */
  15. #define ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
  16. result is invalid */
  17. #define ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
  18. is produced anyway and can be read*/
  19. #define ESP_DS_IV_LEN 16
  20. /* Length of parameter 'C' stored in flash */
  21. #define ESP_DS_C_LEN (12672 / 8)
  22. typedef struct esp_ds_context esp_ds_context_t;
  23. typedef enum {
  24. ESP_DS_RSA_1024 = (1024 / 32) - 1,
  25. ESP_DS_RSA_2048 = (2048 / 32) - 1,
  26. ESP_DS_RSA_3072 = (3072 / 32) - 1,
  27. ESP_DS_RSA_4096 = (4096 / 32) - 1
  28. } esp_digital_signature_length_t;
  29. /**
  30. * Encrypted private key data. Recommended to store in flash in this format.
  31. *
  32. * @note This struct has to match to one from the ROM code! This documentation is mostly taken from there.
  33. */
  34. typedef struct esp_digital_signature_data {
  35. /**
  36. * RSA LENGTH register parameters
  37. * (number of words in RSA key & operands, minus one).
  38. *
  39. * Max value 127 (for RSA 4096).
  40. *
  41. * This value must match the length field encrypted and stored in 'c',
  42. * or invalid results will be returned. (The DS peripheral will
  43. * always use the value in 'c', not this value, so an attacker can't
  44. * alter the DS peripheral results this way, it will just truncate or
  45. * extend the message and the resulting signature in software.)
  46. *
  47. * @note In IDF, the enum type length is the same as of type unsigned, so they can be used interchangably.
  48. * See the ROM code for the original declaration of struct \c ets_ds_data_t.
  49. */
  50. esp_digital_signature_length_t rsa_length;
  51. /**
  52. * IV value used to encrypt 'c'
  53. */
  54. uint8_t iv[ESP_DS_IV_LEN];
  55. /**
  56. * Encrypted Digital Signature parameters. Result of AES-CBC encryption
  57. * of plaintext values. Includes an encrypted message digest.
  58. */
  59. uint8_t c[ESP_DS_C_LEN];
  60. } esp_ds_data_t;
  61. /** Plaintext parameters used by Digital Signature.
  62. *
  63. * Not used for signing with DS peripheral, but can be encrypted
  64. * in-device by calling esp_ds_encrypt_params()
  65. *
  66. * @note This documentation is mostly taken from the ROM code.
  67. */
  68. typedef struct {
  69. uint32_t Y[4096/32]; //!< RSA exponent
  70. uint32_t M[4096/32]; //!< RSA modulus
  71. uint32_t Rb[4096/32]; //!< RSA r inverse operand
  72. uint32_t M_prime; //!< RSA M prime operand
  73. esp_digital_signature_length_t length; //!< RSA length
  74. } esp_ds_p_data_t;
  75. /**
  76. * Sign the message.
  77. *
  78. * This function is a wrapper around \c esp_ds_finish_sign() and \c esp_ds_start_sign(), so do not use them
  79. * in parallel.
  80. * It blocks until the signing is finished and then returns the signature.
  81. *
  82. * The function calculates a plain RSA signature with help of the DS peripheral.
  83. * The RSA encryption operation is as follows:
  84. * Z = XY mod M where,
  85. * Z is the signature, X is the input message,
  86. * Y and M are the RSA private key parameters.
  87. *
  88. * @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time.
  89. *
  90. * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes
  91. * @param data the encrypted signing key data (AES encrypted RSA key + IV)
  92. * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the
  93. * signing key data
  94. * @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long
  95. *
  96. * @return
  97. * - ESP_OK if successful, the signature was written to the parameter \c signature.
  98. * - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0
  99. * - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key
  100. * - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object
  101. * - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
  102. * - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid.
  103. * - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though
  104. * since the message digest matches.
  105. */
  106. esp_err_t esp_ds_sign(const void *message,
  107. const esp_ds_data_t *data,
  108. hmac_key_id_t key_id,
  109. void *signature);
  110. /**
  111. * Start the signing process.
  112. *
  113. * This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing
  114. * process.
  115. *
  116. * The function calculates a plain RSA signature with help of the DS peripheral.
  117. * The RSA encryption operation is as follows:
  118. * Z = XY mod M where,
  119. * Z is the signature, X is the input message,
  120. * Y and M are the RSA private key parameters.
  121. *
  122. * @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call
  123. * \c esp_ds_finish_sign() in a timely manner.
  124. *
  125. * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes
  126. * @param data the encrypted signing key data (AES encrypted RSA key + IV)
  127. * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the
  128. * signing key data
  129. * @param esp_ds_ctx the context object which is needed for finishing the signing process later
  130. *
  131. * @return
  132. * - ESP_OK if successful, the ds operation was started now and has to be finished with \c esp_ds_finish_sign()
  133. * - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0
  134. * - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key
  135. * - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object
  136. * - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
  137. */
  138. esp_err_t esp_ds_start_sign(const void *message,
  139. const esp_ds_data_t *data,
  140. hmac_key_id_t key_id,
  141. esp_ds_context_t **esp_ds_ctx);
  142. /**
  143. * Return true if the DS peripheral is busy, otherwise false.
  144. *
  145. * @note Only valid if \c esp_ds_start_sign() was called before.
  146. */
  147. bool esp_ds_is_busy(void);
  148. /**
  149. * Finish the signing process.
  150. *
  151. * @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long
  152. * @param esp_ds_ctx the context object retreived by \c esp_ds_start_sign()
  153. *
  154. * @return
  155. * - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
  156. * - ESP_ERR_INVALID_ARG if one of the parameters is NULL
  157. * - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid.
  158. * - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though
  159. * since the message digest matches.
  160. */
  161. esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx);
  162. /**
  163. * Encrypt the private key parameters.
  164. *
  165. * @param data Output buffer to store encrypted data, suitable for later use generating signatures.
  166. * The allocated memory must be in internal memory and word aligned since it's filled by DMA. Both is asserted
  167. * at run time.
  168. * @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time.
  169. * @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process
  170. * is done and 'data' is stored.
  171. * @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the
  172. * corresponding HMAC key will be stored to efuse and then permanently erased.
  173. *
  174. * @return
  175. * - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
  176. * - ESP_ERR_INVALID_ARG if one of the parameters is NULL or p_data->rsa_length is too long
  177. */
  178. esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
  179. const void *iv,
  180. const esp_ds_p_data_t *p_data,
  181. const void *key);
  182. #ifdef __cplusplus
  183. }
  184. #endif