1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
7 
8 /************* Include Files ****************/
9 
10 #include "secureboot_basetypes.h"
11 #include "util.h"
12 #include "secureboot_error.h"
13 #include "sb_x509_error.h"
14 #include "util_asn1_parser.h"
15 #include "cc_pal_log.h"
16 #include "bootimagesverifier_def.h"
17 
18 /************************ Defines ******************************/
19 
20 /************************ Enums ******************************/
21 
22 
23 /************************ Typedefs ******************************/
24 
25 
26 /************************ Global Data ******************************/
27 
28 
29 /************* Private function prototype ****************/
30 
31 
32 /************************ Private Functions ******************************/
33 /* The function reads the size of the following item */
UTIL_Asn1ReadItemLength(uint8_t * pInStr,uint32_t * itemLen,uint8_t * index)34 static CCError_t UTIL_Asn1ReadItemLength(uint8_t *pInStr, uint32_t *itemLen, uint8_t *index)
35 {
36     uint8_t currVal = 0;
37     uint32_t i = 0;
38 
39     currVal = *pInStr;
40 
41     /* Parsing Item's length according to X.690 Section 8.1.3 */
42     if (currVal < 0x80){
43         *itemLen = currVal;
44         *index = *index + 1;
45     }
46     else {
47         currVal &= 0x7F;
48         if ((currVal == 0) || (currVal > sizeof(uint32_t))){
49             return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
50         }
51         else {
52             pInStr++;
53             /* read the size according to number of bytes */
54             *itemLen = 0;
55             for (i=0 ; i<currVal ; i++){
56                 *itemLen = (*itemLen << 8) + (*pInStr++);
57             }
58             /* update the size of bytes */
59             *index = *index + currVal + 1;
60         }
61     }
62     if (*itemLen > CC_SB_MAX_CERT_SIZE_IN_BYTES) {
63         return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
64     }
65 
66     return CC_OK;
67 }
68 
69 /* The function reads the ASN1 tag + size and returns it */
UTIL_Asn1ReadItemVerifyTag(uint8_t * pInStr,CCSbCertAsn1Data_t * pAsn1Data,uint8_t tag)70 CCError_t UTIL_Asn1ReadItemVerifyTag(uint8_t *pInStr, CCSbCertAsn1Data_t *pAsn1Data, uint8_t tag)
71 {
72     CCError_t  error = CC_OK;
73 
74     /* Read item id + size */
75     pAsn1Data->tagId = *pInStr++;
76     if (pAsn1Data->tagId != tag) {
77         return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
78     }
79     pAsn1Data->index = 1;
80     error = UTIL_Asn1ReadItemLength(pInStr, &(pAsn1Data->itemSize), &(pAsn1Data->index));
81 
82     return error;
83 }
84 
85 /* The function reads the ASN1 tag + size and returns it */
UTIL_Asn1ReadItemVerifyTagFW(uint8_t ** ppInStr,CCSbCertAsn1Data_t * pAsn1Data,uint8_t tag,unsigned long startAddress,unsigned long endAddress)86 CCError_t UTIL_Asn1ReadItemVerifyTagFW(uint8_t **ppInStr, CCSbCertAsn1Data_t *pAsn1Data, uint8_t tag, unsigned long startAddress, unsigned long endAddress)
87 {
88     CCError_t  error = CC_OK;
89     uint8_t *tempCertPtr = *ppInStr;
90 
91     /* Read item id + size */
92     pAsn1Data->tagId = *tempCertPtr++;
93 
94     if (pAsn1Data->tagId != tag) {
95         CC_PAL_LOG_WARN("Invalid tag 0x%x, expected 0x%x\n", pAsn1Data->tagId, tag);
96         return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
97     }
98     pAsn1Data->index = 1;
99     error = UTIL_Asn1ReadItemLength(tempCertPtr, &(pAsn1Data->itemSize), &(pAsn1Data->index));
100     if (error != CC_OK) {
101         CC_PAL_LOG_WARN("Failed UTIL_Asn1ReadItemLength 0x%x\n", error);
102         return error;
103     }
104 
105     *ppInStr = *ppInStr + pAsn1Data->index;
106     /* verify that index does not increment the cert pointer to invalid address (beyond the certificate boundaries) */
107     UTILS_ASN1_CERT_VERIFY_PTR_RET((unsigned long)*ppInStr, startAddress, endAddress);
108 
109     return error;
110 }
111 
112