1 /*
2 * Copyright (c) 2018, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef NRF_CCM_H__
33 #define NRF_CCM_H__
34
35 #include <nrfx.h>
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 /**
42 * @defgroup nrf_ccm_hal AES CCM HAL
43 * @{
44 * @ingroup nrf_ccm
45 * @brief Hardware access layer for managing the AES CCM peripheral.
46 */
47
48 /**
49 * @brief CCM tasks.
50 */
51 typedef enum
52 {
53 /*lint -save -e30*/
54 NRF_CCM_TASK_KSGEN = offsetof(NRF_CCM_Type, TASKS_KSGEN), ///< Start generation of key-stream.
55 NRF_CCM_TASK_CRYPT = offsetof(NRF_CCM_Type, TASKS_CRYPT), ///< Start encryption/decryption.
56 NRF_CCM_TASK_STOP = offsetof(NRF_CCM_Type, TASKS_STOP), ///< Stop encryption/decryption.
57 #if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
58 NRF_CCM_TASK_RATEOVERRIDE = offsetof(NRF_CCM_Type, TASKS_RATEOVERRIDE), ///< Override DATARATE setting in MODE register.
59 #endif
60 /*lint -restore*/
61 } nrf_ccm_task_t;
62
63 /**
64 * @brief CCM events.
65 */
66 typedef enum
67 {
68 /*lint -save -e30*/
69 NRF_CCM_EVENT_ENDKSGEN = offsetof(NRF_CCM_Type, EVENTS_ENDKSGEN), ///< Keystream generation complete.
70 NRF_CCM_EVENT_ENDCRYPT = offsetof(NRF_CCM_Type, EVENTS_ENDCRYPT), ///< Encrypt/decrypt complete.
71 NRF_CCM_EVENT_ERROR = offsetof(NRF_CCM_Type, EVENTS_ERROR), ///< CCM error event.
72 /*lint -restore*/
73 } nrf_ccm_event_t;
74
75 /**
76 * @brief CCM interrupts.
77 */
78 typedef enum
79 {
80 NRF_CCM_INT_ENDKSGEN_MASK = CCM_INTENSET_ENDKSGEN_Msk, ///< Interrupt on ENDKSGEN event.
81 NRF_CCM_INT_ENDCRYPT_MASK = CCM_INTENSET_ENDCRYPT_Msk, ///< Interrupt on ENDCRYPT event.
82 NRF_CCM_INT_ERROR_MASK = CCM_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event.
83 } nrf_ccm_int_mask_t;
84
85 /**
86 * @brief CCM modes of operation.
87 */
88 typedef enum
89 {
90 NRF_CCM_MODE_ENCRYPTION = CCM_MODE_MODE_Encryption, ///< Encryption mode.
91 NRF_CCM_MODE_DECRYPTION = CCM_MODE_MODE_Decryption, ///< Decryption mode.
92 } nrf_ccm_mode_t;
93
94 #if defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
95 /**
96 * @brief CCM data rates.
97 */
98 typedef enum
99 {
100 NRF_CCM_DATARATE_1M = CCM_MODE_DATARATE_1Mbit, ///< 1 Mbps.
101 NRF_CCM_DATARATE_2M = CCM_MODE_DATARATE_2Mbit, ///< 2 Mbps.
102 #if defined(CCM_MODE_DATARATE_125Kbps) || defined(__NRFX_DOXYGEN__)
103 NRF_CCM_DATARATE_125K = CCM_MODE_DATARATE_125Kbps, ///< 125 Kbps.
104 #endif
105 #if defined(CCM_MODE_DATARATE_500Kbps) || defined(__NRFX_DOXYGEN__)
106 NRF_CCM_DATARATE_500K = CCM_MODE_DATARATE_500Kbps, ///< 500 Kbps.
107 #endif
108 } nrf_ccm_datarate_t;
109 #endif // defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
110
111 #if defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
112 /**
113 * @brief CCM packet length options.
114 */
115 typedef enum
116 {
117 NRF_CCM_LENGTH_DEFAULT = CCM_MODE_LENGTH_Default, ///< Default length.
118 NRF_CCM_LENGTH_EXTENDED = CCM_MODE_LENGTH_Extended, ///< Extended length.
119 } nrf_ccm_length_t;
120 #endif // defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
121
122 /**
123 * @brief CCM configuration.
124 */
125 typedef struct {
126 nrf_ccm_mode_t mode;
127 #if defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
128 nrf_ccm_datarate_t datarate;
129 #endif
130 #if defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
131 nrf_ccm_length_t length;
132 #endif
133 } nrf_ccm_config_t;
134
135 /**
136 * @brief Function for activating a specific CCM task.
137 *
138 * @param[in] p_reg Pointer to the peripheral registers structure.
139 * @param[in] task Task to activate.
140 */
141 __STATIC_INLINE void nrf_ccm_task_trigger(NRF_CCM_Type * p_reg,
142 nrf_ccm_task_t task);
143
144 /**
145 * @brief Function for getting the address of a specific CCM task register.
146 *
147 * @param[in] p_reg Pointer to the peripheral registers structure.
148 * @param[in] task Requested task.
149 *
150 * @return Address of the specified task register.
151 */
152 __STATIC_INLINE uint32_t nrf_ccm_task_address_get(NRF_CCM_Type const * p_reg,
153 nrf_ccm_task_t task);
154
155 /**
156 * @brief Function for clearing a specific CCM event.
157 *
158 * @param[in] p_reg Pointer to the peripheral registers structure.
159 * @param[in] event Event to clear.
160 */
161 __STATIC_INLINE void nrf_ccm_event_clear(NRF_CCM_Type * p_reg,
162 nrf_ccm_event_t event);
163
164 /**
165 * @brief Function for checking the state of a specific CCM event.
166 *
167 * @param[in] p_reg Pointer to the peripheral registers structure.
168 * @param[in] event Event to check.
169 *
170 * @retval true If the event is set.
171 * @retval false If the event is not set.
172 */
173 __STATIC_INLINE bool nrf_ccm_event_check(NRF_CCM_Type const * p_reg,
174 nrf_ccm_event_t event);
175
176 /**
177 * @brief Function for getting the address of a specific CCM event register.
178 *
179 * @param[in] p_reg Pointer to the peripheral registers structure.
180 * @param[in] event Requested event.
181 *
182 * @return Address of the specified event register.
183 */
184 __STATIC_INLINE uint32_t nrf_ccm_event_address_get(NRF_CCM_Type const * p_reg,
185 nrf_ccm_event_t event);
186
187 /**
188 * @brief Function for enabling specified interrupts.
189 *
190 * @param[in] p_reg Pointer to the peripheral registers structure.
191 * @param[in] mask Interrupts to enable.
192 */
193 __STATIC_INLINE void nrf_ccm_int_enable(NRF_CCM_Type * p_reg, uint32_t mask);
194
195 /**
196 * @brief Function for disabling specified interrupts.
197 *
198 * @param[in] p_reg Pointer to the peripheral registers structure.
199 * @param[in] mask Interrupts to disable.
200 */
201 __STATIC_INLINE void nrf_ccm_int_disable(NRF_CCM_Type * p_reg, uint32_t mask);
202
203 /**
204 * @brief Function for retrieving the state of a given interrupt.
205 *
206 * @param[in] p_reg Pointer to the peripheral registers structure.
207 * @param[in] ccm_int Interrupt to check.
208 *
209 * @retval true If the interrupt is enabled.
210 * @retval false If the interrupt is not enabled.
211 */
212 __STATIC_INLINE bool nrf_ccm_int_enable_check(NRF_CCM_Type const * p_reg,
213 nrf_ccm_int_mask_t ccm_int);
214
215 /**
216 * @brief Function for enabling the CCM peripheral.
217 *
218 * @param[in] p_reg Pointer to the peripheral registers structure.
219 */
220 __STATIC_INLINE void nrf_ccm_enable(NRF_CCM_Type * p_reg);
221
222 /**
223 * @brief Function for disabling the CCM peripheral.
224 *
225 * @param[in] p_reg Pointer to the peripheral registers structure.
226 */
227 __STATIC_INLINE void nrf_ccm_disable(NRF_CCM_Type * p_reg);
228
229 /**
230 * @brief Function for setting the CCM peripheral configuration.
231 *
232 * @param[in] p_reg Pointer to the peripheral registers structure.
233 * @param[in] p_config Pointer to the structure with configuration to be set.
234 */
235 __STATIC_INLINE void nrf_ccm_configure(NRF_CCM_Type * p_reg,
236 nrf_ccm_config_t const * p_config);
237
238 #if defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos) || defined(__NRFX_DOXYGEN__)
239 /**
240 * @brief Function for setting the length of key-stream generated
241 * when the packet length is configured as extended.
242 *
243 * @param[in] p_reg Pointer to the peripheral registers structure.
244 * @param[in] size Maximum length of the key-stream.
245 */
246 __STATIC_INLINE void nrf_ccm_maxpacketsize_set(NRF_CCM_Type * p_reg,
247 uint8_t size);
248 #endif // defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos) || defined(__NRFX_DOXYGEN__)
249
250 /**
251 * @brief Function for getting the MIC check result.
252 *
253 * @param[in] p_reg Pointer to the peripheral registers structure.
254 *
255 * @retval true If the MIC check passed.
256 * @retval false If the MIC check failed.
257 */
258 __STATIC_INLINE bool nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg);
259
260 /**
261 * @brief Function for setting the pointer to the data structure
262 * holding the AES key and the CCM NONCE vector.
263 *
264 * @param[in] p_reg Pointer to the peripheral registers structure.
265 * @param[in] p_data Pointer to the data structure.
266 */
267 __STATIC_INLINE void nrf_ccm_cnfptr_set(NRF_CCM_Type * p_reg,
268 uint32_t const * p_data);
269
270 /**
271 * @brief Function for getting the pointer to the data structure
272 * holding the AES key and the CCM NONCE vector.
273 *
274 * @param[in] p_reg Pointer to the peripheral registers structure.
275 *
276 * @return Pointer to the data structure.
277 */
278 __STATIC_INLINE uint32_t * nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg);
279
280 /**
281 * @brief Function for setting the input data pointer.
282 *
283 * @param[in] p_reg Pointer to the peripheral registers structure.
284 * @param[in] p_data Input data pointer.
285 */
286 __STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type * p_reg,
287 uint32_t const * p_data);
288
289 /**
290 * @brief Function for getting the input data pointer.
291 *
292 * @param[in] p_reg Pointer to the peripheral registers structure.
293 *
294 * @return Input data pointer.
295 */
296 __STATIC_INLINE uint32_t * nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg);
297
298 /**
299 * @brief Function for setting the output data pointer.
300 *
301 * @param[in] p_reg Pointer to the peripheral registers structure.
302 * @param[in] p_data Output data pointer.
303 */
304 __STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type * p_reg,
305 uint32_t const * p_data);
306
307 /**
308 * @brief Function for getting the output data pointer.
309 *
310 * @param[in] p_reg Pointer to the peripheral registers structure.
311 *
312 * @return Output data pointer.
313 */
314 __STATIC_INLINE uint32_t * nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg);
315
316 /**
317 * @brief Function for setting the pointer to the scratch area used for
318 * temporary storage.
319 *
320 * @param[in] p_reg Pointer to the peripheral registers structure.
321 * @param[in] p_area Pointer to the scratch area.
322 */
323 __STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg,
324 uint32_t const * p_area);
325
326 /**
327 * @brief Function for getting the pointer to the scratch area.
328 *
329 * @param[in] p_reg Pointer to the peripheral registers structure.
330 *
331 * @return Pointer to the scratch area.
332 */
333 __STATIC_INLINE uint32_t * nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg);
334
335 #if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
336 /**
337 * @brief Function for setting the data rate override value.
338 *
339 * @param[in] p_reg Pointer to the peripheral registers structure.
340 * @param[in] datarate Override value to be applied when the RATEOVERRIDE task
341 * is triggered.
342 */
343 __STATIC_INLINE void nrf_ccm_datarate_override_set(NRF_CCM_Type * p_reg,
344 nrf_ccm_datarate_t datarate);
345 #endif // defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
346
347 #ifndef SUPPRESS_INLINE_IMPLEMENTATION
348
nrf_ccm_task_trigger(NRF_CCM_Type * p_reg,nrf_ccm_task_t task)349 __STATIC_INLINE void nrf_ccm_task_trigger(NRF_CCM_Type * p_reg,
350 nrf_ccm_task_t task)
351 {
352 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
353 }
354
nrf_ccm_task_address_get(NRF_CCM_Type const * p_reg,nrf_ccm_task_t task)355 __STATIC_INLINE uint32_t nrf_ccm_task_address_get(NRF_CCM_Type const * p_reg,
356 nrf_ccm_task_t task)
357 {
358 return ((uint32_t)p_reg + (uint32_t)task);
359 }
360
nrf_ccm_event_clear(NRF_CCM_Type * p_reg,nrf_ccm_event_t event)361 __STATIC_INLINE void nrf_ccm_event_clear(NRF_CCM_Type * p_reg,
362 nrf_ccm_event_t event)
363 {
364 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
365 #if __CORTEX_M == 0x04
366 volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
367 (void)dummy;
368 #endif
369 }
370
nrf_ccm_event_check(NRF_CCM_Type const * p_reg,nrf_ccm_event_t event)371 __STATIC_INLINE bool nrf_ccm_event_check(NRF_CCM_Type const * p_reg,
372 nrf_ccm_event_t event)
373 {
374 return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
375 }
376
nrf_ccm_event_address_get(NRF_CCM_Type const * p_reg,nrf_ccm_event_t event)377 __STATIC_INLINE uint32_t nrf_ccm_event_address_get(NRF_CCM_Type const * p_reg,
378 nrf_ccm_event_t event)
379 {
380 return ((uint32_t)p_reg + (uint32_t)event);
381 }
382
nrf_ccm_int_enable(NRF_CCM_Type * p_reg,uint32_t mask)383 __STATIC_INLINE void nrf_ccm_int_enable(NRF_CCM_Type * p_reg, uint32_t mask)
384 {
385 p_reg->INTENSET = mask;
386 }
387
nrf_ccm_int_disable(NRF_CCM_Type * p_reg,uint32_t mask)388 __STATIC_INLINE void nrf_ccm_int_disable(NRF_CCM_Type * p_reg, uint32_t mask)
389 {
390 p_reg->INTENCLR = mask;
391 }
392
nrf_ccm_int_enable_check(NRF_CCM_Type const * p_reg,nrf_ccm_int_mask_t ccm_int)393 __STATIC_INLINE bool nrf_ccm_int_enable_check(NRF_CCM_Type const * p_reg,
394 nrf_ccm_int_mask_t ccm_int)
395 {
396 return (bool)(p_reg->INTENSET & ccm_int);
397 }
398
nrf_ccm_enable(NRF_CCM_Type * p_reg)399 __STATIC_INLINE void nrf_ccm_enable(NRF_CCM_Type * p_reg)
400 {
401 p_reg->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos);
402 }
403
nrf_ccm_disable(NRF_CCM_Type * p_reg)404 __STATIC_INLINE void nrf_ccm_disable(NRF_CCM_Type * p_reg)
405 {
406 p_reg->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos);
407 }
408
nrf_ccm_configure(NRF_CCM_Type * p_reg,nrf_ccm_config_t const * p_config)409 __STATIC_INLINE void nrf_ccm_configure(NRF_CCM_Type * p_reg,
410 nrf_ccm_config_t const * p_config)
411 {
412 p_reg->MODE = (((uint32_t)p_config->mode << CCM_MODE_MODE_Pos) |
413 #if defined(CCM_MODE_DATARATE_Pos)
414 ((uint32_t)p_config->datarate << CCM_MODE_DATARATE_Pos) |
415 #endif
416 #if defined(CCM_MODE_LENGTH_Pos)
417 ((uint32_t)p_config->length << CCM_MODE_LENGTH_Pos) |
418 #endif
419 0);
420 }
421
422 #if defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos)
nrf_ccm_maxpacketsize_set(NRF_CCM_Type * p_reg,uint8_t size)423 __STATIC_INLINE void nrf_ccm_maxpacketsize_set(NRF_CCM_Type * p_reg,
424 uint8_t size)
425 {
426 NRFX_ASSERT((size >= 0x1B) && (size <= 0xFB));
427
428 p_reg->MAXPACKETSIZE = size;
429 }
430 #endif // defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos)
431
nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg)432 __STATIC_INLINE bool nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg)
433 {
434 return (bool)(p_reg->MICSTATUS);
435 }
436
nrf_ccm_cnfptr_set(NRF_CCM_Type * p_reg,uint32_t const * p_data)437 __STATIC_INLINE void nrf_ccm_cnfptr_set(NRF_CCM_Type * p_reg,
438 uint32_t const * p_data)
439 {
440 p_reg->CNFPTR = (uint32_t)p_data;
441 }
442
nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg)443 __STATIC_INLINE uint32_t * nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg)
444 {
445 return (uint32_t *)(p_reg->CNFPTR);
446 }
447
nrf_ccm_inptr_set(NRF_CCM_Type * p_reg,uint32_t const * p_data)448 __STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type * p_reg,
449 uint32_t const * p_data)
450 {
451 p_reg->INPTR = (uint32_t)p_data;
452 }
453
nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg)454 __STATIC_INLINE uint32_t * nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg)
455 {
456 return (uint32_t *)(p_reg->INPTR);
457 }
458
nrf_ccm_outptr_set(NRF_CCM_Type * p_reg,uint32_t const * p_data)459 __STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type * p_reg,
460 uint32_t const * p_data)
461 {
462 p_reg->OUTPTR = (uint32_t)p_data;
463 }
464
nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg)465 __STATIC_INLINE uint32_t * nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg)
466 {
467 return (uint32_t *)(p_reg->OUTPTR);
468 }
469
nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg,uint32_t const * p_area)470 __STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg,
471 uint32_t const * p_area)
472 {
473 p_reg->SCRATCHPTR = (uint32_t)p_area;
474 }
475
nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg)476 __STATIC_INLINE uint32_t * nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg)
477 {
478 return (uint32_t *)(p_reg->SCRATCHPTR);
479 }
480
481 #if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos)
nrf_ccm_datarate_override_set(NRF_CCM_Type * p_reg,nrf_ccm_datarate_t datarate)482 __STATIC_INLINE void nrf_ccm_datarate_override_set(NRF_CCM_Type * p_reg,
483 nrf_ccm_datarate_t datarate)
484 {
485 p_reg->RATEOVERRIDE = ((uint32_t)datarate << CCM_RATEOVERRIDE_RATEOVERRIDE_Pos);
486 }
487 #endif
488
489 #endif // SUPPRESS_INLINE_IMPLEMENTATION
490
491 /** @} */
492
493 #ifdef __cplusplus
494 }
495 #endif
496
497 #endif // NRF_CCM_H__
498