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