188edb362Sopenharmony_ci/*
288edb362Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
388edb362Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
488edb362Sopenharmony_ci * you may not use this file except in compliance with the License.
588edb362Sopenharmony_ci * You may obtain a copy of the License at
688edb362Sopenharmony_ci *
788edb362Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
888edb362Sopenharmony_ci *
988edb362Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1088edb362Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1188edb362Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1288edb362Sopenharmony_ci * See the License for the specific language governing permissions and
1388edb362Sopenharmony_ci * limitations under the License.
1488edb362Sopenharmony_ci */
1588edb362Sopenharmony_ci
1688edb362Sopenharmony_ci#include "module_dm.h"
1788edb362Sopenharmony_ci
1888edb362Sopenharmony_ci#ifdef SUPPORT_HVB
1988edb362Sopenharmony_ci#include "fs_dm.h"
2088edb362Sopenharmony_ci#include "fs_hvb.h"
2188edb362Sopenharmony_ci#include "hvb_cert.h"
2288edb362Sopenharmony_ci#endif
2388edb362Sopenharmony_ci
2488edb362Sopenharmony_ci#include "directory_ex.h"
2588edb362Sopenharmony_ci#include "log/log.h"
2688edb362Sopenharmony_ci#include "securec.h"
2788edb362Sopenharmony_ci
2888edb362Sopenharmony_ci#ifdef __cplusplus
2988edb362Sopenharmony_ci#if __cplusplus
3088edb362Sopenharmony_ciextern "C" {
3188edb362Sopenharmony_ci#endif
3288edb362Sopenharmony_ci#endif
3388edb362Sopenharmony_ci
3488edb362Sopenharmony_ciusing namespace OHOS::SysInstaller;
3588edb362Sopenharmony_ciusing namespace Updater;
3688edb362Sopenharmony_ci
3788edb362Sopenharmony_ci#ifdef SUPPORT_HVB
3888edb362Sopenharmony_cistatic bool CheckVerifiedData(const struct hvb_verified_data *vd)
3988edb362Sopenharmony_ci{
4088edb362Sopenharmony_ci    if (vd == nullptr) {
4188edb362Sopenharmony_ci        LOG(ERROR) << "verified data is nullptr";
4288edb362Sopenharmony_ci        return false;
4388edb362Sopenharmony_ci    }
4488edb362Sopenharmony_ci    if (vd->num_loaded_certs != 1) {
4588edb362Sopenharmony_ci        LOG(ERROR) << "invalid cert num " << vd->num_loaded_certs;
4688edb362Sopenharmony_ci        return false;
4788edb362Sopenharmony_ci    }
4888edb362Sopenharmony_ci    return true;
4988edb362Sopenharmony_ci}
5088edb362Sopenharmony_ci#endif
5188edb362Sopenharmony_ci
5288edb362Sopenharmony_cibool CreateDmDevice(const OHOS::SysInstaller::ModuleFile &moduleFile, std::string &deviceName)
5388edb362Sopenharmony_ci{
5488edb362Sopenharmony_ci#ifdef SUPPORT_HVB
5588edb362Sopenharmony_ci    struct hvb_verified_data *vd = moduleFile.GetVerifiedData();
5688edb362Sopenharmony_ci    struct hvb_cert cert;
5788edb362Sopenharmony_ci    DmVerityTarget target;
5888edb362Sopenharmony_ci    char *devPath = nullptr;
5988edb362Sopenharmony_ci    std::string devName = OHOS::ExtractFileName(deviceName);
6088edb362Sopenharmony_ci    enum hvb_errno hr = HVB_OK;
6188edb362Sopenharmony_ci    int ret = 0;
6288edb362Sopenharmony_ci
6388edb362Sopenharmony_ci    LOG(INFO) << "CreateDmDevice deviceName=" << deviceName;
6488edb362Sopenharmony_ci    if (!CheckVerifiedData(vd)) {
6588edb362Sopenharmony_ci        return false;
6688edb362Sopenharmony_ci    }
6788edb362Sopenharmony_ci    hr = hvb_cert_parser(&cert, &(vd->certs[0].data));
6888edb362Sopenharmony_ci    if (hr != HVB_OK) {
6988edb362Sopenharmony_ci        LOG(ERROR) << "parse cert error " << hr;
7088edb362Sopenharmony_ci        return false;
7188edb362Sopenharmony_ci    }
7288edb362Sopenharmony_ci    ret = FsHvbConstructVerityTarget(&target, deviceName.c_str(), &cert);
7388edb362Sopenharmony_ci    if (ret != 0) {
7488edb362Sopenharmony_ci        LOG(ERROR) << "create dm verity target error " << ret;
7588edb362Sopenharmony_ci        goto exit;
7688edb362Sopenharmony_ci    }
7788edb362Sopenharmony_ci    ret = FsDmCreateDevice(&devPath, devName.c_str(), &target);
7888edb362Sopenharmony_ci    if (ret != 0) {
7988edb362Sopenharmony_ci        LOG(ERROR) << "create dm verity device error " << ret;
8088edb362Sopenharmony_ci        goto exit;
8188edb362Sopenharmony_ci    }
8288edb362Sopenharmony_ci    ret = FsDmInitDmDev(devPath, true);
8388edb362Sopenharmony_ci    if (ret != 0) {
8488edb362Sopenharmony_ci        LOG(ERROR) << "init dm device error " << ret;
8588edb362Sopenharmony_ci        goto exit;
8688edb362Sopenharmony_ci    }
8788edb362Sopenharmony_ci    deviceName = std::string(devPath);
8888edb362Sopenharmony_ci    LOG(INFO) << "Create dm device success. path=" << deviceName;
8988edb362Sopenharmony_ci    free(devPath);
9088edb362Sopenharmony_ci
9188edb362Sopenharmony_ciexit:
9288edb362Sopenharmony_ci    FsHvbDestoryVerityTarget(&target);
9388edb362Sopenharmony_ci    return ret == 0;
9488edb362Sopenharmony_ci#else
9588edb362Sopenharmony_ci    LOG(INFO) << "do not support hvb";
9688edb362Sopenharmony_ci    return true;
9788edb362Sopenharmony_ci#endif
9888edb362Sopenharmony_ci}
9988edb362Sopenharmony_ci
10088edb362Sopenharmony_cibool RemoveDmDevice(std::string deviceName)
10188edb362Sopenharmony_ci{
10288edb362Sopenharmony_ci    int ret = 0;
10388edb362Sopenharmony_ci#ifdef SUPPORT_HVB
10488edb362Sopenharmony_ci    std::string devName = OHOS::ExtractFileName(deviceName);
10588edb362Sopenharmony_ci    ret = FsDmRemoveDevice(devName.c_str());
10688edb362Sopenharmony_ci    if (ret != 0) {
10788edb362Sopenharmony_ci        LOG(ERROR) << "fs rm device error, ret=" << ret;
10888edb362Sopenharmony_ci    }
10988edb362Sopenharmony_ci#endif
11088edb362Sopenharmony_ci    return (ret == 0);
11188edb362Sopenharmony_ci}
11288edb362Sopenharmony_ci
11388edb362Sopenharmony_ci#ifdef __cplusplus
11488edb362Sopenharmony_ci#if __cplusplus
11588edb362Sopenharmony_ci}
11688edb362Sopenharmony_ci#endif
11788edb362Sopenharmony_ci#endif
118