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