1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 /************* Include Files ****************/
9 #include "cc_hal_plat.h"
10 #include "cc_regs.h"
11 #include "cc_pal_mem.h"
12 #include "cc_pal_mutex.h"
13 #include "cc_pal_abort.h"
14 #include "cc_util_int_defs.h"
15 #include "mbedtls_cc_util_defs.h"
16 #include "cc_util_error.h"
17 #include "cc_aes_defs.h"
18 #include "aes_driver.h"
19 #include "driver_defs.h"
20 #include "cc_util_cmac.h"
21 #include "dx_crys_kernel.h"
22 
23 /************************************************************************************/
24 /****************         CMAC key derivation    ************************************/
25 /************************************************************************************/
26 
27 
UtilCmacBuildDataForDerivation(const uint8_t * pLabel,size_t labelSize,const uint8_t * pContextData,size_t contextSize,uint8_t * pDataIn,size_t * pDataInSize,size_t derivedKeySize)28 CCUtilError_t UtilCmacBuildDataForDerivation( const uint8_t               *pLabel,
29                                              size_t                      labelSize,
30                                              const uint8_t               *pContextData,
31                                              size_t                      contextSize,
32                                              uint8_t            *pDataIn,
33                                              size_t                 *pDataInSize,
34                                              size_t                      derivedKeySize)
35 {
36         uint32_t      length = 0;
37         uint32_t      lengthReverse = 0;
38         uint32_t      i = 0;
39 
40         /* Check Label, Context, DerivedKey sizes */
41         if (derivedKeySize > CC_UTIL_MAX_DERIVED_KEY_SIZE_IN_BYTES) {
42                 return CC_UTIL_ILLEGAL_PARAMS_ERROR;
43         }
44 
45         if (derivedKeySize * CC_BITS_IN_BYTE > 0xFF) {
46                 length = CC_UTIL_FIX_DATA_MAX_SIZE_IN_BYTES;
47         } else {
48                 length = CC_UTIL_FIX_DATA_MIN_SIZE_IN_BYTES;
49         }
50 
51         if ( ((labelSize != 0) && (pLabel == NULL)) ||
52              (labelSize == 0) ||
53              (labelSize > CC_UTIL_MAX_LABEL_LENGTH_IN_BYTES) ) {
54                 return CC_UTIL_ILLEGAL_PARAMS_ERROR;
55         }
56 
57         if ( ((contextSize != 0) && (pContextData == NULL)) ||
58              (contextSize == 0) ||
59              (contextSize > CC_UTIL_MAX_CONTEXT_LENGTH_IN_BYTES) ) {
60                 return CC_UTIL_ILLEGAL_PARAMS_ERROR;
61         }
62         if ((pDataIn == NULL) ||
63              (*pDataInSize == 0) ||
64              (*pDataInSize < (contextSize+labelSize+length)) ) {
65                 return CC_UTIL_ILLEGAL_PARAMS_ERROR;
66         }
67 
68         i = 1;
69         if (labelSize!=0) {
70                 CC_PalMemCopy((pDataIn+i), pLabel, labelSize);
71                 i+=labelSize;
72         }
73 
74         pDataIn[i++] = 0x00;
75 
76         if (contextSize!=0) {
77                 CC_PalMemCopy((pDataIn+i), pContextData, contextSize);
78                 i+=contextSize;
79         }
80 
81         length = derivedKeySize * CC_BITS_IN_BYTE;
82         if (length > 0xFF) {
83                 /* Reverse words order and bytes in each word */
84                 lengthReverse = ((length & 0xFF00)>>8) | ((length & 0xFF)<<8);
85                 CC_PalMemCopy((pDataIn+i), (uint8_t*)&lengthReverse, 2);
86                 i += 2;
87         } else {
88                 CC_PalMemCopy((pDataIn+i), (uint8_t*)&length, 1);
89                 i += 1;
90         }
91         *pDataInSize = i;
92 
93         return CC_OK;
94 }
UtilCmacDeriveKey(UtilKeyType_t keyType,CCAesUserKeyData_t * pUserKey,uint8_t * pDataIn,size_t dataInSize,CCUtilAesCmacResult_t pCmacResult)95 CCUtilError_t UtilCmacDeriveKey(UtilKeyType_t       keyType,
96                 CCAesUserKeyData_t      *pUserKey,
97                 uint8_t         *pDataIn,
98                 size_t                  dataInSize,
99                 CCUtilAesCmacResult_t   pCmacResult)
100 {
101         uint32_t      rc;
102         AesContext_t    aesCtxBuf;
103         CCBuffInfo_t inBuffInfo;
104         CCBuffInfo_t outBuffInfo;
105 
106         /* Check inputs */
107         if (NULL == pDataIn) {
108                 return CC_UTIL_DATA_IN_POINTER_INVALID_ERROR;
109         }
110         if (NULL == pCmacResult) {
111                 return CC_UTIL_DATA_OUT_POINTER_INVALID_ERROR;
112         }
113         if ((dataInSize < CC_UTIL_CMAC_DERV_MIN_DATA_IN_SIZE) ||
114             (dataInSize > CC_UTIL_CMAC_DERV_MAX_DATA_IN_SIZE)) {
115                 return CC_UTIL_DATA_IN_SIZE_INVALID_ERROR;
116         }
117 
118         switch(keyType){
119         case UTIL_ROOT_KEY:
120                 /* Set AES key to ROOT KEY */
121                 aesCtxBuf.cryptoKey = RKEK_KEY;
122                 aesCtxBuf.keySizeId = KEY_SIZE_256_BIT;
123                 break;
124         case UTIL_KCP_KEY:
125                 /* Set AES key to ROOT KEY */
126                 aesCtxBuf.cryptoKey = KCP_KEY;
127                 aesCtxBuf.keySizeId = KEY_SIZE_128_BIT;
128                 break;
129         case UTIL_KPICV_KEY:
130                 /* Set AES key to ROOT KEY */
131                 aesCtxBuf.cryptoKey = KPICV_KEY;
132                 aesCtxBuf.keySizeId = KEY_SIZE_128_BIT;
133                 break;
134         case UTIL_USER_KEY:
135                 if ((pUserKey->keySize != CC_UTIL_AES_128BIT_SIZE) &&
136                     (pUserKey->keySize != CC_UTIL_AES_192BIT_SIZE) &&
137                     (pUserKey->keySize != CC_UTIL_AES_256BIT_SIZE)) {
138                         return CC_UTIL_INVALID_USER_KEY_SIZE;
139                 }
140                 /* Set AES key to USER KEY, and copy the key to the context */
141                 aesCtxBuf.cryptoKey = USER_KEY;
142                 switch (pUserKey->keySize) {
143                 case CC_UTIL_AES_128BIT_SIZE:
144                         aesCtxBuf.keySizeId = KEY_SIZE_128_BIT;
145                         break;
146                 case CC_UTIL_AES_192BIT_SIZE:
147                         aesCtxBuf.keySizeId = KEY_SIZE_192_BIT;
148                         break;
149                 case CC_UTIL_AES_256BIT_SIZE:
150                         aesCtxBuf.keySizeId = KEY_SIZE_256_BIT;
151                         break;
152                 default:
153                         break;
154                 }
155                 CC_PalMemCopy(aesCtxBuf.keyBuf, pUserKey->pKey, pUserKey->keySize);
156                 break;
157         default:
158                 return CC_UTIL_INVALID_KEY_TYPE;
159         }
160 
161 
162         /* call CC_AES_Init with CMAC */
163         aesCtxBuf.mode               = CIPHER_CMAC;
164         aesCtxBuf.dir                = CRYPTO_DIRECTION_ENCRYPT;
165         aesCtxBuf.dataBlockType      = FIRST_BLOCK;
166         aesCtxBuf.inputDataAddrType  = DLLI_ADDR;
167         aesCtxBuf.outputDataAddrType = DLLI_ADDR;
168         CC_PalMemSetZero(aesCtxBuf.ivBuf, AES_IV_SIZE);
169 
170         /* set data buffers structures */
171         rc = SetDataBuffersInfo(pDataIn, dataInSize, &inBuffInfo,
172                                 pCmacResult, CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES, &outBuffInfo);
173         if (rc != 0) {
174              CC_PAL_LOG_ERR("illegal data buffers\n");
175              return CC_UTIL_FATAL_ERROR;
176         }
177 
178         rc = FinishAesDrv(&aesCtxBuf, &inBuffInfo, &outBuffInfo, dataInSize);
179         if (rc != 0) {
180                 return CC_UTIL_FATAL_ERROR;
181         }
182 
183         CC_PalMemCopy(pCmacResult, aesCtxBuf.ivBuf, CC_AES_BLOCK_SIZE_IN_BYTES);
184 
185         return CC_UTIL_OK;
186 }
187 
188 
189 
190 
191