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_pal_types.h"
10 #include "cc_pal_mem.h"
11 #include "cc_pal_mutex.h"
12 #include "cc_pal_abort.h"
13
14 #include "secureboot_defs.h"
15 #include "secureboot_stage_defs.h"
16 #include "secureboot_gen_defs.h"
17 #include "bootimagesverifier_error.h"
18 #include "bsv_error.h"
19 #include "secdebug_defs.h"
20 #include "secureboot_base_swimgverify.h"
21 #include "cc_hal.h"
22 #include "mbedtls_cc_mng_int.h"
23 #include "mbedtls_cc_mng_error.h"
24 #include "cc_util_pm.h"
25 #include "cc_int_general_defs.h"
26
27 /************************ Defines ******************************/
28
29 /************************ Enums ******************************/
30
31 /************************ Typedefs ******************************/
32
33 /************************ Global Data ******************************/
34 extern CC_PalMutex CCAsymCryptoMutex;
35 extern CC_PalMutex CCSymCryptoMutex;
36
37 /************************ Private functions ******************************/
38
GetMngKeyIndex(CCSbPubKeyIndexType_t keyIndex,mbedtls_mng_pubKeyType_t * mngKeyIndex)39 static CCError_t GetMngKeyIndex(CCSbPubKeyIndexType_t keyIndex, mbedtls_mng_pubKeyType_t *mngKeyIndex)
40 {
41 switch (keyIndex) {
42 case CC_SB_HASH_BOOT_KEY_0_128B:
43 *mngKeyIndex = CC_MNG_HASH_BOOT_KEY_0_128B;
44 break;
45 case CC_SB_HASH_BOOT_KEY_1_128B:
46 *mngKeyIndex = CC_MNG_HASH_BOOT_KEY_1_128B;
47 break;
48 case CC_SB_HASH_BOOT_KEY_256B:
49 *mngKeyIndex = CC_MNG_HASH_BOOT_KEY_256B;
50 break;
51 case CC_SB_HASH_BOOT_NOT_USED:
52 *mngKeyIndex = CC_MNG_HASH_BOOT_NOT_USED;
53 break;
54 case CC_SB_HASH_MAX_NUM:
55 *mngKeyIndex = CC_MNG_HASH_MAX_NUM;
56 break;
57 default:
58 return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
59 }
60
61 return CC_OK;
62 }
63
64 /************************ Public functions ******************************/
65
SBRT_ImageLoadAndVerify(CCSbFlashReadFunc preHashflashRead_func,void * preHashUserContext,unsigned long hwBaseAddress,uint8_t isLoadFromFlash,uint8_t isVerifyImage,bsvCryptoMode_t cryptoMode,CCBsvKeyType_t keyType,AES_Iv_t AESIv,uint8_t * pSwRecSignedData,uint32_t * pSwRecNoneSignedData,uint32_t * workspace_ptr,uint32_t workspaceSize)66 CCError_t SBRT_ImageLoadAndVerify(CCSbFlashReadFunc preHashflashRead_func,
67 void *preHashUserContext,
68 unsigned long hwBaseAddress,
69 uint8_t isLoadFromFlash,
70 uint8_t isVerifyImage,
71 bsvCryptoMode_t cryptoMode,
72 CCBsvKeyType_t keyType,
73 AES_Iv_t AESIv,
74 uint8_t *pSwRecSignedData,
75 uint32_t *pSwRecNoneSignedData,
76 uint32_t *workspace_ptr,
77 uint32_t workspaceSize)
78 {
79 CCError_t error = CC_OK;
80 ContentCertImageRecord_t cntImageRec;
81
82 /* Loading only is not supported for SBRT */
83 if (isVerifyImage == CC_FALSE){
84 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
85 }
86
87 /* In any case, loading operation shall be ignored (and not failed) and the image will be only verified. */
88 if (isLoadFromFlash == CC_TRUE){
89
90 /* Initialize parameters */
91 CC_PalMemCopy((uint8_t *)&cntImageRec, pSwRecSignedData, sizeof(ContentCertImageRecord_t));
92
93 /* overwrite load address to ignore loading */
94 cntImageRec.loadAddr = CC_SW_COMP_NO_MEM_LOAD_INDICATION;
95 CC_PalMemCopy(pSwRecSignedData, (uint8_t*)&cntImageRec, sizeof(ContentCertImageRecord_t));
96 }
97
98 /* lock mutex for more CC operations */
99 error = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
100 if (error != 0) {
101 CC_PalAbort("Fail to acquire mutex\n");
102 }
103
104 /* increase CC counter at the beginning of each operation */
105 error = CC_IS_WAKE;
106 if (error != 0) {
107 CC_PalAbort("Fail to increase PM counter\n");
108 }
109
110 error = CCSbImageLoadAndVerify(preHashflashRead_func, preHashUserContext,
111 hwBaseAddress, isLoadFromFlash, isVerifyImage,
112 cryptoMode, keyType, AESIv, pSwRecSignedData,
113 pSwRecNoneSignedData, workspace_ptr, workspaceSize);
114
115 /* decrease CC counter at the end of each operation */
116 if (CC_IS_IDLE != CC_SUCCESS) {
117 CC_PalAbort("Fail to decrease PM counter\n");
118 }
119
120 /* release mutex */
121 if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
122 CC_PalAbort("Fail to release mutex\n");
123 }
124
125 return error;
126 }
127
SBRT_RSA_PSS_Verify(unsigned long hwBaseAddress,CCHashResult_t mHash,uint32_t * pN,uint32_t * pNp,uint32_t * pSign)128 CCError_t SBRT_RSA_PSS_Verify(unsigned long hwBaseAddress, /* [in] HW base address of registers. */
129 CCHashResult_t mHash, /* [in] Pointer to the SHA256 hash of the message. */
130 uint32_t *pN, /* [in] Pointer to the RSA modulus (LE words array). */
131 uint32_t *pNp, /* [in] Pointer to the Barrett tag of the RSA modulus (LE words array). */
132 uint32_t *pSign /* [out] Pointer to the signature output (it is placed as BE bytes
133 array into words buffer for alignments goal). */)
134 {
135
136 CCError_t error = CC_OK;
137
138 error = CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE);
139 if (error != CC_SUCCESS) {
140 CC_PalAbort("Fail to acquire mutex\n");
141 }
142
143 /* verify that the device is not in fatal error state before activating the PKA engine */
144 CC_IS_FATAL_ERR_ON(error);
145 if (error == CC_TRUE) {
146 error = CC_BSV_FATAL_ERR_IS_LOCKED_ERR;
147 goto _EndUnlockMutex;
148 }
149
150 /* increase CC counter at the beginning of each operation */
151 error = CC_IS_WAKE;
152 if (error != CC_SUCCESS) {
153 CC_PalAbort("Fail to increase PM counter\n");
154 }
155
156 error = RSA_PSS_Verify(hwBaseAddress, mHash, pN, pNp, pSign);
157
158 /* decrease CC counter at the end of each operation */
159 if (CC_IS_IDLE != CC_SUCCESS) {
160 CC_PalAbort("Fail to decrease PM counter\n");
161 }
162
163 _EndUnlockMutex:
164 if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
165 CC_PalAbort("Fail to release mutex\n");
166 }
167
168 return error;
169
170 }
171
SBRT_HalClearInterruptBit(unsigned long hwBaseAddress,uint32_t data)172 void SBRT_HalClearInterruptBit(unsigned long hwBaseAddress, uint32_t data)
173 {
174 CC_UNUSED_PARAM(hwBaseAddress);
175 CC_HalClearInterruptBit(data);
176 return;
177 }
178
SBRT_HalMaskInterrupt(unsigned long hwBaseAddress,uint32_t data)179 void SBRT_HalMaskInterrupt(unsigned long hwBaseAddress, uint32_t data)
180 {
181 CC_UNUSED_PARAM(hwBaseAddress);
182 CC_HalMaskInterrupt(data);
183 return;
184 }
185
SBRT_HalWaitInterrupt(unsigned long hwBaseAddress,uint32_t data)186 CCError_t SBRT_HalWaitInterrupt(unsigned long hwBaseAddress, uint32_t data)
187 {
188 CC_UNUSED_PARAM(hwBaseAddress);
189 return CC_HalWaitInterrupt(data);
190 }
191
SBRT_LcsGet(unsigned long hwBaseAddress,uint32_t * pLcs)192 CCError_t SBRT_LcsGet(unsigned long hwBaseAddress, uint32_t *pLcs)
193 {
194
195 CC_UNUSED_PARAM(hwBaseAddress);
196 return mbedtls_mng_lcsGet(pLcs);
197 }
198
SBRT_OTPWordRead(unsigned long hwBaseAddress,uint32_t otpAddress,uint32_t * pOtpWord)199 CCError_t SBRT_OTPWordRead(unsigned long hwBaseAddress, uint32_t otpAddress, uint32_t *pOtpWord)
200 {
201 CC_UNUSED_PARAM(hwBaseAddress);
202 return mbedtls_mng_otpWordRead(otpAddress, pOtpWord);
203 }
204
SBRT_SwVersionGet(unsigned long hwBaseAddress,CCSbPubKeyIndexType_t keyIndex,uint32_t * swVersion)205 CCError_t SBRT_SwVersionGet(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t *swVersion)
206 {
207 CCError_t error = CC_OK;
208 mbedtls_mng_pubKeyType_t mngKeyIndex;
209
210 CC_UNUSED_PARAM(hwBaseAddress);
211
212 error = GetMngKeyIndex(keyIndex, &mngKeyIndex);
213 if (error != CC_OK)
214 return error;
215
216 return mbedtls_mng_swVersionGet(mngKeyIndex, swVersion);
217 }
218
SBRT_PubKeyHashGet(unsigned long hwBaseAddress,CCSbPubKeyIndexType_t keyIndex,uint32_t * hashedPubKey,uint32_t hashResultSizeWords)219 CCError_t SBRT_PubKeyHashGet(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t *hashedPubKey, uint32_t hashResultSizeWords)
220 {
221 CCError_t error = CC_OK;
222 mbedtls_mng_pubKeyType_t mngKeyIndex;
223
224 CC_UNUSED_PARAM(hwBaseAddress);
225
226 error = GetMngKeyIndex(keyIndex, &mngKeyIndex);
227 if (error != CC_OK)
228 return error;
229
230 return mbedtls_mng_pubKeyHashGet(mngKeyIndex, hashedPubKey, hashResultSizeWords);
231 }
232
SBRT_SHA256(unsigned long hwBaseAddress,uint8_t * pDataIn,size_t dataSize,CCHashResult_t hashBuff)233 CCError_t SBRT_SHA256( unsigned long hwBaseAddress,
234 uint8_t *pDataIn,
235 size_t dataSize,
236 CCHashResult_t hashBuff)
237 {
238 CCError_t error = CC_OK;
239
240 /* verify that data is limited to 64KB */
241 if ( dataSize >= CC_BSV_SHA256_MAX_DATA_SIZE_IN_BYTES) {
242 return CC_BSV_INVALID_DATA_SIZE_ERROR;
243 }
244
245 /* verify valid buffer pointer */
246 if ( (pDataIn == NULL) && (dataSize!=0) ) {
247 return CC_BSV_INVALID_DATA_IN_POINTER_ERROR;
248 }
249
250 /* verify valid buffer pointer */
251 if (hashBuff == NULL) {
252 return CC_BSV_INVALID_RESULT_BUFFER_POINTER_ERROR;
253 }
254
255 /* lock mutex for more CC operations */
256 error = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
257 if (error != 0) {
258 CC_PalAbort("Fail to acquire mutex\n");
259 }
260
261 /* increase CC counter at the beginning of each operation */
262 error = CC_IS_WAKE;
263 if (error != 0) {
264 CC_PalAbort("Fail to increase PM counter\n");
265 }
266
267 InitBsvHash(hwBaseAddress);
268
269 error = ProcessBsvHash(hwBaseAddress, (uint32_t)pDataIn, dataSize);
270 if (error != CC_OK){
271 // in case of error, ProcessBsvHash responsible to call FreeBsvHash
272 UTIL_MemSet((uint8_t*)hashBuff, 0, CC_BSV_SHA256_DIGEST_SIZE_IN_BYTES);
273 goto _END_SHA256;
274 }
275
276 FinishBsvHash(hwBaseAddress, hashBuff);
277
278 _END_SHA256:
279 /* decrease CC counter at the end of each operation */
280 if (CC_IS_IDLE != CC_SUCCESS) {
281 CC_PalAbort("Fail to decrease PM counter\n");
282 }
283
284 /* release mutex */
285 if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
286 CC_PalAbort("Fail to release mutex\n");
287 }
288
289 return error;
290 }
291
SBRT_CryptoImageInit(unsigned long hwBaseAddress,bsvCryptoMode_t mode,CCBsvKeyType_t keyType)292 CCError_t SBRT_CryptoImageInit( unsigned long hwBaseAddress,
293 bsvCryptoMode_t mode,
294 CCBsvKeyType_t keyType)
295 {
296 /* verify tunneling mode */
297 if ((mode!=BSV_CRYPTO_HASH) &&
298 (mode!=BSV_CRYPTO_AES_AND_HASH) &&
299 (mode!=BSV_CRYPTO_AES_TO_HASH_AND_DOUT)){
300 return CC_BSV_INVALID_CRYPTO_MODE_ERROR;
301 }
302
303 if(mode != BSV_CRYPTO_HASH){
304 /* for image decryption only KCE and KCEICV are supported */
305 if ((keyType!=CC_BSV_CE_KEY) && (keyType!=CC_BSV_ICV_CE_KEY)){
306 return CC_BSV_INVALID_KEY_TYPE_ERROR;
307 }
308 }
309
310 /* initiate HW engines */
311 InitBsvHash(hwBaseAddress);
312
313 if (mode != BSV_CRYPTO_HASH){
314 InitBsvAes(hwBaseAddress);
315
316 /* overwrite crypto mode */
317 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,mode);
318 }
319
320 return CC_OK;
321 }
322
SBRT_CryptoImageUpdate(unsigned long hwBaseAddress,bsvCryptoMode_t mode,CCBsvKeyType_t keyType,uint32_t * pCtrStateBuf,uint8_t * pDataIn,uint8_t * pDataOut,size_t dataSize,CCHashResult_t hashBuff,uint8_t isLoadIV)323 CCError_t SBRT_CryptoImageUpdate( unsigned long hwBaseAddress,
324 bsvCryptoMode_t mode,
325 CCBsvKeyType_t keyType,
326 uint32_t *pCtrStateBuf,
327 uint8_t *pDataIn,
328 uint8_t *pDataOut,
329 size_t dataSize,
330 CCHashResult_t hashBuff,
331 uint8_t isLoadIV)
332 {
333 CCError_t error = CC_OK;
334
335 /* data in processing */
336 if (mode == BSV_CRYPTO_HASH){
337 error = ProcessBsvHash(hwBaseAddress, (uint32_t)pDataIn, dataSize);
338 } else {
339 error = ProcessBsvAes(hwBaseAddress, BSV_AES_CIPHER_CTR, keyType, NULL, CC_BSV_128BITS_KEY_SIZE_IN_BYTES,
340 pCtrStateBuf, (uint32_t)pDataIn, (uint32_t)pDataOut, dataSize, isLoadIV);
341 }
342
343 if (error != CC_OK){
344 FreeBsvHash(hwBaseAddress);
345 UTIL_MemSet((uint8_t*)hashBuff, 0, CC_BSV_SHA256_DIGEST_SIZE_IN_BYTES);
346 }
347
348 return error;
349 }
350
351
SBRT_CryptoImageFinish(unsigned long hwBaseAddress,bsvCryptoMode_t mode,CCHashResult_t hashBuff)352 CCError_t SBRT_CryptoImageFinish( unsigned long hwBaseAddress,
353 bsvCryptoMode_t mode,
354 CCHashResult_t hashBuff)
355 {
356
357 /* close HW engines */
358
359 FinishBsvHash(hwBaseAddress, hashBuff);
360 if (mode != BSV_CRYPTO_HASH){
361 FinishBsvAes(hwBaseAddress, BSV_AES_CIPHER_CTR, NULL);
362 }
363
364 return CC_OK;
365 }
366
SBRT_MemCmp(uint8_t * pBuff1,uint8_t * pBuff2,uint32_t size)367 uint32_t SBRT_MemCmp( uint8_t *pBuff1 , uint8_t *pBuff2 , uint32_t size)
368 {
369 /* same as ROM code for security issues */
370
371 /* loop variable */
372 uint32_t i;
373 uint32_t stat = 0;
374
375 /* FUNCTION LOGIC */
376
377 for( i = 0; i < size; i++ ) {
378 stat |= (pBuff1[i] ^ pBuff2[i]);
379 }
380
381 if(stat == 0)
382 return CC_TRUE;
383 else
384 return CC_FALSE;
385
386 }
387
SBRT_ReverseMemCopy(uint8_t * pDst,uint8_t * pSrc,uint32_t size)388 void SBRT_ReverseMemCopy( uint8_t *pDst, uint8_t *pSrc, uint32_t size)
389 {
390 /* FUNCTION DECLARATIONS */
391
392 /* loop variable */
393 uint32_t i;
394 uint8_t tmp;
395
396 /* buffers position identifiers */
397 uint32_t dstPos, srcPos;
398
399 /* FUNCTION LOGIC */
400
401 /* initialize the source and the destination position */
402 dstPos = size - 1;
403 srcPos = 0;
404
405 /* execute the reverse copy in case of different buffers */
406 if (pDst != pSrc) {
407 for( i = 0 ; i < size ; i++ )
408 pDst[dstPos--] = pSrc[srcPos++];
409 } else {
410 /* execute the reverse copy in case of in-place reversing */
411 for( i = 0 ; i < size/2 ; i++ ) {
412 tmp = pDst[dstPos];
413 pDst[dstPos--] = pSrc[srcPos];
414 pSrc[srcPos++] = tmp;
415 }
416 }
417
418 return;
419
420 }
421
422
423
424