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 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 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 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 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 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 383 __STATIC_INLINE void nrf_ccm_int_enable(NRF_CCM_Type * p_reg, uint32_t mask) 384 { 385 p_reg->INTENSET = mask; 386 } 387 388 __STATIC_INLINE void nrf_ccm_int_disable(NRF_CCM_Type * p_reg, uint32_t mask) 389 { 390 p_reg->INTENCLR = mask; 391 } 392 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 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 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 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) 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 432 __STATIC_INLINE bool nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg) 433 { 434 return (bool)(p_reg->MICSTATUS); 435 } 436 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 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 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 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 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 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 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 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) 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