• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hks_ha_plugin.h"
17 
18 #include <cstring>
19 
20 #include "securec.h"
21 #include "hks_ha_event_queue.h"
22 #include "hks_mem.h"
23 #include "hks_log.h"
24 #include "hks_plugin_adapter.h"
25 #include "hks_plugin_def.h"
26 #include "hks_template.h"
27 #include "hks_report_generate_key.h"
28 #include "hks_report_import_key.h"
29 #include "hks_report_delete_key.h"
30 #include "hks_report_check_key_exited.h"
31 #include "hks_report_rename_key.h"
32 #include "hks_report_three_stage.h"
33 #include "hks_report_list_aliases.h"
34 #include "hks_report_data_size.h"
35 #include "hks_report_three_stage_build.h"
36 #include "hks_param.h"
37 
38 static HksEventProcMap g_eventProcMap[] = {
39     {
40         HKS_EVENT_CRYPTO,
41         HksParamSetToEventInfoCrypto,
42         HksEventInfoNeedReportCrypto,
43         HksEventInfoIsEqualCrypto,
44         HksEventInfoAddCrypto,
45         HksEventInfoToMapCrypto,
46     },
47     {
48         HKS_EVENT_SIGN_VERIFY,
49         HksParamSetToEventInfoCrypto,
50         HksEventInfoNeedReportCrypto,
51         HksEventInfoIsEqualCrypto,
52         HksEventInfoAddCrypto,
53         HksEventInfoToMapCrypto,
54     },
55     {
56         HKS_EVENT_DERIVE,
57         HksParamSetToEventInfoAgreeDerive,
58         HksEventInfoNeedReportAgreeDerive,
59         HksEventInfoIsEqualAgreeDerive,
60         HksEventInfoAddAgreeDerive,
61         HksEventInfoToMapAgreeDerive,
62     },
63     {
64         HKS_EVENT_AGREE,
65         HksParamSetToEventInfoAgreeDerive,
66         HksEventInfoNeedReportAgreeDerive,
67         HksEventInfoIsEqualAgreeDerive,
68         HksEventInfoAddAgreeDerive,
69         HksEventInfoToMapAgreeDerive,
70     },
71     {
72         HKS_EVENT_MAC,
73         HksParamSetToEventInfoMac,
74         HksEventInfoNeedReportMac,
75         HksEventInfoIsEqualMac,
76         HksEventInfoAddMac,
77         HksEventInfoToMapMac,
78     },
79     {
80         HKS_EVENT_ATTEST,
81         HksParamSetToEventInfoAttest,
82         HksEventInfoNeedReportAttest,
83         HksEventInfoIsEqualAttest,
84         HksEventInfoAddAttest,
85         HksEventInfoToMapAttest,
86     },
87     {
88         HKS_EVENT_GENERATE_KEY,
89         HksParamSetToEventInfoForKeyGen,
90         HksEventInfoIsNeedReportForKeyGen,
91         HksEventInfoIsEqualForKeyGen,
92         HksEventInfoAddForKeyGen,
93         HksEventInfoToMapForKeyGen
94     },
95     {
96         HKS_EVENT_IMPORT_KEY,
97         HksParamSetToEventInfoForImport,
98         HksEventInfoIsNeedReportForImport,
99         HksEventInfoIsEqualForImport,
100         HksEventInfoAddForImport,
101         HksEventInfoToMapForImport,
102     },
103     {
104         HKS_EVENT_DELETE_KEY,
105         HksParamSetToEventInfoForDelete,
106         HksEventInfoIsNeedReportForDelete,
107         HksEventInfoIsEqualForDelete,
108         HksEventInfoAddForDelete,
109         HksEventInfoToMapForDelete
110     },
111     {
112         HKS_EVENT_CHECK_KEY_EXISTED,
113         HksParamSetToEventInfoForCheckKeyExited,
114         HksEventInfoIsNeedReportForCheckKeyExited,
115         HksEventInfoIsEqualForCheckKeyExited,
116         HksEventInfoAddForCheckKeyExited,
117         HksEventInfoToMapForCheckKeyExited
118     },
119     {
120         HKS_EVENT_RENAME_KEY,
121         HksParamSetToEventInfoForRename,
122         HksEventInfoIsNeedReportForRename,
123         HksEventInfoIsEqualForRename,
124         HksEventInfoAddForRename,
125         HksEventInfoToMapForRename
126     },
127     {
128         HKS_EVENT_LIST_ALIASES,
129         HksParamSetToEventInfoForListAliases,
130         HksEventInfoIsNeedReportForListAliases,
131         HksEventInfoIsEqualForListAliases,
132         HksEventInfoAddForListAliases,
133         HksEventInfoToMapForListAliases
134     },
135     {
136         HKS_EVENT_DATA_SIZE_STATISTICS,
137         HksParamSetToEventInfoForDataSize,
138         HksEventInfoIsNeedReportForDataSize,
139         HksEventInfoIsEqualForDataSize,
140         HksEventInfoAddForDataSize,
141         HksEventInfoToMapForDataSize
142     }
143 };
144 
HksHaPlugin()145 HksHaPlugin::HksHaPlugin() : queue(), stopFlag(false)
146 {}
147 
~HksHaPlugin()148 HksHaPlugin::~HksHaPlugin()
149 {
150     Destroy();
151 }
152 
Destroy()153 void HksHaPlugin::Destroy()
154 {
155     queue.Stop();
156 
157     StopWorkerThread();
158 
159     eventCacheList.RemoveFront(eventCacheList.GetSize());
160 }
161 
StartWorkerThread()162 void HksHaPlugin::StartWorkerThread()
163 {
164     workerThread = std::thread(&HksHaPlugin::WorkerThread, this);
165 }
166 
StopWorkerThread()167 void HksHaPlugin::StopWorkerThread()
168 {
169     stopFlag = true;
170 }
171 
Enqueue(uint32_t eventId,struct HksParamSet * paramSet)172 bool HksHaPlugin::Enqueue(uint32_t eventId, struct HksParamSet *paramSet)
173 {
174     return queue.Enqueue(eventId, paramSet);
175 }
176 
HksEventProcFind(uint32_t eventId)177 HksEventProcMap *HksHaPlugin::HksEventProcFind(uint32_t eventId)
178 {
179     for (uint32_t i = 0; i < HKS_ARRAY_SIZE(g_eventProcMap); ++i) {
180         HKS_IF_TRUE_RETURN(g_eventProcMap[i].eventId == eventId, &g_eventProcMap[i])
181     }
182     return nullptr;
183 }
184 
HandlerReport(HksEventQueueItem & item)185 void HksHaPlugin::HandlerReport(HksEventQueueItem &item)
186 {
187     HKS_IF_NULL_LOGE_RETURN_VOID(item.paramSet, "HandlerReport: paramSet is"
188         "null for eventId %" LOG_PUBLIC "u", item.eventId);
189 
190     uint32_t eventId = item.eventId;
191     auto procMap = HksEventProcFind(eventId);
192     HKS_IF_NULL_LOGE_RETURN_VOID(procMap, "HandlerReport: Event ID %" LOG_PUBLIC "u not found in"
193         "the eventProcMap", eventId);
194 
195     struct HksEventInfo *eventInfo = (struct HksEventInfo *)HksMalloc(sizeof(struct HksEventInfo));
196     HKS_IF_NULL_LOGE_RETURN_VOID(eventInfo, "Failed to allocate HksEventInfo");
197 
198     int32_t ret = procMap->eventInfoCreate(item.paramSet, eventInfo);
199     if (ret != HKS_SUCCESS) {
200         HKS_LOG_E("Failed to create HksEventInfo for eventId %" LOG_PUBLIC "u", eventId);
201         HKS_FREE(eventInfo);
202         return;
203     }
204 
205     bool needReport = procMap->needReport(eventInfo);
206     HKS_IF_NOT_TRUE_RETURN(needReport, HandleStatisticEvent(eventInfo, eventId, procMap))
207 
208     std::unordered_map<std::string, std::string> eventMap;
209     ret = procMap->eventInfoToMap(eventInfo, eventMap);
210     HKS_IF_NOT_SUCC_LOGE(ret, "Failed to convert HksEventInfo to map"
211         "for eventId %" LOG_PUBLIC "u", eventId);
212     HandleFaultEvent(&eventInfo->common, eventMap);
213 
214     HksFreeEventInfo(&eventInfo);
215     HKS_FREE(eventInfo);
216 }
217 
WorkerThread()218 void HksHaPlugin::WorkerThread()
219 {
220     while (!stopFlag) {
221         HksEventQueueItem item;
222         bool success = queue.Dequeue(item);
223         if (!success) {
224             continue;
225         }
226 
227         HandlerReport(item);
228         HksFreeParamSet(&item.paramSet);
229     }
230 }
231 
HandleFaultEvent(HksEventCommonInfo * commonInfo,std::unordered_map<std::string,std::string> & eventMap)232 void HksHaPlugin::HandleFaultEvent(
233     HksEventCommonInfo *commonInfo, std::unordered_map<std::string, std::string> &eventMap)
234 {
235     int32_t ret = HksPluginOnLocalRequest(CODE_FAULT_METRICS, commonInfo, &eventMap);
236     HKS_IF_NOT_SUCC_LOGE_RETURN_VOID(ret, "Failed to call OnSingleEventRequest: error code %" LOG_PUBLIC "d", ret);
237 }
238 
GetCurrentTimestamp()239 static uint32_t GetCurrentTimestamp()
240 {
241     return static_cast<uint32_t>(time(nullptr));
242 }
243 
HandleStatisticEvent(struct HksEventInfo * eventInfo,uint32_t eventId,HksEventProcMap * procMap)244 void HksHaPlugin::HandleStatisticEvent(struct HksEventInfo *eventInfo, uint32_t eventId, HksEventProcMap *procMap)
245 {
246     HKS_IF_NULL_LOGE_RETURN_VOID(eventInfo, "HandleStatisticEvent: Invalid eventInfo parameters");
247     HKS_IF_NULL_LOGE_RETURN_VOID(procMap, "HandleStatisticEvent: Invalid procMap parameters");
248 
249     bool found = eventCacheList.FindAndUpdate(eventInfo, procMap);
250     if (!found) {
251         AddEventCache(eventId, eventInfo);
252     } else {
253         HksFreeEventInfo(&eventInfo);
254         HKS_FREE(eventInfo);
255     }
256 
257     uint32_t currentSize = eventCacheList.GetSize();
258     HKS_IF_TRUE_RETURN_VOID(currentSize <= 0)
259 
260     HKS_IF_TRUE_RETURN_VOID(eventCacheList.cacheList.empty())
261     const HksEventCacheNode &firstNode = eventCacheList.cacheList.front();
262     uint32_t reportCount = 0;
263     time_t currentTime = GetCurrentTimestamp();
264 
265     HKS_IF_TRUE_RETURN_VOID((currentTime - firstNode.timestamp) <= MAX_CACHE_DURATION && currentSize < MAX_CACHE_SIZE)
266     reportCount = currentSize;
267     HKS_LOG_I("HksHaPlugin::HandleStatisticEvent:reportCount is %" LOG_PUBLIC "u", reportCount);
268     BatchReportEvents(reportCount);
269 }
270 
AddEventCache(uint32_t eventId,struct HksEventInfo * eventInfo)271 void HksHaPlugin::AddEventCache(uint32_t eventId, struct HksEventInfo *eventInfo)
272 {
273     HksEventCacheNode newNode{eventId, GetCurrentTimestamp(), eventInfo};
274     eventCacheList.Add(newNode);
275 }
276 
FillEventInfos(uint32_t reportCount,HksEventWithMap * eventsWithMap)277 int32_t HksHaPlugin::FillEventInfos(uint32_t reportCount, HksEventWithMap *eventsWithMap)
278 {
279     uint32_t count = 0;
280 
281     for (auto it = eventCacheList.cacheList.begin(); it != eventCacheList.cacheList.end() && count < reportCount;
282          ++it) {
283         if (it->data) {
284             struct HksEventInfo *eventInfo = it->data;
285             eventsWithMap[count].common = eventInfo->common;
286 
287             HksEventProcMap *procMap = HksEventProcFind(eventsWithMap[count].common.eventId);
288             HKS_IF_NULL_LOGI_RETURN(procMap, HKS_ERROR_NULL_POINTER, "procMap is null");
289 
290             int32_t ret = procMap->eventInfoToMap(eventInfo, eventsWithMap[count].eventMap);
291             if (ret != HKS_SUCCESS) {
292                 HKS_LOG_E("FillEventInfos: Failed to convert HksEventInfo to map for eventId %" LOG_PUBLIC "u",
293                     eventsWithMap[count].common.eventId);
294                 continue;
295             }
296         }
297         ++count;
298     }
299 
300     return HKS_SUCCESS;
301 }
302 
CallBatchReport(uint32_t reportCount,HksEventWithMap * eventsWithMap)303 int32_t HksHaPlugin::CallBatchReport(uint32_t reportCount, HksEventWithMap *eventsWithMap)
304 {
305     int32_t ret = HksPluginOnLocalRequest(CODE_STATISTICS_METRICS, (const void *)eventsWithMap, (void *)&reportCount);
306     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "CallBatchReport: HksHaPlugin_OnBatchEventRequest failed,"
307         "error code: %" LOG_PUBLIC "d", ret);
308 
309     return HKS_SUCCESS;
310 }
311 
RemoveReportedEvents(uint32_t reportCount)312 void HksHaPlugin::RemoveReportedEvents(uint32_t reportCount)
313 {
314     eventCacheList.RemoveFront(reportCount);
315 }
316 
BatchReportEvents(uint32_t reportCount)317 int32_t HksHaPlugin::BatchReportEvents(uint32_t reportCount)
318 {
319     HKS_IF_TRUE_LOGI_RETURN(reportCount > eventCacheList.GetSize(), HKS_ERROR_INVALID_ARGUMENT,
320         "HksHaPlugin::BatchReportEvents:reportCount > queueSize")
321     HksEventWithMap *eventsWithMap = new (std::nothrow) HksEventWithMap[reportCount];
322     HKS_IF_NULL_LOGI_RETURN(eventsWithMap, HKS_ERROR_NULL_POINTER, "eventsWithMap is null");
323 
324     int32_t ret = HKS_SUCCESS;
325     do {
326         ret = FillEventInfos(reportCount, eventsWithMap);
327         HKS_IF_NOT_SUCC_LOGI_BREAK(ret, "HksHaPlugin::BatchReportEvents:FillEventInfos fail");
328         ret = CallBatchReport(reportCount, eventsWithMap);
329         HKS_IF_NOT_SUCC_LOGI_BREAK(ret, "HksHaPlugin::BatchReportEvents:CallBatchReport fail");
330     } while (0);
331 
332     RemoveReportedEvents(reportCount);
333     delete[] eventsWithMap;
334 
335     return HKS_SUCCESS;
336 }
337 
HksHaPluginInit(void)338 int32_t HksHaPluginInit(void)
339 {
340     HksHaPlugin::GetInstance().StartWorkerThread();
341     return HKS_SUCCESS;
342 }
343 
HksHaPluginDestroy()344 void HksHaPluginDestroy()
345 {
346     HksHaPlugin::GetInstance().Destroy();
347 }