1 /***************************************************************************//**
2  * @file
3  * @brief Cryptography 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 #ifndef EM_CRYPTO_H
31 #define EM_CRYPTO_H
32 
33 #include "em_device.h"
34 
35 # if defined(__GNUC__)
36 #  define CRYPTO_WARNINGS_NO_CAST_ALIGN \
37   _Pragma("GCC diagnostic push")        \
38   _Pragma("GCC diagnostic ignored \"-Wcast-align\"")
39 
40 #  define CRYPTO_WARNINGS_RESET \
41   _Pragma("GCC diagnostic pop")
42 # else
43 #  define CRYPTO_WARNINGS_NO_CAST_ALIGN
44 #  define CRYPTO_WARNINGS_RESET
45 # endif
46 
47 #if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
48 
49 #include "em_bus.h"
50 #include "sl_common.h"
51 #include "em_crypto_compat.h"
52 #include <stdbool.h>
53 #include <string.h>
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 /***************************************************************************//**
60  * @addtogroup crypto CRYPTO - Cryptography Accelerator
61  *
62  * @brief Cryptography accelerator peripheral API
63  *
64  * @details
65  *   For cryptographic support, users should consider the
66  *   crypto APIs of the mbedTLS library provided by Silicon Labs instead of the
67  *   interface provided in em_crypto.h. The mbedTLS library provides a much
68  *   richer crypto API, including hardware acceleration of several functions.
69  *
70  *   The main purpose of em_crypto.h is to implement a thin software interface
71  *   for the CRYPTO hardware functions especially for the accelerated APIs of
72  *   the mbedTLS library. Additionally, em_crypto.h implement the AES API of the
73  *   em_aes.h (supported by classic EFM32) for backward compatibility. The
74  *   following list summarizes the em_crypto.h interface:
75  *
76  *   - AES (Advanced Encryption Standard) [AES](/gecko-platform/<docspace-docleaf-version>/platform-emlib-efr32xg1/crypto#aes)
77  *   - SHA (Secure Hash Algorithm) [SHA](/gecko-platform/<docspace-docleaf-version>/platform-emlib-efr32xg1/crypto#sha)
78  *   - Big Integer multiplier [CRYPTO_Mul](/gecko-platform/<docspace-docleaf-version>/platform-emlib-efr32xg1/crypto#crypto-mul)
79  *   - Functions for loading data and executing instruction sequences [Load and Execute Instruction Sequences](/gecko-platform/<docspace-docleaf-version>/platform-emlib-efr32xg1/crypto#load-and-execute-instruction-sequences)
80  *
81  *   @n @section crypto_aes AES
82  *   The AES APIs include support for AES-128 and AES-256 with block cipher
83  *   modes:
84  *   @li CBC - Cipher Block Chaining mode
85  *   @li CFB - Cipher Feedback mode
86  *   @li CTR - Counter mode
87  *   @li ECB - Electronic Code Book mode
88  *   @li OFB - Output Feedback mode
89  *
90  *   For the AES APIs, input/output data (plaintext, ciphertext, key, and so on) are
91  *   treated as byte arrays, starting with most significant byte. In other words, 32 bytes
92  *   of plaintext (B0...B31) is located in memory in the same order, with B0 at
93  *   the lower address and B31 at the higher address.
94  *
95  *   Byte arrays must always be a multiple of AES block size, i.e., a multiple
96  *   of 16. Padding, if required, is done at the end of the byte array.
97  *
98  *   Byte arrays should be word (32 bit)-aligned for performance
99  *   considerations, since the array is accessed with 32 bit access type.
100  *   The core MCUs supports unaligned accesses but with a performance penalty.
101  *
102  *   You can specify the same output buffer as input buffer as long
103  *   as they point to the same address. In that case, the provided input buffer
104  *   is replaced with the encrypted/decrypted output. Notice that the buffers
105  *   must be exactly overlapping. If partly overlapping, the behavior is
106  *   undefined.
107  *
108  *   It is up to the user to use a cipher mode according to its requirements
109  *   to avoid breaking security. See the specific cipher mode
110  *   theory for details.
111  *
112  *   References:
113  *   @li Wikipedia - Cipher modes, en.wikipedia.org/wiki/Cipher_modes
114  *
115  *   @li Recommendation for Block Cipher Modes of Operation,
116  *      NIST Special Publication 800-38A, 2001 Edition,
117  *      csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
118  *
119  *   @li Recommendation for Block Cipher Modes of Operation,
120  *      csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
121  *
122  *   @n @section crypto_sha SHA
123  *   The SHA APIs include support for
124  *   @li SHA-1 @ref CRYPTO_SHA_1
125  *   @li SHA-256 @ref CRYPTO_SHA_256
126  *
127  *   The SHA-1 implementation is FIPS-180-1 compliant, ref:
128  *   @li Wikipedia -  SHA-1, en.wikipedia.org/wiki/SHA-1
129  *   @li SHA-1 spec - www.itl.nist.gov/fipspubs/fip180-1.htm
130  *
131  *   The SHA-256 implementation is FIPS-180-2 compliant, ref:
132  *   @li Wikipedia -  SHA-2, en.wikipedia.org/wiki/SHA-2
133  *   @li SHA-2 spec - csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
134  *
135  *   @n @section crypto_mul CRYPTO_Mul
136  *   @ref CRYPTO_Mul is a function for multiplying big integers that are
137  *   bigger than the operand size of the MUL instruction, which is 128 bits.
138  *   CRYPTO_Mul multiplies all partial operands of the input operands using
139  *   MUL to form a resulting number which may be twice the size of
140  *   the operands.
141  *
142  *   CRPYTO_Mul is typically used by RSA implementations, which perform a
143  *   huge amount of multiplication and square operations to
144  *   implement modular exponentiation.
145  *   Some RSA implementations use a number representation including arrays
146  *   of 32-bit words of variable size. Compile with
147  *   -D USE_VARIABLE_SIZED_DATA_LOADS to load these numbers
148  *   directly into CRYPTO without converting the number representation.
149  *
150  *   @n @section crypto_exec Load and Execute Instruction Sequences
151  *   The functions for loading data and executing instruction sequences can
152  *   be used to implement complex algorithms, such as elliptic curve cryptography
153  *   (ECC)) and authenticated encryption algorithms. There are two typical
154  *   modes of operation, as follows:
155  *   @li Multi-sequence operation
156  *   @li Single static instruction sequence operation
157  *
158  *   In multi-sequence mode, the software starts by loading input data,
159  *   an instruction sequence, execute, and finally read the result. This
160  *   process is repeated until the full crypto operation is complete.
161  *
162  *   When using a single static instruction sequence, only one
163  *   instruction sequence is loaded initially. The sequence can be set up
164  *   to run multiple times. Data can be loaded during the execution of the
165  *   sequence by using DMA, BUFC and/or programmed I/O directly from the MCU
166  *   core. For details about how to program the instruction sequences, see
167  *   the reference manual of the particular Silicon Labs device.
168  *
169  *   To load input data to the CRYPTO module, use any of the following
170  *   functions:
171  *   @li @ref CRYPTO_DataWrite  - Write 128 bits to a DATA register.
172  *   @li @ref CRYPTO_DDataWrite - Write 256 bits to a DDATA register.
173  *   @li @ref CRYPTO_QDataWrite - Write 512 bits to a QDATA register.
174  *
175  *   To read output data from the CRYPTO module use any of the
176  *   following functions:
177  *   @li @ref CRYPTO_DataRead  - Read 128 bits from a DATA register.
178  *   @li @ref CRYPTO_DDataRead - Read 256 bits from a DDATA register.
179  *   @li @ref CRYPTO_QDataRead - Read 512 bits from a QDATA register.
180  *
181  *   To load an instruction sequence to the CRYPTO module, use
182  *   @ref CRYPTO_InstructionSequenceLoad.
183  *
184  *   To execute the current instruction sequence in the CRYPTO module,
185  *   use @ref CRYPTO_InstructionSequenceExecute.
186  *
187  *   To check whether an instruction sequence has completed,
188  *   use @ref CRYPTO_InstructionSequenceDone.
189  *
190  *   To wait for an instruction sequence to complete,
191  *   use @ref CRYPTO_InstructionSequenceWait.
192  *
193  *   To optimally load (with regards to speed) and execute an
194  *   instruction sequence, use any of the CRYPTO_EXECUTE_X macros (where X is
195  *   in the range 1-20) defined in em_crypto.h. E.g. CRYPTO_EXECUTE_19.
196  * @{
197  ******************************************************************************/
198 
199 /*******************************************************************************
200  ******************************   DEFINES    ***********************************
201  ******************************************************************************/
202 
203 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
204 /** Default CRYPTO instance for deprecated AES functions. */
205 #if !defined(DEFAULT_CRYPTO)
206 #if defined(CRYPTO)
207 #define DEFAULT_CRYPTO CRYPTO
208 #elif defined(CRYPTO0)
209 #define DEFAULT_CRYPTO CRYPTO0
210 #endif
211 #endif
212 
213 /** Data sizes used by CRYPTO operations. */
214 #define CRYPTO_DATA_SIZE_IN_BITS           (128)
215 #define CRYPTO_DATA_SIZE_IN_BYTES          (CRYPTO_DATA_SIZE_IN_BITS / 8)
216 #define CRYPTO_DATA_SIZE_IN_32BIT_WORDS    (CRYPTO_DATA_SIZE_IN_BYTES / sizeof(uint32_t))
217 
218 #define CRYPTO_KEYBUF_SIZE_IN_BITS         (256)
219 #define CRYPTO_KEYBUF_SIZE_IN_BYTES        (CRYPTO_DDATA_SIZE_IN_BITS / 8)
220 #define CRYPTO_KEYBUF_SIZE_IN_32BIT_WORDS  (CRYPTO_DDATA_SIZE_IN_BYTES / sizeof(uint32_t))
221 
222 #define CRYPTO_DDATA_SIZE_IN_BITS          (256)
223 #define CRYPTO_DDATA_SIZE_IN_BYTES         (CRYPTO_DDATA_SIZE_IN_BITS / 8)
224 #define CRYPTO_DDATA_SIZE_IN_32BIT_WORDS   (CRYPTO_DDATA_SIZE_IN_BYTES / sizeof(uint32_t))
225 
226 #define CRYPTO_QDATA_SIZE_IN_BITS          (512)
227 #define CRYPTO_QDATA_SIZE_IN_BYTES         (CRYPTO_QDATA_SIZE_IN_BITS / 8)
228 #define CRYPTO_QDATA_SIZE_IN_32BIT_WORDS   (CRYPTO_QDATA_SIZE_IN_BYTES / sizeof(uint32_t))
229 
230 #define CRYPTO_DATA260_SIZE_IN_32BIT_WORDS (9)
231 
232 /** SHA-1 digest sizes */
233 #define CRYPTO_SHA1_DIGEST_SIZE_IN_BITS    (160)
234 #define CRYPTO_SHA1_DIGEST_SIZE_IN_BYTES   (CRYPTO_SHA1_DIGEST_SIZE_IN_BITS / 8)
235 
236 /** SHA-256 digest sizes */
237 #define CRYPTO_SHA256_DIGEST_SIZE_IN_BITS  (256)
238 #define CRYPTO_SHA256_DIGEST_SIZE_IN_BYTES (CRYPTO_SHA256_DIGEST_SIZE_IN_BITS / 8)
239 
240 /**
241  * Read and write all 260 bits of DDATA0 when in 260 bit mode.
242  */
243 #define CRYPTO_DDATA0_260_BITS_READ(crypto, bigint260)  CRYPTO_DData0Read260(crypto, bigint260)
244 #define CRYPTO_DDATA0_260_BITS_WRITE(crypto, bigint260) CRYPTO_DData0Write260(crypto, bigint260)
245 /** @endcond */
246 
247 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
248 /**
249  * Instruction sequence load macros CRYPTO_SEQ_LOAD_X (where X is in the range
250  * 1-20), for example, @ref CRYPTO_SEQ_LOAD_20.
251  * Use these macros for faster execution than the function API.
252  */
253 #define CRYPTO_SEQ_LOAD_1(crypto, a1) { \
254     crypto->SEQ0 =  a1 |  (CRYPTO_CMD_INSTR_END << 8); }
255 #define CRYPTO_SEQ_LOAD_2(crypto, a1, a2) { \
256     crypto->SEQ0 =  a1 |  (a2 << 8) |  (CRYPTO_CMD_INSTR_END << 16); }
257 #define CRYPTO_SEQ_LOAD_3(crypto, a1, a2, a3) { \
258     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) | (CRYPTO_CMD_INSTR_END << 24); }
259 #define CRYPTO_SEQ_LOAD_4(crypto, a1, a2, a3, a4) {              \
260     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24); \
261     crypto->SEQ1 =  CRYPTO_CMD_INSTR_END; }
262 #define CRYPTO_SEQ_LOAD_5(crypto, a1, a2, a3, a4, a5) {          \
263     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24); \
264     crypto->SEQ1 =  a5 |  (CRYPTO_CMD_INSTR_END << 8); }
265 #define CRYPTO_SEQ_LOAD_6(crypto, a1, a2, a3, a4, a5, a6) {      \
266     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24); \
267     crypto->SEQ1 =  a5 |  (a6 << 8) |  (CRYPTO_CMD_INSTR_END << 16); }
268 #define CRYPTO_SEQ_LOAD_7(crypto, a1, a2, a3, a4, a5, a6, a7) {  \
269     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24); \
270     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (CRYPTO_CMD_INSTR_END << 24); }
271 #define CRYPTO_SEQ_LOAD_8(crypto, a1, a2, a3, a4, a5, a6, a7, a8) { \
272     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);    \
273     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);    \
274     crypto->SEQ2 =  CRYPTO_CMD_INSTR_END; }
275 #define CRYPTO_SEQ_LOAD_9(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9) { \
276     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);        \
277     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);        \
278     crypto->SEQ2 =  a9 | (CRYPTO_CMD_INSTR_END << 8); }
279 #define CRYPTO_SEQ_LOAD_10(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { \
280     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);              \
281     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);              \
282     crypto->SEQ2 =  a9 | (a10 << 8) | (CRYPTO_CMD_INSTR_END << 16); }
283 #define CRYPTO_SEQ_LOAD_11(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) { \
284     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                   \
285     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                   \
286     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (CRYPTO_CMD_INSTR_END << 24); }
287 #define CRYPTO_SEQ_LOAD_12(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) { \
288     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                        \
289     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                        \
290     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                        \
291     crypto->SEQ3 = CRYPTO_CMD_INSTR_END; }
292 #define CRYPTO_SEQ_LOAD_13(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) { \
293     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                             \
294     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                             \
295     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                             \
296     crypto->SEQ3 = a13 | (CRYPTO_CMD_INSTR_END << 8); }
297 #define CRYPTO_SEQ_LOAD_14(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) { \
298     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                  \
299     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                  \
300     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                  \
301     crypto->SEQ3 = a13 | (a14 << 8) | (CRYPTO_CMD_INSTR_END << 16); }
302 #define CRYPTO_SEQ_LOAD_15(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) { \
303     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                       \
304     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                       \
305     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                       \
306     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (CRYPTO_CMD_INSTR_END << 24); }
307 #define CRYPTO_SEQ_LOAD_16(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) { \
308     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                            \
309     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                            \
310     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                            \
311     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                            \
312     crypto->SEQ4 = CRYPTO_CMD_INSTR_END; }
313 #define CRYPTO_SEQ_LOAD_17(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) { \
314     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                                 \
315     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                                 \
316     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                                 \
317     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                                 \
318     crypto->SEQ4 = a17 | (CRYPTO_CMD_INSTR_END << 8); }
319 #define CRYPTO_SEQ_LOAD_18(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) { \
320     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                                      \
321     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                                      \
322     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                                      \
323     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                                      \
324     crypto->SEQ4 = a17 | (a18 << 8) | (CRYPTO_CMD_INSTR_END << 16); }
325 #define CRYPTO_SEQ_LOAD_19(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) { \
326     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                                           \
327     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                                           \
328     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                                           \
329     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                                           \
330     crypto->SEQ4 = a17 | (a18 << 8) | (a19 << 16) | (CRYPTO_CMD_INSTR_END << 24); }
331 #define CRYPTO_SEQ_LOAD_20(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) { \
332     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                                                \
333     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                                                \
334     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                                                \
335     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                                                \
336     crypto->SEQ4 = a17 | (a18 << 8) | (a19 << 16) | (a20 << 24); }
337 /** @endcond */
338 
339 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
340 /**
341  * Instruction sequence execution macros CRYPTO_EXECUTE_X (where X is in range
342  * 1-20), for example @ref CRYPTO_EXECUTE_19.
343  * Use these macros for faster execution than the function API.
344  */
345 #define CRYPTO_EXECUTE_1(crypto, a1) { \
346     crypto->SEQ0 = a1 | (CRYPTO_CMD_INSTR_EXEC << 8); }
347 #define CRYPTO_EXECUTE_2(crypto, a1, a2) { \
348     crypto->SEQ0 = a1 | (a2 << 8) | (CRYPTO_CMD_INSTR_EXEC << 16); }
349 #define CRYPTO_EXECUTE_3(crypto, a1, a2, a3) { \
350     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (CRYPTO_CMD_INSTR_EXEC << 24); }
351 #define CRYPTO_EXECUTE_4(crypto, a1, a2, a3, a4) {           \
352     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24); \
353     crypto->SEQ1 = CRYPTO_CMD_INSTR_EXEC; }
354 #define CRYPTO_EXECUTE_5(crypto, a1, a2, a3, a4, a5) {       \
355     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24); \
356     crypto->SEQ1 = a5 | (CRYPTO_CMD_INSTR_EXEC << 8); }
357 #define CRYPTO_EXECUTE_6(crypto, a1, a2, a3, a4, a5, a6) {   \
358     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24); \
359     crypto->SEQ1 = a5 | (a6 << 8) | (CRYPTO_CMD_INSTR_EXEC << 16); }
360 #define CRYPTO_EXECUTE_7(crypto, a1, a2, a3, a4, a5, a6, a7) { \
361     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24);   \
362     crypto->SEQ1 = a5 | (a6 << 8) | (a7 << 16) | (CRYPTO_CMD_INSTR_EXEC << 24); }
363 #define CRYPTO_EXECUTE_8(crypto, a1, a2, a3, a4, a5, a6, a7, a8) { \
364     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24);       \
365     crypto->SEQ1 = a5 | (a6 << 8) | (a7 << 16) | (a8 << 24);       \
366     crypto->SEQ2 = CRYPTO_CMD_INSTR_EXEC; }
367 #define CRYPTO_EXECUTE_9(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9) { \
368     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24);           \
369     crypto->SEQ1 = a5 | (a6 << 8) | (a7 << 16) | (a8 << 24);           \
370     crypto->SEQ2 = a9 | (CRYPTO_CMD_INSTR_EXEC << 8); }
371 #define CRYPTO_EXECUTE_10(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { \
372     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24);                 \
373     crypto->SEQ1 = a5 | (a6 << 8) | (a7 << 16) | (a8 << 24);                 \
374     crypto->SEQ2 = a9 | (a10 << 8) | (CRYPTO_CMD_INSTR_EXEC << 16); }
375 #define CRYPTO_EXECUTE_11(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) { \
376     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24);                      \
377     crypto->SEQ1 = a5 | (a6 << 8) | (a7 << 16) | (a8 << 24);                      \
378     crypto->SEQ2 = a9 | (a10 << 8) | (a11 << 16) | (CRYPTO_CMD_INSTR_EXEC << 24); }
379 #define CRYPTO_EXECUTE_12(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) { \
380     crypto->SEQ0 = a1 |  (a2 << 8) |  (a3 << 16) | (a4 << 24);                         \
381     crypto->SEQ1 = a5 |  (a6 << 8) |  (a7 << 16) | (a8 << 24);                         \
382     crypto->SEQ2 = a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                        \
383     crypto->SEQ3 = CRYPTO_CMD_INSTR_EXEC; }
384 #define CRYPTO_EXECUTE_13(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) { \
385     crypto->SEQ0 = a1  | (a2 << 8)  | (a3 << 16)  | (a4 << 24);                             \
386     crypto->SEQ1 = a5  | (a6 << 8)  | (a7 << 16)  | (a8 << 24);                             \
387     crypto->SEQ2 = a9  | (a10 << 8) | (a11 << 16) | (a12 << 24);                            \
388     crypto->SEQ3 = a13 | (CRYPTO_CMD_INSTR_EXEC << 8); }
389 #define CRYPTO_EXECUTE_14(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) { \
390     crypto->SEQ0 = a1 | (a2 << 8) | (a3 << 16) | (a4 << 24);                                     \
391     crypto->SEQ1 = a5 | (a6 << 8) | (a7 << 16) | (a8 << 24);                                     \
392     crypto->SEQ2 = a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                  \
393     crypto->SEQ3 = a13 | (a14 << 8) | (CRYPTO_CMD_INSTR_EXEC << 16); }
394 #define CRYPTO_EXECUTE_15(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) { \
395     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                      \
396     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                      \
397     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                      \
398     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (CRYPTO_CMD_INSTR_EXEC << 24); }
399 #define CRYPTO_EXECUTE_16(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) { \
400     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                           \
401     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                           \
402     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                           \
403     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                           \
404     crypto->SEQ4 = CRYPTO_CMD_INSTR_EXEC; }
405 #define CRYPTO_EXECUTE_17(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) { \
406     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) | (a4 << 24);                                                 \
407     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) | (a8 << 24);                                                 \
408     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                                \
409     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                                \
410     crypto->SEQ4 = a17 | (CRYPTO_CMD_INSTR_EXEC << 8); }
411 #define CRYPTO_EXECUTE_18(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) { \
412     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                                     \
413     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                                     \
414     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                                     \
415     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                                     \
416     crypto->SEQ4 = a17 | (a18 << 8) | (CRYPTO_CMD_INSTR_EXEC << 16); }
417 #define CRYPTO_EXECUTE_19(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) { \
418     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                                          \
419     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                                          \
420     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                                          \
421     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                                          \
422     crypto->SEQ4 = a17 | (a18 << 8) | (a19 << 16) | (CRYPTO_CMD_INSTR_EXEC << 24); }
423 #define CRYPTO_EXECUTE_20(crypto, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) { \
424     crypto->SEQ0 =  a1 |  (a2 << 8) |  (a3 << 16) |  (a4 << 24);                                                               \
425     crypto->SEQ1 =  a5 |  (a6 << 8) |  (a7 << 16) |  (a8 << 24);                                                               \
426     crypto->SEQ2 =  a9 | (a10 << 8) | (a11 << 16) | (a12 << 24);                                                               \
427     crypto->SEQ3 = a13 | (a14 << 8) | (a15 << 16) | (a16 << 24);                                                               \
428     crypto->SEQ4 = a17 | (a18 << 8) | (a19 << 16) | (a20 << 24);                                                               \
429     CRYPTO_InstructionSequenceExecute(crypto); }
430 /** @endcond */
431 
432 /*******************************************************************************
433  ******************************   TYPEDEFS   ***********************************
434  ******************************************************************************/
435 
436 /**
437  * CRYPTO data types used for data load functions. This data type is
438  * capable of storing a 128 bits value as used in the crypto DATA
439  * registers.
440  */
441 typedef uint32_t CRYPTO_Data_TypeDef[CRYPTO_DATA_SIZE_IN_32BIT_WORDS];
442 
443 /**
444  * CRYPTO data type used for data load functions. This data type
445  * is capable of storing a 256 bits value as used in the crypto DDATA
446  * registers.
447  */
448 typedef uint32_t CRYPTO_DData_TypeDef[CRYPTO_DDATA_SIZE_IN_32BIT_WORDS];
449 
450 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
451 typedef uint32_t* CRYPTO_DDataPtr_TypeDef;
452 /** @endcond */
453 
454 /**
455  * CRYPTO data type used for data load functions. This data type is
456  * capable of storing a 512 bits value as used in the crypto QDATA
457  * registers.
458  */
459 typedef uint32_t CRYPTO_QData_TypeDef[CRYPTO_QDATA_SIZE_IN_32BIT_WORDS];
460 
461 /**
462  * CRYPTO data type used for data load functions. This data type is
463  * capable of storing a 260 bits value as used by the @ref CRYPTO_DData0Write260
464  * function.
465  *
466  * Note that this data type is multiple of 32 bit words, so the
467  * actual storage used by this type is 32x9=288 bits.
468  */
469 typedef uint32_t CRYPTO_Data260_TypeDef[CRYPTO_DATA260_SIZE_IN_32BIT_WORDS];
470 
471 /**
472  * CRYPTO data type used for data load functions. This data type is
473  * capable of storing 256 bits as used in the crypto KEYBUF register.
474  */
475 typedef uint32_t CRYPTO_KeyBuf_TypeDef[CRYPTO_KEYBUF_SIZE_IN_32BIT_WORDS];
476 
477 /**
478  * CRYPTO 128 bit Data register pointer type. The 128 bit registers are used to
479  * load 128 bit values as input and output data for cryptographic and big
480  * integer arithmetic functions of the CRYPTO module.
481  */
482 typedef volatile uint32_t* CRYPTO_DataReg_TypeDef;
483 
484 /**
485  * CRYPTO 256 bit DData (Double Data) register pointer type. The 256 bit
486  * registers are used to load 256 bit values as input and output data for
487  * cryptographic and big integer arithmetic functions of the CRYPTO module.
488  */
489 typedef volatile uint32_t* CRYPTO_DDataReg_TypeDef;
490 
491 /**
492  * CRYPTO 512 bit QData (Quad data) register pointer type. The 512 bit
493  * registers are used to load 512 bit values as input and output data for
494  * cryptographic and big integer arithmetic functions of the CRYPTO module.
495  */
496 typedef volatile uint32_t* CRYPTO_QDataReg_TypeDef;
497 
498 /** CRYPTO modulus identifiers. */
499 typedef enum {
500   cryptoModulusBin256        = CRYPTO_WAC_MODULUS_BIN256,       /**< Generic 256 bit modulus 2^256 */
501   cryptoModulusBin128        = CRYPTO_WAC_MODULUS_BIN128,       /**< Generic 128 bit modulus 2^128 */
502   cryptoModulusGcmBin128     = CRYPTO_WAC_MODULUS_GCMBIN128,    /**< GCM 128 bit modulus = 2^128 + 2^7 + 2^2 + 2 + 1 */
503   cryptoModulusEccB233       = CRYPTO_WAC_MODULUS_ECCBIN233P,   /**< ECC B233 prime modulus = 2^233 + 2^74 + 1   */
504   cryptoModulusEccB163       = CRYPTO_WAC_MODULUS_ECCBIN163P,   /**< ECC B163 prime modulus = 2^163 + 2^7 + 2^6 + 2^3 + 1 */
505   cryptoModulusEccP256       = CRYPTO_WAC_MODULUS_ECCPRIME256P, /**< ECC P256 prime modulus = 2^256 - 2^224 + 2^192 + 2^96 - 1 */
506   cryptoModulusEccP224       = CRYPTO_WAC_MODULUS_ECCPRIME224P, /**< ECC P224 prime modulus = 2^224 - 2^96 - 1 */
507   cryptoModulusEccP192       = CRYPTO_WAC_MODULUS_ECCPRIME192P, /**< ECC P192 prime modulus = 2^192 - 2^64 - 1 */
508   cryptoModulusEccB233Order  = CRYPTO_WAC_MODULUS_ECCBIN233N,   /**< ECC B233 order modulus   */
509   cryptoModulusEccB233KOrder = CRYPTO_WAC_MODULUS_ECCBIN233KN,  /**< ECC B233K order modulus */
510   cryptoModulusEccB163Order  = CRYPTO_WAC_MODULUS_ECCBIN163N,   /**< ECC B163 order modulus */
511   cryptoModulusEccB163KOrder = CRYPTO_WAC_MODULUS_ECCBIN163KN,  /**< ECC B163K order modulus */
512   cryptoModulusEccP256Order  = CRYPTO_WAC_MODULUS_ECCPRIME256N, /**< ECC P256 order modulus */
513   cryptoModulusEccP224Order  = CRYPTO_WAC_MODULUS_ECCPRIME224N, /**< ECC P224 order modulus */
514   cryptoModulusEccP192Order  = CRYPTO_WAC_MODULUS_ECCPRIME192N  /**< ECC P192 order modulus */
515 } CRYPTO_ModulusId_TypeDef;
516 
517 /** CRYPTO multiplication widths for wide arithmetic operations. */
518 typedef enum {
519   cryptoMulOperand256Bits     = CRYPTO_WAC_MULWIDTH_MUL256, /**< 256 bits operands */
520   cryptoMulOperand128Bits     = CRYPTO_WAC_MULWIDTH_MUL128, /**< 128 bits operands */
521   cryptoMulOperandModulusBits = CRYPTO_WAC_MULWIDTH_MULMOD  /**< MUL operand width
522                                                                  is specified by the
523                                                                  modulus type.*/
524 } CRYPTO_MulOperandWidth_TypeDef;
525 
526 /** CRYPTO result widths for MUL operations. */
527 typedef enum {
528   cryptoResult128Bits = CRYPTO_WAC_RESULTWIDTH_128BIT, /**< Multiplication result width is 128 bits*/
529   cryptoResult256Bits = CRYPTO_WAC_RESULTWIDTH_256BIT, /**< Multiplication result width is 256 bits*/
530   cryptoResult260Bits = CRYPTO_WAC_RESULTWIDTH_260BIT  /**< Multiplication result width is 260 bits*/
531 } CRYPTO_ResultWidth_TypeDef;
532 
533 /** CRYPTO result widths for MUL operations. */
534 typedef enum {
535   cryptoInc1byte = CRYPTO_CTRL_INCWIDTH_INCWIDTH1, /**< inc width is 1 byte*/
536   cryptoInc2byte = CRYPTO_CTRL_INCWIDTH_INCWIDTH2, /**< inc width is 2 byte*/
537   cryptoInc3byte = CRYPTO_CTRL_INCWIDTH_INCWIDTH3, /**< inc width is 3 byte*/
538   cryptoInc4byte = CRYPTO_CTRL_INCWIDTH_INCWIDTH4  /**< inc width is 4 byte*/
539 } CRYPTO_IncWidth_TypeDef;
540 
541 /** CRYPTO key width. */
542 typedef enum {
543   cryptoKey128Bits = 8,     /**< Key width is 128 bits*/
544   cryptoKey256Bits = 16,    /**< Key width is 256 bits*/
545 } CRYPTO_KeyWidth_TypeDef;
546 
547 /**
548  * The maximum number of crypto instructions in an instruction sequence.
549  */
550 #define CRYPTO_MAX_SEQUENCE_INSTRUCTIONS (20)
551 
552 /**
553  * Instruction sequence type.
554  * Fill in the desired operations from step1, step2, and so on.
555  * The CRYPTO_CMD_INSTR_END marks the end of the sequence.
556  * Bit fields are used to format the memory layout of the struct equal to the
557  * sequence registers in the CRYPTO module.
558  */
559 typedef uint8_t CRYPTO_InstructionSequence_TypeDef[CRYPTO_MAX_SEQUENCE_INSTRUCTIONS];
560 
561 /** Default instruction sequence consisting of all ENDs. The user can
562     initialize the instruction sequence with this default value set and fill
563     in the desired operations from step 1. The first END instruction marks
564     the end of the sequence. */
565 #define CRYPTO_INSTRUCTIONSEQUENSE_DEFAULT                            \
566   { CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, \
567     CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, \
568     CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, \
569     CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, \
570     CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, \
571     CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END, \
572     CRYPTO_CMD_INSTR_END, CRYPTO_CMD_INSTR_END }
573 
574 /** SHA-1 Digest type. */
575 typedef uint8_t CRYPTO_SHA1_Digest_TypeDef[CRYPTO_SHA1_DIGEST_SIZE_IN_BYTES];
576 
577 /** SHA-256 Digest type. */
578 typedef uint8_t CRYPTO_SHA256_Digest_TypeDef[CRYPTO_SHA256_DIGEST_SIZE_IN_BYTES];
579 
580 /**
581  * @brief
582  *   AES counter modification function pointer.
583  *
584  * @note
585  *   This is defined for backwards compatibility with EFM32 em_aes.h.
586  *   The CRYPTO implementation of counter mode does not support counter update
587  *   callbacks.
588  *
589  * @param[in]  ctr   A counter value to be modified.
590  */
591 typedef void (*CRYPTO_AES_CtrFuncPtr_TypeDef)(uint8_t * ctr);
592 
593 /*******************************************************************************
594  *****************************   PROTOTYPES   **********************************
595  ******************************************************************************/
596 
597 /***************************************************************************//**
598  * @brief
599  *   Set the modulus type used for wide arithmetic operations.
600  *
601  * @details
602  *   This function sets the modulus type to be used by the modulus instructions
603  *   of the CRYPTO module.
604  *
605  * @param[in]  crypto
606  *   A pointer to the CRYPTO peripheral register block.
607  *
608  * @param[in]  modulusId
609  *   A modulus type.
610  ******************************************************************************/
611 void CRYPTO_ModulusSet(CRYPTO_TypeDef *          crypto,
612                        CRYPTO_ModulusId_TypeDef  modulusId);
613 
614 /***************************************************************************//**
615  * @brief
616  *   Set the number of bits in the operands of the MUL instruction.
617  *
618  * @details
619  *   This function sets the number of bits to be used in the operands of
620  *   the MUL instruction.
621  *
622  * @param[in]  crypto
623  *   A pointer to the CRYPTO peripheral register block.
624  *
625  * @param[in]  mulOperandWidth
626  *   Multiplication width in bits.
627  ******************************************************************************/
628 __STATIC_INLINE
CRYPTO_MulOperandWidthSet(CRYPTO_TypeDef * crypto,CRYPTO_MulOperandWidth_TypeDef mulOperandWidth)629 void CRYPTO_MulOperandWidthSet(CRYPTO_TypeDef *crypto,
630                                CRYPTO_MulOperandWidth_TypeDef mulOperandWidth)
631 {
632   uint32_t temp = crypto->WAC & (~_CRYPTO_WAC_MULWIDTH_MASK);
633   crypto->WAC = temp | (uint32_t)mulOperandWidth;
634 }
635 
636 /***************************************************************************//**
637  * @brief
638  *   Set the width of the results of the non-modulus instructions.
639  *
640  * @details
641  *   This function sets the result width of the non-modulus instructions.
642  *
643  * @param[in]  crypto
644  *   A pointer to the CRYPTO peripheral register block.
645  *
646  * @param[in]  resultWidth
647  *   A result width of non-modulus instructions.
648  ******************************************************************************/
649 __STATIC_INLINE
CRYPTO_ResultWidthSet(CRYPTO_TypeDef * crypto,CRYPTO_ResultWidth_TypeDef resultWidth)650 void CRYPTO_ResultWidthSet(CRYPTO_TypeDef *crypto,
651                            CRYPTO_ResultWidth_TypeDef resultWidth)
652 {
653   uint32_t temp = crypto->WAC & (~_CRYPTO_WAC_RESULTWIDTH_MASK);
654   crypto->WAC = temp | (uint32_t)resultWidth;
655 }
656 
657 /***************************************************************************//**
658  * @brief
659  *   Set the width of the DATA1 increment instruction DATA1INC.
660  *
661  * @details
662  *   This function sets the width of the DATA1 increment instruction
663  *   CRYPTO_CMD_INSTR_DATA1INC.
664  *
665  * @param[in]  crypto
666  *   A pointer to CRYPTO peripheral register block.
667  *
668  * @param[in]  incWidth
669  *   An incrementation width.
670  ******************************************************************************/
CRYPTO_IncWidthSet(CRYPTO_TypeDef * crypto,CRYPTO_IncWidth_TypeDef incWidth)671 __STATIC_INLINE void CRYPTO_IncWidthSet(CRYPTO_TypeDef *crypto,
672                                         CRYPTO_IncWidth_TypeDef incWidth)
673 {
674   uint32_t temp = crypto->CTRL & (~_CRYPTO_CTRL_INCWIDTH_MASK);
675   crypto->CTRL = temp | (uint32_t)incWidth;
676 }
677 
678 /***************************************************************************//**
679  * @brief
680  *   Write a 128 bit value into a crypto register.
681  *
682  * @note
683  *   This function provides a low-level API for writing to the multi-word
684  *   registers in the crypto peripheral. Applications should use
685  *   @ref CRYPTO_DataWrite, @ref CRYPTO_DDataWrite or @ref CRYPTO_QDataWrite
686  *   for writing to DATA, DDATA, and QDATA registers.
687  *
688  * @param[in]  reg
689  *   A pointer to the crypto register.
690  *
691  * @param[in]  val
692  *   This is a pointer to 4 32 bit integers that contains the 128 bit value
693  *   which will be written to the crypto register.
694  ******************************************************************************/
695 void CRYPTO_BurstToCrypto(volatile uint32_t * reg,
696                           const uint32_t * val);
697 
698 /***************************************************************************//**
699  * @brief
700  *   Read a 128 bit value from a crypto register.
701  *
702  * @note
703  *   This function provides a low-level API for reading one of the multi-word
704  *   registers in the crypto peripheral. Applications should use
705  *   @ref CRYPTO_DataRead, @ref CRYPTO_DDataRead or @ref CRYPTO_QDataRead
706  *   for reading the value of DATA, DDATA, and QDATA registers.
707  *
708  * @param[in]  reg
709  *   A pointer to the crypto register.
710  *
711  * @param[out]  val
712  *   This is a pointer to an array that is capable of holding 4 32 bit integers
713  *   that will be filled with the 128 bit value from the crypto register.
714  ******************************************************************************/
715 void CRYPTO_BurstFromCrypto(volatile uint32_t * reg, uint32_t * val);
716 
717 /***************************************************************************//**
718  * @brief
719  *   Write 128 bits of data to a DATAX register in the CRYPTO module.
720  *
721  * @details
722  *   Write 128 bits of data to a DATAX register in the crypto module. The data
723  *   value is typically input to a big integer operation (see crypto
724  *   instructions).
725  *
726  * @param[in]  dataReg    The 128 bit DATA register.
727  * @param[in]  val        Value of the data to write to the DATA register.
728  *                        Has to be word-aligned.
729  ******************************************************************************/
730 void CRYPTO_DataWrite(CRYPTO_DataReg_TypeDef dataReg,
731                       const CRYPTO_Data_TypeDef val);
732 
733 /***************************************************************************//**
734  * @brief
735  *   Write 128 bits of unaligned data to a DATAX register in the CRYPTO module.
736  *
737  * @details
738  *   Write 128 bits of unaligned data to a DATAX register in the CRYPTO module.
739  *   The data pointer does not have to be word-aligned, but an unaligned pointer
740  *   might incur a performance hit.
741  *
742  * @param[in]  reg    The 128 bit DATA register.
743  * @param[in]  val    Pointer to value to write to the DATA register.
744  *                    Can be unaligned.
745  ******************************************************************************/
746 CRYPTO_WARNINGS_NO_CAST_ALIGN
747 void CRYPTO_DataWriteUnaligned(volatile uint32_t * reg,
748                                const uint8_t * val);
749 CRYPTO_WARNINGS_RESET
750 
751 /***************************************************************************//**
752  * @brief
753  *   Read 128 bits of data from a DATAX register in the CRYPTO module.
754  *
755  * @details
756  *   Read 128 bits of data from a DATAX register in the crypto module. The data
757  *   value is typically output from a big integer operation (see crypto
758  *   instructions)
759  *
760  * @param[in]  dataReg   The 128 bit DATA register.
761  * @param[out] val       Location where to store the value in memory.
762  *                       Has to be word-aligned.
763  ******************************************************************************/
764 void CRYPTO_DataRead(CRYPTO_DataReg_TypeDef  dataReg,
765                      CRYPTO_Data_TypeDef     val);
766 
767 /***************************************************************************//**
768  * @brief
769  *   Read 128 bits of data from a DATAX register in the CRYPTO module to an
770  *   unaligned pointer.
771  *
772  * @details
773  *   Write 128 bits of unaligned data to a DATAX register in the CRYPTO module
774  *   to an unaligned pointer. The output pointer does not have to be
775  *   word-aligned, but an unaligned pointer might incur a performance penalty.
776  *
777  * @param[in]  reg    The 128 bit DATA register.
778  * @param[out] val    Location where to store the value in memory.
779  *                    Can be unaligned.
780  ******************************************************************************/
781 CRYPTO_WARNINGS_NO_CAST_ALIGN
782 void CRYPTO_DataReadUnaligned(volatile uint32_t * reg,
783                               uint8_t * val);
784 CRYPTO_WARNINGS_RESET
785 
786 /***************************************************************************//**
787  * @brief
788  *   Write 256 bits of data to a DDATAX register in the CRYPTO module.
789  *
790  * @details
791  *   Write 256 bits of data into a DDATAX (Double Data) register in the crypto
792  *   module. The data value is typically input to a big integer operation (see
793  *   crypto instructions).
794  *
795  * @param[in]  ddataReg   The 256 bit DDATA register.
796  * @param[in]  val        Value of the data to write to the DDATA register.
797  ******************************************************************************/
798 void CRYPTO_DDataWrite(CRYPTO_DDataReg_TypeDef ddataReg,
799                        const CRYPTO_DData_TypeDef val);
800 
801 /***************************************************************************//**
802  * @brief
803  *   Read 256 bits of data from a DDATAX register in the CRYPTO module.
804  *
805  * @details
806  *   Read 256 bits of data from a DDATAX (Double Data) register in the crypto
807  *   module. The data value is typically output from a big integer operation
808  *   (see crypto instructions).
809  *
810  * @param[in]  ddataReg   The 256 bit DDATA register.
811  * @param[out] val        Location where to store the value in memory.
812  ******************************************************************************/
813 void CRYPTO_DDataRead(CRYPTO_DDataReg_TypeDef  ddataReg,
814                       CRYPTO_DData_TypeDef     val);
815 
816 /***************************************************************************//**
817  * @brief
818  *   Read 256 bits of data from a DDATAX register in the CRYPTO module to an
819  *   unaligned pointer.
820  *
821  * @details
822  *   Read 256 bits from a DDATAX register in the CRYPTO module. The output
823  *   buffer pointer does not have to be word-aligned, but an unaligned pointer
824  *   might incur a performance penalty.
825  *
826  * @param[in]  ddataReg   The 256 bit DDATA register.
827  * @param[out] val        Location where to store the value in memory.
828  *                        Can be unaligned.
829  ******************************************************************************/
830 CRYPTO_WARNINGS_NO_CAST_ALIGN
831 void CRYPTO_DDataReadUnaligned(CRYPTO_DDataReg_TypeDef ddataReg,
832                                uint8_t * val);
833 CRYPTO_WARNINGS_RESET
834 
835 /***************************************************************************//**
836  * @brief
837  *   Write 512 bits of data to a QDATAX register in the CRYPTO module.
838  *
839  * @details
840  *   Write 512 bits of data into a QDATAX (Quad Data) register in the crypto module
841  *   The data value is typically input to a big integer operation (see crypto
842  *   instructions).
843  *
844  * @param[in]  qdataReg   The 512 bits QDATA register.
845  * @param[in]  val        Value of the data to write to the QDATA register.
846  ******************************************************************************/
847 void CRYPTO_QDataWrite(CRYPTO_QDataReg_TypeDef qdataReg,
848                        const CRYPTO_QData_TypeDef val);
849 
850 /***************************************************************************//**
851  * @brief
852  *   Write 512 bits of unaligned data to a QDATAX register in the CRYPTO module.
853  *
854  * @details
855  *   Write 512 bits of unaligned data to a QDATAX register in the CRYPTO module.
856  *   The data pointer does not have to be word-aligned, but an unaligned pointer
857  *   might incur a performance hit.
858  *
859  * @param[in]  qdataReg   The 512 bits QDATA register.
860  * @param[in]  val        Pointer to value to write to the QDATA register.
861  *                        Can be unaligned.
862  ******************************************************************************/
863 CRYPTO_WARNINGS_NO_CAST_ALIGN
864 void CRYPTO_QDataWriteUnaligned(CRYPTO_QDataReg_TypeDef qdataReg,
865                                 const uint8_t * val);
866 CRYPTO_WARNINGS_RESET
867 
868 /***************************************************************************//**
869  * @brief
870  *   Read 512 bits of data from a QDATAX register in the CRYPTO module.
871  *
872  * @details
873  *   Read 512 bits of data from a QDATAX register in the crypto module. The data
874  *   value is typically input to a big integer operation (see crypto
875  *   instructions).
876  *
877  * @param[in]  qdataReg   The 512 bits QDATA register.
878  * @param[in]  val        Value of the data to write to the QDATA register.
879  ******************************************************************************/
880 void CRYPTO_QDataRead(CRYPTO_QDataReg_TypeDef qdataReg,
881                       CRYPTO_QData_TypeDef    val);
882 
883 /***************************************************************************//**
884  * @brief
885  *   Set the key value to be used by the CRYPTO module.
886  *
887  * @details
888  *   Write 128 or 256 bit key to the KEYBUF register in the crypto module.
889  *
890  * @param[in]  crypto
891  *   A pointer to the CRYPTO peripheral register block.
892  *
893  * @param[in]  val
894  *   Value of the data to write to the KEYBUF register. Has to be word-aligned.
895  *
896  * @param[in]  keyWidth
897  *   Key width - 128 or 256 bits.
898  ******************************************************************************/
899 void CRYPTO_KeyBufWrite(CRYPTO_TypeDef          *crypto,
900                         CRYPTO_KeyBuf_TypeDef    val,
901                         CRYPTO_KeyWidth_TypeDef  keyWidth);
902 
903 /***************************************************************************//**
904  * @brief
905  *   Set the key value to be used by the CRYPTO module.
906  *
907  * @details
908  *   Write 128 or 256 bit key to the KEYBUF register in the crypto module. The
909  *   input key buffer does not have to be word-aligned, but an unaligned value
910  *   might incur a performance penalty.
911  *
912  * @param[in]  crypto
913  *   A pointer to the CRYPTO peripheral register block.
914  *
915  * @param[in]  val
916  *   Pointer to value to write to the KEYBUF register. Can be unaligned.
917  *
918  * @param[in]  keyWidth
919  *   Key width - 128 or 256 bits.
920  ******************************************************************************/
921 CRYPTO_WARNINGS_NO_CAST_ALIGN
922 void CRYPTO_KeyBufWriteUnaligned(CRYPTO_TypeDef          *crypto,
923                                  const uint8_t *          val,
924                                  CRYPTO_KeyWidth_TypeDef  keyWidth);
925 CRYPTO_WARNINGS_RESET
926 
927 void CRYPTO_KeyRead(CRYPTO_TypeDef *crypto,
928                     CRYPTO_KeyBuf_TypeDef   val,
929                     CRYPTO_KeyWidth_TypeDef keyWidth);
930 
931 void CRYPTO_KeyReadUnaligned(CRYPTO_TypeDef *         crypto,
932                              uint8_t *                val,
933                              CRYPTO_KeyWidth_TypeDef  keyWidth);
934 
935 /***************************************************************************//**
936  * @brief
937  *   Quick write 128 bit key to the CRYPTO module.
938  *
939  * @details
940  *   Quick write 128 bit key to the KEYBUF register in the CRYPTO module.
941  *
942  * @param[in]  crypto
943  *   A pointer to the CRYPTO peripheral register block.
944  *
945  * @param[in]  val
946  *   Value of the data to write to the KEYBUF register.
947  ******************************************************************************/
948 void CRYPTO_KeyBuf128Write(CRYPTO_TypeDef *crypto,
949                            const uint32_t * val);
950 
951 /***************************************************************************//**
952  * @brief
953  *   Quick read access of the carry bit from arithmetic operations.
954  *
955  * @details
956  *   This function reads the carry bit of the CRYPTO ALU.
957  *
958  * @param[in]  crypto
959  *   A pointer to the CRYPTO peripheral register block.
960  *
961  * @return
962  *   Returns 'true' if carry is 1, and 'false' if carry is 0.
963  ******************************************************************************/
CRYPTO_CarryIsSet(CRYPTO_TypeDef * crypto)964 __STATIC_INLINE bool CRYPTO_CarryIsSet(CRYPTO_TypeDef *crypto)
965 {
966   return ((crypto->DSTATUS & _CRYPTO_DSTATUS_CARRY_MASK)
967           >> _CRYPTO_DSTATUS_CARRY_SHIFT) != 0UL;
968 }
969 
970 /***************************************************************************//**
971  * @brief
972  *   Quick read access of the 4 LSbits of the DDATA0 register.
973  *
974  * @details
975  *   This function quickly retrieves the 4 least significant bits of the
976  *   DDATA0 register via the DDATA0LSBS bit field in the DSTATUS register.
977  *
978  * @param[in]  crypto
979  *   A pointer to the CRYPTO peripheral register block.
980  *
981  * @return
982  *   Returns the 4 LSbits of DDATA0.
983  ******************************************************************************/
CRYPTO_DData0_4LSBitsRead(CRYPTO_TypeDef * crypto)984 __STATIC_INLINE uint8_t CRYPTO_DData0_4LSBitsRead(CRYPTO_TypeDef *crypto)
985 {
986   return (uint8_t)((crypto->DSTATUS & _CRYPTO_DSTATUS_DDATA0LSBS_MASK)
987                    >> _CRYPTO_DSTATUS_DDATA0LSBS_SHIFT);
988 }
989 
990 /***************************************************************************//**
991  * @brief
992  *   Read 260 bits from the DDATA0 register.
993  *
994  * @details
995  *   This functions reads 260 bits from the DDATA0 register in the CRYPTO
996  *   module. The data value is typically output from a big integer operation
997  *   (see crypto instructions) when the result width is set to 260 bits by
998  *   calling CRYPTO_ResultWidthSet(cryptoResult260Bits);
999  *
1000  * @param[in]  crypto
1001  *   A pointer to the CRYPTO peripheral register block.
1002  *
1003  * @param[out] val
1004  *   A location to store the value in memory.
1005  ******************************************************************************/
CRYPTO_DData0Read260(CRYPTO_TypeDef * crypto,CRYPTO_Data260_TypeDef val)1006 __STATIC_INLINE void CRYPTO_DData0Read260(CRYPTO_TypeDef *crypto,
1007                                           CRYPTO_Data260_TypeDef val)
1008 {
1009   CRYPTO_DDataRead(&crypto->DDATA0, val);
1010   val[8] = (crypto->DSTATUS & _CRYPTO_DSTATUS_DDATA0MSBS_MASK)
1011            >> _CRYPTO_DSTATUS_DDATA0MSBS_SHIFT;
1012 }
1013 
1014 /***************************************************************************//**
1015  * @brief
1016  *   Write 260 bits to the DDATA0 register.
1017  *
1018  * @details
1019  *   This functions writes 260 bits to the DDATA0 register in the CRYPTO
1020  *   module. The data value is typically input to a big integer operation
1021  *   (see crypto instructions) when the result width is set to 260 bits by
1022  *   calling CRYPTO_ResultWidthSet(cryptoResult260Bits);
1023  *
1024  * @param[in]  crypto
1025  *   Pointer to CRYPTO peripheral register block.
1026  *
1027  * @param[out] val
1028  *   Location where of the value in memory.
1029  ******************************************************************************/
CRYPTO_DData0Write260(CRYPTO_TypeDef * crypto,const CRYPTO_Data260_TypeDef val)1030 __STATIC_INLINE void CRYPTO_DData0Write260(CRYPTO_TypeDef *crypto,
1031                                            const CRYPTO_Data260_TypeDef val)
1032 {
1033   CRYPTO_DDataWrite(&crypto->DDATA0, val);
1034   crypto->DDATA0BYTE32 = val[8] & _CRYPTO_DDATA0BYTE32_DDATA0BYTE32_MASK;
1035 }
1036 
1037 /***************************************************************************//**
1038  * @brief
1039  *   Quick read the MSbit of the DDATA1 register.
1040  *
1041  * @details
1042  *   This function reads the most significant bit (bit 255) of the DDATA1
1043  *   register via the DDATA1MSB bit field in the DSTATUS register. This can
1044  *   be used to quickly check the signedness of a big integer resident in the
1045  *   CRYPTO module.
1046  *
1047  * @param[in]  crypto
1048  *   A pointer to the CRYPTO peripheral register block.
1049  *
1050  * @return
1051  *   Returns 'true' if MSbit is 1, and 'false' if MSbit is 0.
1052  ******************************************************************************/
CRYPTO_DData1_MSBitRead(CRYPTO_TypeDef * crypto)1053 __STATIC_INLINE bool CRYPTO_DData1_MSBitRead(CRYPTO_TypeDef *crypto)
1054 {
1055   return ((crypto->DSTATUS & _CRYPTO_DSTATUS_DDATA1MSB_MASK)
1056           >> _CRYPTO_DSTATUS_DDATA1MSB_SHIFT) != 0UL;
1057 }
1058 
1059 /***************************************************************************//**
1060  * @brief
1061  *   Load a sequence of instructions to be executed on the current values in
1062  *   the data registers.
1063  *
1064  * @details
1065  *   This function loads a sequence of instructions to the crypto module. The
1066  *   instructions will be executed when the CRYPTO_InstructionSequenceExecute
1067  *   function is called. The first END marks the end of the sequence.
1068  *
1069  * @param[in]  crypto
1070  *   A pointer to the CRYPTO peripheral register block.
1071  *
1072  * @param[in]  instructionSequence
1073  *   An instruction sequence to load.
1074  ******************************************************************************/
1075 CRYPTO_WARNINGS_NO_CAST_ALIGN
1076 __STATIC_INLINE
CRYPTO_InstructionSequenceLoad(CRYPTO_TypeDef * crypto,const CRYPTO_InstructionSequence_TypeDef instructionSequence)1077 void CRYPTO_InstructionSequenceLoad(CRYPTO_TypeDef *crypto,
1078                                     const CRYPTO_InstructionSequence_TypeDef instructionSequence)
1079 {
1080   const uint32_t * pas = (const uint32_t *) instructionSequence;
1081 
1082   crypto->SEQ0 = pas[0];
1083   crypto->SEQ1 = pas[1];
1084   crypto->SEQ2 = pas[2];
1085   crypto->SEQ3 = pas[3];
1086   crypto->SEQ4 = pas[4];
1087 }
1088 CRYPTO_WARNINGS_RESET
1089 
1090 /***************************************************************************//**
1091  * @brief
1092  *   Execute the current programmed instruction sequence.
1093  *
1094  * @details
1095  *   This function starts the execution of the current instruction sequence
1096  *   in the CRYPTO module.
1097  *
1098  * @param[in]  crypto
1099  *   A pointer to the CRYPTO peripheral register block.
1100  ******************************************************************************/
CRYPTO_InstructionSequenceExecute(CRYPTO_TypeDef * crypto)1101 __STATIC_INLINE void CRYPTO_InstructionSequenceExecute(CRYPTO_TypeDef *crypto)
1102 {
1103   /* Start the command sequence. */
1104   crypto->CMD = CRYPTO_CMD_SEQSTART;
1105 }
1106 
1107 /***************************************************************************//**
1108  * @brief
1109  *   Check whether the execution of an instruction sequence has completed.
1110  *
1111  * @details
1112  *   This function checks whether an instruction sequence has completed.
1113  *
1114  * @param[in]  crypto
1115  *   A pointer to the CRYPTO peripheral register block.
1116  *
1117  * @return
1118  *   Returns 'true' if the instruction sequence is done, and 'false' if not.
1119  ******************************************************************************/
CRYPTO_InstructionSequenceDone(CRYPTO_TypeDef * crypto)1120 __STATIC_INLINE bool CRYPTO_InstructionSequenceDone(CRYPTO_TypeDef *crypto)
1121 {
1122   /* Return true if operation has completed. */
1123   return (crypto->STATUS
1124           & (CRYPTO_STATUS_INSTRRUNNING | CRYPTO_STATUS_SEQRUNNING)) == 0UL;
1125 }
1126 
1127 /***************************************************************************//**
1128  * @brief
1129  *   Wait for completion of the current sequence of instructions.
1130  *
1131  * @details
1132  *   This function "busy"-waits until the execution of the ongoing instruction
1133  *   sequence has completed.
1134  *
1135  * @param[in]  crypto
1136  *   A pointer to the CRYPTO peripheral register block.
1137  ******************************************************************************/
CRYPTO_InstructionSequenceWait(CRYPTO_TypeDef * crypto)1138 __STATIC_INLINE void CRYPTO_InstructionSequenceWait(CRYPTO_TypeDef *crypto)
1139 {
1140   while (!CRYPTO_InstructionSequenceDone(crypto)) {
1141   }
1142 }
1143 
1144 /***************************************************************************//**
1145  * @brief
1146  *   Wait for completion of the current command.
1147  *
1148  * @details
1149  *   This function "busy"-waits until the execution of the ongoing instruction
1150  *   has completed.
1151  *
1152  * @param[in]  crypto
1153  *   A pointer to the CRYPTO peripheral register block.
1154  ******************************************************************************/
CRYPTO_InstructionWait(CRYPTO_TypeDef * crypto)1155 __STATIC_INLINE void CRYPTO_InstructionWait(CRYPTO_TypeDef *crypto)
1156 {
1157   /* Wait for completion */
1158   while ((crypto->IF & CRYPTO_IF_INSTRDONE) == 0UL) {
1159   }
1160   crypto->IFC = CRYPTO_IF_INSTRDONE;
1161 }
1162 
1163 void CRYPTO_SHA_1(CRYPTO_TypeDef                *crypto,
1164                   const uint8_t                 *msg,
1165                   uint64_t                       msgLen,
1166                   CRYPTO_SHA1_Digest_TypeDef     digest);
1167 
1168 void CRYPTO_SHA_256(CRYPTO_TypeDef              *crypto,
1169                     const uint8_t               *msg,
1170                     uint64_t                     msgLen,
1171                     CRYPTO_SHA256_Digest_TypeDef digest);
1172 
1173 void CRYPTO_Mul(CRYPTO_TypeDef *crypto,
1174                 uint32_t * A, int aSize,
1175                 uint32_t * B, int bSize,
1176                 uint32_t * R, int rSize);
1177 
1178 void CRYPTO_AES_CBC128(CRYPTO_TypeDef *crypto,
1179                        uint8_t * out,
1180                        const uint8_t * in,
1181                        unsigned int len,
1182                        const uint8_t * key,
1183                        const uint8_t * iv,
1184                        bool encrypt);
1185 
1186 void CRYPTO_AES_CBC256(CRYPTO_TypeDef *crypto,
1187                        uint8_t * out,
1188                        const uint8_t * in,
1189                        unsigned int len,
1190                        const uint8_t * key,
1191                        const uint8_t * iv,
1192                        bool encrypt);
1193 
1194 void CRYPTO_AES_PCBC128(CRYPTO_TypeDef *crypto,
1195                         uint8_t * out,
1196                         const uint8_t * in,
1197                         unsigned int len,
1198                         const uint8_t * key,
1199                         const uint8_t * iv,
1200                         bool encrypt);
1201 
1202 void CRYPTO_AES_PCBC256(CRYPTO_TypeDef *crypto,
1203                         uint8_t * out,
1204                         const uint8_t * in,
1205                         unsigned int len,
1206                         const uint8_t * key,
1207                         const uint8_t * iv,
1208                         bool encrypt);
1209 
1210 void CRYPTO_AES_CFB128(CRYPTO_TypeDef *crypto,
1211                        uint8_t * out,
1212                        const uint8_t * in,
1213                        unsigned int len,
1214                        const uint8_t * key,
1215                        const uint8_t * iv,
1216                        bool encrypt);
1217 
1218 void CRYPTO_AES_CFB256(CRYPTO_TypeDef *crypto,
1219                        uint8_t * out,
1220                        const uint8_t * in,
1221                        unsigned int len,
1222                        const uint8_t * key,
1223                        const uint8_t * iv,
1224                        bool encrypt);
1225 
1226 void CRYPTO_AES_CTR128(CRYPTO_TypeDef *crypto,
1227                        uint8_t * out,
1228                        const uint8_t * in,
1229                        unsigned int len,
1230                        const uint8_t * key,
1231                        uint8_t * ctr,
1232                        CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc);
1233 
1234 void CRYPTO_AES_CTR256(CRYPTO_TypeDef *crypto,
1235                        uint8_t * out,
1236                        const uint8_t * in,
1237                        unsigned int len,
1238                        const uint8_t * key,
1239                        uint8_t * ctr,
1240                        CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc);
1241 
1242 void CRYPTO_AES_CTRUpdate32Bit(uint8_t * ctr);
1243 void CRYPTO_AES_DecryptKey128(CRYPTO_TypeDef *crypto, uint8_t * out, const uint8_t * in);
1244 void CRYPTO_AES_DecryptKey256(CRYPTO_TypeDef *crypto, uint8_t * out, const uint8_t * in);
1245 
1246 void CRYPTO_AES_ECB128(CRYPTO_TypeDef *crypto,
1247                        uint8_t * out,
1248                        const uint8_t * in,
1249                        unsigned int len,
1250                        const uint8_t * key,
1251                        bool encrypt);
1252 
1253 void CRYPTO_AES_ECB256(CRYPTO_TypeDef *crypto,
1254                        uint8_t * out,
1255                        const uint8_t * in,
1256                        unsigned int len,
1257                        const uint8_t * key,
1258                        bool encrypt);
1259 
1260 void CRYPTO_AES_OFB128(CRYPTO_TypeDef *crypto,
1261                        uint8_t * out,
1262                        const uint8_t * in,
1263                        unsigned int len,
1264                        const uint8_t * key,
1265                        const uint8_t * iv);
1266 
1267 void CRYPTO_AES_OFB256(CRYPTO_TypeDef *crypto,
1268                        uint8_t * out,
1269                        const uint8_t * in,
1270                        unsigned int len,
1271                        const uint8_t * key,
1272                        const uint8_t * iv);
1273 
1274 /***************************************************************************//**
1275  * @brief
1276  *   Clear one or more pending CRYPTO interrupts.
1277  *
1278  * @param[in] crypto
1279  *   A pointer to the CRYPTO peripheral register block.
1280  *
1281  * @param[in] flags
1282  *   A pending CRYPTO interrupt source to clear. Use a bitwise logic OR combination of
1283  *   valid interrupt flags for the CRYPTO module (CRYPTO_IF_nnn).
1284  ******************************************************************************/
CRYPTO_IntClear(CRYPTO_TypeDef * crypto,uint32_t flags)1285 __STATIC_INLINE void CRYPTO_IntClear(CRYPTO_TypeDef *crypto, uint32_t flags)
1286 {
1287   crypto->IFC = flags;
1288 }
1289 
1290 /***************************************************************************//**
1291  * @brief
1292  *   Disable one or more CRYPTO interrupts.
1293  *
1294  * @param[in] crypto
1295  *   A pointer to the CRYPTO peripheral register block.
1296  *
1297  * @param[in] flags
1298  *   CRYPTO interrupt sources to disable. Use a bitwise logic OR combination of
1299  *   valid interrupt flags for the CRYPTO module (CRYPTO_IF_nnn).
1300  ******************************************************************************/
CRYPTO_IntDisable(CRYPTO_TypeDef * crypto,uint32_t flags)1301 __STATIC_INLINE void CRYPTO_IntDisable(CRYPTO_TypeDef *crypto, uint32_t flags)
1302 {
1303   crypto->IEN &= ~(flags);
1304 }
1305 
1306 /***************************************************************************//**
1307  * @brief
1308  *   Enable one or more CRYPTO interrupts.
1309  *
1310  * @note
1311  *   Depending on the use, a pending interrupt may already be set prior to
1312  *   enabling the interrupt. Consider using CRYPTO_IntClear() prior to enabling
1313  *   if such a pending interrupt should be ignored.
1314  *
1315  * @param[in] crypto
1316  *   A pointer to the CRYPTO peripheral register block.
1317  *
1318  * @param[in] flags
1319  *   CRYPTO interrupt sources to enable. Use a bitwise logic OR combination of
1320  *   valid interrupt flags for the CRYPTO module (CRYPTO_IF_nnn).
1321  ******************************************************************************/
CRYPTO_IntEnable(CRYPTO_TypeDef * crypto,uint32_t flags)1322 __STATIC_INLINE void CRYPTO_IntEnable(CRYPTO_TypeDef *crypto, uint32_t flags)
1323 {
1324   crypto->IEN |= flags;
1325 }
1326 
1327 /***************************************************************************//**
1328  * @brief
1329  *   Get pending CRYPTO interrupt flags.
1330  *
1331  * @note
1332  *   The event bits are not cleared by the use of this function.
1333  *
1334  * @param[in] crypto
1335  *   A pointer to the CRYPTO peripheral register block.
1336  *
1337  * @return
1338  *   CRYPTO interrupt sources pending. A bitwise logic OR combination of valid
1339  *   interrupt flags for the CRYPTO module (CRYPTO_IF_nnn).
1340  ******************************************************************************/
CRYPTO_IntGet(CRYPTO_TypeDef * crypto)1341 __STATIC_INLINE uint32_t CRYPTO_IntGet(CRYPTO_TypeDef *crypto)
1342 {
1343   return crypto->IF;
1344 }
1345 
1346 /***************************************************************************//**
1347  * @brief
1348  *   Get enabled and pending CRYPTO interrupt flags.
1349  *   Useful for handling more interrupt sources in the same interrupt handler.
1350  *
1351  * @note
1352  *   Interrupt flags are not cleared by the use of this function.
1353  *
1354  * @param[in] crypto
1355  *   A pointer to the CRYPTO peripheral register block.
1356  *
1357  * @return
1358  *   Pending and enabled CRYPTO interrupt sources
1359  *   The return value is the bitwise AND of
1360  *   - the enabled interrupt sources in CRYPTO_IEN and
1361  *   - the pending interrupt flags CRYPTO_IF
1362  ******************************************************************************/
CRYPTO_IntGetEnabled(CRYPTO_TypeDef * crypto)1363 __STATIC_INLINE uint32_t CRYPTO_IntGetEnabled(CRYPTO_TypeDef *crypto)
1364 {
1365   uint32_t tmp;
1366 
1367   /* Store IEN in temporary variable in order to define explicit order
1368    * of volatile accesses. */
1369   tmp = crypto->IEN;
1370 
1371   /* Bitwise AND of pending and enabled interrupts */
1372   return crypto->IF & tmp;
1373 }
1374 
1375 /***************************************************************************//**
1376  * @brief
1377  *   Set one or more pending CRYPTO interrupts from software.
1378  *
1379  * @param[in] crypto
1380  *   A pointer to the CRYPTO peripheral register block.
1381  *
1382  * @param[in] flags
1383  *   CRYPTO interrupt sources to set to pending. Use a bitwise logic OR combination
1384  *   of valid interrupt flags for the CRYPTO module (CRYPTO_IF_nnn).
1385  ******************************************************************************/
CRYPTO_IntSet(CRYPTO_TypeDef * crypto,uint32_t flags)1386 __STATIC_INLINE void CRYPTO_IntSet(CRYPTO_TypeDef *crypto, uint32_t flags)
1387 {
1388   crypto->IFS = flags;
1389 }
1390 
1391 #ifdef __cplusplus
1392 }
1393 #endif
1394 
1395 /** @} (end addtogroup crypto) */
1396 
1397 #endif /* defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0) */
1398 
1399 #endif /* EM_CRYPTO_H */
1400