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 #define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
9 
10 /************* Include Files ****************/
11 #include "secureboot_basetypes.h"
12 #include "rsa_bsv.h"
13 #include "bootimagesverifier_def.h"
14 #include "secureboot_error.h"
15 #include "bootimagesverifier_error.h"
16 #include "bootimagesverifier_parser.h"
17 #include "secureboot_stage_defs.h"
18 #include "nvm.h"
19 #include "bootimagesverifier_swcomp.h"
20 #include "secureboot_base_swimgverify.h"
21 #include "cc_pal_log.h"
22 
23 
24 /************************ Defines ******************************/
25 
26 /************************ Enums ******************************/
27 
28 /************************ Typedefs ******************************/
29 
30 /************************ Global Data ******************************/
31 
32 /************************ Internal Functions ******************************/
33 
34 /************************ Public Functions ******************************/
35 
CCCertValidateSWComps(CCSbFlashReadFunc flashRead_func,void * userContext,unsigned long hwBaseAddress,CCSbPubKeyIndexType_t keyIndex,CCSbCertParserSwCompsInfo_t * pSwImagesData,uint32_t * pSwImagesAddData,uint32_t * workspace_ptr,uint32_t workspaceSize)36 CCError_t CCCertValidateSWComps(CCSbFlashReadFunc flashRead_func,
37                   void *userContext,
38                   unsigned long hwBaseAddress,
39                   CCSbPubKeyIndexType_t keyIndex,
40                   CCSbCertParserSwCompsInfo_t *pSwImagesData,
41                   uint32_t *pSwImagesAddData,
42                   uint32_t *workspace_ptr,
43                   uint32_t workspaceSize)
44 {
45     /* error variable */
46     CCError_t error = CC_OK;
47 
48     /* internal index */
49     uint32_t i = 0;
50 
51     /* internal pointer for the certificate main body, might not be word aligned */
52     uint8_t *pSwRecSignedData = NULL;
53     /* the non-signed part is always word aligned */
54     uint32_t *pSwRecNoneSignedData = NULL;
55 
56     /* AES IV buffer */
57     AES_Iv_t AESIv;
58     uint8_t *nonce;
59     CCswCodeEncType_t swCodeEncType;
60     CCBsvKeyType_t  keyType;
61     bsvCryptoMode_t cryptoMode;
62     CCswCryptoType_t swCryptoType;
63     CCswLoadVerifyScheme_t swLoadVerifyScheme;
64 
65     uint32_t lcs;
66 
67     uint8_t isLoadFromFlash;
68     uint8_t isVerifyImage;
69         ContentCertImageRecord_t cntImageRec;
70 
71     /*------------------
72         CODE
73     -------------------*/
74 
75     /* Point to the s/w record signed data: hash, load address, max size, code enc */
76     pSwRecSignedData = pSwImagesData->pSwCompsData;
77 
78     /* Point to the s/w record non-signed data: storage address, actual size */
79     pSwRecNoneSignedData = pSwImagesAddData;
80 
81     nonce = pSwImagesData->nonce;
82     swCodeEncType = pSwImagesData->swCodeEncType;
83     swCryptoType = pSwImagesData->swCryptoType;
84     swLoadVerifyScheme = pSwImagesData->swLoadVerifyScheme;
85 
86     /* Set default CC mode to Hash only (no encrypted images) */
87     cryptoMode = BSV_CRYPTO_HASH;
88     keyType = CC_BSV_END_OF_KEY_TYPE;
89 
90     /* Get LCS */
91     error = NVM_GetLCS(hwBaseAddress, &lcs);
92     if (error != CC_OK){
93         return error;
94     }
95 
96     switch(swLoadVerifyScheme){
97     case CC_SB_LOAD_AND_VERIFY:
98         isLoadFromFlash = CC_TRUE;
99         isVerifyImage = CC_TRUE;
100         break;
101     case CC_SB_VERIFY_ONLY_IN_FLASH:
102         isLoadFromFlash = CC_TRUE;
103         isVerifyImage = CC_TRUE;
104         break;
105     case CC_SB_VERIFY_ONLY_IN_MEM:
106         isLoadFromFlash = CC_FALSE;
107         isVerifyImage = CC_TRUE;
108         break;
109     case CC_SB_LOAD_ONLY:
110         isLoadFromFlash = CC_TRUE;
111         isVerifyImage = CC_FALSE;
112         /* Loading only is validate only in none secure lifecycle */
113         if (lcs == CC_BSV_SECURE_LCS) {
114             return CC_BOOT_IMG_VERIFIER_ILLEGAL_LCS_FOR_OPERATION_ERR;
115         }
116         break;
117     default:
118         return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
119     }
120 
121     /* Set AES key type */
122     switch (swCodeEncType){
123     case CC_SB_NO_IMAGE_ENCRYPTION:
124         break;
125     case CC_SB_ICV_CODE_ENCRYPTION:
126         keyType = CC_BSV_ICV_CE_KEY;
127         if ((keyIndex!=CC_SB_HASH_BOOT_KEY_0_128B) && (keyIndex!=CC_SB_HASH_BOOT_KEY_256B)){
128             return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
129         }
130         break;
131     case CC_SB_OEM_CODE_ENCRYPTION:
132         keyType = CC_BSV_CE_KEY;
133         if ((keyIndex!=CC_SB_HASH_BOOT_KEY_1_128B) && (keyIndex!=CC_SB_HASH_BOOT_KEY_256B)){
134             return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
135         }
136         break;
137     default:
138         return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
139     }
140 
141     /* Case of encrypted SW image */
142     if (swCodeEncType != CC_SB_NO_IMAGE_ENCRYPTION) {
143 
144         /* SB should fail if CE is needed in RMA lcs */
145         if (lcs == CC_BSV_RMA_LCS) {
146             return CC_BOOT_IMG_VERIFIER_ILLEGAL_LCS_FOR_OPERATION_ERR;
147         }
148 
149         /* image can not be encrypted in case of "load only" or "verify in flash" */
150         if ( (swLoadVerifyScheme == CC_SB_LOAD_ONLY) || (swLoadVerifyScheme == CC_SB_VERIFY_ONLY_IN_FLASH) ) {
151             return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
152         }
153 
154         /* Set crypto mode */
155         switch (swCryptoType){
156         case CC_SB_HASH_ON_DECRYPTED_IMAGE:
157             /* do AES decrypt on cipher image, and then do hash is done on plain image */
158             cryptoMode = BSV_CRYPTO_AES_TO_HASH_AND_DOUT;
159             break;
160         case CC_SB_HASH_ON_ENCRYPTED_IMAGE:
161             /* do AES decrypt and Hash on cipher image */
162             cryptoMode = BSV_CRYPTO_AES_AND_HASH;
163             break;
164         default:
165             return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
166         }
167 
168         /* Initiate AES IV with nonce data */
169         UTIL_MemSet((uint8_t*)AESIv, 0, AES_IV_COUNTER_SIZE_IN_BYTES);
170         UTIL_MemCopy((uint8_t*)&AESIv[0], nonce, CC_SB_MAX_SIZE_NONCE_BYTES);
171     }
172 
173     /* Load and verify all images in the certificate */
174     /*-----------------------------------------------*/
175     for (i = 0; i < pSwImagesData->numOfSwComps; i++ ) {
176 
177         /* In case of encrypted image, set AES IV CTR */
178         if ((isVerifyImage == CC_TRUE) && (keyType != CC_BSV_END_OF_KEY_TYPE)) {
179             UTIL_MemCopy((uint8_t *)&cntImageRec, (uint8_t *)pSwRecSignedData, sizeof(ContentCertImageRecord_t));
180 #ifdef BIG__ENDIAN
181             UTIL_MemCopy((uint8_t*)&AESIv[2], (uint8_t*)&cntImageRec.loadAddr, sizeof(CCAddr_t));
182 #else
183             UTIL_ReverseMemCopy((uint8_t*)&AESIv[2], (uint8_t*)&cntImageRec.loadAddr, sizeof(CCAddr_t));
184 #endif
185         }
186 
187         /* Load and/or verify image as needed */
188         error = _CCSbImageLoadAndVerify(flashRead_func, userContext,/* Flash Read function */
189                              hwBaseAddress,         /* CC base address */
190                              isLoadFromFlash,       /* should image be copied from Flash with user callback */
191                              isVerifyImage,         /* should image be verified with hash (and Aes if needed) */
192                              cryptoMode,            /* crypto mode type */
193                              keyType,           /* code encryption type definition */
194                              AESIv,             /* AES IV buffer */
195                              pSwRecSignedData,      /* pointer to SW component signed data - not word aligned for x.509 */
196                              pSwRecNoneSignedData,  /* pointer to SW components non-signed data. always word aligned */
197                              workspace_ptr, workspaceSize); /* workspace & workspaceSize to load the SW component into */
198 
199         if (error != CC_OK){
200             return error;
201         }
202 
203         /* Point to the next SW record */
204         pSwRecSignedData = (uint8_t *)((unsigned long)pSwRecSignedData + SW_REC_SIGNED_DATA_SIZE_IN_BYTES);
205         pSwRecNoneSignedData = (uint32_t *)((unsigned long)pSwRecNoneSignedData + SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES);
206 
207     }
208 
209     return CC_OK;
210 }
211 
212