summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/include/fsl_dcp.h
blob: b604cdd60c6d67cd288e460c2b324d4c8bf5fcfb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
/*
 * Copyright 2017-2020 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef _FSL_DCP_H_
#define _FSL_DCP_H_

#include "fsl_common.h"

/*******************************************************************************
 * Definitions
 *******************************************************************************/

/*!
 * @addtogroup dcp_driver
 * @{
 */
/*! @name Driver version */
/*@{*/
/*! @brief DCP driver version. Version 2.1.5.
 *
 * Current version: 2.1.5
 *
 * Change log:
 *
 * - Version 2.1.5
 *  - Improvements
 *   - Add support for DCACHE.
 *
 * - Version 2.1.4
 *  - Bug Fix
 *   - Fix CRC-32 computation issue on the code's block boundary size.
 *
 * - Version 2.1.3
 *  - Bug Fix
 *   - MISRA C-2012 issue fixed: rule 10.1, 10.3, 10.4, 11.9, 14.4, 16.4 and 17.7.
 *
 * - Version 2.1.2
 *   - Fix sign-compare warning in dcp_reverse_and_copy.
 *
 * - Version 2.1.1
 *   - Add DCP status clearing when channel operation is complete
 *
 * - 2.1.0
 *   - Add byte/word swap feature for key, input and output data
 *
 * - Version 2.0.0
 *   - Initial version
 */
#define FSL_DCP_DRIVER_VERSION (MAKE_VERSION(2, 1, 5))
/*@}*/

/*! @brief DCP status return codes. */
enum _dcp_status
{
    kStatus_DCP_Again = MAKE_STATUS(kStatusGroup_DCP, 0), /*!< Non-blocking function shall be called again. */
};

/*! @brief DCP channel enable.
 *
 */
typedef enum _dcp_ch_enable
{
    kDCP_chDisable   = 0U,  /*!< DCP channel disable */
    kDCP_ch0Enable   = 1U,  /*!< DCP channel 0 enable */
    kDCP_ch1Enable   = 2U,  /*!< DCP channel 1 enable */
    kDCP_ch2Enable   = 4U,  /*!< DCP channel 2 enable */
    kDCP_ch3Enable   = 8U,  /*!< DCP channel 3 enable */
    kDCP_chEnableAll = 15U, /*!< DCP channel enable all */
} _dcp_ch_enable_t;

/*! @brief DCP interrupt enable.
 *
 */
typedef enum _dcp_ch_int_enable
{
    kDCP_chIntDisable = 0U, /*!< DCP interrupts disable */
    kDCP_ch0IntEnable = 1U, /*!< DCP channel 0 interrupt enable */
    kDCP_ch1IntEnable = 2U, /*!< DCP channel 1 interrupt enable */
    kDCP_ch2IntEnable = 4U, /*!< DCP channel 2 interrupt enable */
    kDCP_ch3IntEnable = 8U, /*!< DCP channel 3 interrupt enable */
} _dcp_ch_int_enable_t;

/*! @brief DCP channel selection.
 *
 */
typedef enum _dcp_channel
{
    kDCP_Channel0 = (1u << 16), /*!< DCP channel 0. */
    kDCP_Channel1 = (1u << 17), /*!< DCP channel 1. */
    kDCP_Channel2 = (1u << 18), /*!< DCP channel 2. */
    kDCP_Channel3 = (1u << 19), /*!< DCP channel 3. */
} dcp_channel_t;

/*! @brief DCP key slot selection.
 *
 */
typedef enum _dcp_key_slot
{
    kDCP_KeySlot0     = 0U, /*!< DCP key slot 0. */
    kDCP_KeySlot1     = 1U, /*!< DCP key slot 1. */
    kDCP_KeySlot2     = 2U, /*!< DCP key slot 2.*/
    kDCP_KeySlot3     = 3U, /*!< DCP key slot 3. */
    kDCP_OtpKey       = 4U, /*!< DCP OTP key. */
    kDCP_OtpUniqueKey = 5U, /*!< DCP unique OTP key. */
    kDCP_PayloadKey   = 6U, /*!< DCP payload key. */
} dcp_key_slot_t;

/*! @brief DCP key, input & output swap options
 *
 */
typedef enum _dcp_swap
{
    kDCP_NoSwap         = 0x0U,
    kDCP_KeyByteSwap    = 0x40000U,
    kDCP_KeyWordSwap    = 0x80000U,
    kDCP_InputByteSwap  = 0x100000U,
    kDCP_InputWordSwap  = 0x200000U,
    kDCP_OutputByteSwap = 0x400000U,
    kDCP_OutputWordSwap = 0x800000U,
} dcp_swap_t;

/*! @brief DCP's work packet. */
typedef struct _dcp_work_packet
{
    uint32_t nextCmdAddress;
    uint32_t control0;
    uint32_t control1;
    uint32_t sourceBufferAddress;
    uint32_t destinationBufferAddress;
    uint32_t bufferSize;
    uint32_t payloadPointer;
    uint32_t status;
} dcp_work_packet_t;

/*! @brief Specify DCP's key resource and DCP channel. */
typedef struct _dcp_handle
{
    dcp_channel_t channel;  /*!< Specify DCP channel. */
    dcp_key_slot_t keySlot; /*!< For operations with key (such as AES encryption/decryption), specify DCP key slot. */
    uint32_t swapConfig;    /*!< For configuration of key, input, output byte/word swap options */
    uint32_t keyWord[4];
    uint32_t iv[4];
} dcp_handle_t;

/*! @brief DCP's context buffer, used by DCP for context switching between channels. */
typedef struct _dcp_context
{
    uint32_t x[208 / sizeof(uint32_t)];
} dcp_context_t;

/*! @brief DCP's configuration structure. */
typedef struct _dcp_config
{
    bool gatherResidualWrites;      /*!< Enable the ragged writes to the unaligned buffers. */
    bool enableContextCaching;      /*!< Enable the caching of contexts between the operations. */
    bool enableContextSwitching;    /*!< Enable automatic context switching for the channels. */
    uint8_t enableChannel;          /*!< DCP channel enable. */
    uint8_t enableChannelInterrupt; /*!< Per-channel interrupt enable. */
} dcp_config_t;

/*! @} */

/*******************************************************************************
 * AES Definitions
 *******************************************************************************/

/*!
 * @addtogroup dcp_driver_aes
 * @{
 */

/*! AES block size in bytes */
#define DCP_AES_BLOCK_SIZE 16

/*!
 *@}
 */ /* end of dcp_driver_aes */

/*******************************************************************************
 * HASH Definitions
 ******************************************************************************/
/*!
 * @addtogroup dcp_driver_hash
 * @{
 */

/* DCP cannot correctly compute hash for message with zero size. When enabled, driver bypases DCP and returns correct
 * hash value. If you are sure, that the driver will never be called with zero sized message, you can disable this
 * feature to reduce code size */
#define DCP_HASH_CAVP_COMPATIBLE

/*! @brief Supported cryptographic block cipher functions for HASH creation */
typedef enum _dcp_hash_algo_t
{
    kDCP_Sha1,   /*!< SHA_1 */
    kDCP_Sha256, /*!< SHA_256 */
    kDCP_Crc32,  /*!< CRC_32 */
} dcp_hash_algo_t;

/*! @brief DCP HASH Context size. */
#define DCP_SHA_BLOCK_SIZE  128U               /*!< internal buffer block size  */
#define DCP_HASH_BLOCK_SIZE DCP_SHA_BLOCK_SIZE /*!< DCP hash block size  */

/*! @brief DCP HASH Context size. */
#define DCP_HASH_CTX_SIZE 64

/*! @brief Storage type used to save hash context. */
typedef struct _dcp_hash_ctx_t
{
    uint32_t x[DCP_HASH_CTX_SIZE];
} dcp_hash_ctx_t;

/*!
 *@}
 */ /* end of dcp_driver_hash */

/*******************************************************************************
 * API
 ******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @addtogroup dcp_driver
 * @{
 */

/*!
 * @brief   Enables clock to and enables DCP
 *
 * Enable DCP clock and configure DCP.
 *
 * @param base DCP base address
 * @param config Pointer to configuration structure.
 */
void DCP_Init(DCP_Type *base, const dcp_config_t *config);

/*!
 * @brief   Disable DCP clock
 *
 * Reset DCP and Disable DCP clock.
 *
 * @param base DCP base address
 */
void DCP_Deinit(DCP_Type *base);

/*!
 * @brief Gets the default configuration structure.
 *
 * This function initializes the DCP configuration structure to a default value. The default
 * values are as follows.
 *   dcpConfig->gatherResidualWrites = true;
 *   dcpConfig->enableContextCaching = true;
 *   dcpConfig->enableContextSwitching = true;
 *   dcpConfig->enableChannnel = kDCP_chEnableAll;
 *   dcpConfig->enableChannelInterrupt = kDCP_chIntDisable;
 *
 * @param[out] config Pointer to configuration structure.
 */
void DCP_GetDefaultConfig(dcp_config_t *config);

/*!
 * @brief Poll and wait on DCP channel.
 *
 * Polls the specified DCP channel until current it completes activity.
 *
 * @param   base DCP peripheral base address.
 * @param   handle Specifies DCP channel.
 * @return  kStatus_Success When data processing completes without error.
 * @return  kStatus_Fail When error occurs.
 */
status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle);

/*!
 *@}
 */ /* end of dcp_driver */

/*******************************************************************************
 * AES API
 ******************************************************************************/

/*!
 * @addtogroup dcp_driver_aes
 * @{
 */

/*!
 * @brief Set AES key to dcp_handle_t struct and optionally to DCP.
 *
 * Sets the AES key for encryption/decryption with the dcp_handle_t structure.
 * The dcp_handle_t input argument specifies keySlot.
 * If the keySlot is kDCP_OtpKey, the function will check the OTP_KEY_READY bit and will return it's ready to use
 * status.
 * For other keySlot selections, the function will copy and hold the key in dcp_handle_t struct.
 * If the keySlot is one of the four DCP SRAM-based keys (one of kDCP_KeySlot0, kDCP_KeySlot1, kDCP_KeySlot2,
 * kDCP_KeySlot3),
 * this function will also load the supplied key to the specified keySlot in DCP.
 *
 * @param   base DCP peripheral base address.
 * @param   handle Handle used for the request.
 * @param   key 0-mod-4 aligned pointer to AES key.
 * @param   keySize AES key size in bytes. Shall equal 16.
 * @return  status from set key operation
 */
status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize);

/*!
 * @brief Encrypts AES on one or multiple 128-bit block(s).
 *
 * Encrypts AES.
 * The source plaintext and destination ciphertext can overlap in system memory.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for this request.
 * @param plaintext Input plain text to encrypt
 * @param[out] ciphertext Output cipher text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @return Status from encrypt operation
 */
status_t DCP_AES_EncryptEcb(
    DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size);

/*!
 * @brief Decrypts AES on one or multiple 128-bit block(s).
 *
 * Decrypts AES.
 * The source ciphertext and destination plaintext can overlap in system memory.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for this request.
 * @param ciphertext Input plain text to encrypt
 * @param[out] plaintext Output cipher text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @return Status from decrypt operation
 */
status_t DCP_AES_DecryptEcb(
    DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size);

/*!
 * @brief Encrypts AES using CBC block mode.
 *
 * Encrypts AES using CBC block mode.
 * The source plaintext and destination ciphertext can overlap in system memory.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for this request.
 * @param plaintext Input plain text to encrypt
 * @param[out] ciphertext Output cipher text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @param iv Input initial vector to combine with the first input block.
 * @return Status from encrypt operation
 */
status_t DCP_AES_EncryptCbc(DCP_Type *base,
                            dcp_handle_t *handle,
                            const uint8_t *plaintext,
                            uint8_t *ciphertext,
                            size_t size,
                            const uint8_t iv[16]);

/*!
 * @brief Decrypts AES using CBC block mode.
 *
 * Decrypts AES using CBC block mode.
 * The source ciphertext and destination plaintext can overlap in system memory.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for this request.
 * @param ciphertext Input cipher text to decrypt
 * @param[out] plaintext Output plain text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @param iv Input initial vector to combine with the first input block.
 * @return Status from decrypt operation
 */
status_t DCP_AES_DecryptCbc(DCP_Type *base,
                            dcp_handle_t *handle,
                            const uint8_t *ciphertext,
                            uint8_t *plaintext,
                            size_t size,
                            const uint8_t iv[16]);

/*!
 *@}
 */ /* end of dcp_driver_aes */

/*!
 * @addtogroup dcp_nonblocking_driver_aes
 * @{
 */
/*!
 * @brief Encrypts AES using the ECB block mode.
 *
 * Puts AES ECB encrypt work packet to DCP channel.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for this request.
 * @param[out] dcpPacket Memory for the DCP work packet.
 * @param plaintext Input plain text to encrypt.
 * @param[out] ciphertext Output cipher text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @return kStatus_Success The work packet has been scheduled at DCP channel.
 * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
 */
status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base,
                                       dcp_handle_t *handle,
                                       dcp_work_packet_t *dcpPacket,
                                       const uint8_t *plaintext,
                                       uint8_t *ciphertext,
                                       size_t size);

/*!
 * @brief Decrypts AES using ECB block mode.
 *
 * Puts AES ECB decrypt dcpPacket to DCP input job ring.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for this request.
 * @param[out] dcpPacket Memory for the DCP work packet.
 * @param ciphertext Input cipher text to decrypt
 * @param[out] plaintext Output plain text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @return kStatus_Success The work packet has been scheduled at DCP channel.
 * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
 */
status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base,
                                       dcp_handle_t *handle,
                                       dcp_work_packet_t *dcpPacket,
                                       const uint8_t *ciphertext,
                                       uint8_t *plaintext,
                                       size_t size);

/*!
 * @brief Encrypts AES using CBC block mode.
 *
 * Puts AES CBC encrypt dcpPacket to DCP input job ring.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for this request. Specifies jobRing.
 * @param[out] dcpPacket Memory for the DCP work packet.
 * @param plaintext Input plain text to encrypt
 * @param[out] ciphertext Output cipher text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @param iv Input initial vector to combine with the first input block.
 * @return kStatus_Success The work packet has been scheduled at DCP channel.
 * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
 */
status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base,
                                       dcp_handle_t *handle,
                                       dcp_work_packet_t *dcpPacket,
                                       const uint8_t *plaintext,
                                       uint8_t *ciphertext,
                                       size_t size,
                                       const uint8_t *iv);

/*!
 * @brief Decrypts AES using CBC block mode.
 *
 * Puts AES CBC decrypt dcpPacket to DCP input job ring.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for this request. Specifies jobRing.
 * @param[out] dcpPacket Memory for the DCP work packet.
 * @param ciphertext Input cipher text to decrypt
 * @param[out] plaintext Output plain text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @param iv Input initial vector to combine with the first input block.
 * @return kStatus_Success The work packet has been scheduled at DCP channel.
 * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
 */
status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base,
                                       dcp_handle_t *handle,
                                       dcp_work_packet_t *dcpPacket,
                                       const uint8_t *ciphertext,
                                       uint8_t *plaintext,
                                       size_t size,
                                       const uint8_t *iv);

/*!
 *@}
 */ /* end of dcp_nonblocking_driver_aes */

/*******************************************************************************
 * HASH API
 ******************************************************************************/

/*!
 * @addtogroup dcp_driver_hash
 * @{
 */
/*!
 * @brief Initialize HASH context
 *
 * This function initializes the HASH.
 *
 * @param base DCP peripheral base address
 * @param handle Specifies the DCP channel used for hashing.
 * @param[out] ctx Output hash context
 * @param algo Underlaying algorithm to use for hash computation.
 * @return Status of initialization
 */
status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo);

/*!
 * @brief Add data to current HASH
 *
 * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
 * hashed. The functions blocks. If it returns kStatus_Success, the running hash
 * has been updated (DCP has processed the input data), so the memory at the input pointer
 * can be released back to system. The DCP context buffer is updated with the running hash
 * and with all necessary information to support possible context switch.
 *
 * @param base DCP peripheral base address
 * @param[in,out] ctx HASH context
 * @param input Input data
 * @param inputSize Size of input data in bytes
 * @return Status of the hash update operation
 */
status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize);

/*!
 * @brief Finalize hashing
 *
 * Outputs the final hash (computed by DCP_HASH_Update()) and erases the context.
 *
 * @param base DCP peripheral base address
 * @param[in,out] ctx Input hash context
 * @param[out] output Output hash data
 * @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
 * output[] buffer. On function return, it stores the number of updated output bytes.
 * @return Status of the hash finish operation
 */
status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize);

/*!
 * @brief Create HASH on given data
 *
 * Perform the full SHA or CRC32 in one function call. The function is blocking.
 *
 * @param base DCP peripheral base address
 * @param handle Handle used for the request.
 * @param algo Underlaying algorithm to use for hash computation.
 * @param input Input data
 * @param inputSize Size of input data in bytes
 * @param[out] output Output hash data
 * @param[out] outputSize Output parameter storing the size of the output hash in bytes
 * @return Status of the one call hash operation.
 */
status_t DCP_HASH(DCP_Type *base,
                  dcp_handle_t *handle,
                  dcp_hash_algo_t algo,
                  const uint8_t *input,
                  size_t inputSize,
                  uint8_t *output,
                  size_t *outputSize);

/*!
 *@}
 */ /* end of dcp_driver_hash */

#if defined(__cplusplus)
}
#endif

#endif /* _FSL_DCP_H_ */