• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "hcs_blob_if.h"
10 #include "hdf_log.h"
11 
12 #define HDF_LOG_TAG hcs_blob_if
13 
14 static bool g_byteAlign = false;
15 
HcsIsByteAlign(void)16 bool HcsIsByteAlign(void)
17 {
18     return g_byteAlign;
19 }
20 
HcsGetDataTypeOffset(const char * start)21 int32_t HcsGetDataTypeOffset(const char *start)
22 {
23     int32_t len;
24     switch (HcsGetPrefix(start)) {
25         case CONFIG_BYTE:
26             len = HCS_BYTE_LENGTH + HCS_PREFIX_LENGTH;
27             break;
28         case CONFIG_WORD:
29             len = HCS_WORD_LENGTH + HCS_PREFIX_LENGTH;
30             break;
31         case CONFIG_DWORD:
32         case CONFIG_REFERENCE:
33             len = HCS_DWORD_LENGTH + HCS_PREFIX_LENGTH;
34             break;
35         case CONFIG_QWORD:
36             len = HCS_QWORD_LENGTH + HCS_PREFIX_LENGTH;
37             break;
38         case CONFIG_STRING:
39             len = HCS_STRING_LENGTH(start + HCS_PREFIX_LENGTH) + HCS_PREFIX_LENGTH;
40             break;
41         default:
42             len = HDF_FAILURE;
43             break;
44     }
45     return len;
46 }
47 
HcsGetArrayLength(const char * start)48 static int32_t HcsGetArrayLength(const char *start)
49 {
50     int32_t arrayLen = HCS_PREFIX_LENGTH + HCS_WORD_LENGTH;
51     uint16_t count;
52     uint16_t i;
53     if (!HcsSwapToUint16(&count, start + HCS_PREFIX_LENGTH, CONFIG_WORD)) {
54         HDF_LOGE("%{public}s failed", __func__);
55         return HDF_FAILURE;
56     }
57     for (i = 0; i < count; i++) {
58         int32_t lenData = HcsGetDataTypeOffset(start + arrayLen);
59         if (lenData < 0) {
60             return HDF_FAILURE;
61         }
62         arrayLen += lenData;
63     }
64     return arrayLen;
65 }
66 
HcsGetAttrLength(const char * start)67 int32_t HcsGetAttrLength(const char *start)
68 {
69     int32_t length = HCS_PREFIX_LENGTH + HCS_STRING_LENGTH(start + HCS_PREFIX_LENGTH);
70     int32_t dataLen;
71     switch (HcsGetPrefix(start + length)) {
72         case CONFIG_BYTE:
73         case CONFIG_WORD:
74         case CONFIG_DWORD:
75         case CONFIG_QWORD:
76         case CONFIG_STRING:
77         case CONFIG_REFERENCE:
78             dataLen = HcsGetDataTypeOffset(start + length);
79             break;
80         case CONFIG_ARRAY:
81             dataLen = HcsGetArrayLength(start + length);
82             break;
83         default:
84             dataLen = HDF_FAILURE;
85             break;
86     }
87     return (dataLen < 0) ? HDF_FAILURE : (dataLen + length);
88 }
89 
HcsGetNodeOrAttrLength(const char * start)90 int32_t HcsGetNodeOrAttrLength(const char *start)
91 {
92     int32_t length;
93     switch (HcsGetPrefix(start)) {
94         case CONFIG_NODE:
95             length = HCS_STRING_LENGTH(start + HCS_PREFIX_LENGTH) + HCS_PREFIX_LENGTH + HCS_DWORD_LENGTH;
96             break;
97         case CONFIG_ATTR:
98             length = HcsGetAttrLength(start);
99             break;
100         default:
101             length = HDF_FAILURE;
102             break;
103     }
104     return length;
105 }
106 
HcsGetNodeLength(const char * blob)107 int32_t HcsGetNodeLength(const char *blob)
108 {
109     int32_t rootLen = HcsGetNodeOrAttrLength(blob);
110     if (rootLen < 0) {
111         HDF_LOGE("%{public}s failed, the rootLen is %{public}d", __func__, rootLen);
112         return HDF_FAILURE;
113     }
114     rootLen += (int32_t)HcsByteCodeToUint32(blob + HCS_PREFIX_LENGTH + HCS_STRING_LENGTH(blob + HCS_PREFIX_LENGTH));
115     return rootLen;
116 }
117 
HcsSwapToUint8(uint8_t * value,const char * realValue,uint32_t type)118 bool HcsSwapToUint8(uint8_t *value, const char *realValue, uint32_t type)
119 {
120     if (type == CONFIG_BYTE) {
121         *value = g_byteAlign ? (uint8_t)HcsByteCodeToUint32(realValue) : HcsByteCodeToUint8(realValue);
122         return true;
123     }
124     HDF_LOGE("%{public}s failed, type: %{public}u", __func__, type);
125     return false;
126 }
127 
HcsSwapToUint16(uint16_t * value,const char * realValue,uint32_t type)128 bool HcsSwapToUint16(uint16_t *value, const char *realValue, uint32_t type)
129 {
130     uint8_t data;
131     if (type == CONFIG_WORD) {
132         *value =  g_byteAlign ? (uint16_t)HcsByteCodeToUint32(realValue) : HcsByteCodeToUint16(realValue);
133         return true;
134     }
135     if (HcsSwapToUint8(&data, realValue, type)) {
136         *value = data;
137         return true;
138     }
139     HDF_LOGE("%{public}s failed, type: %{public}u", __func__, type);
140     return false;
141 }
142 
HcsSwapToUint32(uint32_t * value,const char * realValue,uint32_t type)143 bool HcsSwapToUint32(uint32_t *value, const char *realValue, uint32_t type)
144 {
145     uint16_t data;
146     if (type == CONFIG_DWORD) {
147         *value = HcsByteCodeToUint32(realValue);
148         return true;
149     }
150     if (HcsSwapToUint16(&data, realValue, type)) {
151         *value = data;
152         return true;
153     }
154     HDF_LOGE("%{public}s failed, type: %{public}u", __func__, type);
155     return false;
156 }
157 
HcsSwapToUint64(uint64_t * value,const char * realValue,uint32_t type)158 bool HcsSwapToUint64(uint64_t *value, const char *realValue, uint32_t type)
159 {
160     uint32_t data;
161     if (type == CONFIG_QWORD) {
162         *value = HcsByteCodeToUint64(realValue);
163         return true;
164     }
165     if (HcsSwapToUint32(&data, realValue, type)) {
166         *value = data;
167         return true;
168     }
169     HDF_LOGE("%{public}s failed, type: %{public}u", __func__, type);
170     return false;
171 }
172 
CheckHcsBlobLength(uint32_t length,struct HbcHeader * header)173 static bool CheckHcsBlobLength(uint32_t length, struct HbcHeader *header)
174 {
175     uint32_t rootNodeLen = HCS_STRING_LENGTH(HBC_ROOT_NAME) + HCS_PREFIX_LENGTH + HCS_DWORD_LENGTH;
176     uint32_t minLength = rootNodeLen + HBC_HEADER_LENGTH;
177     uint32_t blobLength;
178     if (header->totalSize >= 0) {
179         blobLength = (uint32_t)(HBC_HEADER_LENGTH + header->totalSize);
180         g_byteAlign = false;
181         HDF_LOGI("%{public}s: the blobLength: %{public}u, byteAlign: %{public}d", __func__, blobLength, g_byteAlign);
182     } else {
183         blobLength = (uint32_t)(HBC_HEADER_LENGTH - header->totalSize);
184         g_byteAlign = true;
185         HDF_LOGI("%{public}s: the blobLength: %{public}u, byteAlign: %{public}d", __func__, blobLength, g_byteAlign);
186     }
187     if ((length != blobLength) || (blobLength < minLength)) {
188         HDF_LOGE("%{public}s failed, Hcsblob file length is %{public}u,  but the calculated length is %u",
189                  __func__, length, blobLength);
190         return false;
191     }
192     return true;
193 }
194 
HcsCheckBlobFormat(const char * start,uint32_t length)195 bool HcsCheckBlobFormat(const char *start, uint32_t length)
196 {
197     struct HbcHeader *header = NULL;
198     if ((start == NULL) || (length < HBC_HEADER_LENGTH) || (length > HBC_BLOB_MAX_LENGTH)) {
199         HDF_LOGE("%{public}s failed, Hcsblob file length is %{public}u", __func__, length);
200         return false;
201     }
202     header = (struct HbcHeader *)start;
203     if (header->magicNumber != HBC_MAGIC_NUMBER) {
204         HDF_LOGE("%{public}s failed, the magic number of HBC is %{public}x", __func__, header->magicNumber);
205         return false;
206     }
207     if (!CheckHcsBlobLength(length, header)) {
208         return false;
209     }
210     return true;
211 }
212