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