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