1 /*
2  * Copyright (c) 2015-2019, 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       CryptoCC32XX.h
34  *
35  *  @brief      Crypto driver implementation for a CC32XX Crypto controller.
36  *
37  *  The Crypto header file should be included in an application as follows:
38  *  @code
39  *  #include <ti/drivers/crypto/CryptoCC32XX.h>
40  *  @endcode
41  *
42  *  # Operation #
43  *
44  *  The CryptoCC32XX driver is used several security methods (AES, DES and HMAC Hash functions).
45  *  This driver provides API for encrypt/decrypt (AES and DES)
46  *  and sign/verify (HMAC hash)
47  *
48  *  The application initializes the CryptoCC32XX driver by calling CryptoCC32XX_init()
49  *  and is then ready to open a Crypto by calling CryptoCC32XX_open().
50  *
51  *  The APIs in this driver serve as an interface to a typical TI-RTOS
52  *  application. The specific peripheral implementations are responsible to
53  *  create all the OSAL specific primitives to allow for thread-safe
54  *  operation.
55  *
56  *  ## Opening the driver #
57  *
58  *  @code
59  *  CryptoCC32XX_Handle      handle;
60  *
61  *  handle = CryptoCC32XX_open(CryptoCC32XX_configIndexValue,   CryptoCC32XX_AES |
62                                                                 CryptoCC32XX_DES |
63                                                                 CryptoCC32XX_HMAC);
64  *  if (!handle) {
65  *      System_printf("CryptoCC32XX did not open");
66  *  }
67  *  @endcode
68  *
69  *
70  *  ## AES data encryption #
71  *
72  *  @code
73  *  CryptoCC32XX_EncryptMethod  method = desiredMethod;
74  *  CryptoCC32XX_Params         params;
75  *  unsigned char               plainData[16] = "whatsoever123456";
76  *  unsigned int                plainDataLen = sizeof(plainData);
77  *  unsigned char               cipherData[16];
78  *  unsigned int                cipherDataLen;
79  *
80  *  params.aes.keySize = desiredKeySize;
81  *  params.aes.pKey = (CryptoCC32XX_KeyPtr)desiredKey; // desiredKey length should be as the desiredKeySize
82  *  params.aes.pIV = (void *)pointerToInitVector;
83  *  ret = CryptoCC32XX_encrypt(handle, method , plainData, plainDataLen, cipherData , &cipherDataLen , &params);
84  *
85  *  @endcode
86  *
87  *  ## Generate HMAC Hash signature #
88  *
89  *  @code
90  *  CryptoCC32XX_HmacMethod hmacMethod = desiredHmacMethod;
91  *  CryptoCC32XX_Params     params;
92  *  unsigned char           dataBuff[] = "whatsoever";
93  *  unsigned int            dataLength = sizeof(dataBuff);
94  *  unsigned char           signatureBuff[32];
95  *
96  *  params.pKey = pointerToHMACkey;
97  *  params.moreData = 0;
98  *  ret = CryptoCC32XX_sign(handle, hmacMethod , &dataBuff, dataLength, &signatureBuff, &params);
99  *
100  *  @endcode
101  *
102  *  # Implementation #
103  *
104  *  The CryptoCC32XX driver interface module is joined (at link time) to a
105  *  NULL-terminated array of CryptoCC32XX_Config data structures named *CryptoCC32XX_config*.
106  *  *CryptoCC32XX_config* is implemented in the application with each entry being an
107  *  instance of a CryptoCC32XX peripheral. Each entry in *CryptoCC32XX_config* contains a:
108  *  - (void *) data object that is pointed to CryptoCC32XX_Object
109  *
110  *
111  *  ============================================================================
112  */
113 
114 #ifndef ti_drivers_crypto_CryptoCC32XX__include
115 #define ti_drivers_crypto_CryptoCC32XX__include
116 
117 #include <stdint.h>
118 #include <stddef.h>
119 #include <stdbool.h>
120 #include <ti/drivers/dpl/HwiP.h>
121 #include <ti/drivers/dpl/SemaphoreP.h>
122 
123 #ifdef __cplusplus
124 extern "C" {
125 #endif
126 
127 #define CryptoCC32XX_CMD_RESERVED             32
128 
129 #define CryptoCC32XX_STATUS_RESERVED          -32
130 
131 /*!
132  * @brief   Successful status code returned by Crypto Common functions.
133  *
134  */
135 #define CryptoCC32XX_STATUS_SUCCESS           0
136 
137 /*!
138  * @brief   Generic error status code returned by Crypto Common functions.
139  *
140  */
141 #define CryptoCC32XX_STATUS_ERROR             -1
142 
143 /*!
144  * @brief   An error status code returned by Crypto Common functions for undefined
145  * command codes.
146  *
147  */
148 #define CryptoCC32XX_STATUS_UNDEFINEDCMD      -2
149 
150 /*!
151  * @brief   An error status code returned by CryptoCC32XX_verify for define error in
152  * verifying a given Hash value.
153  *
154  */
155 #define CryptoCC32XX_STATUS_ERROR_VERIFY      -3
156 
157 /*!
158  * @brief   An error status code returned by Crypto Common functions for define
159  * cryptographic type not supported.
160  *
161  */
162 #define CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED -4
163 
164 
165 #define CryptoCC32XX_MAX_TYPES  3
166 
167 #define CryptoCC32XX_MD5_BLOCK_SIZE     64
168 #define CryptoCC32XX_SHA1_BLOCK_SIZE    64
169 #define CryptoCC32XX_SHA256_BLOCK_SIZE  64
170 
171 #define CryptoCC32XX_MD5_DIGEST_SIZE    16
172 #define CryptoCC32XX_SHA1_DIGEST_SIZE   20
173 #define CryptoCC32XX_SHA256_DIGEST_SIZE 32
174 
175 #define CryptoCC32XX_MAX_DIGEST_SIZE CryptoCC32XX_SHA256_DIGEST_SIZE
176 #define CryptoCC32XX_MAX_BLOCK_SIZE  CryptoCC32XX_SHA256_BLOCK_SIZE
177 
178 
179 /*!
180  *  @brief  Cryptography types configuration
181  *
182  *  This enum defines bitwise Cryptography types.
183  */
184 typedef enum
185 {
186     CryptoCC32XX_AES  = 0x01,    /*!< Advanced Encryption Standard */
187     CryptoCC32XX_DES  = 0x02,    /*!< Data Encryption Standard */
188     CryptoCC32XX_HMAC = 0x04,    /*!< Cryptographic hash function */
189 }CryptoCC32XX_Type;
190 
191 /*!
192  *  @brief  AES and DES Cryptography methods configuration
193  *  Keep the Crypto method in the lower 8 bit and
194  *  Crypto type in the upper 8 bits
195  *
196  *  This enum defines the AES and DES Cryptography modes.
197  */
198 typedef enum
199 {
200     CryptoCC32XX_AES_ECB = (CryptoCC32XX_AES << 8) | 1, /*!< AES Electronic CodeBook */
201     CryptoCC32XX_AES_CBC,                         /*!< AES Cipher Block Chaining */
202     CryptoCC32XX_AES_CTR,                         /*!< AES Counter */
203     CryptoCC32XX_AES_ICM,                         /*!< AES Integer Counter Mode */
204     CryptoCC32XX_AES_CFB,                         /*!< AES Cipher FeedBack */
205     CryptoCC32XX_AES_GCM,                         /*!< AES Galois/Counter Mode */
206     CryptoCC32XX_AES_CCM,                         /*!< AES Counter with CBC-MAC Mode */
207 
208     CryptoCC32XX_DES_ECB = (CryptoCC32XX_DES << 8) | 1, /*!< DES Electronic CodeBook */
209     CryptoCC32XX_DES_CBC,                         /*!< DES Cipher Block Chaining */
210     CryptoCC32XX_DES_CFB,                         /*!< DES Cipher FeedBack */
211 
212 }CryptoCC32XX_EncryptMethod;
213 
214 /*!
215  *  @brief  HMAC Cryptography methods configuration
216  *  Keep the Crypto method in the lower 8 bit and
217  *  Crypto type in the upper 8 bits
218  *
219  *  This enum defines the HMAC HASH algorithms modes.
220  */
221 typedef enum
222 {
223     CryptoCC32XX_HMAC_MD5 = (CryptoCC32XX_HMAC << 8) | 1,   /*!< MD5 used keyed-hash message authentication code */
224     CryptoCC32XX_HMAC_SHA1,                           /*!< SHA1 used keyed-hash message authentication code */
225     CryptoCC32XX_HMAC_SHA224,                         /*!< SHA224 used keyed-hash message authentication code */
226     CryptoCC32XX_HMAC_SHA256                          /*!< SHA256 used keyed-hash message authentication code */
227 
228 }CryptoCC32XX_HmacMethod;
229 
230 /*!
231  *  @brief  AES Cryptography key size type configuration
232  *
233  *  This enum defines the AES key size types
234  */
235 typedef enum
236 {
237     CryptoCC32XX_AES_KEY_SIZE_128BIT,
238     CryptoCC32XX_AES_KEY_SIZE_192BIT,
239     CryptoCC32XX_AES_KEY_SIZE_256BIT
240 
241 }CryptoCC32XX_AesKeySize;
242 
243 /*!
244  *  @brief  DES Cryptography key size type configuration
245  *
246  *  This enum defines the DES key size types
247  */
248 typedef enum
249 {
250     CryptoCC32XX_DES_KEY_SIZE_SINGLE,
251     CryptoCC32XX_DES_KEY_SIZE_TRIPLE
252 
253 }CryptoCC32XX_DesKeySize;
254 
255 
256 /*!
257  *  @brief  AES Additional Authentication Data input parameters
258  *
259  *  This structure defines the AES Additional Authentication Data input parameters used for
260  *  CryptoCC32XX_AES_GCM and CryptoCC32XX_AES_CCM
261  */
262 typedef struct
263 {
264     uint8_t                 *pKey2;     /*!< pointer to AES second key (CryptoCC32XX_AES_CCM) */
265     CryptoCC32XX_AesKeySize key2Size;   /*!< AES second Key size type (CryptoCC32XX_AES_CCM) */
266     size_t                  len;        /*!< length of the additional authentication data in bytes */
267 }CryptoCC32XX_AesAadInputParams;
268 
269 /*!
270  *  @brief  AES Additional Authentication Data Parameters
271  *
272  *  This union defines the AES additional authentication parameters used for
273  *  CryptoCC32XX_AES_GCM and CryptoCC32XX_AES_CCM
274  */
275 typedef union
276 {
277     CryptoCC32XX_AesAadInputParams input;   /*!<an input - additional authentication data */
278     uint8_t                        tag[16]; /*!<an output - pointer to a 4-word array where the hash tag is written */
279 }CryptoCC32XX_AesAadParams;
280 
281 /*!
282  *  @brief  AES Parameters
283  *
284  *  This structure defines the AES parameters used in CryptoCC32XX_encrypt and CryptoCC32XX_decrypt functions.
285  */
286 typedef struct
287 {
288     const uint8_t             *pKey;      /*!< pointer to AES key */
289     CryptoCC32XX_AesKeySize   keySize;    /*!< AES Key size type */
290     void                      *pIV;       /*!< Pointer to AES Initialization Vector */
291     CryptoCC32XX_AesAadParams aadParams;
292 }CryptoCC32XX_AesParams;
293 
294 /*!
295  *  @brief  DES Parameters
296  *
297  *  This structure defines the DES parameters used in CryptoCC32XX_encrypt and CryptoCC32XX_decrypt functions.
298  */
299 typedef struct
300 {
301     const uint8_t           *pKey;      /*!< pointer to DES key */
302     CryptoCC32XX_DesKeySize keySize;    /*!< DES Key size type */
303     void                    *pIV;       /*!< Pointer to DES Initialization Vector */
304 }CryptoCC32XX_DesParams;
305 
306 /*!
307  *  @brief  Cryptography Parameters
308  *
309  *  This union defines the AES and DES Cryptographic types
310  */
311 typedef union
312 {
313     CryptoCC32XX_AesParams        aes;
314     CryptoCC32XX_DesParams        des;
315 }CryptoCC32XX_EncryptParams;
316 
317 /*!
318  *  @brief  HMAC Parameters
319  *
320  *  This structure defines the Hmac parameters used in CryptoCC32XX_sign and CryptoCC32XX_verify functions.
321  */
322 typedef struct
323 {
324     /*! pointer to hash key */
325     uint8_t  *pKey;
326     /*! True value will NOT close the HMAC HW machine */
327     uint8_t  moreData;
328     /*! Reserved for future use */
329     void     *pContext;
330     /*! True if no data was written to the HMAC HW machine */
331     uint8_t  first;
332     /*! Number of bytes that was written to the HMAC HW machine */
333     uint32_t digestCount;
334     /*! Intermediate digest */
335     uint8_t  innerDigest[CryptoCC32XX_MAX_DIGEST_SIZE];
336     /*! Internal buffer - used when moreData sets to true and the data length is not an integer multiple of blockSize */
337     uint8_t  buff[CryptoCC32XX_MAX_BLOCK_SIZE];
338     /*! Number of bytes in buff */
339     uint32_t buffLen;
340     /*! Block size of the hashing algorithm in use */
341     uint32_t blockSize;
342 }CryptoCC32XX_HmacParams;
343 
344 /*!
345  *  @brief  Crypto Global configuration
346  *
347  *  The CryptoCC32XX_Config structure contains a set of pointers used to characterize
348  *  the Crypto driver implementation.
349  *
350  *  This structure needs to be defined before calling CryptoCC32XX_init() and it must
351  *  not be changed thereafter.
352  *
353  *  @sa     CryptoCC32XX_init()
354  */
355 typedef struct {
356 
357     /*! Pointer to a driver specific data object */
358     void               *object;
359 
360 } CryptoCC32XX_Config;
361 
362 /*!
363  *  @brief      A handle that is returned from a CryptoCC32XX_open() call.
364  */
365 typedef  CryptoCC32XX_Config *CryptoCC32XX_Handle;
366 
367 /*!
368  *  @brief  CryptoCC32XX Object
369  *
370  *  The application must not access any member variables of this structure!
371  */
372 typedef struct {
373     /*! Interrupt handles */
374     HwiP_Handle     hwiHandle[CryptoCC32XX_MAX_TYPES];
375     /*! flag to indicate module is open */
376     bool            isOpen;
377     /*! Semaphore handles */
378     SemaphoreP_Handle   sem[CryptoCC32XX_MAX_TYPES];
379 } CryptoCC32XX_Object;
380 
381 /*!
382  *  @brief  Function to close a given Crypto peripheral specified by the Crypto
383  *  handle.
384  *
385  *  @pre    CryptoCC32XX_open() had to be called first.
386  *
387  *  @param  handle  A CryptoCC32XX_Handle returned from CryptoCC32XX_open
388  *
389  *  @sa     CryptoCC32XX_open()
390  */
391 void CryptoCC32XX_close(CryptoCC32XX_Handle handle);
392 
393 /*!
394  *  @brief  Function to initializes the Crypto module
395  *
396  *  @pre    The CryptoCC32XX_Config structure must exist and be persistent before this
397  *          function can be called. This function must also be called before
398  *          any other Crypto driver APIs. This function call does not modify any
399  *          peripheral registers.
400  */
401 void CryptoCC32XX_init(void);
402 
403 /*!
404  *  @brief  Opens a Crypto object with a given index and returns a CryptoCC32XX_Handle.
405  *
406  *  @pre    Crypto module has been initialized
407  *
408  *  @param  index         Logical peripheral number for the Crypto indexed into
409  *                        the CryptoCC32XX_config table
410  *
411  *  @param  types         Define bitwise Crypto Types to support
412  *
413  *  @return A CryptoCC32XX_Handle on success or a NULL on an error or if it has been
414  *          opened already.
415  *
416  *  @sa     CryptoCC32XX_init()
417  *  @sa     CryptoCC32XX_HmacParams_init()
418  *  @sa     CryptoCC32XX_close()
419  */
420 CryptoCC32XX_Handle CryptoCC32XX_open(uint32_t index, uint32_t types);
421 
422 /*!
423  *  @brief  Initialize params structure to default values.
424  *
425  *  The default parameters are:
426  *   - pKey: 0
427  *   - moreData: 0
428  *   - *pContext: 0
429  *   - first: 1
430  *   - digestCount: 0
431  *   - innerDigest: 0
432  *   - buff: 0
433  *   - buffLen: 0
434  *   - blockSize: CryptoCC32XX_SHA256_BLOCK_SIZE
435  *
436  *  @param params  Pointer to the instance configuration parameters.
437  */
438 void CryptoCC32XX_HmacParams_init(CryptoCC32XX_HmacParams *params);
439 
440 
441 /*!
442  *  @brief Function which encrypt given data by a given AES or DES method.
443  *  relevant to CryptoCC32XX_AES and CryptoCC32XX_DES
444  *
445  *  @param  handle      A CryptoCC32XX_Handle
446  *
447  *  @param  method      An AES or DES encryption method to use on a given plain data.
448  *
449  *  @param  pInBuff     Pointer to plain data to encrypt.
450  *
451  *  @param  inLen       Size of plain data to encrypt.
452  *
453  *  @param  pOutBuff    Pointer to encrypted data (cipher text).
454  *
455  *  @param  outLen      Size of encrypted data.
456  *
457  *  @param  pParams     Specific parameters according to Crypto Type (AES or DES).
458  *
459  *  @return             Returns CryptoCC32XX_STATUS_SUCCESS if successful else would return
460  *                      CryptoCC32XX_STATUS_ERROR on an error.
461  *
462  *  @sa                 CryptoCC32XX_open()
463  */
464 int32_t CryptoCC32XX_encrypt(  CryptoCC32XX_Handle handle, CryptoCC32XX_EncryptMethod method ,
465                             void *pInBuff, size_t inLen,
466                             void *pOutBuff , size_t *outLen , CryptoCC32XX_EncryptParams *pParams);
467 
468 /*!
469  *  @brief Function which decrypt given cipher data by a given AES or DES method.
470  *  relevant to CryptoCC32XX_AES and CryptoCC32XX_DES
471  *
472  *  @param  handle      A CryptoCC32XX_Handle
473  *
474  *  @param  method      An AES or DES decryption method to use on a given cipher data.
475  *
476  *  @param  pInBuff     Pointer to cipher data to decrypt.
477  *
478  *  @param  inLen       Size of cipher data to decrypt.
479  *
480  *  @param  pOutBuff    Pointer to decrypted data (plain text).
481  *
482  *  @param  outLen      Size of decrypted data.
483  *
484  *  @param  pParams     Specific parameters according to Crypto Type (AES or DES).
485  *
486  *  @return             Returns CryptoCC32XX_STATUS_SUCCESS if successful else would return
487  *                      CryptoCC32XX_STATUS_ERROR on an error.
488  *
489  *  @sa                 CryptoCC32XX_open()
490  */
491 int32_t CryptoCC32XX_decrypt(  CryptoCC32XX_Handle handle, CryptoCC32XX_EncryptMethod method ,
492                             void *pInBuff, size_t inLen,
493                             void *pOutBuff , size_t *outLen , CryptoCC32XX_EncryptParams *pParams);
494 
495 /*!
496  *  @brief Function which generates the HMAC Hash value of given plain Text.
497  *  relevant to CryptoCC32XX_HMAC
498  *
499  *  @param  handle      A CryptoCC32XX_Handle
500  *
501  *  @param  method      HMAC Hash algorithm to use in order to generates the hash value
502  *
503  *  @param  pBuff       Pointer to plain data.
504  *
505  *  @param  len         Size of plain data.
506  *
507  *  @param  pSignature  As input pointer to the given HMAC Hash value in case the HMAC flag was set
508  *                      and as output pointer for the generated Hash value.
509  *
510  *  @param  pParams     Specific parameters according to HMAC algorithm
511  *
512  *  @return             Returns CryptoCC32XX_STATUS_SUCCESS if successful else would return
513  *                      CryptoCC32XX_STATUS_ERROR on an error.
514  *
515  *  @sa                 CryptoCC32XX_open()
516  */
517 int32_t CryptoCC32XX_sign( CryptoCC32XX_Handle handle, CryptoCC32XX_HmacMethod method ,
518                         void *pBuff, size_t len,
519                         uint8_t *pSignature, CryptoCC32XX_HmacParams *pParams);
520 
521 /*!
522  *  @brief Function which verify a given Hash value on given plain Text.
523  *  relevant to CryptoCC32XX_HMAC
524  *
525  *  @param  handle      A CryptoCC32XX_Handle
526  *
527  *  @param  method      HMAC Hash algorithm to use in order to verify the hash value
528  *
529  *  @param  pBuff       Pointer to plain data.
530  *
531  *  @param  len         Size of plain data.
532  *
533  *  @param  pSignature  As input pointer to the given HMAC Hash value in case the HMAC flag was set
534  *                      and as output pointer for the generated Hash value.
535  *
536  *  @param  pParams     Specific parameters according to HMAC algorithm.
537  *
538  *  @return             Returns CryptoCC32XX_STATUS_SUCCESS if value was successfully verified
539  *                      else would return CryptoCC32XX_STATUS_ERROR.
540  *
541  *  @sa                 CryptoCC32XX_open()
542  */
543 int32_t CryptoCC32XX_verify(   CryptoCC32XX_Handle handle, CryptoCC32XX_HmacMethod method ,
544                             void *pBuff, size_t len,
545                             uint8_t *pSignature, CryptoCC32XX_HmacParams *pParams);
546 
547 
548 #ifdef __cplusplus
549 }
550 #endif
551 
552 #endif /* ti_drivers_CryptoCC32XX__include */
553