1 /*
2  * Copyright (c) 2023 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 "module_dm.h"
17 
18 #ifdef SUPPORT_HVB
19 #include "fs_dm.h"
20 #include "fs_hvb.h"
21 #include "hvb_cert.h"
22 #endif
23 
24 #include "directory_ex.h"
25 #include "log/log.h"
26 #include "securec.h"
27 
28 #ifdef __cplusplus
29 #if __cplusplus
30 extern "C" {
31 #endif
32 #endif
33 
34 using namespace OHOS::SysInstaller;
35 using namespace Updater;
36 
37 #ifdef SUPPORT_HVB
CheckVerifiedData(const struct hvb_verified_data * vd)38 static bool CheckVerifiedData(const struct hvb_verified_data *vd)
39 {
40     if (vd == nullptr) {
41         LOG(ERROR) << "verified data is nullptr";
42         return false;
43     }
44     if (vd->num_loaded_certs != 1) {
45         LOG(ERROR) << "invalid cert num " << vd->num_loaded_certs;
46         return false;
47     }
48     return true;
49 }
50 #endif
51 
CreateDmDevice(const OHOS::SysInstaller::ModuleFile & moduleFile,std::string & deviceName)52 bool CreateDmDevice(const OHOS::SysInstaller::ModuleFile &moduleFile, std::string &deviceName)
53 {
54 #ifdef SUPPORT_HVB
55     struct hvb_verified_data *vd = moduleFile.GetVerifiedData();
56     struct hvb_cert cert;
57     DmVerityTarget target;
58     char *devPath = nullptr;
59     std::string devName = OHOS::ExtractFileName(deviceName);
60     enum hvb_errno hr = HVB_OK;
61     int ret = 0;
62 
63     LOG(INFO) << "CreateDmDevice deviceName=" << deviceName;
64     if (!CheckVerifiedData(vd)) {
65         return false;
66     }
67     hr = hvb_cert_parser(&cert, &(vd->certs[0].data));
68     if (hr != HVB_OK) {
69         LOG(ERROR) << "parse cert error " << hr;
70         return false;
71     }
72     ret = FsHvbConstructVerityTarget(&target, deviceName.c_str(), &cert);
73     if (ret != 0) {
74         LOG(ERROR) << "create dm verity target error " << ret;
75         goto exit;
76     }
77     ret = FsDmCreateDevice(&devPath, devName.c_str(), &target);
78     if (ret != 0) {
79         LOG(ERROR) << "create dm verity device error " << ret;
80         goto exit;
81     }
82     ret = FsDmInitDmDev(devPath, true);
83     if (ret != 0) {
84         LOG(ERROR) << "init dm device error " << ret;
85         goto exit;
86     }
87     deviceName = std::string(devPath);
88     LOG(INFO) << "Create dm device success. path=" << deviceName;
89     free(devPath);
90 
91 exit:
92     FsHvbDestoryVerityTarget(&target);
93     return ret == 0;
94 #else
95     LOG(INFO) << "do not support hvb";
96     return true;
97 #endif
98 }
99 
RemoveDmDevice(std::string deviceName)100 bool RemoveDmDevice(std::string deviceName)
101 {
102     int ret = 0;
103 #ifdef SUPPORT_HVB
104     std::string devName = OHOS::ExtractFileName(deviceName);
105     ret = FsDmRemoveDevice(devName.c_str());
106     if (ret != 0) {
107         LOG(ERROR) << "fs rm device error, ret=" << ret;
108     }
109 #endif
110     return (ret == 0);
111 }
112 
113 #ifdef __cplusplus
114 #if __cplusplus
115 }
116 #endif
117 #endif
118