• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "libdm/dm_target.h"
18 
19 #include <android-base/logging.h>
20 #include <android-base/macros.h>
21 #include <android-base/strings.h>
22 
23 #include <libdm/dm.h>
24 
25 namespace android {
26 namespace dm {
27 
Serialize() const28 std::string DmTarget::Serialize() const {
29     // Create a string containing a dm_target_spec, parameter data, and an
30     // explicit null terminator.
31     std::string data(sizeof(dm_target_spec), '\0');
32     data += GetParameterString();
33     data.push_back('\0');
34 
35     // The kernel expects each target to be 8-byte aligned.
36     size_t padding = DM_ALIGN(data.size()) - data.size();
37     for (size_t i = 0; i < padding; i++) {
38         data.push_back('\0');
39     }
40 
41     // Finally fill in the dm_target_spec.
42     struct dm_target_spec* spec = reinterpret_cast<struct dm_target_spec*>(&data[0]);
43     spec->sector_start = start();
44     spec->length = size();
45     snprintf(spec->target_type, sizeof(spec->target_type), "%s", name().c_str());
46     spec->next = (uint32_t)data.size();
47     return data;
48 }
49 
GetParameterString() const50 std::string DmTargetZero::GetParameterString() const {
51     // The zero target type has no additional parameters.
52     return "";
53 }
54 
GetParameterString() const55 std::string DmTargetLinear::GetParameterString() const {
56     return block_device_ + " " + std::to_string(physical_sector_);
57 }
58 
DmTargetVerity(uint64_t start,uint64_t length,uint32_t version,const std::string & block_device,const std::string & hash_device,uint32_t data_block_size,uint32_t hash_block_size,uint32_t num_data_blocks,uint32_t hash_start_block,const std::string & hash_algorithm,const std::string & root_digest,const std::string & salt)59 DmTargetVerity::DmTargetVerity(uint64_t start, uint64_t length, uint32_t version,
60                                const std::string& block_device, const std::string& hash_device,
61                                uint32_t data_block_size, uint32_t hash_block_size,
62                                uint32_t num_data_blocks, uint32_t hash_start_block,
63                                const std::string& hash_algorithm, const std::string& root_digest,
64                                const std::string& salt)
65     : DmTarget(start, length), valid_(true) {
66     base_args_ = {
67             std::to_string(version),
68             block_device,
69             hash_device,
70             std::to_string(data_block_size),
71             std::to_string(hash_block_size),
72             std::to_string(num_data_blocks),
73             std::to_string(hash_start_block),
74             hash_algorithm,
75             root_digest,
76             salt,
77     };
78 }
79 
UseFec(const std::string & device,uint32_t num_roots,uint32_t num_blocks,uint32_t start)80 void DmTargetVerity::UseFec(const std::string& device, uint32_t num_roots, uint32_t num_blocks,
81                             uint32_t start) {
82     optional_args_.emplace_back("use_fec_from_device");
83     optional_args_.emplace_back(device);
84     optional_args_.emplace_back("fec_roots");
85     optional_args_.emplace_back(std::to_string(num_roots));
86     optional_args_.emplace_back("fec_blocks");
87     optional_args_.emplace_back(std::to_string(num_blocks));
88     optional_args_.emplace_back("fec_start");
89     optional_args_.emplace_back(std::to_string(start));
90 }
91 
SetVerityMode(const std::string & mode)92 void DmTargetVerity::SetVerityMode(const std::string& mode) {
93     if (mode != "restart_on_corruption" && mode != "ignore_corruption") {
94         LOG(ERROR) << "Unknown verity mode: " << mode;
95         valid_ = false;
96         return;
97     }
98     optional_args_.emplace_back(mode);
99 }
100 
IgnoreZeroBlocks()101 void DmTargetVerity::IgnoreZeroBlocks() {
102     optional_args_.emplace_back("ignore_zero_blocks");
103 }
104 
GetParameterString() const105 std::string DmTargetVerity::GetParameterString() const {
106     std::string base = android::base::Join(base_args_, " ");
107     if (optional_args_.empty()) {
108         return base;
109     }
110     std::string optional = android::base::Join(optional_args_, " ");
111     return base + " " + std::to_string(optional_args_.size()) + " " + optional;
112 }
113 
GetParameterString() const114 std::string DmTargetAndroidVerity::GetParameterString() const {
115     return keyid_ + " " + block_device_;
116 }
117 
118 }  // namespace dm
119 }  // namespace android
120