aes_hal.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. #if SOC_GDMA_SUPPORT_EXTMEM
  67. /* An L2 FIFO bigger than 40 bytes is need when accessing external ram */
  68. gdma_ll_tx_extend_fifo_size_to(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, 40);
  69. gdma_ll_rx_extend_l2_fifo_size_to(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, 40);
  70. gdma_ll_tx_set_block_size_psram(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
  71. gdma_ll_rx_set_block_size_psram(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
  72. #endif //SOC_GDMA_SUPPORT_EXTMEM
  73. /* Set descriptors */
  74. gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, (uint32_t)input);
  75. gdma_ll_rx_set_desc_addr(&GDMA, SOC_GDMA_AES_DMA_CHANNEL, (uint32_t)output);
  76. gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  77. gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  78. /* Start transfer */
  79. gdma_ll_tx_start(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  80. gdma_ll_rx_start(&GDMA, SOC_GDMA_AES_DMA_CHANNEL);
  81. }
  82. static inline bool aes_hal_dma_done(const lldesc_t *output)
  83. {
  84. return (gdma_ll_rx_is_fsm_idle(&GDMA, SOC_GDMA_AES_DMA_CHANNEL) && (output->owner == 0));
  85. }
  86. #endif //SOC_AES_GENERAL_DMA
  87. #if SOC_AES_CRYPTO_DMA
  88. /**
  89. * @brief Initialize the DMA
  90. *
  91. * @param input AES input descriptor (outlink)
  92. * @param output AES output descriptor (inlink)
  93. */
  94. static inline void aes_hal_dma_init(const lldesc_t *input, const lldesc_t *output)
  95. {
  96. crypto_dma_ll_reset();
  97. crypto_dma_ll_set_mode(CRYPTO_DMA_AES);
  98. /* Set descriptors, input to AES comes from outlink DMA and viceversa */
  99. crypto_dma_ll_outlink_set((uint32_t)input);
  100. crypto_dma_ll_inlink_set((uint32_t)output);
  101. /* Start transfer */
  102. crypto_dma_ll_outlink_start();
  103. crypto_dma_ll_inlink_start();
  104. }
  105. static inline bool aes_hal_dma_done(lldesc_t *output)
  106. {
  107. return (crypto_dma_ll_inlink_is_eof() && (output->owner == 0));
  108. }
  109. #endif //SOC_AES_CRYPTO_DMA
  110. void aes_hal_transform_dma_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks)
  111. {
  112. aes_ll_dma_enable(true);
  113. aes_hal_dma_init(input, output);
  114. /* Write the number of blocks */
  115. aes_ll_set_num_blocks(num_blocks);
  116. /* Start encrypting/decrypting */
  117. aes_ll_start_transform();
  118. }
  119. void aes_hal_transform_dma_finish(void)
  120. {
  121. aes_ll_dma_exit();
  122. aes_ll_dma_enable(false);
  123. }
  124. void aes_hal_mode_init(esp_aes_mode_t mode)
  125. {
  126. /* Set the algorith mode CBC, CFB ... */
  127. aes_ll_set_block_mode(mode);
  128. /* Presently hard-coding the INC function to 32 bit */
  129. if (mode == ESP_AES_BLOCK_MODE_CTR) {
  130. aes_ll_set_inc();
  131. }
  132. }
  133. void aes_hal_set_iv(const uint8_t *iv)
  134. {
  135. aes_ll_set_iv(iv);
  136. }
  137. void aes_hal_read_iv(uint8_t *iv)
  138. {
  139. aes_ll_read_iv(iv);
  140. }
  141. static inline void aes_hal_wait_done(void)
  142. {
  143. while (aes_ll_get_state() != ESP_AES_STATE_DONE) {}
  144. }
  145. void aes_hal_wait_dma_done(lldesc_t *output)
  146. {
  147. /* Checking this if interrupt is used also, to avoid
  148. issues with AES fault injection
  149. */
  150. aes_hal_wait_done();
  151. /* Wait for DMA write operation to complete */
  152. while (1) {
  153. if ( aes_hal_dma_done(output) ) {
  154. break;
  155. }
  156. }
  157. }
  158. #endif //SOC_AES_SUPPORT_DMA
  159. #if SOC_AES_SUPPORT_GCM
  160. void aes_hal_gcm_calc_hash(uint8_t *gcm_hash)
  161. {
  162. aes_ll_dma_enable(true);
  163. aes_ll_start_transform();
  164. aes_hal_wait_idle();
  165. aes_ll_gcm_read_hash(gcm_hash);
  166. }
  167. void aes_hal_transform_dma_gcm_start(const lldesc_t *input, const lldesc_t *output, size_t num_blocks)
  168. {
  169. aes_hal_dma_init(input, output);
  170. /* Write the number of blocks */
  171. aes_ll_set_num_blocks(num_blocks);
  172. /* Start encrypting/decrypting */
  173. aes_ll_cont_transform();
  174. }
  175. void aes_hal_gcm_init(size_t aad_num_blocks, size_t num_valid_bit)
  176. {
  177. aes_ll_gcm_set_aad_num_blocks(aad_num_blocks);
  178. aes_ll_gcm_set_num_valid_bit(num_valid_bit);
  179. }
  180. void aes_hal_gcm_read_tag(uint8_t *tag, size_t tag_len)
  181. {
  182. uint8_t tag_res[TAG_BYTES];
  183. aes_ll_gcm_read_tag(tag_res);
  184. memcpy(tag, tag_res, tag_len);
  185. }
  186. #endif //SOC_AES_SUPPORT_GCM