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
30extern "C" {
31#endif
32#endif
33
34using namespace OHOS::SysInstaller;
35using namespace Updater;
36
37#ifdef SUPPORT_HVB
38static 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
52bool 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
91exit:
92    FsHvbDestoryVerityTarget(&target);
93    return ret == 0;
94#else
95    LOG(INFO) << "do not support hvb";
96    return true;
97#endif
98}
99
100bool 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