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