1 /*
2 * Copyright (c) 2021-2024 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_sa.h"
17
18 #include <ipc_skeleton.h>
19 #include <iservice_registry.h>
20 #include <mutex>
21 #include <securec.h>
22 #include <set>
23 #include <sstream>
24 #include <string_ex.h>
25 #include <system_ability_definition.h>
26 #include "parameters.h"
27 #include "hks_client_service.h"
28 #include "hks_dcm_callback_handler.h"
29 #include "hks_ipc_service.h"
30 #include "hks_log.h"
31 #include "hks_mem.h"
32 #include "hks_message_handler.h"
33 #include "hks_plugin_adapter.h"
34 #include "hks_response.h"
35 #include "hks_template.h"
36 #include "hks_type_inner.h"
37 #include "hks_upgrade.h"
38 #include "hks_upgrade_lock.h"
39 #include "hks_util.h"
40 #include "hks_xcollie.h"
41 #include "huks_service_ipc_interface_code.h"
42 #include "hks_ha_plugin.h"
43 #include "rwlock.h"
44
45 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
46 #include "malloc.h"
47 #endif
48
49 #ifdef SUPPORT_COMMON_EVENT
50 #include <pthread.h>
51 #include <unistd.h>
52
53 #include "hks_event_observer.h"
54 #endif
55
56 #include <array>
57 #include <cinttypes>
58 #include <filesystem>
59 #include <string>
60 #include <system_error>
61
62 #ifdef HKS_USE_RKC_IN_STANDARD
63 #include <dirent.h>
64 #endif
65
66 uint32_t g_sessionId = 0;
67
68 namespace OHOS {
69 namespace Security {
70 namespace Hks {
71
72 const std::string BOOTEVENT_HUKSSERVICE_READY = "bootevent.huksService.ready";
73 const int32_t MAX_OPERATIONS_EACH_PID = 32;
74
75 REGISTER_SYSTEM_ABILITY_BY_ID(HksService, SA_ID_KEYSTORE_SERVICE, true);
76
77 std::mutex HksService::instanceLock;
78 sptr<HksService> HksService::instance;
79 const uint32_t MAX_MALLOC_LEN = 1 * 1024 * 1024; /* max malloc size 1 MB */
80
81 #ifdef SUPPORT_COMMON_EVENT
82 const uint32_t MAX_DELAY_TIMES = 100;
83 #endif
84
85 #ifdef SUPPORT_COMMON_EVENT
SubscribEvent()86 static void SubscribEvent()
87 {
88 for (uint32_t i = 0; i < MAX_DELAY_TIMES; ++i) {
89 if (SystemEventObserver::SubscribeEvent()) {
90 HKS_LOG_I("subscribe system event success, i = %" LOG_PUBLIC "u", i);
91 pthread_detach(pthread_self());
92 return;
93 } else {
94 HKS_LOG_E("subscribe system event failed %" LOG_PUBLIC "u times", i);
95 usleep(HKS_SLEEP_TIME_FOR_RETRY);
96 }
97 }
98 HKS_LOG_E("subscribe system event failed");
99 pthread_detach(pthread_self());
100 return;
101 }
102
HksSubscribeEvent()103 static void HksSubscribeEvent()
104 {
105 pthread_t subscribeThread;
106 HKS_IF_TRUE_LOGE_RETURN_VOID(pthread_create(&subscribeThread, nullptr, (void *(*)(void *))SubscribEvent,
107 nullptr) == -1, "create thread failed")
108 pthread_setname_np(subscribeThread, "HUKS_SUBSCRIBE_THREAD");
109 HKS_LOG_I("create thread success");
110 }
111 #endif
112
IsInvalidLength(uint32_t length)113 static inline bool IsInvalidLength(uint32_t length)
114 {
115 return (length == 0) || (length > MAX_MALLOC_LEN);
116 }
117
ProcessMessage(uint32_t code,uint32_t outSize,const struct HksBlob & srcData,MessageParcel & reply)118 static int32_t ProcessMessage(uint32_t code, uint32_t outSize, const struct HksBlob &srcData, MessageParcel &reply)
119 {
120 uint32_t size = sizeof(HKS_IPC_MESSAGE_HANDLER) / sizeof(HKS_IPC_MESSAGE_HANDLER[0]);
121 for (uint32_t i = 0; i < size; ++i) {
122 if (code == HKS_IPC_MESSAGE_HANDLER[i].msgId) {
123 HKS_IPC_MESSAGE_HANDLER[i].handler(reinterpret_cast<const struct HksBlob *>(&srcData),
124 reinterpret_cast<const uint8_t *>(&reply));
125 return HKS_SUCCESS;
126 }
127 }
128
129 HKS_IF_TRUE_LOGE_RETURN(outSize > MAX_MALLOC_LEN, HKS_ERROR_INVALID_ARGUMENT,
130 "outSize is invalid, size:%" LOG_PUBLIC "u", outSize)
131
132 size = sizeof(HKS_IPC_THREE_STAGE_HANDLER) / sizeof(HKS_IPC_THREE_STAGE_HANDLER[0]);
133 for (uint32_t i = 0; i < size; ++i) {
134 if (code == HKS_IPC_THREE_STAGE_HANDLER[i].msgId) {
135 struct HksBlob outData = { 0, nullptr };
136 if (outSize != 0) {
137 outData.size = outSize;
138 outData.data = static_cast<uint8_t *>(HksMalloc(outData.size));
139 HKS_IF_NULL_LOGE_RETURN(outData.data, HKS_ERROR_MALLOC_FAIL, "Malloc outData failed.")
140 }
141 HKS_IPC_THREE_STAGE_HANDLER[i].handler(reinterpret_cast<const struct HksBlob *>(&srcData), &outData,
142 reinterpret_cast<const uint8_t *>(&reply));
143 HKS_FREE_BLOB(outData);
144 break;
145 }
146 }
147 return HKS_SUCCESS;
148 }
149
HksService(int saId,bool runOnCreate=true)150 HksService::HksService(int saId, bool runOnCreate = true)
151 : SystemAbility(saId, runOnCreate), registerToService_(false), runningState_(STATE_NOT_START)
152 {
153 HKS_LOG_D("HksService");
154 }
155
~HksService()156 HksService::~HksService()
157 {
158 HKS_LOG_D("~HksService");
159 }
160
GetInstance()161 sptr<HksService> HksService::GetInstance()
162 {
163 std::lock_guard<std::mutex> autoLock(instanceLock);
164 HKS_IF_TRUE_RETURN(instance != nullptr, instance)
165 instance = new (std::nothrow) HksService(SA_ID_KEYSTORE_SERVICE, true);
166 return instance;
167 }
168
Init()169 bool HksService::Init()
170 {
171 HKS_LOG_I("HksService::Init Ready to init");
172 HKS_IF_TRUE_LOGI_RETURN(registerToService_, true, "HksService::Init already finished.")
173
174 int32_t ret = HksServiceInitialize();
175 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, false, "Init hks service failed!")
176 sptr<HksService> ptrInstance = HksService::GetInstance();
177 HKS_IF_NULL_LOGE_RETURN(ptrInstance, false, "HksService::Init GetInstance Failed")
178 HKS_IF_NOT_TRUE_LOGE_RETURN(Publish(ptrInstance), false, "HksService::Init Publish Failed")
179
180 ret = HksHaPluginInit();
181 HKS_IF_NOT_SUCC_LOGE(ret, "Init ha plugin failed!");
182
183 HKS_LOG_I("HksService::Init Publish service success");
184 registerToService_ = true;
185
186 if (!system::GetBoolParameter(BOOTEVENT_HUKSSERVICE_READY.c_str(), false)) {
187 system::SetParameter(BOOTEVENT_HUKSSERVICE_READY.c_str(), "true");
188 HKS_LOG_E("set bootevent.huksService.ready true");
189 }
190 HKS_LOG_I("HksService::Init success.");
191 return true;
192 }
193
HksInitMemPolicy(void)194 static void HksInitMemPolicy(void)
195 {
196 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
197 // disable mem cache and delay free because the size of mem data in HUKS is associated with caller tasks and
198 // changeable, which is not suitable for this case
199 (void)mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
200 (void)mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
201 #endif
202 }
203
OnRemoteDied(const wptr<IRemoteObject> & remoteObject)204 void HksDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remoteObject)
205 {
206 int32_t index = 0;
207 while (HksServiceAbortByPid(callingPid_) == HKS_SUCCESS && index < MAX_OPERATIONS_EACH_PID) {
208 index++;
209 }
210 HKS_LOG_I("The death process[%" LOG_PUBLIC "d] cache has been cleared [%" LOG_PUBLIC "d] operations!",
211 callingPid_, index);
212 }
213
HksDeathRecipient(int32_t callingPid)214 HksDeathRecipient::HksDeathRecipient(int32_t callingPid)
215 {
216 callingPid_ = callingPid;
217 }
218
ProcessAttestOrNormalMessage(uint32_t code,MessageParcel & data,uint32_t outSize,const struct HksBlob & srcData,MessageParcel & reply)219 static int32_t ProcessAttestOrNormalMessage(
220 uint32_t code, MessageParcel &data, uint32_t outSize, const struct HksBlob &srcData, MessageParcel &reply)
221 {
222 // Since we have wrote a HksStub instance in client side, we can now read it if it is anonymous attestation.
223 if (code == HKS_MSG_ATTEST_KEY) {
224 HksIpcServiceAttestKey(reinterpret_cast<const HksBlob *>(&srcData),
225 reinterpret_cast<const uint8_t *>(&reply), nullptr);
226 return HKS_SUCCESS;
227 } else if (code == HKS_MSG_ATTEST_KEY_ASYNC_REPLY) {
228 auto ptr = data.ReadRemoteObject();
229 // ReadRemoteObject will fail if huks_service has no selinux permission to call the client side.
230 HKS_IF_NULL_LOGE_RETURN(ptr, HKS_ERROR_IPC_INIT_FAIL, "ReadRemoteObject ptr failed")
231
232 HksIpcServiceAttestKey(reinterpret_cast<const HksBlob *>(&srcData),
233 reinterpret_cast<const uint8_t *>(&reply), reinterpret_cast<const uint8_t *>(ptr.GetRefPtr()));
234 return HKS_SUCCESS;
235 } else if (code == HKS_MSG_INIT) {
236 sptr<IRemoteObject> remoteObject = data.ReadRemoteObject();
237 if (remoteObject != HKS_NULL_POINTER) {
238 int32_t callingPid = IPCSkeleton::GetCallingPid();
239 remoteObject->AddDeathRecipient(new OHOS::Security::Hks::HksDeathRecipient(callingPid));
240 HKS_LOG_I("Add bundleDead for pid: %" LOG_PUBLIC "d", callingPid);
241 }
242 }
243 return ProcessMessage(code, outSize, srcData, reply);
244 }
245
ProcessRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply)246 static void ProcessRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply)
247 {
248 uint32_t outSize = 0;
249 struct HksBlob srcData = { 0, nullptr };
250 int32_t ret = HKS_ERROR_INVALID_ARGUMENT;
251 do {
252 HKS_IF_NOT_TRUE_LOGE_BREAK(data.ReadUint32(outSize), "Read outSize failed!")
253
254 ret = HksPluginOnLocalRequest(CODE_UPGRADE, NULL, NULL);
255 HKS_IF_NOT_SUCC_BREAK(ret, "Failed to handle local request. ret = %" LOG_PUBLIC "d", ret);
256
257 ret = HKS_ERROR_INVALID_ARGUMENT;
258 HKS_IF_TRUE_LOGE_BREAK(!data.ReadUint32(srcData.size) || IsInvalidLength(srcData.size),
259 "srcData size is invalid, size:%" LOG_PUBLIC "u", srcData.size)
260
261 ret = HKS_ERROR_MALLOC_FAIL;
262 srcData.data = static_cast<uint8_t *>(HksMalloc(srcData.size));
263 HKS_IF_NULL_LOGE_BREAK(srcData.data, "Malloc srcData failed.")
264
265 ret = HKS_ERROR_IPC_MSG_FAIL;
266 const uint8_t *pdata = data.ReadBuffer(static_cast<size_t>(srcData.size));
267 HKS_IF_NULL_BREAK(pdata)
268 (void)memcpy_s(srcData.data, srcData.size, pdata, srcData.size);
269 ret = ProcessAttestOrNormalMessage(code, data, outSize, srcData, reply);
270 } while (0);
271
272 HKS_FREE_BLOB(srcData);
273 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HksSendResponse(reinterpret_cast<const uint8_t *>(&reply), ret, nullptr),
274 "handle ipc msg failed!")
275 }
276
GetTimeoutMonitorMarkTag(uint32_t code,uint32_t callingUid)277 static std::string GetTimeoutMonitorMarkTag(uint32_t code, uint32_t callingUid)
278 {
279 std::string markTag = (std::ostringstream{} << "huks:OnRemoteRequest, code = " << code << ", callingUid = " <<
280 callingUid << ", sessionId = " << g_sessionId).str();
281 return markTag;
282 }
283
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)284 int HksService::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
285 {
286 HksInitMemPolicy();
287
288 uint64_t enterTime = 0;
289 (void)HksElapsedRealTime(&enterTime);
290 g_sessionId++;
291 auto callingUid = IPCSkeleton::GetCallingUid();
292 int userId = HksGetOsAccountIdFromUid(callingUid);
293
294 #ifdef L2_STANDARD
295 HksClearThreadErrorMsg();
296 constexpr unsigned int DEFAULT_TIMEOUT = 5U; // seconds
297 HksXCollie hksXCollie(GetTimeoutMonitorMarkTag(code, callingUid), DEFAULT_TIMEOUT, [](void *)->void {}, nullptr,
298 HiviewDFX::XCOLLIE_FLAG_LOG);
299 #endif
300
301 HKS_LOG_I("code:%" LOG_PUBLIC "u, callingUid = %" LOG_PUBLIC "d, userId = %" LOG_PUBLIC
302 "d, sessionId = %" LOG_PUBLIC "u", code, callingUid, userId, g_sessionId);
303
304 #ifdef HUKS_ENABLE_UPGRADE_KEY_STORAGE_SECURE_LEVEL
305 // judge whether is upgrading, wait for upgrade finished
306 HKS_IF_NOT_SUCC_LOGE_RETURN(HksWaitIfPowerOnUpgrading(), HW_SYSTEM_ERROR, "wait on upgrading failed.")
307 HksUpgradeOrRequestLockRead();
308 #endif
309
310 if (code < HksIpcInterfaceCode::HKS_MSG_BASE || code >= HksIpcInterfaceCode::HKS_MSG_MAX) {
311 int32_t ret = RetryLoadPlugin();
312 if (ret != HKS_SUCCESS) {
313 HksSendResponse(reinterpret_cast<const uint8_t *>(&reply), ret, nullptr);
314 ret = HKS_SUCCESS; // send error code by IPC.
315 } else {
316 ret = HksPluginOnRemoteRequest(code, &data, &reply, &option);
317 }
318 #ifdef HUKS_ENABLE_UPGRADE_KEY_STORAGE_SECURE_LEVEL
319 HksUpgradeOrRequestUnlockRead();
320 #endif
321 return ret;
322 }
323
324 int retSys;
325 // this is the temporary version which comments the descriptor check
326 if (HksService::GetDescriptor() != data.ReadInterfaceToken()) {
327 HKS_LOG_E("descriptor is diff.");
328 retSys = HW_SYSTEM_ERROR;
329 } else {
330 ProcessRemoteRequest(code, data, reply);
331 uint64_t leaveTime = 0;
332 (void)HksElapsedRealTime(&leaveTime);
333 HKS_LOG_I("finish code:%" LOG_PUBLIC "d, total cost %" LOG_PUBLIC PRIu64 " ms, sessionId = %"
334 LOG_PUBLIC "u, finish result:%" LOG_PUBLIC "d",
335 code, leaveTime - enterTime, g_sessionId, reply.ReadInt32());
336 retSys = NO_ERROR;
337 }
338
339 #ifdef HUKS_ENABLE_UPGRADE_KEY_STORAGE_SECURE_LEVEL
340 HksUpgradeOrRequestUnlockRead();
341 #endif
342 return retSys;
343 }
344
345 #define OLD_PATH "/data/service/el2/public/huks_service/maindata"
346 #define NEW_PATH "/data/service/el1/public/huks_service/maindata"
347
348 #ifdef HKS_USE_RKC_IN_STANDARD
349 #define OLD_MINE_PATH "/data/data/huks_service/maindata"
350 #define INTERMEDIATE_MINE_RKC_PATH "/data/service/el1/public/huks_service/maindata/hks_client"
351 #define NEW_MINE_RKC_PATH "/data/data/huks_service/maindata/hks_client"
352
353 #define DEFAULT_PATH_LEN 1024
354 #endif
355
356 #ifdef HKS_USE_RKC_IN_STANDARD
MoveMineOldFile(const char * oldDir,const char * newDir)357 void MoveMineOldFile(const char *oldDir, const char *newDir)
358 {
359 auto dir = opendir(oldDir);
360 HKS_IF_NULL_LOGE_RETURN_VOID(dir, "open old dir failed!")
361 struct dirent *ptr;
362 while ((ptr = readdir(dir)) != NULL) {
363 // move dir expect hks_client, for it is the rkc root key and should be in same position
364 if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0 || strcmp(ptr->d_name, "hks_client") == 0) {
365 continue;
366 }
367 char curPath[DEFAULT_PATH_LEN] = { 0 };
368 HKS_IF_NOT_EOK_BREAK(strcpy_s(curPath, DEFAULT_PATH_LEN, oldDir))
369 HKS_IF_NOT_EOK_BREAK(strcat_s(curPath, DEFAULT_PATH_LEN, "/"))
370 HKS_IF_NOT_EOK_BREAK(strcat_s(curPath, DEFAULT_PATH_LEN, ptr->d_name))
371 char newPath[DEFAULT_PATH_LEN] = { 0 };
372 HKS_IF_NOT_EOK_BREAK(strcpy_s(newPath, DEFAULT_PATH_LEN, newDir))
373 HKS_IF_NOT_EOK_BREAK(strcat_s(newPath, DEFAULT_PATH_LEN, "/"))
374 HKS_IF_NOT_EOK_BREAK(strcat_s(newPath, DEFAULT_PATH_LEN, ptr->d_name))
375 std::error_code errCode{};
376 std::filesystem::create_directory(newDir, errCode);
377 HKS_IF_TRUE_LOGE(errCode.value() != 0, "create_directory newDir failed %" LOG_PUBLIC "s",
378 errCode.message().c_str())
379 std::filesystem::copy(curPath, newPath,
380 std::filesystem::copy_options::recursive | std::filesystem::copy_options::overwrite_existing, errCode);
381 HKS_IF_TRUE_LOGE_BREAK(errCode.value() != 0, "copy curPath to newPath failed %" LOG_PUBLIC "s",
382 errCode.message().c_str())
383 std::filesystem::remove_all(curPath, errCode);
384 HKS_IF_TRUE_LOGE(errCode.value() != 0, "remove_all curPath failed %" LOG_PUBLIC "s", errCode.message().c_str())
385 }
386 closedir(dir);
387 }
388 #endif
389
MoveDirectoryTree(const char * oldDir,const char * newDir)390 void MoveDirectoryTree(const char *oldDir, const char *newDir)
391 {
392 std::error_code errCode{};
393 std::filesystem::create_directory(newDir, errCode);
394 if (errCode.value() != 0) {
395 HKS_LOG_E("create_directory newDir failed %" LOG_PUBLIC "s", errCode.message().c_str());
396 } else {
397 HKS_LOG_I("create_directory newDir ok!");
398 }
399 std::filesystem::copy(oldDir, newDir,
400 std::filesystem::copy_options::recursive | std::filesystem::copy_options::overwrite_existing, errCode);
401 HKS_IF_TRUE_LOGE_RETURN_VOID(errCode.value() != 0, "copy oldDir to newDir failed %" LOG_PUBLIC "s",
402 errCode.message().c_str())
403 HKS_LOG_I("copy oldDir to newDir ok!");
404 std::filesystem::remove_all(oldDir, errCode);
405 HKS_IF_TRUE_LOGE_RETURN_VOID(errCode.value() != 0, "remove_all oldDir failed %" LOG_PUBLIC "s",
406 errCode.message().c_str())
407 HKS_LOG_I("remove_all oldDir ok!");
408 }
409
OnStart()410 void HksService::OnStart()
411 {
412 HKS_LOG_I("HksService OnStart");
413 std::lock_guard<std::mutex> lock(runningStateLock);
414 HKS_IF_TRUE_LOGI_RETURN_VOID(std::atomic_load(&runningState_) == STATE_RUNNING, "HksService has already started")
415 MoveDirectoryTree(OLD_PATH, NEW_PATH);
416 #ifdef HKS_USE_RKC_IN_STANDARD
417 // the intermediate mine's rkc is located in INTERMEDIATE_MINE_RKC_PATH, normal keys is located in NEW_PATH
418 MoveDirectoryTree(INTERMEDIATE_MINE_RKC_PATH, NEW_MINE_RKC_PATH);
419 // the original mine's rkc and normal keys are both located in OLD_MINE_PATH, should move all expect for rkc files
420 MoveMineOldFile(OLD_MINE_PATH, NEW_PATH);
421 #endif
422
423 HKS_IF_NOT_SUCC_LOGE_RETURN_VOID(HksProcessConditionCreate(), "create process condition on init failed.")
424
425 // lock before huks init, for the upgrading will be thread safe.
426 #ifdef HUKS_ENABLE_UPGRADE_KEY_STORAGE_SECURE_LEVEL
427 {
428 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> writeGuard(g_upgradeOrRequestLock);
429 #endif
430
431 HKS_IF_NOT_TRUE_LOGE_RETURN_VOID(Init(), "Failed to init HksService")
432
433 #ifdef SUPPORT_COMMON_EVENT
434 (void)AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
435 #endif
436
437 // this should be excuted after huks published and listener added.
438 HksUpgradeOnPowerOn();
439 #ifdef HUKS_ENABLE_UPGRADE_KEY_STORAGE_SECURE_LEVEL
440 }
441 HksUpgradeOnPowerOnDoneNotifyAll();
442 #endif
443
444 std::atomic_store(&runningState_, STATE_RUNNING);
445 IPCSkeleton::SetMaxWorkThreadNum(HUKS_IPC_THREAD_NUM);
446 HKS_LOG_I("HksService start success.");
447 }
448
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)449 void HksService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
450 {
451 HKS_LOG_I("systemAbilityId is %" LOG_PUBLIC "d!", systemAbilityId);
452 #ifdef SUPPORT_COMMON_EVENT
453 HksSubscribeEvent();
454 #endif
455 }
456
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)457 void HksService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
458 {
459 HKS_LOG_I("systemAbilityId is %" LOG_PUBLIC "d!", systemAbilityId);
460 }
461
OnStop()462 void HksService::OnStop()
463 {
464 HKS_LOG_I("HksService Service OnStop");
465 std::lock_guard<std::mutex> lock(runningStateLock);
466 std::atomic_store(&runningState_, STATE_NOT_START);
467 registerToService_ = false;
468 #ifndef HKS_UNTRUSTED_RUNNING_ENV
469 HksCloseDcmFunction();
470 #endif // HKS_UNTRUSTED_RUNNING_ENV
471 }
472 } // namespace Hks
473 } // namespace Security
474 } // namespace OHOS
475