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 #pragma once
15 
16 #include <stdbool.h>
17 #include "soc/hwcrypto_reg.h"
18 #include "hal/sha_types.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 
25 /**
26  * @brief Start a new SHA block conversions (no initial hash in HW)
27  *
28  * @param sha_type The SHA algorithm type
29  */
sha_ll_start_block(esp_sha_type sha_type)30 static inline void sha_ll_start_block(esp_sha_type sha_type)
31 {
32     REG_WRITE(SHA_MODE_REG, sha_type);
33     REG_WRITE(SHA_START_REG, 1);
34 }
35 
36 /**
37  * @brief Continue a SHA block conversion (initial hash in HW)
38  *
39  * @param sha_type The SHA algorithm type
40  */
sha_ll_continue_block(esp_sha_type sha_type)41 static inline void sha_ll_continue_block(esp_sha_type sha_type)
42 {
43     REG_WRITE(SHA_MODE_REG, sha_type);
44     REG_WRITE(SHA_CONTINUE_REG, 1);
45 }
46 
47 /**
48  * @brief Start a new SHA message conversion using DMA (no initial hash in HW)
49  *
50  * @param sha_type The SHA algorithm type
51  */
sha_ll_start_dma(esp_sha_type sha_type)52 static inline void sha_ll_start_dma(esp_sha_type sha_type)
53 {
54     REG_WRITE(SHA_MODE_REG, sha_type);
55     REG_WRITE(SHA_DMA_START_REG, 1);
56 }
57 
58 /**
59  * @brief Continue a SHA message conversion using DMA (initial hash in HW)
60  *
61  * @param sha_type The SHA algorithm type
62  */
sha_ll_continue_dma(esp_sha_type sha_type)63 static inline void sha_ll_continue_dma(esp_sha_type sha_type)
64 {
65     REG_WRITE(SHA_MODE_REG, sha_type);
66     REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
67 }
68 
69 /**
70  * @brief Load the current hash digest to digest register
71  *
72  * @note Happens automatically on ESP32S3
73  *
74  * @param sha_type The SHA algorithm type
75  */
sha_ll_load(esp_sha_type sha_type)76 static inline void sha_ll_load(esp_sha_type sha_type)
77 {
78 }
79 
80 /**
81  * @brief Sets the number of message blocks to be hashed
82  *
83  * @note DMA operation only
84  *
85  * @param num_blocks Number of message blocks to process
86  */
sha_ll_set_block_num(size_t num_blocks)87 static inline void sha_ll_set_block_num(size_t num_blocks)
88 {
89     REG_WRITE(SHA_BLOCK_NUM_REG, num_blocks);
90 }
91 
92 /**
93  * @brief Checks if the SHA engine is currently busy hashing a block
94  *
95  * @return true SHA engine busy
96  * @return false SHA engine idle
97  */
sha_ll_busy(void)98 static inline bool sha_ll_busy(void)
99 {
100     return REG_READ(SHA_BUSY_REG);
101 }
102 
103 /**
104  * @brief Write a text (message) block to the SHA engine
105  *
106  * @param input_text Input buffer to be written to the SHA engine
107  * @param block_word_len Number of words in block
108  */
sha_ll_fill_text_block(const void * input_text,size_t block_word_len)109 static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len)
110 {
111     uint32_t *data_words = (uint32_t *)input_text;
112     uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
113 
114     for (int i = 0; i < block_word_len; i++) {
115         REG_WRITE(&reg_addr_buf[i], data_words[i]);
116     }
117 }
118 
119 /**
120  * @brief Read the message digest from the SHA engine
121  *
122  * @param sha_type The SHA algorithm type
123  * @param digest_state Buffer that message digest will be written to
124  * @param digest_word_len Length of the message digest
125  */
sha_ll_read_digest(esp_sha_type sha_type,void * digest_state,size_t digest_word_len)126 static inline void sha_ll_read_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
127 {
128     uint32_t *digest_state_words = (uint32_t *)digest_state;
129     const size_t REG_WIDTH = sizeof(uint32_t);
130 
131     for (size_t i = 0; i < digest_word_len; i++) {
132         digest_state_words[i] = REG_READ(SHA_H_BASE + (i * REG_WIDTH));
133     }
134 
135 }
136 
137 /**
138  * @brief Write the message digest to the SHA engine
139  *
140  * @param sha_type The SHA algorithm type
141  * @param digest_state Message digest to be written to SHA engine
142  * @param digest_word_len Length of the message digest
143  */
sha_ll_write_digest(esp_sha_type sha_type,void * digest_state,size_t digest_word_len)144 static inline void sha_ll_write_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
145 {
146     uint32_t *digest_state_words = (uint32_t *)digest_state;
147     uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
148 
149     for (int i = 0; i < digest_word_len; i++) {
150         REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
151     }
152 }
153 
154 
155 #ifdef __cplusplus
156 }
157 #endif
158