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