1 /*
2  * Copyright (c) 2021-2023, Texas Instruments Incorporated
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
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ==========================================================================
33  *  @file       AESCommonLPF3.h
34  *
35  *  @brief      AESCommon driver implementation for the Low Power F3 family
36  *
37  *  The AESCommonLPF3 module provides common functionality used by the
38  *  AES mode-specific implementations for the Low Power F3 family.
39  */
40 
41 #ifndef ti_drivers_aescommon_AESCommonLPF3__include
42 #define ti_drivers_aescommon_AESCommonLPF3__include
43 
44 #include <stdbool.h>
45 #include <stdint.h>
46 
47 #include <ti/drivers/AESCommon.h>
48 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
49 
50 #include <ti/drivers/dpl/HwiP.h>
51 
52 #include <ti/devices/DeviceFamily.h>
53 #include DeviceFamily_constructPath(inc/hw_types.h)
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 /*
60  * Unaligned input/output pointer arguments are not supported by default
61  * because the performance will be up to 5x slower. Enabling unaligned I/O
62  * is strongly discouraged.
63  */
64 #ifndef AESCommonLPF3_UNALIGNED_IO_SUPPORT_ENABLE
65     #define AESCommonLPF3_UNALIGNED_IO_SUPPORT_ENABLE 0
66 #endif
67 
68 /* DMA Channel Numbers */
69 #define DMA_CH4 4U
70 #define DMA_CH5 5U
71 
72 /* DMA Channel 4 is reserved for AES Channel A (input) */
73 #define AESCommonLPF3_DMA_CHA_BITMASK ((uint32_t)1U << DMA_CH4)
74 /* DMA Channel 5 is reserved for AES Channel B (output) */
75 #define AESCommonLPF3_DMA_CHB_BITMASK ((uint32_t)1U << DMA_CH5)
76 
77 /*!
78  *  @brief      AESCommonLPF3 Hardware Attributes
79  */
80 typedef struct
81 {
82     /*!
83      * @brief Crypto Peripheral's interrupt priority.
84      *
85      * The Low Power F3 devices use either three or two priority bits,
86      * depending on the device. That means ~0 has the same effect as (7 << 5)
87      * or (3 << 6), respectively.
88      *
89      * Setting the priority to 0 is not supported by this driver.
90      *
91      * HWI's with priority 0 ignore the HWI dispatcher to support zero-latency
92      * interrupts, thus invalidating the critical sections in this driver.
93      */
94     uint8_t intPriority;
95 } AESCommonLPF3_HWAttrs;
96 
97 /*!
98  *  @brief      AESCommonLPF3 Object
99  *
100  *  The application must not access any member variables of this structure!
101  */
102 typedef struct
103 {
104     uint32_t semaphoreTimeout;
105     CryptoKey key;
106     volatile int_fast16_t returnStatus;
107     AES_ReturnBehavior returnBehavior;
108     bool isOpen;
109     volatile bool cryptoResourceLocked;
110     volatile bool operationInProgress;
111     volatile bool powerConstraintSet;
112 } AESCommonLPF3_Object;
113 
114 /*!
115  *  @cond NODOC
116  *
117  *  @brief  Initializes the common Crypto Resource RTOS objects used by AES drivers.
118  *
119  *  @note   The RTOS objects are common to all AES modes and are initialized
120  *          only once.
121  */
122 void AESCommonLPF3_init(void);
123 
124 /*! @endcond */
125 
126 /*!
127  *  @cond NODOC
128  *
129  *  @brief  Constructs a new driver instance.
130  *
131  *  @param [in] object         #AESCommonLPF3_Object to configure the driver
132  *                             instance.
133  *  @param [in] returnBehavior #AES_ReturnBehavior to configure the driver
134  *                              instance.
135  *  @param [in] timeout        timeout to configure the driver instance.
136  */
137 int_fast16_t AESCommonLPF3_construct(AESCommonLPF3_Object *object, AES_ReturnBehavior returnBehavior, uint32_t timeout);
138 /*! @endcond */
139 
140 /*!
141  *  @cond NODOC
142  *
143  *  @brief  Loads the Key material into the AES HW
144  *
145  *  @param [in] key         Pointer to the CryptoKey object containing the keyMaterial
146  */
147 void AESCommonLPF3_loadKey(const CryptoKey *key);
148 /*! @endcond */
149 
150 /*!
151  *  @cond NODOC
152  *
153  *  @brief  Initializes the key and autoCFG values for an AES operation.
154  *
155  *  @param [in] key         Pointer to the CryptoKey object containing the keyMaterial
156  *  @param [in] autoCfgVal  The AUTOCFG value to be set.
157  */
158 void AESCommonLPF3_setupOperation(CryptoKey *key, uint32_t autoCfgVal);
159 /*! @endcond */
160 
161 /*!
162  *  @cond NODOC
163  *
164  *  @brief  Closes a given driver instance.
165  *
166  *  @param  [in] object  Pointer to an AESCommonLPF3 object
167  *
168  */
169 void AESCommonLPF3_close(AESCommonLPF3_Object *object);
170 /*! @endcond */
171 
172 /*!
173  *  @cond NODOC
174  *
175  *  @brief Marks an operation to be in progress.
176  *
177  *  @param  [in] object  Pointer to an AESCommonLPF3 object
178  *
179  *  @retval AES_STATUS_SUCCESS  Successfully set operation in progress
180  *  @retval AES_STATUS_ERROR    Another operation already in progress
181  */
182 int_fast16_t AESCommonLPF3_setOperationInProgress(AESCommonLPF3_Object *object);
183 /*! @endcond */
184 
185 /*!
186  *  @cond NODOC
187  *
188  *  @brief Clears an operation to be in progress.
189  *
190  *  @param  [in] object  Pointer to an AESCommonLPF3 object
191  *
192  */
AESCommonLPF3_clearOperationInProgress(AESCommonLPF3_Object * object)193 __STATIC_INLINE void AESCommonLPF3_clearOperationInProgress(AESCommonLPF3_Object *object)
194 {
195     object->operationInProgress = false;
196 }
197 /*! @endcond */
198 
199 /*!
200  *  @cond NODOC
201  *
202  *  @brief Cleans up the driver object fields that can be reset
203  *         in common across all AES modes after an operation is done
204  *         and also releases the lock on the crypto resource.
205  *
206  *  @param  [in] object  Pointer to an AESCommonLPF3 object
207  *
208  *  @retval none
209  */
210 void AESCommonLPF3_cleanup(AESCommonLPF3_Object *object);
211 /*! @endcond */
212 
213 /*!
214  *  @cond NODOC
215  *
216  *  @brief  Sets up a segmented operation.
217  *
218  *  @param [in] object  Pointer to an #AESCommonLPF3_Object
219  *  @param [in] key     Pointer to the CryptoKey object to store in object
220  */
221 int_fast16_t AESCommonLPF3_setupSegmentedOperation(AESCommonLPF3_Object *object, const CryptoKey *key);
222 /*! @endcond */
223 
224 /*!
225  *  @cond NODOC
226  *
227  *  @brief  Checks whether the data length is valid for the given \a input and
228  *          \a output pointers.
229  *
230  *  @param [in] input     Pointer to the input data
231  *  @param [in] output    Pointer to the output data
232  *  @param [in] length    Length of the data in bytes
233  *
234  *  @return true if length is valid, false otherwise.
235  */
236 bool AESCommonLPF3_isDMALengthValid(const void *input, const void *output, size_t length);
237 /*! @endcond */
238 
239 /*!
240  *  @cond NODOC
241  *
242  *  @brief  Configures the AES input DMA channel A for a transfer.
243  *
244  *  @note Max \a inputLength depends on the alignment of the \a input pointer.
245  *        If \a input is word-aligned, max \a inputLength is 4KB.
246  *        If \a input is halfword-aligned, max \a inputLength is 2KB.
247  *        If \a input is byte-aligned, max \a inputLength is 1KB.
248  *        \a inputLength be a multiple of AES_BLOCK_SIZE for proper triggering.
249  *
250  *  @param [in] input              Pointer to the input data
251  *  @param [in] inputLength        Length of the input data in bytes,
252  *                                 Must be a multiple of AES_BLOCK_SIZE.
253  */
254 void AESCommonLPF3_configInputDMA(const void *input, size_t inputLength);
255 /*! @endcond */
256 
257 /*!
258  *  @cond NODOC
259  *
260  *  @brief  Configures the AES output DMA channel B for a transfer.
261  *
262  *  @note Max \a outputLength depends on the alignment of the \a output pointer.
263  *        If \a output is word-aligned, max \a outputLength is 4KB.
264  *        If \a output is halfword-aligned, max \a outputLength is 2KB.
265  *        If \a output is byte-aligned, max \a outputLength is 1KB.
266  *        \a outputLength must match the \a inputLength used to call
267  *        #AESCommonLPF3_configInputDMA.
268  *
269  *  @param [out] output              Pointer to the output data
270  *  @param [in]  outputLength        Length of the output data in bytes,
271  *                                   Must be a multiple of AES_BLOCK_SIZE.
272  */
273 void AESCommonLPF3_configOutputDMA(void *output, size_t outputLength);
274 /*! @endcond */
275 
276 /*!
277  *  @cond NODOC
278  *
279  *  @brief  Cancels the AES input channels A. If \a cancelChannelB is true,
280  *          cancels AES output DMA channel B as well.
281  *
282  *  @param [in]  object              Pointer to an #AESCommonLPF3_Object
283  *  @param [out] cancelChannelB      Boolean indicating whether DMA Channel B should be cancelled
284  */
285 void AESCommonLPF3_cancelDMA(bool cancelChannelB);
286 /*! @endcond */
287 
288 /*!
289  *  @cond NODOC
290  *
291  *  @brief  Handles common cancellation operations: <br>
292  *          1) Cancels DMA channel(s) <br>
293  *          2) Sets return status <br>
294  *          3) Clears operation in-progress flag <br>
295  *          4) Releases crypto resource lock
296  *
297  *  @param [in]  object              Pointer to an #AESCommonLPF3_Object
298  *  @param [out] cancelDMAChannelB   Boolean indicating whether DMA Channel B should be cancelled
299  */
300 void AESCommonLPF3_cancelOperation(AESCommonLPF3_Object *object, bool cancelDMAChannelB);
301 /*! @endcond */
302 
303 /*!
304  *  @cond NODOC
305  *
306  *  @brief  Sets the callback function, interrupt priority and enables the AES interrupt.
307  *
308  *  @param [in] hwiFxn       Interrupt callback function
309  *  @param [in] hwiFxnArg    Interrupt callback function argument
310  *  @param [in] intPriority  Interrupt priority
311  */
312 void AESCommonLPF3_setupHwi(HwiP_Fxn hwiFxn, uintptr_t hwiFxnArg, uint8_t intPriority);
313 /*! @endcond */
314 
315 /*!
316  *  @cond NODOC
317  *
318  *  @brief  Clears and disables AES interrupts and release power constraint if set.
319  *
320  *  @param [in]  object      Pointer to an #AESCommonLPF3_Object
321  */
322 void AESCommonLPF3_cleanupHwi(AESCommonLPF3_Object *object);
323 /*! @endcond */
324 
325 /*!
326  *  @cond NODOC
327  *
328  *  @brief  Sets the AES DMA configuration and sets power constraint.
329  *
330  *  @param [in]  object      Pointer to an #AESCommonLPF3_Object
331  *  @param [in]  dmaConfig   AES DMA configuration
332  */
333 void AESCommonLPF3_setupDMA(AESCommonLPF3_Object *object, uint32_t dmaConfig);
334 /*! @endcond */
335 
336 #ifdef __cplusplus
337 }
338 #endif
339 
340 #endif /* ti_drivers_aescommon_AESCommonLPF3__include */
341