• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 #pragma once
16 
17 #include "soc/hwcrypto_reg.h"
18 #include "soc/dport_access.h"
19 #include "hal/aes_types.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 
26 /**
27  * @brief State of AES accelerator, busy or idle
28  *
29  */
30 typedef enum {
31     ESP_AES_STATE_BUSY = 0, /* Transform in progress */
32     ESP_AES_STATE_IDLE,     /* AES accelerator is idle */
33 } esp_aes_state_t;
34 
35 
36 /**
37  * @brief Write the encryption/decryption key to hardware
38  *
39  * @param key Key to be written to the AES hardware
40  * @param key_word_len Number of words in the key
41  *
42  * @return Number of bytes written to hardware, used for fault injection check,
43  *         if a write was skipped then this sum is likely to be wrong
44  */
aes_ll_write_key(const uint8_t * key,size_t key_word_len)45 static inline uint8_t aes_ll_write_key(const uint8_t *key, size_t key_word_len)
46 {
47     /* This variable is used for fault injection checks, so marked volatile to avoid optimisation */
48     volatile uint8_t key_bytes_in_hardware = 0;
49     uint32_t *key_words = (uint32_t *)key;
50 
51     for (int i = 0; i < key_word_len; i++) {
52         DPORT_REG_WRITE(AES_KEY_BASE + i * 4, *(key_words + i));
53         key_bytes_in_hardware += 4;
54     }
55     return key_bytes_in_hardware;
56 }
57 
58 /**
59  * @brief Sets the mode
60  *
61  * @param mode ESP_AES_ENCRYPT = 1, or ESP_AES_DECRYPT = 0
62  * @param key_bytes Number of bytes in the key
63  */
aes_ll_set_mode(int mode,uint8_t key_bytes)64 static inline void aes_ll_set_mode(int mode, uint8_t key_bytes)
65 {
66     const uint32_t MODE_DECRYPT_BIT = 4;
67     unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT;
68 
69     /* See TRM for the mapping between keylength and mode bit */
70     DPORT_REG_WRITE(AES_MODE_REG, mode_reg_base + ((key_bytes / 8) - 2));
71 }
72 
73 /**
74  * @brief Writes message block to AES hardware
75  *
76  * @param input Block to be written
77  */
aes_ll_write_block(const uint8_t * input)78 static inline void aes_ll_write_block(const uint8_t *input)
79 {
80     const uint32_t *input_words = (const uint32_t *)input;
81     uint32_t i0;
82     uint32_t i1;
83     uint32_t i2;
84     uint32_t i3;
85 
86     /* Storing i0,i1,i2,i3 in registers not an array
87     helps a lot with optimisations at -Os level */
88     i0 = input_words[0];
89     DPORT_REG_WRITE(AES_TEXT_BASE, i0);
90 
91     i1 = input_words[1];
92     DPORT_REG_WRITE(AES_TEXT_BASE + 4, i1);
93 
94     i2 = input_words[2];
95     DPORT_REG_WRITE(AES_TEXT_BASE + 8, i2);
96 
97     i3 = input_words[3];
98     DPORT_REG_WRITE(AES_TEXT_BASE + 12, i3);
99 }
100 
101 /**
102  * @brief Read the AES block
103  *
104  * @note If a transform was ran then this is the output
105  *
106  * @param output the output of the transform, length = AES_BLOCK_BYTES
107  */
aes_ll_read_block(void * output)108 static inline void aes_ll_read_block(void *output)
109 {
110     uint32_t *output_words = (uint32_t *)output;
111     esp_dport_access_read_buffer(output_words, AES_TEXT_BASE, AES_BLOCK_WORDS);
112 }
113 
114 
115 /**
116  * @brief Starts block transform
117  *
118  */
aes_ll_start_transform(void)119 static inline void aes_ll_start_transform(void)
120 {
121     DPORT_REG_WRITE(AES_START_REG, 1);
122 }
123 
124 
125 /**
126  * @brief Read state of AES accelerator
127  *
128  * @return esp_aes_state_t
129  */
aes_ll_get_state(void)130 static inline esp_aes_state_t aes_ll_get_state(void)
131 {
132     return DPORT_REG_READ(AES_IDLE_REG);
133 }
134 
135 #ifdef __cplusplus
136 }
137 #endif
138