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 "bsp_api.h"
12 #include "hw_sce_aes_private.h"
13 #include "hw_sce_ra_private.h"
14
15 /***********************************************************************************************************************
16 * Global variables and functions
17 ***********************************************************************************************************************/
18
hw_gcm_calculation(uint8_t * input,uint8_t * output,uint32_t data_len,uint8_t * atag,uint8_t * initial_vector,uint32_t iv_len,uint8_t * aad,uint32_t aad_len)19 fsp_err_t hw_gcm_calculation (uint8_t * input,
20 uint8_t * output,
21 uint32_t data_len,
22 uint8_t * atag,
23 uint8_t * initial_vector,
24 uint32_t iv_len,
25 uint8_t * aad,
26 uint32_t aad_len)
27 {
28 uint32_t len = 0;
29 uint32_t temp_len = 0;
30 uint32_t temp_value = 0;
31 uint8_t first_block_null_aad = 0;
32 uint8_t Jn[16] = {0};
33 uint8_t J0[16] = {0};
34 uint8_t data[16] = {0};
35 uint8_t local_in[SIZE_AES_BLOCK_BYTES] = {0};
36 uint8_t local_out[SIZE_AES_BLOCK_BYTES] = {0};
37 uint8_t * ptr;
38 uint8_t * ptr_out_temp;
39 uint8_t * ptr_out;
40 fsp_err_t status = FSP_SUCCESS;
41 uint8_t temp_output[SIZE_AES_BLOCK_BYTES];
42 bool src_unaligned = !HW_32BIT_ALIGNED((uint32_t) &input[0]);
43 bool dst_unaligned = !HW_32BIT_ALIGNED((uint32_t) &output[0]);
44 uint8_t * buf_in = input;
45 uint8_t * buf_out = output;
46 uint8_t * p_in = input;
47 uint8_t * p_out = output;
48
49 if (src_unaligned)
50 {
51 memset(local_in, 0, (size_t) sizeof(local_in));
52 p_in = &local_in[0];
53 }
54
55 if (dst_unaligned)
56 {
57 p_out = &local_out[0];
58 }
59
60 if ((uint8_t) iv_len == 12)
61 {
62 memcpy(&J0, initial_vector, 12);
63 J0[15] = 1;
64 }
65 else
66 {
67 ptr = initial_vector;
68 temp_len = iv_len;
69 R_AES_B->AESDCNTL |= R_AES_AESDCNTL_BIT_2 | R_AES_AESDCNTL_BIT_3;
70 do
71 {
72 len = 16;
73 if (temp_len < 16)
74 {
75 len = temp_len;
76 }
77
78 temp_len -= len;
79 hw_aes_start(ptr, &J0[0], 1);
80 ptr += len;
81 } while (temp_len > 0);
82
83 for (int16_t iLoop = 0; iLoop < 8; iLoop++)
84 {
85 data[iLoop] = 0;
86 }
87
88 for (int16_t iLoop = 0; iLoop < 8; iLoop++)
89 {
90 temp_len = (uint32_t) ((uint8_t) iv_len * 8);
91 temp_len >>= (8 * iLoop);
92 data[15 - iLoop] = (uint8_t) temp_len;
93 }
94
95 hw_aes_start(&data[0], &J0[0], 1);
96 }
97
98 /* Flow to Obtain J0 from IV End */
99 /* Flow to Obtain J1 from J0 */
100
101 memcpy(Jn, J0, 16);
102
103 for (int16_t iLoop = 0; iLoop < 4; iLoop++)
104 {
105 temp_value = Jn[15 - iLoop];
106 if (temp_value != 0xFF) // NOLINT(readability-magic-numbers)
107 {
108 Jn[15 - iLoop] += 1;
109 break;
110 }
111
112 Jn[15 - iLoop] = 0;
113 }
114
115 hw_aes_set_iv(Jn);
116
117 /* Athentication Tag Creation Start */
118 if (aad_len != 0)
119 {
120 /* Flow to Obtain AAD Hash Value Start */
121 ptr = aad;
122 temp_len = aad_len;
123 R_AES_B->AESDCNTL |= R_AES_AESDCNTL_BIT_2;
124
125 do
126 {
127 len = 16;
128 if (temp_len < 16)
129 {
130 len = temp_len;
131 memset(data, 0, (size_t) sizeof(data));
132 memcpy(data, ptr, (size_t) len);
133 hw_aes_start(&data[0], &data[0], 1);
134 }
135 else
136 {
137 hw_aes_start(ptr, &data[0], 1);
138 }
139
140 ptr += len;
141 temp_len -= len;
142 } while (temp_len > 0);
143
144 /* Flow to Obtain AAD Hash Value End */
145 }
146 else
147 {
148 first_block_null_aad = 1;
149 }
150
151 /* Encryption Flow Start */
152 if (data_len != 0)
153 {
154 ptr = input;
155 ptr_out = output;
156 temp_len = data_len;
157 do
158 {
159 if (src_unaligned)
160 {
161 memcpy(&local_in[0], &buf_in[0], SIZE_AES_BLOCK_BYTES);
162 }
163
164 ptr_out_temp = &temp_output[0];
165 temp_value = 0;
166 len = SIZE_AES_BLOCK_BYTES;
167 if (temp_len < SIZE_AES_BLOCK_BYTES)
168 {
169 len = temp_len;
170 temp_value = temp_len * 8;
171 temp_value <<= 8;
172 temp_value |= R_AES_AESDCNTL_BIT_4;
173 }
174
175 temp_len -= len;
176 R_AES_B->AESDCNTL = ((uint16_t) temp_value | R_AES_AESDCNTL_BIT_5);
177 if (first_block_null_aad == 1)
178 {
179 first_block_null_aad = 0;
180 R_AES_B->AESDCNTL |= R_AES_AESDCNTL_BIT_2;
181 }
182
183 if ((src_unaligned || dst_unaligned) && (temp_len > 0)) // unaligned data in normal block
184 {
185 hw_aes_start(p_in, p_out, 1);
186 ptr_out += SIZE_AES_BLOCK_BYTES;
187 if (dst_unaligned)
188 {
189 memcpy(&buf_out[0], &p_out[0], SIZE_AES_BLOCK_BYTES);
190 buf_out += SIZE_AES_BLOCK_BYTES;
191 }
192 else
193 {
194 p_out += SIZE_AES_BLOCK_BYTES;
195 }
196
197 if (src_unaligned)
198 {
199 buf_in += SIZE_AES_BLOCK_BYTES;
200 }
201 else
202 {
203 p_in += SIZE_AES_BLOCK_BYTES;
204 }
205 }
206 else if (temp_len > 0)
207 {
208 hw_aes_start(ptr, ptr_out, 1);
209 ptr_out += SIZE_AES_BLOCK_BYTES;
210 }
211 else
212 {
213 memset(data, 0, sizeof(data));
214 memcpy(data, ptr, (size_t) len);
215 hw_aes_start(&data[0], ptr_out_temp, 1);
216 memcpy(ptr_out, &temp_output[0], (size_t) len);
217 ptr_out_temp += SIZE_AES_BLOCK_BYTES;
218 ptr_out += SIZE_AES_BLOCK_BYTES;
219 }
220
221 ptr += len;
222 for (int16_t iLoop = 0; iLoop < 4; iLoop++)
223 {
224 temp_value = Jn[15 - iLoop];
225 if (temp_value == 0xFF) // NOLINT(readability-magic-numbers)
226 {
227 Jn[15 - iLoop] = 0;
228 }
229 else
230 {
231 Jn[15 - iLoop] += 1;
232 break;
233 }
234 }
235
236 hw_aes_set_iv(Jn);
237 } while (temp_len > 0);
238 }
239
240 /* Encryption Flow End */
241
242 hw_aes_set_iv(J0);
243 for (int16_t iLoop = 0; iLoop < 8; iLoop++)
244 {
245 temp_len = aad_len * 8;
246 temp_len >>= (8 * iLoop);
247 Jn[7 - iLoop] = (uint8_t) temp_len;
248 temp_len = data_len * 8;
249 temp_len >>= (8 * iLoop);
250 Jn[15 - iLoop] = (uint8_t) temp_len;
251 }
252
253 if (((uint8_t) iv_len == 12) && (aad_len == 0) && (data_len == 0))
254 {
255 R_AES_B->AESDCNTL = R_AES_AESDCNTL_BIT_2 | R_AES_AESDCNTL_BIT_3 | R_AES_AESDCNTL_BIT_6;
256 }
257 else if (((uint8_t) iv_len != 12) && (aad_len == 0) && (data_len == 0))
258 {
259 R_AES_B->AESDCNTL = R_AES_AESDCNTL_BIT_2 | R_AES_AESDCNTL_BIT_6;
260 }
261 else
262 {
263 R_AES_B->AESDCNTL = R_AES_AESDCNTL_BIT_6;
264 }
265
266 hw_aes_start(&Jn[0], atag, 1);
267
268 /* Athentication Tag Creation End*/
269 return status;
270 }
271