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