1 /*
2  * Copyright (c) 2025, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef NRF_CRACEN_CM_DMA_H__
35 #define NRF_CRACEN_CM_DMA_H__
36 
37 #include <nrfx.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * @defgroup nrf_cracen_cm_dma_hal CRACEN CryptoMaster DMA layer.
45  * @{
46  * @ingroup nrf_cracen
47  * @brief   Helper layer that provides common functionality for the CRACEN Cryptmaster DMA.
48  */
49 
50 /** @brief CRACEN CryptoMaster DMA descriptor. */
51 typedef struct __PACKED __ALIGN(4) nrf_cracen_cm_dma_desc {
52     uint8_t *                       p_addr; /**< Address of the data block. */
53     struct nrf_cracen_cm_dma_desc * p_next; /**< Pointer to a possibly chained descriptor. */
54     uint32_t                        length; /**< Number of bytes in the data block. */
55     uint32_t                        dmatag; /**< User tag (only used for fetch). */
56 } nrf_cracen_cm_dma_desc_t;
57 
58 /**
59  * @brief This value can be used as a DMA descriptor next address to indicate there is no next
60  *        descriptor, and therefore the DMA should stop with current one.
61  */
62 #define NRF_CRACEN_CM_DMA_DESC_STOP ((struct nrf_cracen_cm_dma_desc *)0x1)
63 
64 /**
65  * @brief When this value is OR'ed with a descriptor length field, the DMA will read from/write into
66  *        the FIFO extra dummy bytes so the operation will finish at a FIFO word boundary.
67  */
68 #define NRF_CRACEN_CM_DMA_DESC_LENGTH_REALIGN (1UL << 29)
69 
70 /**
71  * @brief When this value is OR'ed into the DMA tag, the data will be routed to the selected crypto
72  *        engine configuration interface, otherwise the data is routed to its data interface.
73  */
74 #define NRF_CRACEN_CM_DMA_TAG_CONFIG 0x10UL
75 
76 /**
77  * @brief This can value can be OR'ed into the DMA tag. It will be passed as the "last" side signal
78  *        to the selected crypto engine with the data block. It is up to each crypto engine how to
79  *        interpret it.
80  */
81 #define NRF_CRACEN_CM_DMA_TAG_LAST 0x20UL
82 
83 /** @brief Offset of the DataType field in data tags */
84 #define NRF_CRACEN_CM_DMA_TAG_DATATYPE_OFFSET 6
85 
86 /** @brief CRACEN CM DMA tag engine selection values. */
87 typedef enum
88 {
89     NRF_CRACEN_CM_DMA_TAG_ENGINE_AES    = 0x1, ///< Select the AES engine.
90     NRF_CRACEN_CM_DMA_TAG_ENGINE_HASH   = 0x3, ///< Select the Hash engine.
91     NRF_CRACEN_CM_DMA_TAG_ENGINE_BYPASS = 0xF, ///< Select the engine bypass.
92 } nrf_cracen_cm_dma_tag_engine_t;
93 
94 /** @brief CRACEN CM DMA tag data type selection values. */
95 typedef enum
96 {
97     NRF_CRACEN_CM_DMA_TAG_DATATYPE_AES_PAYLOAD        = (0 << NRF_CRACEN_CM_DMA_TAG_DATATYPE_OFFSET), ///< (for AES engine) Payload (encrypted).
98     NRF_CRACEN_CM_DMA_TAG_DATATYPE_AES_HEADER         = (1 << NRF_CRACEN_CM_DMA_TAG_DATATYPE_OFFSET), ///< (for AES engine) Header (not encrypted, but authenticated).
99     NRF_CRACEN_CM_DMA_TAG_DATATYPE_HASH_MESSAGE       = (0 << NRF_CRACEN_CM_DMA_TAG_DATATYPE_OFFSET), ///< (for Hash engine) Message.
100     NRF_CRACEN_CM_DMA_TAG_DATATYPE_HASH_INIT_DATA     = (1 << NRF_CRACEN_CM_DMA_TAG_DATATYPE_OFFSET), ///< (for Hash engine) Initialization data.
101     NRF_CRACEN_CM_DMA_TAG_DATATYPE_HASH_HMAC_KEY      = (2 << NRF_CRACEN_CM_DMA_TAG_DATATYPE_OFFSET), ///< (for Hash engine) HMAC Key.
102     NRF_CRACEN_CM_DMA_TAG_DATATYPE_HASH_HMAC_REF_HASH = (3 << NRF_CRACEN_CM_DMA_TAG_DATATYPE_OFFSET), ///< (for Hash engine) Reference hash.
103 } nrf_cracen_cm_dma_tag_datatype_t;
104 
105 /**
106  * @brief Generate a tag targeting a configuration register in the the AES crypto engine.
107  *
108  * @param[in] reg_off Register offset, one of @ref nrf_cracen_cm_aes_reg_offset_t.
109  */
110 #define NRF_CRACEN_CM_DMA_TAG_AES_CONFIG(reg_off) \
111 	(NRF_CRACEN_CM_DMA_TAG_ENGINE_AES | NRF_CRACEN_CM_DMA_TAG_CONFIG | (reg_off << 8))
112 
113 /** @brief CRACEN CM AES crypto engine configuration interface registers offsets. */
114 typedef enum
115 {
116     NRF_CRACEN_CM_AES_REG_OFFSET_CONFIG = 0x0,  ///< Config register.
117     NRF_CRACEN_CM_AES_REG_OFFSET_KEY    = 0x8,  ///< AES key (up to 32 bytes).
118     NRF_CRACEN_CM_AES_REG_OFFSET_IV     = 0x28, ///< AES initialization vector (16 bytes).
119     NRF_CRACEN_CM_AES_REG_OFFSET_IV2    = 0x38, ///< AES initialization vector, used for context switching (16 bytes).
120     NRF_CRACEN_CM_AES_REG_OFFSET_KEY2   = 0x48, ///< AES tweak key (for XTS only) (up to 32 bytes).
121     NRF_CRACEN_CM_AES_REG_OFFSET_MASK   = 0x68, ///< Initial value for LFSR (used for countermeasure).
122 } nrf_cracen_cm_aes_reg_offset_t;
123 
124 /** @brief CRACEN CM AES crypto engine configuration modes of operation. */
125 typedef enum
126 {
127     NRF_CRACEN_CM_AES_CONFIG_MODE_ECB      = 0x001,  ///< ECB mode.
128     NRF_CRACEN_CM_AES_CONFIG_MODE_CBC      = 0x002,  ///< CBC mode.
129     NRF_CRACEN_CM_AES_CONFIG_MODE_CTR      = 0x004,  ///< CTR mode.
130     NRF_CRACEN_CM_AES_CONFIG_MODE_CFB      = 0x008,  ///< CFB mode.
131     NRF_CRACEN_CM_AES_CONFIG_MODE_OFB      = 0x010,  ///< OFB mode.
132     NRF_CRACEN_CM_AES_CONFIG_MODE_CCM      = 0x020,  ///< CCM mode.
133     NRF_CRACEN_CM_AES_CONFIG_MODE_GMC_GMAC = 0x040,  ///< GMC/GMAC mode.
134     NRF_CRACEN_CM_AES_CONFIG_MODE_XTS      = 0x080,  ///< XTS mode.
135     NRF_CRACEN_CM_AES_CONFIG_MODE_CMAC     = 0x100,  ///< CMAC mode.
136 } nrf_cracen_cm_aes_config_mode_t;
137 
138 /** @brief CRACEN CM AES crypto engine configuration key selection. */
139 typedef enum
140 {
141     NRF_CRACEN_CM_AES_CONFIG_KEY_SW_PROGRAMMED = 0x0,  ///< Use key programmed by CPU (normal mode).
142     NRF_CRACEN_CM_AES_CONFIG_KEY_AESKEY        = 0x1,  ///< Use special HW input key AESKey[255:0].
143 } nrf_cracen_cm_aes_config_key_t;
144 
145 /**
146  * @brief Generate the value to be written in the AES crypto engine configuration register given its
147  *        parameters.
148  *
149  * @param[in] mode_of_operation AES mode of operation, one of @ref nrf_cracen_cm_aes_config_mode_t.
150  * @param[in] key_sel           SW or HW key selection, one of @ref nrf_cracen_cm_aes_config_key_t.
151  * @param[in] context_save      True if operation in AES mode is not final and the engine will return the context.
152  * @param[in] context_load      True if operation in AES mode is not initial and the context is provided as input.
153  * @param[in] decrypt           True if decryption is to be executed, false if encryption.
154  *
155  * @note This configuration register can only be written using the cryptomaster DMA engine.
156  */
157 #define NRF_CRACEN_CM_AES_CONFIG(mode_of_operation, key_sel, context_save, context_load, decrypt) \
158     (  (((key_sel >> 2) & 0x7) << 28)     \
159      | ((mode_of_operation & 0x1FF) << 8) \
160      | ((key_sel & 0x3) << 6)             \
161      | ((context_save ? 1 : 0) << 5 )     \
162      | ((context_load ? 1 : 0) << 4 )     \
163      | (decrypt ? 1 : 0)                  \
164     )
165 
166 /** @} */
167 
168 #ifdef __cplusplus
169 }
170 #endif
171 
172 #endif // NRF_CRACEN_CM_DMA_H__
173