1 /*
2 * Copyright (c) 2001-2020, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7
8 /************* Include Files ****************/
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <string.h>
12 #include "cc_pal_log.h"
13 #include "cc_prod_error.h"
14 #include "prod_hw_defs.h"
15 #include "cc_regs.h"
16 #include "dx_host.h"
17 #include "dx_crys_kernel.h"
18 #include "prod_crypto_driver.h"
19 #include "cc_pal_mem.h"
20 #include "aes_driver.h"
21 #include "driver_defs.h"
22 #include "cc_production_asset.h"
23 #include "cc_aes_defs.h"
24 #include "mbedtls/ccm.h"
25
26 /**
27 * This function is used to perform AES operation.
28 *
29 * @param[in] pInternalKey - a pointer to internal key
30 * @param[in] pDataIn - a pointer to input buffer - address must be 32bit aligned
31 * @param[in] dataInSize - size of data in bytes
32 * @param[in] pOutbuff - a pointer to output buffer- address must be 32bit aligned
33 * @param[in] outbuffSize - size of data out bytes
34 *
35 */
36
CC_PROD_AesCcmDecrypt(uint8_t * pKey,uint32_t keySizeInBytes,uint8_t * pNonce,uint32_t nonceSizeInBytes,uint8_t * pAddData,uint32_t addDataSizeInBytes,uint8_t * pCipherData,uint32_t dataSize,uint8_t * pPlainBuff,uint32_t tagSize,uint8_t * pTagBuff,unsigned long workspaceAddr,uint32_t workspaceSize)37 uint32_t CC_PROD_AesCcmDecrypt(uint8_t *pKey,
38 uint32_t keySizeInBytes,
39 uint8_t *pNonce,
40 uint32_t nonceSizeInBytes,
41 uint8_t *pAddData,
42 uint32_t addDataSizeInBytes,
43 uint8_t *pCipherData,
44 uint32_t dataSize,
45 uint8_t *pPlainBuff,
46 uint32_t tagSize,
47 uint8_t *pTagBuff,
48 unsigned long workspaceAddr,
49 uint32_t workspaceSize)
50 {
51
52 uint32_t rc = 0;
53 mbedtls_ccm_context *pCtx;
54
55 if (workspaceSize < sizeof(mbedtls_ccm_context) || (workspaceAddr % CC_32BIT_WORD_SIZE)) {
56 CC_PAL_LOG_ERR("invalid workspace\n");
57 return CC_PROD_INVALID_PARAM_ERR;
58 }
59 pCtx = (mbedtls_ccm_context *)workspaceAddr;
60
61 mbedtls_ccm_init(pCtx);
62
63 rc = mbedtls_ccm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, pKey, keySizeInBytes * CC_BITS_IN_BYTE);
64 if (rc != 0) {
65 CC_PAL_LOG_ERR("Failed to mbedtls_ccm_setkey 0x%x\n", rc);
66 return rc;
67 }
68
69 rc = mbedtls_ccm_auth_decrypt(pCtx, dataSize,
70 pNonce, nonceSizeInBytes,
71 pAddData, addDataSizeInBytes,
72 pCipherData, pPlainBuff,
73 pTagBuff, tagSize);
74 if (rc != 0) {
75 CC_PAL_LOG_ERR("Failed to mbedtls_ccm_auth_decrypt 0x%x\n", rc);
76 }
77
78 return rc;
79 }
80
81
82 /**
83 * This function is used to perform AES operation.
84 *
85 * @param[in] pInternalKey - a pointer to internal key
86 * @param[in] pDataIn - a pointer to input buffer - address must be 32bit aligned
87 * @param[in] dataInSize - size of data in bytes
88 * @param[in] pOutbuff - a pointer to output buffer- address must be 32bit aligned
89 * @param[in] outbuffSize - size of data out bytes
90 *
91 */
CC_PROD_Aes(aesMode_t cipherMode,cryptoDirection_t encDecDir,cryptoKeyType_t keyType,uint8_t * pKey,uint32_t keySizeInBytes,uint8_t * pIv,uint32_t ivSizeInBytes,uint32_t * pDataIn,uint32_t dataInSize,uint32_t * pOutbuff)92 uint32_t CC_PROD_Aes(aesMode_t cipherMode,
93 cryptoDirection_t encDecDir,
94 cryptoKeyType_t keyType,
95 uint8_t *pKey,
96 uint32_t keySizeInBytes,
97 uint8_t *pIv,
98 uint32_t ivSizeInBytes,
99 uint32_t *pDataIn,
100 uint32_t dataInSize,
101 uint32_t *pOutbuff)
102 {
103 uint32_t error;
104 AesContext_t aesCtx;
105
106 error = CC_PROD_AesInit(&aesCtx,
107 cipherMode,
108 encDecDir,
109 keyType, pKey, keySizeInBytes,
110 pIv, ivSizeInBytes);
111 if (error != CC_OK) {
112 return error;
113 }
114 error = CC_PROD_AesProcess(&aesCtx,
115 pDataIn, dataInSize,
116 pOutbuff);
117 if (error != CC_OK) {
118 return error;
119 }
120 if ((cipherMode == CIPHER_CBC_MAC) && (pOutbuff != NULL)){
121 CC_PalMemCopy((uint8_t *)pOutbuff, (uint8_t *)aesCtx.ivBuf, CC_AES_BLOCK_SIZE_IN_BYTES);
122 }
123 return CC_OK;
124 }
125
126 /**
127 * This function is used to perform AES CBC MAC operation.
128 *
129 * @param[in] pKey - a pointer to internal key
130 * @param[in] pDataIn - a pointer to input buffer
131 * @param[in] blockSize - size of data in bytes
132 * @param[in] pCmacResult - a pointer to output buffer
133 *
134 */
CC_PROD_AesInit(AesContext_t * pAesCtx,aesMode_t cipherMode,cryptoDirection_t encDecDir,cryptoKeyType_t keyType,uint8_t * pKey,uint32_t keySizeInBytes,uint8_t * pIv,uint32_t ivSizeInBytes)135 uint32_t CC_PROD_AesInit(AesContext_t *pAesCtx,
136 aesMode_t cipherMode,
137 cryptoDirection_t encDecDir,
138 cryptoKeyType_t keyType,
139 uint8_t *pKey,
140 uint32_t keySizeInBytes,
141 uint8_t *pIv,
142 uint32_t ivSizeInBytes)
143 {
144 switch (keySizeInBytes) {
145 case 16:
146 pAesCtx->keySizeId = KEY_SIZE_128_BIT;
147 break;
148 case 24:
149 pAesCtx->keySizeId = KEY_SIZE_192_BIT;
150 break;
151 case 32:
152 pAesCtx->keySizeId = KEY_SIZE_256_BIT;
153 break;
154 default:
155 CC_PAL_LOG_ERR("NOT OK\n");
156 return 1;
157 }
158 pAesCtx->mode = cipherMode;
159 pAesCtx->dir = encDecDir;
160 pAesCtx->cryptoKey = keyType;
161 pAesCtx->padType = CRYPTO_PADDING_NONE;
162 pAesCtx->dataBlockType = FIRST_BLOCK;
163 pAesCtx->inputDataAddrType = DLLI_ADDR;
164 pAesCtx->outputDataAddrType = DLLI_ADDR;
165 CC_PalMemCopy((uint8_t *)pAesCtx->ivBuf, pIv, ivSizeInBytes);
166 if (keyType == USER_KEY) {
167 CC_PalMemCopy((uint8_t *)pAesCtx->keyBuf, pKey, keySizeInBytes);
168 }
169
170 return CC_OK;
171 }
172
173
174 /**
175 * This function is used to perform AES CBC MAC operation.
176 *
177 * @param[in] cipherMode - the aes mode
178 * @param[in] pDataIn - a pointer to input buffer - address must be 32bit aligned
179 * @param[in] dataInSize - size of data in bytes
180 * @param[out] pOutbuff - a pointer to output buffer - address must be 32bit aligned
181 * @param[in] outbuffSize - the expectedsize of output buffer in bytes
182 *
183 */
CC_PROD_AesProcess(AesContext_t * pAesCtx,uint32_t * pDataIn,uint32_t dataInSize,uint32_t * pOutbuff)184 uint32_t CC_PROD_AesProcess(AesContext_t *pAesCtx,
185 uint32_t *pDataIn,
186 uint32_t dataInSize,
187 uint32_t *pOutbuff)
188 {
189 uint32_t error;
190 CCBuffInfo_t inBuffInfo;
191 CCBuffInfo_t outBuffInfo;
192
193 /* set data buffers structures */
194 error = SetDataBuffersInfo((uint8_t*)pDataIn, dataInSize, &inBuffInfo,
195 (uint8_t*)pOutbuff, dataInSize, &outBuffInfo);
196 if (error != 0) {
197 CC_PAL_LOG_ERR("illegal data buffers\n");
198 return error;
199 }
200
201 return ProcessAesDrv(pAesCtx, &inBuffInfo, &outBuffInfo, dataInSize);
202 }
203
204
205
CC_PROD_KeyDerivation(cryptoKeyType_t keyType,uint8_t * pUserKey,const uint8_t * pLabel,size_t labelSize,const uint8_t * pContextData,size_t contextSize,uint8_t * pDerivedKey)206 uint32_t CC_PROD_KeyDerivation(cryptoKeyType_t keyType,
207 uint8_t *pUserKey,
208 const uint8_t *pLabel,
209 size_t labelSize,
210 const uint8_t *pContextData,
211 size_t contextSize,
212 uint8_t *pDerivedKey)
213 {
214 uint32_t dataInSize = 0;
215 drvError_t drvRc;
216 AesContext_t aesCtx;
217 uint8_t dataIn[PROD_KEY_TMP_LABEL_SIZE + PROD_KEY_TMP_CONTEXT_SIZE + 3] = { 0 };
218 CCBuffInfo_t inBuffInfo;
219 CCBuffInfo_t outBuffInfo;
220
221 /* Check inputs */
222 if (((keyType != USER_KEY) && (keyType != RTL_KEY)) ||
223 ((keyType == USER_KEY) && (pUserKey == NULL)) ||
224 (labelSize > PROD_KEY_TMP_LABEL_SIZE) ||
225 (pLabel == NULL) ||
226 (contextSize > PROD_KEY_TMP_CONTEXT_SIZE) ||
227 (pContextData == NULL) ||
228 (pDerivedKey == NULL)) {
229 return CC_PROD_INVALID_PARAM_ERR;
230 }
231
232 /* Generate dataIn buffer for CMAC: iteration || Label || 0x00 || context || length
233 since deruved key is 128 bits we have only 1 iteration */
234 dataInSize = 0;
235 dataIn[dataInSize++] = 1;
236 CC_PalMemCopy((uint8_t *)&dataIn[dataInSize], pLabel, labelSize);
237 dataInSize += labelSize;
238
239 dataIn[dataInSize++] = 0x00;
240 CC_PalMemCopy((uint8_t *)&dataIn[dataInSize], pContextData, contextSize);
241 dataInSize += contextSize;
242 dataIn[dataInSize++] = CC_AES_BLOCK_SIZE_IN_BYTES * CC_BITS_IN_BYTE; // all derived keys are 128 bits
243
244 aesCtx.cryptoKey = keyType;
245 aesCtx.keySizeId = KEY_SIZE_128_BIT;
246 if (keyType == USER_KEY) {
247 CC_PalMemCopy(aesCtx.keyBuf, pUserKey, CC_AES_BLOCK_SIZE_IN_BYTES);
248 }
249
250 aesCtx.mode = CIPHER_CMAC;
251 aesCtx.dir = CRYPTO_DIRECTION_ENCRYPT;
252 aesCtx.dataBlockType = FIRST_BLOCK;
253 aesCtx.inputDataAddrType = DLLI_ADDR;
254 aesCtx.outputDataAddrType = DLLI_ADDR;
255 CC_PalMemSetZero(aesCtx.ivBuf, AES_IV_SIZE);
256
257 /* set data buffers structures */
258 drvRc = SetDataBuffersInfo((uint8_t*)dataIn, dataInSize, &inBuffInfo,
259 NULL, 0, &outBuffInfo);
260 if (drvRc != 0) {
261 CC_PAL_LOG_ERR("illegal data buffers\n");
262 return drvRc;
263 }
264 drvRc = FinishAesDrv(&aesCtx, &inBuffInfo, &outBuffInfo, dataInSize);
265 if (drvRc != 0) {
266 return drvRc;
267 }
268 CC_PalMemCopy(pDerivedKey, aesCtx.ivBuf, CC_AES_BLOCK_SIZE_IN_BYTES);
269 return CC_OK;
270 }
271
272
273