aes_hal.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Copyright 2020 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // The HAL layer for AES
  15. #include "hal/aes_hal.h"
  16. #include "hal/aes_ll.h"
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include "soc/soc_caps.h"
  20. #if SOC_AES_CRYPTO_DMA
  21. #include "soc/crypto_dma_reg.h"
  22. #include "hal/crypto_dma_ll.h"
  23. #elif SOC_AES_GENERAL_DMA
  24. #include "hal/gdma_ll.h"
  25. #endif
  26. uint8_t aes_hal_setkey(const uint8_t *key, size_t key_bytes, int mode)
  27. {
  28. aes_ll_set_mode(mode, key_bytes);
  29. uint8_t key_bytes_in_hardware = aes_ll_write_key(key, key_bytes / 4);
  30. /* Used for fault injection check: all words of key data should have been written to hardware */
  31. return key_bytes_in_hardware;
  32. }
  33. /**
  34. * @brief Busy wait until the AES accelerator is idle
  35. *
  36. */
  37. static inline void aes_hal_wait_idle(void)
  38. {
  39. while (aes_ll_get_state() != ESP_AES_STATE_IDLE) {
  40. }
  41. }
  42. void aes_hal_transform_block(const void *input_block, void *output_block)
  43. {
  44. aes_ll_write_block(input_block);
  45. aes_ll_start_transform();
  46. aes_hal_wait_idle();
  47. aes_ll_read_block(output_block);
  48. }
  49. #if SOC_AES_SUPPORT_DMA
  50. #if SOC_AES_GENERAL_DMA
  51. /**
  52. * @brief Initialize the DMA
  53. *
  54. * @param input AES input descriptor (outlink)
  55. * @param output AES output descriptor (inlink)
  56. */
  57. static inline void aes_hal_dma_init(const lldesc_t *input, const lldesc_t *output)
  58. {
  59. /* Update driver when centralized DMA interface implemented, IDF-2192 */
  60. gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
  61. gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
  62. gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
  63. gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
  64. gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_LL_PERIPH_ID_AES);
  65. gdma_ll_rx_connect_to_periph(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_LL_PERIPH_ID_AES);
  66. /* An L2 FIFO bigger than 40 bytes is need when accessing external ram */
  67. gdma_ll_tx_extend_fifo_size_to(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, 40);
  68. gdma_ll_rx_extend_l2_fifo_size_to(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, 40);
  69. gdma_ll_tx_set_block_size_psram(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
  70. gdma_ll_rx_set_block_size_psram(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
  71. /* Set descriptors */
  72. gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, (uint32_t)input);
  73. gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, (uint32_t)output);
  74. gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  75. gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  76. /* Start transfer */
  77. gdma_ll_tx_start(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  78. gdma_ll_rx_start(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  79. }
  80. static inline bool aes_hal_dma_done(const lldesc_t *output)
  81. {
  82. return (gdma_ll_rx_is_fsm_idle(&GDMA, SOC_GDMA_AES_DMA_CHANNEL) && (output->owner == 0));
  83. }
  84. #endif //SOC_AES_GENERAL_DMA
  85. #if SOC_AES_CRYPTO_DMA
  86. /**
  87. * @brief Initialize the DMA
  88. *
  89. * @param input AES input descriptor (outlink)
  90. * @param output AES output descriptor (inlink)
  91. */
  92. static inline void aes_hal_dma_init(const lldesc_t *input, const lldesc_t *output)
  93. {
  94. crypto_dma_ll_reset();
  95. crypto_dma_ll_set_mode(CRYPTO_DMA_AES);
  96. /* Set descriptors, input to AES comes from outlink DMA and viceversa */
  97. crypto_dma_ll_outlink_set((uint32_t)input);
  98. crypto_dma_ll_inlink_set((uint32_t)output);
  99. /* Start transfer */
  100. crypto_dma_ll_outlink_start();
  101. crypto_dma_ll_inlink_start();
  102. }
  103. static inline bool aes_hal_dma_done(lldesc_t *output)
  104. {
  105. return (crypto_dma_ll_inlink_is_eof() && (output->owner == 0));
  106. }
  107. #endif //SOC_AES_CRYPTO_DMA
  108. void aes_hal_transform_dma_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks)
  109. {
  110. aes_ll_dma_enable(true);
  111. aes_hal_dma_init(input, output);
  112. /* Write the number of blocks */
  113. aes_ll_set_num_blocks(num_blocks);
  114. /* Start encrypting/decrypting */
  115. aes_ll_start_transform();
  116. }
  117. void aes_hal_transform_dma_finish(void)
  118. {
  119. aes_ll_dma_exit();
  120. aes_ll_dma_enable(false);
  121. }
  122. void aes_hal_mode_init(esp_aes_mode_t mode)
  123. {
  124. /* Set the algorith mode CBC, CFB ... */
  125. aes_ll_set_block_mode(mode);
  126. /* Presently hard-coding the INC function to 32 bit */
  127. if (mode == ESP_AES_BLOCK_MODE_CTR) {
  128. aes_ll_set_inc();
  129. }
  130. }
  131. void aes_hal_set_iv(const uint8_t *iv)
  132. {
  133. aes_ll_set_iv(iv);
  134. }
  135. void aes_hal_read_iv(uint8_t *iv)
  136. {
  137. aes_ll_read_iv(iv);
  138. }
  139. static inline void aes_hal_wait_done(void)
  140. {
  141. while (aes_ll_get_state() != ESP_AES_STATE_DONE) {}
  142. }
  143. void aes_hal_wait_dma_done(lldesc_t *output)
  144. {
  145. /* Checking this if interrupt is used also, to avoid
  146. issues with AES fault injection
  147. */
  148. aes_hal_wait_done();
  149. /* Wait for DMA write operation to complete */
  150. while (1) {
  151. if ( aes_hal_dma_done(output) ) {
  152. break;
  153. }
  154. }
  155. }
  156. #endif //SOC_AES_SUPPORT_DMA
  157. #if SOC_AES_SUPPORT_GCM
  158. void aes_hal_gcm_calc_hash(uint8_t *gcm_hash)
  159. {
  160. aes_ll_dma_enable(true);
  161. aes_ll_start_transform();
  162. aes_hal_wait_idle();
  163. aes_ll_gcm_read_hash(gcm_hash);
  164. }
  165. void aes_hal_transform_dma_gcm_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks)
  166. {
  167. aes_hal_dma_init(input, output);
  168. /* Write the number of blocks */
  169. aes_ll_set_num_blocks(num_blocks);
  170. /* Start encrypting/decrypting */
  171. aes_ll_cont_transform();
  172. }
  173. void aes_hal_gcm_init(size_t aad_num_blocks, size_t num_valid_bit)
  174. {
  175. aes_ll_gcm_set_aad_num_blocks(aad_num_blocks);
  176. aes_ll_gcm_set_num_valid_bit(num_valid_bit);
  177. }
  178. void aes_hal_gcm_read_tag(uint8_t *tag, size_t tag_len)
  179. {
  180. uint8_t tag_res[TAG_BYTES];
  181. aes_ll_gcm_read_tag(tag_res);
  182. memcpy(tag, tag_res, tag_len);
  183. }
  184. #endif //SOC_AES_SUPPORT_GCM