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
11 #include "secureboot_basetypes.h"
12 #include "secureboot_stage_defs.h"
13 #include "util_asn1_parser.h"
14 #include "util_x509_parser.h"
15 #include "secureboot_error.h"
16 #include "sb_x509_error.h"
17 #include "rsa_bsv.h"
18 #include "cc_pal_log.h"
19 #include "cc_pka_hw_plat_defs.h"
20
21
22 /************************ Defines ******************************/
23
24
25 /************************ Enums ******************************/
26
27
28 /************************ Typedefs ******************************/
29
30
31 /************************ Global Data ******************************/
32 const uint8_t *certType2SubjectNames[CC_X509_CERT_TYPE_MAX] = {
33 /*CC_X509_CERT_TYPE_MIN */ (uint8_t *)NULL,
34 /*CC_X509_CERT_TYPE_KEY */ (uint8_t *)CC_X509_CERT_KEY_CERT,
35 /*CC_X509_CERT_TYPE_CONTENT */ (uint8_t *)CC_X509_CERT_CNT_CERT,
36 /*CC_X509_CERT_TYPE_ENABLER_DBG */ (uint8_t *)CC_X509_CERT_ENABLER_CERT,
37 /*CC_X509_CERT_TYPE_DEVELOPER_DBG */ (uint8_t *)CC_X509_CERT_DEVELOPER_CERT
38 };
39
40 /************* Private function prototype ****************/
41
42
43 /************************ Private Functions ******************************/
44 /* the following function verify the ASN1 tags sequences in case of strings (Issuer name and subject name) */
UTIL_X509VerifyStr(uint8_t ** pCert,uint32_t * dataSize,unsigned long startAddress,unsigned long endAddress)45 CCError_t UTIL_X509VerifyStr(uint8_t **pCert, uint32_t *dataSize, unsigned long startAddress, unsigned long endAddress)
46 {
47 CCError_t error = CC_OK;
48 CCSbCertAsn1Data_t asn1Data;
49
50 /* read SEQ */
51 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
52 if (error != CC_OK) {
53 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
54 }
55 /* read SET */
56 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SET_OF_TAG_ID, startAddress, endAddress);
57 if (error != CC_OK) {
58 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
59 }
60 /* read SEQ */
61 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
62 if (error != CC_OK) {
63 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
64 }
65 /* OBJ ID */
66 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
67 if (error != CC_OK) {
68 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
69 }
70
71 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress)
72
73 /* PRINT STR ID */
74 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_PRNT_STR_TAG_ID, startAddress, endAddress);
75 if (error != CC_OK) {
76 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_UTF8_TAG_ID, startAddress, endAddress);
77 if (error != CC_OK) {
78 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
79 }
80 }
81 *dataSize = asn1Data.itemSize;
82
83 return error;
84 }
85
UTIL_X509VerifyIssuerName(uint8_t * pCert,uint32_t size)86 CCError_t UTIL_X509VerifyIssuerName(uint8_t *pCert, uint32_t size)
87 {
88 CCError_t error = CC_OK;
89
90 error = UTIL_MemCmp(pCert, (uint8_t*)CC_X509_CERT_ISSUER_NAME, size);
91 if (error != CC_TRUE){
92 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
93 }
94 return CC_OK;
95 }
96
97
98 /* the following function verify the subject name */
UTIL_X509VerifySubjectName(uint8_t * pCert,CCX509CertType_t certType,uint32_t subNameSize)99 CCError_t UTIL_X509VerifySubjectName(uint8_t *pCert, CCX509CertType_t certType, uint32_t subNameSize)
100 {
101 CCError_t error = CC_OK;
102 /* validate inputs */
103 if ((NULL == pCert) ||
104 ((certType >= CC_X509_CERT_TYPE_MAX) || (certType <= CC_X509_CERT_TYPE_MIN))) {
105 CC_PAL_LOG_ERR("Invalid inputs\n");
106 return CC_SB_X509_CERT_INV_PARAM;
107 }
108
109 error = UTIL_MemCmp(pCert,(uint8_t*)certType2SubjectNames[certType],subNameSize);
110 if(error != CC_TRUE)
111 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
112
113 return CC_OK;
114 }
115
116
117 /* the following function verify the ASN1 tags sequences in case of strings (Issuer name and subject name) */
UTIL_X509VerifyPubKey(uint8_t ** pCert,CCSbNParams_t * pParamsN,unsigned long startAddress,unsigned long endAddress)118 CCError_t UTIL_X509VerifyPubKey(uint8_t **pCert, CCSbNParams_t *pParamsN, unsigned long startAddress, unsigned long endAddress)
119 {
120 CCError_t error = CC_OK;
121 CCSbCertAsn1Data_t asn1Data;
122 uint8_t objId[] = CC_X509_CERT_RSASSAENC_ID;
123 uint8_t eVal[] = X509_RSA_E_VAL_IN_BYTES;
124
125 /* read SEQ */
126 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
127 if (error != CC_OK)
128 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
129 /* read SEQ */
130 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
131 if (error != CC_OK)
132 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
133 /* OBJ ID */
134 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
135 if ((error != CC_OK) || (asn1Data.itemSize != sizeof(objId))) {
136 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
137 }
138 /* verify ID */
139 if ((error = UTIL_MemCmp(*pCert, objId, asn1Data.itemSize)) != CC_TRUE){
140 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
141 }
142 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
143
144 /* read NULL */
145 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_NULL_TAG_ID, startAddress, endAddress);
146 if (error != CC_OK)
147 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
148 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
149 /* BIT Str */
150 error = UTIL_Asn1ReadItemVerifyTag(*pCert, &asn1Data, CC_X509_CERT_BIT_STR_TAG_ID);
151 if (error != CC_OK)
152 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
153 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.index+1, startAddress, endAddress);//add 1 for unused bits
154 /* SEQ */
155 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
156 if (error != CC_OK)
157 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
158 /* read INT and copy the N into buffer */
159 error = UTIL_Asn1ReadItemVerifyTag(*pCert, &asn1Data, CC_X509_CERT_INT_TAG_ID);
160 if (error != CC_OK)
161 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
162 if (asn1Data.itemSize != SB_CERT_RSA_KEY_SIZE_IN_BYTES){
163 if (asn1Data.itemSize != (SB_CERT_RSA_KEY_SIZE_IN_BYTES + 1)){
164 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
165 }
166 asn1Data.index ++;
167 }
168 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.index, startAddress, endAddress);
169 UTIL_MemCopy((uint8_t*)pParamsN->N, *pCert, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
170 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize-1, startAddress, endAddress);
171
172 /* Verify E is the expected constant */
173 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_INT_TAG_ID, startAddress, endAddress);
174 if (error != CC_OK)
175 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
176
177 if (asn1Data.itemSize != sizeof(eVal)) /* verify the size of E is correct */
178 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
179
180 if ((error = UTIL_MemCmp(*pCert, eVal, asn1Data.itemSize)) != CC_TRUE){
181 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
182 }
183 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
184
185 return CC_OK;
186 }
187
188 /* the following function retrieves the signature */
UTIL_X509GetSignature(uint8_t ** pCert,CCSbSignature_t * signatureP,unsigned long startAddress,unsigned long endAddress)189 CCError_t UTIL_X509GetSignature(uint8_t **pCert, CCSbSignature_t *signatureP, unsigned long startAddress, unsigned long endAddress)
190 {
191 CCError_t error = CC_OK;
192 CCSbCertAsn1Data_t asn1Data;
193 uint8_t objId[] = CC_X509_CERT_SHA256RSAPSS_ID;
194 uint8_t objSha256Id[] = CC_X509_CERT_SHA256_ID;
195 uint8_t objMgf1Id[] = CC_X509_CERT_MGF1_ID;
196
197 /* read SEQ */
198 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
199 if (error != CC_OK) {
200 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
201 }
202 /* OBJ ID */
203 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
204 if (error != CC_OK) {
205 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
206 }
207 if (asn1Data.itemSize != sizeof(objId)) {
208 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
209 }
210 /* verify ID */
211 if ((error = UTIL_MemCmp(*pCert, objId, asn1Data.itemSize)) != CC_TRUE){
212 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
213 }
214 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
215
216 /* verify sha256 + PSS + mgf1 attributes signature */
217 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
218 if (error != CC_OK) {
219 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
220 }
221 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG_ID, startAddress, endAddress);
222 if (error != CC_OK) {
223 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
224 }
225 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
226 if (error != CC_OK) {
227 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
228 }
229 /* verify sha256 */
230 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
231 if (error != CC_OK) {
232 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
233 }
234 if (asn1Data.itemSize != sizeof(objSha256Id)) {
235 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
236 }
237 if ((error = UTIL_MemCmp(*pCert, objSha256Id, asn1Data.itemSize)) != CC_TRUE){
238 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
239 }
240 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
241 /* verify mgf1 + sha256 */
242 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG1_ID, startAddress, endAddress);
243 if (error != CC_OK) {
244 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
245 }
246 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
247 if (error != CC_OK) {
248 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
249 }
250 /* verify mgf1 */
251 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
252 if (error != CC_OK) {
253 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
254 }
255 if (asn1Data.itemSize != sizeof(objMgf1Id)) {
256 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
257 }
258 if ((error = UTIL_MemCmp(*pCert, objMgf1Id, asn1Data.itemSize)) != CC_TRUE){
259 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
260 }
261
262 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
263 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
264 if (error != CC_OK) {
265 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
266 }
267 /* verify sha256 */
268 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
269 if (error != CC_OK) {
270 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
271 }
272 if (asn1Data.itemSize != sizeof(objSha256Id)) {
273 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
274 }
275 if ((error = UTIL_MemCmp(*pCert, objSha256Id, asn1Data.itemSize)) != CC_TRUE){
276 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
277 }
278 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
279
280 /* verify last special tag size */
281 error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG2_ID, startAddress, endAddress);
282 if (error != CC_OK) {
283 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
284 }
285 if (asn1Data.itemSize != CC_X509_CERT_CTX_SPEC_TAG2_SIZE){
286 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
287 }
288 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
289 /* BIT Str */
290 error = UTIL_Asn1ReadItemVerifyTag(*pCert, &asn1Data, CC_X509_CERT_BIT_STR_TAG_ID);
291 if (error != CC_OK) {
292 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
293 }
294 if (asn1Data.itemSize != (SB_CERT_RSA_KEY_SIZE_IN_BYTES + 1)){
295 return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
296 }
297 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.index + 1, startAddress, endAddress);//add 1 for unused bits
298 // copy the signature as reversed buffer
299 UTIL_ReverseMemCopy((uint8_t*)signatureP->sig, *pCert, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
300 UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize-1, startAddress, endAddress);//add 1 for unused bits
301
302 return error;
303 }
304