1 /***************************************************************************//**
2 * @file
3 * @brief Advanced encryption standard (AES) accelerator peripheral API.
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #ifndef EM_AES_H
32 #define EM_AES_H
33
34 #include "em_device.h"
35 #if defined(AES_COUNT) && (AES_COUNT > 0)
36
37 #include "em_aes_compat.h"
38 #include <stdbool.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 /***************************************************************************//**
45 * @addtogroup aes AES - AES Accelerator
46 * @brief Advanced Encryption Standard Accelerator (AES) Peripheral API.
47 *
48 * @details
49 * The AES peripheral supports AES block cipher encryption and decryption with
50 * 128 bit and 256 bit keys. The following block cipher modes are supported:
51 * @li CBC - Cipher Block Chaining mode
52 * @li CFB - Cipher Feedback mode
53 * @li CTR - Counter mode
54 * @li ECB - Electronic Code Book mode
55 * @li OFB - Output Feedback mode
56 *
57 * The following input/output notations should be noted:
58 *
59 * @li Input/output data (plaintext, ciphertext, key, and so on) are treated as
60 * byte arrays, starting with the most significant byte, i.e., 32 bytes of
61 * plaintext (B0...B31) is located in memory in the same order, with B0 at
62 * the lower address and B31 at the higher address.
63 *
64 * @li Byte arrays must always be a multiple of AES block size, i.e., a multiple
65 * of 16. Padding, if required, is done at the end of the byte array.
66 *
67 * @li Byte arrays should be word (32 bit) aligned for performance
68 * considerations, since the array is accessed with a 32 bit access type.
69 * Cortex-M supports unaligned accesses with a performance penalty.
70 *
71 * @li It is possible to specify the same output buffer as an input buffer
72 * as long as they point to the same address. In that case, the provided input
73 * buffer is replaced with the encrypted/decrypted output. Notice that
74 * buffers must be exactly overlapping. If partly overlapping, the
75 * behavior is undefined.
76 *
77 * Use a cipher mode according to its requirements to avoid
78 * breaking security. See a specific cipher mode
79 * theory for details.
80 *
81 * References:
82 * @li Wikipedia - Cipher modes, http://en.wikipedia.org/wiki/Cipher_modes
83 *
84 * @li Recommendation for Block Cipher Modes of Operation,
85 * NIST Special Publication 800-38A, 2001 Edition,
86 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
87 *
88 * The following example shows how to perform an AES-128 CBC encryption:
89 *
90 * Enable clocks:
91 * @include em_aes_clock_enable.c
92 *
93 * Execute AES-128 CBC encryption:
94 * @include em_aes_basic_usage.c
95 *
96 * @{
97 ******************************************************************************/
98
99 /*******************************************************************************
100 ****************************** TYPEDEFS ***********************************
101 ******************************************************************************/
102
103 /**
104 * @brief
105 * An AES counter modification function pointer.
106 * @details
107 * Parameters:
108 * @li ctr - Ptr to byte array (16 bytes) holding a counter to be modified.
109 */
110 typedef void (*AES_CtrFuncPtr_TypeDef)(uint8_t *ctr);
111
112 /*******************************************************************************
113 ***************************** PROTOTYPES **********************************
114 ******************************************************************************/
115
116 void AES_CBC128(uint8_t *out,
117 const uint8_t *in,
118 unsigned int len,
119 const uint8_t *key,
120 const uint8_t *iv,
121 bool encrypt);
122
123 #if defined(AES_CTRL_AES256)
124 void AES_CBC256(uint8_t *out,
125 const uint8_t *in,
126 unsigned int len,
127 const uint8_t *key,
128 const uint8_t *iv,
129 bool encrypt);
130 #endif
131
132 void AES_CFB128(uint8_t *out,
133 const uint8_t *in,
134 unsigned int len,
135 const uint8_t *key,
136 const uint8_t *iv,
137 bool encrypt);
138
139 #if defined(AES_CTRL_AES256)
140 void AES_CFB256(uint8_t *out,
141 const uint8_t *in,
142 unsigned int len,
143 const uint8_t *key,
144 const uint8_t *iv,
145 bool encrypt);
146 #endif
147
148 void AES_CTR128(uint8_t *out,
149 const uint8_t *in,
150 unsigned int len,
151 const uint8_t *key,
152 uint8_t *ctr,
153 AES_CtrFuncPtr_TypeDef ctrFunc);
154
155 #if defined(AES_CTRL_AES256)
156 void AES_CTR256(uint8_t *out,
157 const uint8_t *in,
158 unsigned int len,
159 const uint8_t *key,
160 uint8_t *ctr,
161 AES_CtrFuncPtr_TypeDef ctrFunc);
162 #endif
163
164 void AES_CTRUpdate32Bit(uint8_t *ctr);
165
166 void AES_DecryptKey128(uint8_t *out, const uint8_t *in);
167
168 #if defined(AES_CTRL_AES256)
169 void AES_DecryptKey256(uint8_t *out, const uint8_t *in);
170 #endif
171
172 void AES_ECB128(uint8_t *out,
173 const uint8_t *in,
174 unsigned int len,
175 const uint8_t *key,
176 bool encrypt);
177
178 #if defined(AES_CTRL_AES256)
179 void AES_ECB256(uint8_t *out,
180 const uint8_t *in,
181 unsigned int len,
182 const uint8_t *key,
183 bool encrypt);
184 #endif
185
186 /***************************************************************************//**
187 * @brief
188 * Clear one or more pending AES interrupts.
189 *
190 * @param[in] flags
191 * A pending AES interrupt source to clear. Use a bitwise logic OR combination of
192 * valid interrupt flags for the AES module (AES_IF_nnn).
193 ******************************************************************************/
AES_IntClear(uint32_t flags)194 __STATIC_INLINE void AES_IntClear(uint32_t flags)
195 {
196 AES->IFC = flags;
197 }
198
199 /***************************************************************************//**
200 * @brief
201 * Disable one or more AES interrupts.
202 *
203 * @param[in] flags
204 * An AES interrupt sources to disable. Use a bitwise logic OR combination of
205 * valid interrupt flags for the AES module (AES_IF_nnn).
206 ******************************************************************************/
AES_IntDisable(uint32_t flags)207 __STATIC_INLINE void AES_IntDisable(uint32_t flags)
208 {
209 AES->IEN &= ~(flags);
210 }
211
212 /***************************************************************************//**
213 * @brief
214 * Enable one or more AES interrupts.
215 *
216 * @note
217 * Depending on use, a pending interrupt may already be set prior to
218 * enabling the interrupt. Consider using AES_IntClear() prior to enabling
219 * if a pending interrupt should be ignored.
220 *
221 * @param[in] flags
222 * AES interrupt sources to enable. Use a bitwise logic OR combination of
223 * valid interrupt flags for the AES module (AES_IF_nnn).
224 ******************************************************************************/
AES_IntEnable(uint32_t flags)225 __STATIC_INLINE void AES_IntEnable(uint32_t flags)
226 {
227 AES->IEN |= flags;
228 }
229
230 /***************************************************************************//**
231 * @brief
232 * Get pending AES interrupt flags.
233 *
234 * @note
235 * This function does not clear event bits.
236 *
237 * @return
238 * AES interrupt sources pending. A bitwise logic OR combination of valid
239 * interrupt flags for the AES module (AES_IF_nnn).
240 ******************************************************************************/
AES_IntGet(void)241 __STATIC_INLINE uint32_t AES_IntGet(void)
242 {
243 return AES->IF;
244 }
245
246 /***************************************************************************//**
247 * @brief
248 * Get enabled and pending AES interrupt flags.
249 * Useful for handling more interrupt sources in the same interrupt handler.
250 *
251 * @note
252 * This function does not clear interrupt flags.
253 *
254 * @return
255 * Pending and enabled AES interrupt sources.
256 * The return value is the bitwise AND of
257 * - the enabled interrupt sources in AES_IEN and
258 * - the pending interrupt flags AES_IF
259 ******************************************************************************/
AES_IntGetEnabled(void)260 __STATIC_INLINE uint32_t AES_IntGetEnabled(void)
261 {
262 uint32_t ien;
263
264 ien = AES->IEN;
265 return AES->IF & ien;
266 }
267
268 /***************************************************************************//**
269 * @brief
270 * Set one or more pending AES interrupts from software.
271 *
272 * @param[in] flags
273 * AES interrupt sources to set as pending. Use a bitwise logic OR combination
274 * of valid interrupt flags for the AES module (AES_IF_nnn).
275 ******************************************************************************/
AES_IntSet(uint32_t flags)276 __STATIC_INLINE void AES_IntSet(uint32_t flags)
277 {
278 AES->IFS = flags;
279 }
280
281 void AES_OFB128(uint8_t *out,
282 const uint8_t *in,
283 unsigned int len,
284 const uint8_t *key,
285 const uint8_t *iv);
286
287 #if defined(AES_CTRL_AES256)
288 void AES_OFB256(uint8_t *out,
289 const uint8_t *in,
290 unsigned int len,
291 const uint8_t *key,
292 const uint8_t *iv);
293 #endif
294
295 /** @} (end addtogroup aes) */
296
297 #ifdef __cplusplus
298 }
299 #endif
300
301 #endif /* defined(AES_COUNT) && (AES_COUNT > 0) */
302 #endif /* EM_AES_H */
303