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 "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 "mbedtls/ccm.h"
19 #include "aes_driver.h"
20 #include "driver_defs.h"
21 #include "cc_util_cmac.h"
22 #include "mbedtls_cc_util_asset_prov.h"
23 #include "cc_util_asset_prov_int.h"
24
25
mbedtls_util_asset_pkg_unpack(CCAssetProvKeyType_t keyType,uint32_t assetId,uint32_t * pAssetPkgBuff,size_t assetPackageLen,uint32_t * pAssetData,size_t * pAssetDataLen)26 CCError_t mbedtls_util_asset_pkg_unpack(CCAssetProvKeyType_t keyType,
27 uint32_t assetId,
28 uint32_t *pAssetPkgBuff,
29 size_t assetPackageLen,
30 uint32_t *pAssetData,
31 size_t *pAssetDataLen)
32 {
33 uint32_t rc = CC_OK;
34 CCUtilAesCmacResult_t keyProv = { 0 };
35 uint8_t dataIn[CC_UTIL_MAX_KDF_SIZE_IN_BYTES] = { 0 };
36 size_t dataInSize = CC_UTIL_MAX_KDF_SIZE_IN_BYTES;
37 uint8_t provLabel = 'P';
38 CCAssetProvPkg_t *pAssetPackage = NULL;
39 mbedtls_ccm_context ccmCtx;
40 uint8_t ccmAddData[CC_ASSET_PROV_ADATA_SIZE] = { 0 };
41 uint8_t ccmNonceData[CC_ASSET_PROV_NONCE_SIZE] = { 0 };
42 uint32_t assetDataSize = 0;
43 uint32_t constPkgSize = CC_ASSET_PROV_ADATA_SIZE+CC_ASSET_PROV_NONCE_SIZE+CC_ASSET_PROV_TAG_SIZE;
44 uint32_t minPkgSize = constPkgSize+CC_ASSET_PROV_BLOCK_SIZE;
45
46 /* Validate Inputs */
47 if ((pAssetPkgBuff == NULL) ||
48 (pAssetData == NULL) ||
49 (pAssetDataLen == NULL) ||
50 (assetPackageLen > CC_ASSET_PROV_MAX_ASSET_PKG_SIZE) ||
51 (assetPackageLen < minPkgSize) ||
52 /* Overlapping verification */
53 (((unsigned long)pAssetPkgBuff + assetPackageLen) < (unsigned long)pAssetPkgBuff) ||
54 (assetPackageLen % CC_32BIT_WORD_SIZE) ||
55 ((keyType != ASSET_PROV_KEY_TYPE_KPICV) && (keyType != ASSET_PROV_KEY_TYPE_KCP))) {
56 CC_PAL_LOG_ERR("Invalid params");
57 return CC_UTIL_ILLEGAL_PARAMS_ERROR;
58 }
59 pAssetPackage = (CCAssetProvPkg_t *)pAssetPkgBuff;
60
61 /* Validate asset size, must be multiply of 16 bytes */
62 if ((pAssetPackage->assetSize > CC_ASSET_PROV_MAX_ASSET_SIZE) ||
63 (pAssetPackage->assetSize == 0) ||
64 (pAssetPackage->assetSize % CC_ASSET_PROV_BLOCK_SIZE)) {
65 CC_PAL_LOG_ERR("Invalid asset size 0x%x", pAssetPackage->assetSize);
66 return CC_UTIL_ILLEGAL_PARAMS_ERROR;
67 }
68 /* Verify assetDataSize against assetPkgSize */
69 if ((assetPackageLen < (constPkgSize+pAssetPackage->assetSize)) ||
70 (*pAssetDataLen < pAssetPackage->assetSize)) {
71 CC_PAL_LOG_ERR("Invalid asset size 0x%x", pAssetPackage->assetSize);
72 return CC_UTIL_ILLEGAL_PARAMS_ERROR;
73 }
74 /* Verify package token and version */
75 if ((pAssetPackage->token != CC_ASSET_PROV_TOKEN) ||
76 (pAssetPackage->version != CC_ASSET_PROV_VERSION)) {
77 CC_PAL_LOG_ERR("Invalid token or version");
78 return CC_UTIL_ILLEGAL_PARAMS_ERROR;
79 }
80
81 /* Generate dataIn buffer for CMAC: iteration || 'P' || 0x00 || asset Id || 0x80
82 since deruved key is 128 bits we have only 1 iteration */
83 rc = UtilCmacBuildDataForDerivation(&provLabel,sizeof(provLabel),
84 (uint8_t *)&assetId, sizeof(assetId),
85 dataIn, &dataInSize,
86 (size_t)CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES);
87 if (rc != 0) {
88 CC_PAL_LOG_ERR("Failed UtilCmacBuildDataForDerivation 0x%x", rc);
89 return rc;
90 }
91 dataIn[0] = 1; // only 1 iteration
92 rc = UtilCmacDeriveKey((keyType == ASSET_PROV_KEY_TYPE_KPICV)?UTIL_KPICV_KEY:UTIL_KCP_KEY,
93 NULL,
94 dataIn, dataInSize,
95 keyProv);
96 if (rc != 0) {
97 CC_PAL_LOG_ERR("Failed UtilCmacDeriveKey 0x%x", rc);
98 return rc;
99 }
100
101 /* Decrypt and authenticate the BLOB */
102 mbedtls_ccm_init(&ccmCtx);
103
104 rc = mbedtls_ccm_setkey(&ccmCtx, MBEDTLS_CIPHER_ID_AES, keyProv, CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES * CC_BITS_IN_BYTE);
105 if (rc != 0) {
106 CC_PAL_LOG_ERR("Failed to mbedtls_ccm_setkey 0x%x\n", rc);
107 return rc;
108 }
109
110 assetDataSize = pAssetPackage->assetSize;
111 CC_PalMemCopy(ccmNonceData, pAssetPackage->nonce, CC_ASSET_PROV_NONCE_SIZE);
112 CC_PalMemCopy(ccmAddData, (uint8_t *)pAssetPackage, CC_ASSET_PROV_ADATA_SIZE);
113 rc = mbedtls_ccm_auth_decrypt(&ccmCtx, pAssetPackage->assetSize,
114 ccmNonceData, CC_ASSET_PROV_NONCE_SIZE,
115 ccmAddData, CC_ASSET_PROV_ADATA_SIZE,
116 pAssetPackage->encAsset, (uint8_t *)pAssetData,
117 pAssetPackage->encAsset + pAssetPackage->assetSize, CC_ASSET_PROV_TAG_SIZE);
118 if (rc != 0) {
119 CC_PAL_LOG_ERR("Failed to mbedtls_ccm_auth_decrypt 0x%x\n", rc);
120 return rc;
121 }
122
123 // Set output data
124 *pAssetDataLen = assetDataSize;
125 return CC_OK;
126 }
127
128