aes_hal.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. #include "soc/gdma_channel.h"
  26. #endif
  27. uint8_t aes_hal_setkey(const uint8_t *key, size_t key_bytes, int mode)
  28. {
  29. aes_ll_set_mode(mode, key_bytes);
  30. uint8_t key_bytes_in_hardware = aes_ll_write_key(key, key_bytes / 4);
  31. /* Used for fault injection check: all words of key data should have been written to hardware */
  32. return key_bytes_in_hardware;
  33. }
  34. /**
  35. * @brief Busy wait until the AES accelerator is idle
  36. *
  37. */
  38. static inline void aes_hal_wait_idle(void)
  39. {
  40. while (aes_ll_get_state() != ESP_AES_STATE_IDLE) {
  41. }
  42. }
  43. void aes_hal_transform_block(const void *input_block, void *output_block)
  44. {
  45. aes_ll_write_block(input_block);
  46. aes_ll_start_transform();
  47. aes_hal_wait_idle();
  48. aes_ll_read_block(output_block);
  49. }
  50. #if SOC_AES_SUPPORT_DMA
  51. #if SOC_AES_GENERAL_DMA
  52. /**
  53. * @brief Initialize the DMA
  54. *
  55. * @param input AES input descriptor (outlink)
  56. * @param output AES output descriptor (inlink)
  57. */
  58. static inline void aes_hal_dma_init(const lldesc_t *input, const lldesc_t *output)
  59. {
  60. /* Update driver when centralized DMA interface implemented, IDF-2192 */
  61. gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
  62. gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
  63. gdma_ll_rx_enable_descriptor_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
  64. gdma_ll_rx_enable_data_burst(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, false);
  65. gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, SOC_GDMA_TRIG_PERIPH_AES0);
  66. gdma_ll_rx_connect_to_periph(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, SOC_GDMA_TRIG_PERIPH_AES0);
  67. #if SOC_GDMA_SUPPORT_EXTMEM
  68. /* An L2 FIFO bigger than 40 bytes is need when accessing external ram */
  69. gdma_ll_tx_extend_fifo_size_to(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, 40);
  70. gdma_ll_rx_extend_l2_fifo_size_to(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, 40);
  71. gdma_ll_tx_set_block_size_psram(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
  72. gdma_ll_rx_set_block_size_psram(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
  73. #endif //SOC_GDMA_SUPPORT_EXTMEM
  74. /* Set descriptors */
  75. gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, (uint32_t)input);
  76. gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, (uint32_t)output);
  77. gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  78. gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  79. /* Start transfer */
  80. gdma_ll_tx_start(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  81. gdma_ll_rx_start(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  82. }
  83. static inline bool aes_hal_dma_done(const lldesc_t *output)
  84. {
  85. return (gdma_ll_rx_is_fsm_idle(&GDMA, SOC_GDMA_AES_DMA_CHANNEL) && (output->owner == 0));
  86. }
  87. #endif //SOC_AES_GENERAL_DMA
  88. #if SOC_AES_CRYPTO_DMA
  89. /**
  90. * @brief Initialize the DMA
  91. *
  92. * @param input AES input descriptor (outlink)
  93. * @param output AES output descriptor (inlink)
  94. */
  95. static inline void aes_hal_dma_init(const lldesc_t *input, const lldesc_t *output)
  96. {
  97. crypto_dma_ll_reset();
  98. crypto_dma_ll_set_mode(CRYPTO_DMA_AES);
  99. /* Set descriptors, input to AES comes from outlink DMA and viceversa */
  100. crypto_dma_ll_outlink_set((uint32_t)input);
  101. crypto_dma_ll_inlink_set((uint32_t)output);
  102. /* Start transfer */
  103. crypto_dma_ll_outlink_start();
  104. crypto_dma_ll_inlink_start();
  105. }
  106. static inline bool aes_hal_dma_done(lldesc_t *output)
  107. {
  108. return (crypto_dma_ll_inlink_is_eof() && (output->owner == 0));
  109. }
  110. #endif //SOC_AES_CRYPTO_DMA
  111. void aes_hal_transform_dma_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks)
  112. {
  113. aes_ll_dma_enable(true);
  114. aes_hal_dma_init(input, output);
  115. /* Write the number of blocks */
  116. aes_ll_set_num_blocks(num_blocks);
  117. /* Start encrypting/decrypting */
  118. aes_ll_start_transform();
  119. }
  120. void aes_hal_transform_dma_finish(void)
  121. {
  122. aes_ll_dma_exit();
  123. aes_ll_dma_enable(false);
  124. }
  125. void aes_hal_mode_init(esp_aes_mode_t mode)
  126. {
  127. /* Set the algorith mode CBC, CFB ... */
  128. aes_ll_set_block_mode(mode);
  129. /* Presently hard-coding the INC function to 32 bit */
  130. if (mode == ESP_AES_BLOCK_MODE_CTR) {
  131. aes_ll_set_inc();
  132. }
  133. }
  134. void aes_hal_set_iv(const uint8_t *iv)
  135. {
  136. aes_ll_set_iv(iv);
  137. }
  138. void aes_hal_read_iv(uint8_t *iv)
  139. {
  140. aes_ll_read_iv(iv);
  141. }
  142. static inline void aes_hal_wait_done(void)
  143. {
  144. while (aes_ll_get_state() != ESP_AES_STATE_DONE) {}
  145. }
  146. void aes_hal_wait_dma_done(lldesc_t *output)
  147. {
  148. /* Checking this if interrupt is used also, to avoid
  149. issues with AES fault injection
  150. */
  151. aes_hal_wait_done();
  152. /* Wait for DMA write operation to complete */
  153. while (1) {
  154. if ( aes_hal_dma_done(output) ) {
  155. break;
  156. }
  157. }
  158. }
  159. #endif //SOC_AES_SUPPORT_DMA
  160. #if SOC_AES_SUPPORT_GCM
  161. void aes_hal_gcm_calc_hash(uint8_t *gcm_hash)
  162. {
  163. aes_ll_dma_enable(true);
  164. aes_ll_start_transform();
  165. aes_hal_wait_idle();
  166. aes_ll_gcm_read_hash(gcm_hash);
  167. }
  168. void aes_hal_transform_dma_gcm_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks)
  169. {
  170. aes_hal_dma_init(input, output);
  171. /* Write the number of blocks */
  172. aes_ll_set_num_blocks(num_blocks);
  173. /* Start encrypting/decrypting */
  174. aes_ll_cont_transform();
  175. }
  176. void aes_hal_gcm_init(size_t aad_num_blocks, size_t num_valid_bit)
  177. {
  178. aes_ll_gcm_set_aad_num_blocks(aad_num_blocks);
  179. aes_ll_gcm_set_num_valid_bit(num_valid_bit);
  180. }
  181. void aes_hal_gcm_read_tag(uint8_t *tag, size_t tag_len)
  182. {
  183. uint8_t tag_res[TAG_BYTES];
  184. aes_ll_gcm_read_tag(tag_res);
  185. memcpy(tag, tag_res, tag_len);
  186. }
  187. #endif //SOC_AES_SUPPORT_GCM