1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
8
9 /************* Include Files ****************/
10 #include "secureboot_basetypes.h"
11 #include "secureboot_error.h"
12 #include "bootimagesverifier_error.h"
13 #include "bootimagesverifier_def.h"
14 #include "bootimagesverifier_parser.h"
15 #include "secureboot_base_func.h"
16 #include "secureboot_base_swimgverify.h"
17 #include "cc_pal_log.h"
18 #include "secureboot_defs.h"
19 #include "bootimagesverifier_swcomp.h"
20 #include "common_cert_verify.h"
21 #include "common_cert_parser.h"
22
23 /************************ Defines ******************************/
24
25
26 /************************ Enums ******************************/
27
28
29 /************************ Typedefs ******************************/
30
31
32 /************************ Global Data ******************************/
33
34 /************************ Private functions ******************************/
35
36 /************************ Public functions ******************************/
37
CC_SbCertChainVerificationInit(CCSbCertInfo_t * certPkgInfo)38 CCError_t CC_SbCertChainVerificationInit(CCSbCertInfo_t *certPkgInfo)
39 {
40 if (certPkgInfo == NULL) {
41 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
42 }
43 /*clear the external hash */
44 UTIL_MemSet((uint8_t *)&(certPkgInfo->pubKeyHash), 0x0, sizeof(certPkgInfo->pubKeyHash));
45 certPkgInfo->initDataFlag = 0;
46
47
48 return CC_OK;
49 }
50
51
52 /**
53 @brief This function
54 loadSbCert() loads the certificate from Flash to RAM
55 if called first time, expected certificate is key certificate
56 else, if second time, expected is key or content certificate
57 else, if third, expected is content.
58 Call CCCommonCertVerify(expected types) to verify common certificate fields,
59 and returns pointers to certificate proprietary header, and body.
60 If certificate type in proprietary header is key, call CCCommonKeyCertVerify(), to verify key certificate fields.
61 Otherwise, call CCCommonContentCertVerify(), to verify Content certificate fields.
62 */
CC_SbCertVerifySingle(CCSbFlashReadFunc flashReadFunc,void * userContext,unsigned long hwBaseAddress,CCAddr_t certStoreAddress,CCSbCertInfo_t * pCertPkgInfo,uint32_t * pHeader,uint32_t headerSize,uint32_t * pWorkspace,uint32_t workspaceSize)63 CCError_t CC_SbCertVerifySingle(CCSbFlashReadFunc flashReadFunc,
64 void *userContext,
65 unsigned long hwBaseAddress,
66 CCAddr_t certStoreAddress,
67 CCSbCertInfo_t *pCertPkgInfo,
68 uint32_t *pHeader, // used for X509 header
69 uint32_t headerSize,
70 uint32_t *pWorkspace,
71 uint32_t workspaceSize)
72 {
73 CCError_t rc = CC_OK;
74 uint32_t certLoadWordSize;
75 CertFieldsInfo_t certFields;
76 BufferInfo32_t workspaceInfo;
77 BufferInfo32_t certInfo;
78 BufferInfo32_t x509HeaderInfo;
79 BufferInfo32_t *pX509HeaderInfo = NULL;
80
81
82 /* 1. Verify input parameters */
83 /*----------------------------*/
84 if ((flashReadFunc == NULL) ||
85 (pCertPkgInfo == NULL) ||
86 (pWorkspace == NULL) ||
87 (workspaceSize == 0) ||
88 ((unsigned long)pWorkspace + workspaceSize < (unsigned long)pWorkspace) || /* Verify no overflow in workspace */
89 (workspaceSize < CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES) ||
90 (!IS_ALIGNED(workspaceSize, sizeof(uint32_t))) ||
91 (!IS_ALIGNED(pWorkspace, sizeof(uint32_t)))) {
92 CC_PAL_LOG_ERR("illegal params \n");
93 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
94 }
95 if ((pHeader != NULL) && (headerSize != 0)) {
96 x509HeaderInfo.pBuffer = pHeader;
97 x509HeaderInfo.bufferSize = headerSize;
98 pX509HeaderInfo = &x509HeaderInfo;
99 }
100
101 if (CC_SB_MAX_CERT_SIZE_IN_BYTES < CC_SB_MAX_CONTENT_PKG_SIZE_IN_BYTES) {
102 CC_PAL_LOG_ERR("CC_SB_MAX_CERT_SIZE_IN_BYTES \n");
103 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
104 }
105
106 UTIL_MemSet((uint8_t *)&certFields, 0, sizeof(CertFieldsInfo_t));
107 /* Clearing the RAM just to verify that there is no secret data on it, before starting to process certificate */
108 UTIL_MemSet((uint8_t *)pWorkspace, 0, workspaceSize);
109
110
111 /* 2. Load the certificate from the Flash */
112 /*----------------------------------------*/
113 /* Set the maximum certificate size, and get back the current certificate size.
114 The certificate to load is 32 bit aligned */
115 certLoadWordSize = (CC_SB_MAX_CERT_SIZE_IN_BYTES / CC_32BIT_WORD_SIZE);
116 rc = CCCertLoadCertificate(flashReadFunc,
117 userContext,
118 certStoreAddress,
119 pWorkspace,
120 &certLoadWordSize);
121 if (rc != CC_OK) {
122 CC_PAL_LOG_ERR("CCCertParserLoadCertificate returned 0x%X\n", (unsigned int)rc);
123 return rc;
124 }
125
126 /* workspace order:
127 [0] certificate
128 [certificate size] if content certificate - additional data for images and addresses
129 [end of workspace] N+Np+Signature OR images information */
130 certInfo.pBuffer = pWorkspace;
131
132 /* Set expected certificate type according to the certificate place in chain - first key ,
133 second key or content, third content. Maximal size in content certificate is calculated according to
134 MAX number of possible SW images.*/
135 switch (pCertPkgInfo->initDataFlag) {
136 case CC_SB_FIRST_CERT_IN_CHAIN:
137 certFields.certType = CC_SB_KEY_CERT;
138 certFields.certBodySize = sizeof(KeyCertMain_t);
139 certInfo.bufferSize = CC_SB_MAX_KEY_CERT_SIZE_IN_BYTES;
140 break;
141 case CC_SB_SECOND_CERT_IN_CHAIN:
142 certFields.certType = CC_SB_KEY_OR_CONTENT_CERT;
143 certFields.certBodySize = sizeof(ContentCertMain_t);
144 certInfo.bufferSize = CC_SB_MAX_CONTENT_CERT_SIZE_IN_BYTES;
145 break;
146 case CC_SB_THIRD_CERT_IN_CHAIN:
147 certFields.certType = CC_SB_CONTENT_CERT;
148 certFields.certBodySize = sizeof(ContentCertMain_t);
149 certInfo.bufferSize = CC_SB_MAX_CONTENT_CERT_SIZE_IN_BYTES;
150 break;
151 default:
152 CC_PAL_LOG_ERR("Not expecting any certificate in the chain \n");
153 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
154 }
155
156 // set the workspace for N, Np and signature
157 workspaceInfo.bufferSize = sizeof(workspaceInt_t);
158 workspaceInfo.pBuffer = (uint32_t *)((unsigned long)pWorkspace + workspaceSize - sizeof(workspaceInt_t));
159
160 /* 3. Verify the certificate (Verify the RSA signature and the public key hash) . */
161 rc = CCCommonCertVerify(hwBaseAddress,
162 &certInfo,
163 &certFields,
164 pCertPkgInfo,
165 &workspaceInfo,
166 pX509HeaderInfo);
167 if (rc != CC_OK) {
168 CC_PAL_LOG_ERR("CCCommonCertVerify failed 0x%X\n", rc);
169 return rc;
170 }
171
172
173 /* 4. In case of content certificate - verify the SW images */
174 /*----------------------------------------------------------*/
175 switch (certFields.certType) {
176 case CC_SB_KEY_CERT:
177 /* Verify the key certificate sw version. */
178 rc = CCCommonKeyCertVerify(hwBaseAddress,
179 certFields.certHeader.certFlags,
180 certFields.pCertBody,
181 pCertPkgInfo);
182 /* Update the certificate number in the chain.*/
183 pCertPkgInfo->initDataFlag++;
184 break;
185 case CC_SB_CONTENT_CERT:
186 /* Verify the content certificate sw version and verify the SW images. If needed update the sw version.
187 workspaceInfo may overlap with N+Np+Signature, since N, Np and signature were already verified */
188 workspaceInfo.pBuffer = pWorkspace + certLoadWordSize;
189 workspaceInfo.bufferSize = workspaceSize - certLoadWordSize * CC_32BIT_WORD_SIZE;
190 rc = CCCommonContentCertVerify(flashReadFunc,
191 userContext,
192 hwBaseAddress,
193 certStoreAddress + certLoadWordSize * CC_32BIT_WORD_SIZE,
194 pCertPkgInfo,
195 certFields.certHeader.certFlags,
196 certFields.pCertBody,
197 &workspaceInfo);
198 /* the content certificate is always the last. */
199 pCertPkgInfo->initDataFlag = CC_SB_LAST_CERT_IN_CHAIN;
200 break;
201 default:
202 CC_PAL_LOG_ERR("Illegal certificate type for secure boot flow.\n");
203 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
204 }
205
206 return rc;
207
208 } /* End of CC_SbCertVerifySingle */
209
210
211
212