1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /***********************************************************************************************************************
8 * Includes
9 **********************************************************************************************************************/
10
11 #include "sc324_aes_private.h"
12 #include "hw_sce_private.h"
13 #include "hw_sce_aes_private.h"
14
hw_sc324_aes_kernel_module_enable()15 __STATIC_INLINE void hw_sc324_aes_kernel_module_enable ()
16 {
17 R_AES->AESMOD_b.MODEN = 1;
18 }
19
hw_sc324_aes_kernel_module_disable()20 __STATIC_INLINE void hw_sc324_aes_kernel_module_disable ()
21 {
22 R_AES->AESMOD_b.MODEN = 0;
23 }
24
hw_sc324_aes_kernel_wait_com_write_ready()25 __STATIC_INLINE void hw_sc324_aes_kernel_wait_com_write_ready ()
26 {
27 // wait for com_write_ready
28 while (R_AES->AESCMD_b.CWRDY == 0)
29 {
30 ;
31 }
32 }
33
hw_sc324_aes_kernel_inverse_cipher_set(hw_sc324_aes_encrypt_flag_t flag)34 __STATIC_INLINE void hw_sc324_aes_kernel_inverse_cipher_set (hw_sc324_aes_encrypt_flag_t flag)
35 {
36 // wait for com_write_ready
37 hw_sc324_aes_kernel_wait_com_write_ready();
38
39 // set the inverse_cipher mode to encrypt
40 R_AES->AESCMD_b.INVCIP = flag;
41 }
42
hw_sc324_aes_kernel_chaining_mode_set(hw_sc324_aes_modes_t aes_chaining_mode)43 __STATIC_INLINE void hw_sc324_aes_kernel_chaining_mode_set (hw_sc324_aes_modes_t aes_chaining_mode)
44 {
45 // wait for com_write_ready
46 hw_sc324_aes_kernel_wait_com_write_ready();
47 R_AES->AESCMD_b.CHAIN = aes_chaining_mode;
48 }
49
hw_sc324_aes_endian_convert(uint32_t * p_dest,const uint32_t * p_source,uint32_t num_words)50 static void hw_sc324_aes_endian_convert (uint32_t * p_dest, const uint32_t * p_source, uint32_t num_words)
51 {
52 uint32_t nw;
53 for (nw = 0; nw < num_words; nw++)
54 {
55 p_dest[nw] = __REV(p_source[nw]);
56 }
57 }
58
hw_sc324_aes_kernel_key_set(const uint32_t * p_key,hw_sc324_aes_keysizes_t key_length)59 static void hw_sc324_aes_kernel_key_set (const uint32_t * p_key, hw_sc324_aes_keysizes_t key_length)
60 {
61 uint32_t temp[4];
62
63 // wait for com_write_ready
64 hw_sc324_aes_kernel_wait_com_write_ready();
65
66 // set the key_length
67 R_AES->AESCMD_b.KEYLN = key_length;
68
69 // wait for key_write_ready0
70 while (R_AES->AESCMD_b.KWRDY0 == 0)
71 {
72 ;
73 }
74
75 hw_sc324_aes_endian_convert(temp, (uint32_t *) p_key, 4);
76 R_AES->AESKW0 = temp[0];
77 R_AES->AESKW0 = temp[1];
78 R_AES->AESKW0 = temp[2];
79 R_AES->AESKW0 = temp[3];
80
81 if (key_length == SC324_AES_KEYSIZE_128)
82 {
83 return;
84 }
85
86 // wait for key_write_ready1
87 while (R_AES->AESCMD_b.KWRDY1 == 0)
88 {
89 ;
90 }
91
92 hw_sc324_aes_endian_convert(temp, (uint32_t *) p_key + 4, 4);
93 R_AES->AESKW1 = temp[0];
94 R_AES->AESKW1 = temp[1];
95 R_AES->AESKW1 = temp[2];
96 R_AES->AESKW1 = temp[3];
97 }
98
hw_sc324_aes_kernel_iv_set(const uint32_t * p_iv)99 static void hw_sc324_aes_kernel_iv_set (const uint32_t * p_iv)
100 {
101 uint32_t temp[4];
102
103 // wait for iv_write_ready
104 while (R_AES->AESCMD_b.IWRDY == 0)
105 {
106 ;
107 }
108
109 hw_sc324_aes_endian_convert(temp, p_iv, 4);
110 R_AES->AESIVW = temp[0];
111 R_AES->AESIVW = temp[1];
112 R_AES->AESIVW = temp[2];
113 R_AES->AESIVW = temp[3];
114 }
115
hw_sc324_aes_kernel_iv_get(uint32_t * p_iv)116 static void hw_sc324_aes_kernel_iv_get (uint32_t * p_iv)
117 {
118 uint32_t temp[4];
119
120 // wait for iv_read_ready
121 while (R_AES->AESCMD_b.IRRDY == 0)
122 {
123 ;
124 }
125
126 temp[0] = R_AES->AESIVW;
127 temp[1] = R_AES->AESIVW;
128 temp[2] = R_AES->AESIVW;
129 temp[3] = R_AES->AESIVW;
130
131 hw_sc324_aes_endian_convert(p_iv, temp, 4);
132 }
133
hw_sc324_aes_kernel_data_write(const uint32_t * p_data)134 static void hw_sc324_aes_kernel_data_write (const uint32_t * p_data)
135 {
136 uint32_t temp[4];
137
138 // wait for write_ready
139 while (R_AES->AESCMD_b.DWRDY == 0)
140 {
141 ;
142 }
143
144 hw_sc324_aes_endian_convert(temp, (uint32_t *) p_data, 4);
145 R_AES->AESDW = temp[0];
146 R_AES->AESDW = temp[1];
147 R_AES->AESDW = temp[2];
148 R_AES->AESDW = temp[3];
149 }
150
hw_sc324_aes_kernel_data_read(uint32_t * p_data)151 static void hw_sc324_aes_kernel_data_read (uint32_t * p_data)
152 {
153 uint32_t temp[4];
154
155 // wait for read_ready
156 while (R_AES->AESCMD_b.DRRDY == 0)
157 {
158 ;
159 }
160
161 temp[0] = R_AES->AESDW;
162 temp[1] = R_AES->AESDW;
163 temp[2] = R_AES->AESDW;
164 temp[3] = R_AES->AESDW;
165 hw_sc324_aes_endian_convert(p_data, temp, 4);
166 }
167
168 /*******************************************************************************************************************//**
169 * Helper routine to process AES encryption and Decryption.
170 *
171 * @param p_ctrl The control
172 * @param[in] InData_Key In data key
173 * @param[in] InData_IV In data iv
174 * @param[in] num_words The number words
175 * @param[in] InData_Text In data text
176 * @param OutData_Text The out data text
177 * @param OutData_IV The out data iv
178 *
179 * @retval FSP_SUCCESS The operation completed successfully.
180 * @retval FSP_ERR_CRYPTO_INVALID_SIZE The size of the data must be multiples of 4 WORDS / 16 bytes.
181 *
182 **********************************************************************************************************************/
hw_sc324_aes_kernel_process_data(hw_sc324_aes_ctrl_t * p_ctrl,const uint32_t * InData_Key,const uint32_t * InData_IV,const uint32_t num_words,const uint32_t * InData_Text,uint32_t * OutData_Text,uint32_t * OutData_IV)183 fsp_err_t hw_sc324_aes_kernel_process_data (hw_sc324_aes_ctrl_t * p_ctrl,
184 const uint32_t * InData_Key,
185 const uint32_t * InData_IV,
186 const uint32_t num_words,
187 const uint32_t * InData_Text,
188 uint32_t * OutData_Text,
189 uint32_t * OutData_IV)
190 {
191 // truncate the number of words to process to multiples of 16 bytes (1 block of data)
192 if ((0 == num_words) || (0 != (num_words % SIZE_AES_BLOCK_WORDS)))
193 {
194 return FSP_ERR_CRYPTO_INVALID_SIZE;
195 }
196
197 // 1. Enable AES Module (set the AESMOD.module_en to 1)
198 hw_sc324_aes_kernel_module_enable();
199
200 // 2. Write the key to key_register0 or key_register1
201 // When writing to the key-register0, write 1 word (32 bits) to AESKW0
202 // after confirmation of key_write_ready0 = 1
203 // When writing to the key-register1, write 1 word (32 bits) to AESKW1
204 // after confirmation of key_write_ready1 = 1
205 hw_sc324_aes_kernel_key_set(InData_Key, p_ctrl->keysize);
206
207 // 3. In CBC or CTR mode, write IV data to iv-register
208 // When writing to iv-register, you must write the whole 4 words of data.
209 hw_sc324_aes_kernel_chaining_mode_set(p_ctrl->mode);
210 if (InData_IV)
211 {
212 hw_sc324_aes_kernel_iv_set(InData_IV);
213 }
214
215 // 4. Write the setting data to AESCMD
216 // When writing to the AESCMD, check if the AESCMD.com_write_ready is 1
217 hw_sc324_aes_kernel_inverse_cipher_set(p_ctrl->encrypt_flag);
218
219 for (uint32_t indx = 0; indx < num_words; indx += SIZE_AES_BLOCK_WORDS)
220 {
221 // 5. Write data to data-register (one block (128 bits) of data).
222 // When writing to data-register, write 1 word (32 bits) to AESDW after confirmation of write_ready=1
223 // When you write to the data-register, you write the whole 4 words of data.
224 hw_sc324_aes_kernel_data_write(InData_Text + indx);
225
226 // 6. When encrypt (decrypt) is completed, read_ready will be 1. The read_request will be asserted
227 // and you will be able to read the data on which encrypt (decrypt) was done. Please read
228 // 1 word (32 bits) from AESDW.
229 // When reading iv_data, read 1 word (32 bits) from AESIVW after confirmation of iv_read_ready=1
230 // When you read the iv-window, you must read the whole 4 words of data.
231 hw_sc324_aes_kernel_data_read(OutData_Text + indx);
232
233 // 7. When encrypt (decrypt) is completed, write_ready will be 1. The write_request will be
234 // asserted. When continuing encrypting (decrypting), write 1 block of data (128 bits) to
235 // data-register.
236 // When you write to the data-window, you must write the whole 4 words of data.
237 // When writing to data-register, write 1 word (32 bits) to AESDW after confirmation of write_ready=1
238 continue;
239 }
240
241 if (OutData_IV)
242 {
243 hw_sc324_aes_kernel_iv_get(OutData_IV);
244 }
245
246 // 8. When ending use of a AES module, please write 0 to mode-register.module_en
247 hw_sc324_aes_kernel_module_disable();
248
249 return FSP_SUCCESS;
250 }
251