1*d289c2baSAndroid Build Coastguard Worker /*
2*d289c2baSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*d289c2baSAndroid Build Coastguard Worker *
4*d289c2baSAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person
5*d289c2baSAndroid Build Coastguard Worker * obtaining a copy of this software and associated documentation
6*d289c2baSAndroid Build Coastguard Worker * files (the "Software"), to deal in the Software without
7*d289c2baSAndroid Build Coastguard Worker * restriction, including without limitation the rights to use, copy,
8*d289c2baSAndroid Build Coastguard Worker * modify, merge, publish, distribute, sublicense, and/or sell copies
9*d289c2baSAndroid Build Coastguard Worker * of the Software, and to permit persons to whom the Software is
10*d289c2baSAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
11*d289c2baSAndroid Build Coastguard Worker *
12*d289c2baSAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be
13*d289c2baSAndroid Build Coastguard Worker * included in all copies or substantial portions of the Software.
14*d289c2baSAndroid Build Coastguard Worker *
15*d289c2baSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*d289c2baSAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*d289c2baSAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*d289c2baSAndroid Build Coastguard Worker * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19*d289c2baSAndroid Build Coastguard Worker * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20*d289c2baSAndroid Build Coastguard Worker * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21*d289c2baSAndroid Build Coastguard Worker * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*d289c2baSAndroid Build Coastguard Worker * SOFTWARE.
23*d289c2baSAndroid Build Coastguard Worker */
24*d289c2baSAndroid Build Coastguard Worker
25*d289c2baSAndroid Build Coastguard Worker #include "fake_avb_ops.h"
26*d289c2baSAndroid Build Coastguard Worker
27*d289c2baSAndroid Build Coastguard Worker #include <base/files/file_util.h>
28*d289c2baSAndroid Build Coastguard Worker #include <base/strings/string_util.h>
29*d289c2baSAndroid Build Coastguard Worker #include <endian.h>
30*d289c2baSAndroid Build Coastguard Worker #include <errno.h>
31*d289c2baSAndroid Build Coastguard Worker #include <fcntl.h>
32*d289c2baSAndroid Build Coastguard Worker #include <inttypes.h>
33*d289c2baSAndroid Build Coastguard Worker #include <openssl/rand.h>
34*d289c2baSAndroid Build Coastguard Worker #include <openssl/sha.h>
35*d289c2baSAndroid Build Coastguard Worker #include <string.h>
36*d289c2baSAndroid Build Coastguard Worker #include <sys/stat.h>
37*d289c2baSAndroid Build Coastguard Worker #include <sys/types.h>
38*d289c2baSAndroid Build Coastguard Worker #include <unistd.h>
39*d289c2baSAndroid Build Coastguard Worker
40*d289c2baSAndroid Build Coastguard Worker #include <filesystem>
41*d289c2baSAndroid Build Coastguard Worker #include <iostream>
42*d289c2baSAndroid Build Coastguard Worker
43*d289c2baSAndroid Build Coastguard Worker namespace avb {
44*d289c2baSAndroid Build Coastguard Worker
get_partition_names_read_from()45*d289c2baSAndroid Build Coastguard Worker std::set<std::string> FakeAvbOps::get_partition_names_read_from() {
46*d289c2baSAndroid Build Coastguard Worker return partition_names_read_from_;
47*d289c2baSAndroid Build Coastguard Worker }
48*d289c2baSAndroid Build Coastguard Worker
preload_partition(const std::string & partition,const base::FilePath & path)49*d289c2baSAndroid Build Coastguard Worker bool FakeAvbOps::preload_partition(const std::string& partition,
50*d289c2baSAndroid Build Coastguard Worker const base::FilePath& path) {
51*d289c2baSAndroid Build Coastguard Worker if (preloaded_partitions_.count(partition) > 0) {
52*d289c2baSAndroid Build Coastguard Worker fprintf(stderr, "Partition '%s' already preloaded\n", partition.c_str());
53*d289c2baSAndroid Build Coastguard Worker return false;
54*d289c2baSAndroid Build Coastguard Worker }
55*d289c2baSAndroid Build Coastguard Worker
56*d289c2baSAndroid Build Coastguard Worker int64_t file_size;
57*d289c2baSAndroid Build Coastguard Worker if (!base::GetFileSize(path, &file_size)) {
58*d289c2baSAndroid Build Coastguard Worker fprintf(stderr, "Error getting size of file '%s'\n", path.value().c_str());
59*d289c2baSAndroid Build Coastguard Worker return false;
60*d289c2baSAndroid Build Coastguard Worker }
61*d289c2baSAndroid Build Coastguard Worker
62*d289c2baSAndroid Build Coastguard Worker int fd = open(path.value().c_str(), O_RDONLY);
63*d289c2baSAndroid Build Coastguard Worker if (fd < 0) {
64*d289c2baSAndroid Build Coastguard Worker fprintf(stderr,
65*d289c2baSAndroid Build Coastguard Worker "Error opening file '%s': %s\n",
66*d289c2baSAndroid Build Coastguard Worker path.value().c_str(),
67*d289c2baSAndroid Build Coastguard Worker strerror(errno));
68*d289c2baSAndroid Build Coastguard Worker return false;
69*d289c2baSAndroid Build Coastguard Worker }
70*d289c2baSAndroid Build Coastguard Worker
71*d289c2baSAndroid Build Coastguard Worker uint8_t* buffer = static_cast<uint8_t*>(malloc(file_size));
72*d289c2baSAndroid Build Coastguard Worker ssize_t num_read = read(fd, buffer, file_size);
73*d289c2baSAndroid Build Coastguard Worker if (num_read != file_size) {
74*d289c2baSAndroid Build Coastguard Worker fprintf(stderr,
75*d289c2baSAndroid Build Coastguard Worker "Error reading %zd bytes from file '%s': %s\n",
76*d289c2baSAndroid Build Coastguard Worker file_size,
77*d289c2baSAndroid Build Coastguard Worker path.value().c_str(),
78*d289c2baSAndroid Build Coastguard Worker strerror(errno));
79*d289c2baSAndroid Build Coastguard Worker free(buffer);
80*d289c2baSAndroid Build Coastguard Worker return false;
81*d289c2baSAndroid Build Coastguard Worker }
82*d289c2baSAndroid Build Coastguard Worker close(fd);
83*d289c2baSAndroid Build Coastguard Worker
84*d289c2baSAndroid Build Coastguard Worker preloaded_partitions_[partition] = buffer;
85*d289c2baSAndroid Build Coastguard Worker return true;
86*d289c2baSAndroid Build Coastguard Worker }
87*d289c2baSAndroid Build Coastguard Worker
preload_preallocated_partition(const std::string & partition,uint8_t * buffer,size_t size)88*d289c2baSAndroid Build Coastguard Worker bool FakeAvbOps::preload_preallocated_partition(const std::string& partition,
89*d289c2baSAndroid Build Coastguard Worker uint8_t* buffer,
90*d289c2baSAndroid Build Coastguard Worker size_t size) {
91*d289c2baSAndroid Build Coastguard Worker if (preallocated_preloaded_partitions_.count(partition) > 0) {
92*d289c2baSAndroid Build Coastguard Worker fprintf(stderr, "Partition '%s' already preloaded\n", partition.c_str());
93*d289c2baSAndroid Build Coastguard Worker return false;
94*d289c2baSAndroid Build Coastguard Worker }
95*d289c2baSAndroid Build Coastguard Worker
96*d289c2baSAndroid Build Coastguard Worker preallocated_preloaded_partitions_[partition] = std::make_pair(buffer, size);
97*d289c2baSAndroid Build Coastguard Worker return true;
98*d289c2baSAndroid Build Coastguard Worker }
99*d289c2baSAndroid Build Coastguard Worker
read_from_partition(const char * partition,int64_t offset,size_t num_bytes,void * buffer,size_t * out_num_read)100*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::read_from_partition(const char* partition,
101*d289c2baSAndroid Build Coastguard Worker int64_t offset,
102*d289c2baSAndroid Build Coastguard Worker size_t num_bytes,
103*d289c2baSAndroid Build Coastguard Worker void* buffer,
104*d289c2baSAndroid Build Coastguard Worker size_t* out_num_read) {
105*d289c2baSAndroid Build Coastguard Worker if (hidden_partitions_.find(partition) != hidden_partitions_.end()) {
106*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
107*d289c2baSAndroid Build Coastguard Worker }
108*d289c2baSAndroid Build Coastguard Worker
109*d289c2baSAndroid Build Coastguard Worker std::filesystem::path path =
110*d289c2baSAndroid Build Coastguard Worker (partition_dir_ / partition).replace_extension("img");
111*d289c2baSAndroid Build Coastguard Worker
112*d289c2baSAndroid Build Coastguard Worker partition_names_read_from_.insert(partition);
113*d289c2baSAndroid Build Coastguard Worker
114*d289c2baSAndroid Build Coastguard Worker if (offset < 0) {
115*d289c2baSAndroid Build Coastguard Worker int64_t file_size;
116*d289c2baSAndroid Build Coastguard Worker if (!base::GetFileSize(base::FilePath(path.c_str()), &file_size)) {
117*d289c2baSAndroid Build Coastguard Worker fprintf(stderr, "Error getting size of file '%s'\n", path.c_str());
118*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
119*d289c2baSAndroid Build Coastguard Worker }
120*d289c2baSAndroid Build Coastguard Worker offset = file_size - (-offset);
121*d289c2baSAndroid Build Coastguard Worker }
122*d289c2baSAndroid Build Coastguard Worker
123*d289c2baSAndroid Build Coastguard Worker int fd = open(path.c_str(), O_RDONLY);
124*d289c2baSAndroid Build Coastguard Worker if (fd < 0) {
125*d289c2baSAndroid Build Coastguard Worker fprintf(
126*d289c2baSAndroid Build Coastguard Worker stderr, "Error opening file '%s': %s\n", path.c_str(), strerror(errno));
127*d289c2baSAndroid Build Coastguard Worker if (errno == ENOENT) {
128*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
129*d289c2baSAndroid Build Coastguard Worker } else {
130*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
131*d289c2baSAndroid Build Coastguard Worker }
132*d289c2baSAndroid Build Coastguard Worker }
133*d289c2baSAndroid Build Coastguard Worker if (lseek(fd, offset, SEEK_SET) != offset) {
134*d289c2baSAndroid Build Coastguard Worker fprintf(stderr,
135*d289c2baSAndroid Build Coastguard Worker "Error seeking to pos %zd in file %s: %s\n",
136*d289c2baSAndroid Build Coastguard Worker offset,
137*d289c2baSAndroid Build Coastguard Worker path.c_str(),
138*d289c2baSAndroid Build Coastguard Worker strerror(errno));
139*d289c2baSAndroid Build Coastguard Worker close(fd);
140*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
141*d289c2baSAndroid Build Coastguard Worker }
142*d289c2baSAndroid Build Coastguard Worker ssize_t num_read = read(fd, buffer, num_bytes);
143*d289c2baSAndroid Build Coastguard Worker if (num_read < 0) {
144*d289c2baSAndroid Build Coastguard Worker fprintf(stderr,
145*d289c2baSAndroid Build Coastguard Worker "Error reading %zd bytes from pos %" PRId64 " in file %s: %s\n",
146*d289c2baSAndroid Build Coastguard Worker num_bytes,
147*d289c2baSAndroid Build Coastguard Worker offset,
148*d289c2baSAndroid Build Coastguard Worker path.c_str(),
149*d289c2baSAndroid Build Coastguard Worker strerror(errno));
150*d289c2baSAndroid Build Coastguard Worker close(fd);
151*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
152*d289c2baSAndroid Build Coastguard Worker }
153*d289c2baSAndroid Build Coastguard Worker close(fd);
154*d289c2baSAndroid Build Coastguard Worker
155*d289c2baSAndroid Build Coastguard Worker if (out_num_read != NULL) {
156*d289c2baSAndroid Build Coastguard Worker *out_num_read = num_read;
157*d289c2baSAndroid Build Coastguard Worker }
158*d289c2baSAndroid Build Coastguard Worker
159*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
160*d289c2baSAndroid Build Coastguard Worker }
161*d289c2baSAndroid Build Coastguard Worker
get_preloaded_partition(const char * partition,size_t num_bytes,uint8_t ** out_pointer,size_t * out_num_bytes_preloaded)162*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::get_preloaded_partition(
163*d289c2baSAndroid Build Coastguard Worker const char* partition,
164*d289c2baSAndroid Build Coastguard Worker size_t num_bytes,
165*d289c2baSAndroid Build Coastguard Worker uint8_t** out_pointer,
166*d289c2baSAndroid Build Coastguard Worker size_t* out_num_bytes_preloaded) {
167*d289c2baSAndroid Build Coastguard Worker if (hidden_partitions_.find(partition) != hidden_partitions_.end()) {
168*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
169*d289c2baSAndroid Build Coastguard Worker }
170*d289c2baSAndroid Build Coastguard Worker
171*d289c2baSAndroid Build Coastguard Worker std::map<std::string, std::pair<uint8_t*, size_t>>::iterator prealloc_it =
172*d289c2baSAndroid Build Coastguard Worker preallocated_preloaded_partitions_.find(std::string(partition));
173*d289c2baSAndroid Build Coastguard Worker if (prealloc_it != preallocated_preloaded_partitions_.end()) {
174*d289c2baSAndroid Build Coastguard Worker *out_pointer = prealloc_it->second.first;
175*d289c2baSAndroid Build Coastguard Worker *out_num_bytes_preloaded = std::min(prealloc_it->second.second, num_bytes);
176*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
177*d289c2baSAndroid Build Coastguard Worker }
178*d289c2baSAndroid Build Coastguard Worker
179*d289c2baSAndroid Build Coastguard Worker std::map<std::string, uint8_t*>::iterator it =
180*d289c2baSAndroid Build Coastguard Worker preloaded_partitions_.find(std::string(partition));
181*d289c2baSAndroid Build Coastguard Worker if (it == preloaded_partitions_.end()) {
182*d289c2baSAndroid Build Coastguard Worker *out_pointer = NULL;
183*d289c2baSAndroid Build Coastguard Worker *out_num_bytes_preloaded = 0;
184*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
185*d289c2baSAndroid Build Coastguard Worker }
186*d289c2baSAndroid Build Coastguard Worker
187*d289c2baSAndroid Build Coastguard Worker uint64_t size;
188*d289c2baSAndroid Build Coastguard Worker AvbIOResult result = get_size_of_partition(avb_ops(), partition, &size);
189*d289c2baSAndroid Build Coastguard Worker if (result != AVB_IO_RESULT_OK) {
190*d289c2baSAndroid Build Coastguard Worker return result;
191*d289c2baSAndroid Build Coastguard Worker }
192*d289c2baSAndroid Build Coastguard Worker
193*d289c2baSAndroid Build Coastguard Worker *out_num_bytes_preloaded = std::min(static_cast<size_t>(size), num_bytes);
194*d289c2baSAndroid Build Coastguard Worker *out_pointer = it->second;
195*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
196*d289c2baSAndroid Build Coastguard Worker }
197*d289c2baSAndroid Build Coastguard Worker
write_to_partition(const char * partition,int64_t offset,size_t num_bytes,const void * buffer)198*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::write_to_partition(const char* partition,
199*d289c2baSAndroid Build Coastguard Worker int64_t offset,
200*d289c2baSAndroid Build Coastguard Worker size_t num_bytes,
201*d289c2baSAndroid Build Coastguard Worker const void* buffer) {
202*d289c2baSAndroid Build Coastguard Worker if (hidden_partitions_.find(partition) != hidden_partitions_.end()) {
203*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
204*d289c2baSAndroid Build Coastguard Worker }
205*d289c2baSAndroid Build Coastguard Worker
206*d289c2baSAndroid Build Coastguard Worker std::filesystem::path path =
207*d289c2baSAndroid Build Coastguard Worker (partition_dir_ / partition).replace_extension("img");
208*d289c2baSAndroid Build Coastguard Worker
209*d289c2baSAndroid Build Coastguard Worker if (offset < 0) {
210*d289c2baSAndroid Build Coastguard Worker int64_t file_size;
211*d289c2baSAndroid Build Coastguard Worker if (!base::GetFileSize(base::FilePath(path.c_str()), &file_size)) {
212*d289c2baSAndroid Build Coastguard Worker fprintf(stderr, "Error getting size of file '%s'\n", path.c_str());
213*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
214*d289c2baSAndroid Build Coastguard Worker }
215*d289c2baSAndroid Build Coastguard Worker offset = file_size - (-offset);
216*d289c2baSAndroid Build Coastguard Worker }
217*d289c2baSAndroid Build Coastguard Worker
218*d289c2baSAndroid Build Coastguard Worker int fd = open(path.c_str(), O_WRONLY);
219*d289c2baSAndroid Build Coastguard Worker if (fd < 0) {
220*d289c2baSAndroid Build Coastguard Worker fprintf(
221*d289c2baSAndroid Build Coastguard Worker stderr, "Error opening file '%s': %s\n", path.c_str(), strerror(errno));
222*d289c2baSAndroid Build Coastguard Worker if (errno == ENOENT) {
223*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
224*d289c2baSAndroid Build Coastguard Worker } else {
225*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
226*d289c2baSAndroid Build Coastguard Worker }
227*d289c2baSAndroid Build Coastguard Worker }
228*d289c2baSAndroid Build Coastguard Worker if (lseek(fd, offset, SEEK_SET) != offset) {
229*d289c2baSAndroid Build Coastguard Worker fprintf(stderr,
230*d289c2baSAndroid Build Coastguard Worker "Error seeking to pos %zd in file %s: %s\n",
231*d289c2baSAndroid Build Coastguard Worker offset,
232*d289c2baSAndroid Build Coastguard Worker path.c_str(),
233*d289c2baSAndroid Build Coastguard Worker strerror(errno));
234*d289c2baSAndroid Build Coastguard Worker close(fd);
235*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
236*d289c2baSAndroid Build Coastguard Worker }
237*d289c2baSAndroid Build Coastguard Worker ssize_t num_written = write(fd, buffer, num_bytes);
238*d289c2baSAndroid Build Coastguard Worker if (num_written < 0) {
239*d289c2baSAndroid Build Coastguard Worker fprintf(stderr,
240*d289c2baSAndroid Build Coastguard Worker "Error writing %zd bytes at pos %" PRId64 " in file %s: %s\n",
241*d289c2baSAndroid Build Coastguard Worker num_bytes,
242*d289c2baSAndroid Build Coastguard Worker offset,
243*d289c2baSAndroid Build Coastguard Worker path.c_str(),
244*d289c2baSAndroid Build Coastguard Worker strerror(errno));
245*d289c2baSAndroid Build Coastguard Worker close(fd);
246*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
247*d289c2baSAndroid Build Coastguard Worker }
248*d289c2baSAndroid Build Coastguard Worker close(fd);
249*d289c2baSAndroid Build Coastguard Worker
250*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
251*d289c2baSAndroid Build Coastguard Worker }
252*d289c2baSAndroid Build Coastguard Worker
validate_vbmeta_public_key(AvbOps * ops,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_key_is_trusted)253*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::validate_vbmeta_public_key(
254*d289c2baSAndroid Build Coastguard Worker AvbOps* ops,
255*d289c2baSAndroid Build Coastguard Worker const uint8_t* public_key_data,
256*d289c2baSAndroid Build Coastguard Worker size_t public_key_length,
257*d289c2baSAndroid Build Coastguard Worker const uint8_t* public_key_metadata,
258*d289c2baSAndroid Build Coastguard Worker size_t public_key_metadata_length,
259*d289c2baSAndroid Build Coastguard Worker bool* out_key_is_trusted) {
260*d289c2baSAndroid Build Coastguard Worker if (out_key_is_trusted != NULL) {
261*d289c2baSAndroid Build Coastguard Worker bool pk_matches = (public_key_length == expected_public_key_.size() &&
262*d289c2baSAndroid Build Coastguard Worker (memcmp(expected_public_key_.c_str(),
263*d289c2baSAndroid Build Coastguard Worker public_key_data,
264*d289c2baSAndroid Build Coastguard Worker public_key_length) == 0));
265*d289c2baSAndroid Build Coastguard Worker bool pkmd_matches =
266*d289c2baSAndroid Build Coastguard Worker (public_key_metadata_length == expected_public_key_metadata_.size() &&
267*d289c2baSAndroid Build Coastguard Worker (memcmp(expected_public_key_metadata_.c_str(),
268*d289c2baSAndroid Build Coastguard Worker public_key_metadata,
269*d289c2baSAndroid Build Coastguard Worker public_key_metadata_length) == 0));
270*d289c2baSAndroid Build Coastguard Worker *out_key_is_trusted = pk_matches && pkmd_matches;
271*d289c2baSAndroid Build Coastguard Worker }
272*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
273*d289c2baSAndroid Build Coastguard Worker }
274*d289c2baSAndroid Build Coastguard Worker
validate_public_key_for_partition(AvbOps * ops,const char * partition,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_key_is_trusted,uint32_t * out_rollback_index_location)275*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::validate_public_key_for_partition(
276*d289c2baSAndroid Build Coastguard Worker AvbOps* ops,
277*d289c2baSAndroid Build Coastguard Worker const char* partition,
278*d289c2baSAndroid Build Coastguard Worker const uint8_t* public_key_data,
279*d289c2baSAndroid Build Coastguard Worker size_t public_key_length,
280*d289c2baSAndroid Build Coastguard Worker const uint8_t* public_key_metadata,
281*d289c2baSAndroid Build Coastguard Worker size_t public_key_metadata_length,
282*d289c2baSAndroid Build Coastguard Worker bool* out_key_is_trusted,
283*d289c2baSAndroid Build Coastguard Worker uint32_t* out_rollback_index_location) {
284*d289c2baSAndroid Build Coastguard Worker std::string expected_public_key =
285*d289c2baSAndroid Build Coastguard Worker expected_public_key_for_partition_map_[partition];
286*d289c2baSAndroid Build Coastguard Worker uint32_t rollback_index_location =
287*d289c2baSAndroid Build Coastguard Worker rollback_index_location_for_partition_map_[partition];
288*d289c2baSAndroid Build Coastguard Worker if (out_key_is_trusted != NULL) {
289*d289c2baSAndroid Build Coastguard Worker bool pk_matches = (public_key_length == expected_public_key.size() &&
290*d289c2baSAndroid Build Coastguard Worker (memcmp(expected_public_key.c_str(),
291*d289c2baSAndroid Build Coastguard Worker public_key_data,
292*d289c2baSAndroid Build Coastguard Worker public_key_length) == 0));
293*d289c2baSAndroid Build Coastguard Worker *out_key_is_trusted = pk_matches;
294*d289c2baSAndroid Build Coastguard Worker *out_rollback_index_location = rollback_index_location;
295*d289c2baSAndroid Build Coastguard Worker }
296*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
297*d289c2baSAndroid Build Coastguard Worker }
298*d289c2baSAndroid Build Coastguard Worker
read_rollback_index(AvbOps * ops,size_t rollback_index_location,uint64_t * out_rollback_index)299*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::read_rollback_index(AvbOps* ops,
300*d289c2baSAndroid Build Coastguard Worker size_t rollback_index_location,
301*d289c2baSAndroid Build Coastguard Worker uint64_t* out_rollback_index) {
302*d289c2baSAndroid Build Coastguard Worker if (stored_rollback_indexes_.count(rollback_index_location) == 0) {
303*d289c2baSAndroid Build Coastguard Worker fprintf(stderr,
304*d289c2baSAndroid Build Coastguard Worker "No rollback index for location %zd (has %zd locations).\n",
305*d289c2baSAndroid Build Coastguard Worker rollback_index_location,
306*d289c2baSAndroid Build Coastguard Worker stored_rollback_indexes_.size());
307*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
308*d289c2baSAndroid Build Coastguard Worker }
309*d289c2baSAndroid Build Coastguard Worker *out_rollback_index = stored_rollback_indexes_[rollback_index_location];
310*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
311*d289c2baSAndroid Build Coastguard Worker }
312*d289c2baSAndroid Build Coastguard Worker
write_rollback_index(AvbOps * ops,size_t rollback_index_location,uint64_t rollback_index)313*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::write_rollback_index(AvbOps* ops,
314*d289c2baSAndroid Build Coastguard Worker size_t rollback_index_location,
315*d289c2baSAndroid Build Coastguard Worker uint64_t rollback_index) {
316*d289c2baSAndroid Build Coastguard Worker if (stored_rollback_indexes_.count(rollback_index_location) == 0) {
317*d289c2baSAndroid Build Coastguard Worker fprintf(stderr,
318*d289c2baSAndroid Build Coastguard Worker "No rollback index for location %zd (has %zd locations).\n",
319*d289c2baSAndroid Build Coastguard Worker rollback_index_location,
320*d289c2baSAndroid Build Coastguard Worker stored_rollback_indexes_.size());
321*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
322*d289c2baSAndroid Build Coastguard Worker }
323*d289c2baSAndroid Build Coastguard Worker stored_rollback_indexes_[rollback_index_location] = rollback_index;
324*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
325*d289c2baSAndroid Build Coastguard Worker }
326*d289c2baSAndroid Build Coastguard Worker
read_is_device_unlocked(AvbOps * ops,bool * out_is_device_unlocked)327*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::read_is_device_unlocked(AvbOps* ops,
328*d289c2baSAndroid Build Coastguard Worker bool* out_is_device_unlocked) {
329*d289c2baSAndroid Build Coastguard Worker *out_is_device_unlocked = stored_is_device_unlocked_ ? 1 : 0;
330*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
331*d289c2baSAndroid Build Coastguard Worker }
332*d289c2baSAndroid Build Coastguard Worker
get_unique_guid_for_partition(AvbOps * ops,const char * partition,char * guid_buf,size_t guid_buf_size)333*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::get_unique_guid_for_partition(AvbOps* ops,
334*d289c2baSAndroid Build Coastguard Worker const char* partition,
335*d289c2baSAndroid Build Coastguard Worker char* guid_buf,
336*d289c2baSAndroid Build Coastguard Worker size_t guid_buf_size) {
337*d289c2baSAndroid Build Coastguard Worker if (hidden_partitions_.find(partition) != hidden_partitions_.end()) {
338*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
339*d289c2baSAndroid Build Coastguard Worker }
340*d289c2baSAndroid Build Coastguard Worker // This is faking it a bit but makes testing easy. It works
341*d289c2baSAndroid Build Coastguard Worker // because avb_slot_verify.c doesn't check that the returned GUID
342*d289c2baSAndroid Build Coastguard Worker // is wellformed.
343*d289c2baSAndroid Build Coastguard Worker snprintf(guid_buf, guid_buf_size, "1234-fake-guid-for:%s", partition);
344*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
345*d289c2baSAndroid Build Coastguard Worker }
346*d289c2baSAndroid Build Coastguard Worker
get_size_of_partition(AvbOps * ops,const char * partition,uint64_t * out_size)347*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::get_size_of_partition(AvbOps* ops,
348*d289c2baSAndroid Build Coastguard Worker const char* partition,
349*d289c2baSAndroid Build Coastguard Worker uint64_t* out_size) {
350*d289c2baSAndroid Build Coastguard Worker if (hidden_partitions_.find(partition) != hidden_partitions_.end()) {
351*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
352*d289c2baSAndroid Build Coastguard Worker }
353*d289c2baSAndroid Build Coastguard Worker
354*d289c2baSAndroid Build Coastguard Worker std::filesystem::path path =
355*d289c2baSAndroid Build Coastguard Worker (partition_dir_ / partition).replace_extension("img");
356*d289c2baSAndroid Build Coastguard Worker
357*d289c2baSAndroid Build Coastguard Worker int64_t file_size;
358*d289c2baSAndroid Build Coastguard Worker if (!base::GetFileSize(base::FilePath(path.c_str()), &file_size)) {
359*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
360*d289c2baSAndroid Build Coastguard Worker }
361*d289c2baSAndroid Build Coastguard Worker *out_size = file_size;
362*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
363*d289c2baSAndroid Build Coastguard Worker }
364*d289c2baSAndroid Build Coastguard Worker
read_persistent_value(const char * name,size_t buffer_size,uint8_t * out_buffer,size_t * out_num_bytes_read)365*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::read_persistent_value(const char* name,
366*d289c2baSAndroid Build Coastguard Worker size_t buffer_size,
367*d289c2baSAndroid Build Coastguard Worker uint8_t* out_buffer,
368*d289c2baSAndroid Build Coastguard Worker size_t* out_num_bytes_read) {
369*d289c2baSAndroid Build Coastguard Worker if (out_buffer == NULL && buffer_size > 0) {
370*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE;
371*d289c2baSAndroid Build Coastguard Worker }
372*d289c2baSAndroid Build Coastguard Worker if (stored_values_.count(name) == 0) {
373*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
374*d289c2baSAndroid Build Coastguard Worker }
375*d289c2baSAndroid Build Coastguard Worker if (stored_values_[name].size() > buffer_size) {
376*d289c2baSAndroid Build Coastguard Worker *out_num_bytes_read = stored_values_[name].size();
377*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
378*d289c2baSAndroid Build Coastguard Worker }
379*d289c2baSAndroid Build Coastguard Worker memcpy(out_buffer, stored_values_[name].data(), stored_values_[name].size());
380*d289c2baSAndroid Build Coastguard Worker *out_num_bytes_read = stored_values_[name].size();
381*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
382*d289c2baSAndroid Build Coastguard Worker }
383*d289c2baSAndroid Build Coastguard Worker
write_persistent_value(const char * name,size_t value_size,const uint8_t * value)384*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::write_persistent_value(const char* name,
385*d289c2baSAndroid Build Coastguard Worker size_t value_size,
386*d289c2baSAndroid Build Coastguard Worker const uint8_t* value) {
387*d289c2baSAndroid Build Coastguard Worker stored_values_[name] =
388*d289c2baSAndroid Build Coastguard Worker std::string(reinterpret_cast<const char*>(value), value_size);
389*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
390*d289c2baSAndroid Build Coastguard Worker }
391*d289c2baSAndroid Build Coastguard Worker
read_permanent_attributes(AvbCertPermanentAttributes * attributes)392*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::read_permanent_attributes(
393*d289c2baSAndroid Build Coastguard Worker AvbCertPermanentAttributes* attributes) {
394*d289c2baSAndroid Build Coastguard Worker *attributes = permanent_attributes_;
395*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
396*d289c2baSAndroid Build Coastguard Worker }
397*d289c2baSAndroid Build Coastguard Worker
read_permanent_attributes_hash(uint8_t hash[AVB_SHA256_DIGEST_SIZE])398*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::read_permanent_attributes_hash(
399*d289c2baSAndroid Build Coastguard Worker uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
400*d289c2baSAndroid Build Coastguard Worker if (permanent_attributes_hash_.empty()) {
401*d289c2baSAndroid Build Coastguard Worker SHA256(reinterpret_cast<const unsigned char*>(&permanent_attributes_),
402*d289c2baSAndroid Build Coastguard Worker sizeof(AvbCertPermanentAttributes),
403*d289c2baSAndroid Build Coastguard Worker hash);
404*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
405*d289c2baSAndroid Build Coastguard Worker }
406*d289c2baSAndroid Build Coastguard Worker memset(hash, 0, AVB_SHA256_DIGEST_SIZE);
407*d289c2baSAndroid Build Coastguard Worker permanent_attributes_hash_.copy(reinterpret_cast<char*>(hash),
408*d289c2baSAndroid Build Coastguard Worker AVB_SHA256_DIGEST_SIZE);
409*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
410*d289c2baSAndroid Build Coastguard Worker }
411*d289c2baSAndroid Build Coastguard Worker
set_key_version(size_t rollback_index_location,uint64_t key_version)412*d289c2baSAndroid Build Coastguard Worker void FakeAvbOps::set_key_version(size_t rollback_index_location,
413*d289c2baSAndroid Build Coastguard Worker uint64_t key_version) {
414*d289c2baSAndroid Build Coastguard Worker verified_rollback_indexes_[rollback_index_location] = key_version;
415*d289c2baSAndroid Build Coastguard Worker }
416*d289c2baSAndroid Build Coastguard Worker
get_random(size_t num_bytes,uint8_t * output)417*d289c2baSAndroid Build Coastguard Worker AvbIOResult FakeAvbOps::get_random(size_t num_bytes, uint8_t* output) {
418*d289c2baSAndroid Build Coastguard Worker if (!RAND_bytes(output, num_bytes)) {
419*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_ERROR_IO;
420*d289c2baSAndroid Build Coastguard Worker }
421*d289c2baSAndroid Build Coastguard Worker return AVB_IO_RESULT_OK;
422*d289c2baSAndroid Build Coastguard Worker }
423*d289c2baSAndroid Build Coastguard Worker
my_ops_read_from_partition(AvbOps * ops,const char * partition,int64_t offset,size_t num_bytes,void * buffer,size_t * out_num_read)424*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_read_from_partition(AvbOps* ops,
425*d289c2baSAndroid Build Coastguard Worker const char* partition,
426*d289c2baSAndroid Build Coastguard Worker int64_t offset,
427*d289c2baSAndroid Build Coastguard Worker size_t num_bytes,
428*d289c2baSAndroid Build Coastguard Worker void* buffer,
429*d289c2baSAndroid Build Coastguard Worker size_t* out_num_read) {
430*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
431*d289c2baSAndroid Build Coastguard Worker ->delegate()
432*d289c2baSAndroid Build Coastguard Worker ->read_from_partition(partition, offset, num_bytes, buffer, out_num_read);
433*d289c2baSAndroid Build Coastguard Worker }
434*d289c2baSAndroid Build Coastguard Worker
my_ops_get_preloaded_partition(AvbOps * ops,const char * partition,size_t num_bytes,uint8_t ** out_pointer,size_t * out_num_bytes_preloaded)435*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_get_preloaded_partition(
436*d289c2baSAndroid Build Coastguard Worker AvbOps* ops,
437*d289c2baSAndroid Build Coastguard Worker const char* partition,
438*d289c2baSAndroid Build Coastguard Worker size_t num_bytes,
439*d289c2baSAndroid Build Coastguard Worker uint8_t** out_pointer,
440*d289c2baSAndroid Build Coastguard Worker size_t* out_num_bytes_preloaded) {
441*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
442*d289c2baSAndroid Build Coastguard Worker ->delegate()
443*d289c2baSAndroid Build Coastguard Worker ->get_preloaded_partition(
444*d289c2baSAndroid Build Coastguard Worker partition, num_bytes, out_pointer, out_num_bytes_preloaded);
445*d289c2baSAndroid Build Coastguard Worker }
446*d289c2baSAndroid Build Coastguard Worker
my_ops_write_to_partition(AvbOps * ops,const char * partition,int64_t offset,size_t num_bytes,const void * buffer)447*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_write_to_partition(AvbOps* ops,
448*d289c2baSAndroid Build Coastguard Worker const char* partition,
449*d289c2baSAndroid Build Coastguard Worker int64_t offset,
450*d289c2baSAndroid Build Coastguard Worker size_t num_bytes,
451*d289c2baSAndroid Build Coastguard Worker const void* buffer) {
452*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)->delegate()->write_to_partition(
453*d289c2baSAndroid Build Coastguard Worker partition, offset, num_bytes, buffer);
454*d289c2baSAndroid Build Coastguard Worker }
455*d289c2baSAndroid Build Coastguard Worker
my_ops_validate_vbmeta_public_key(AvbOps * ops,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_key_is_trusted)456*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_validate_vbmeta_public_key(
457*d289c2baSAndroid Build Coastguard Worker AvbOps* ops,
458*d289c2baSAndroid Build Coastguard Worker const uint8_t* public_key_data,
459*d289c2baSAndroid Build Coastguard Worker size_t public_key_length,
460*d289c2baSAndroid Build Coastguard Worker const uint8_t* public_key_metadata,
461*d289c2baSAndroid Build Coastguard Worker size_t public_key_metadata_length,
462*d289c2baSAndroid Build Coastguard Worker bool* out_key_is_trusted) {
463*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
464*d289c2baSAndroid Build Coastguard Worker ->delegate()
465*d289c2baSAndroid Build Coastguard Worker ->validate_vbmeta_public_key(ops,
466*d289c2baSAndroid Build Coastguard Worker public_key_data,
467*d289c2baSAndroid Build Coastguard Worker public_key_length,
468*d289c2baSAndroid Build Coastguard Worker public_key_metadata,
469*d289c2baSAndroid Build Coastguard Worker public_key_metadata_length,
470*d289c2baSAndroid Build Coastguard Worker out_key_is_trusted);
471*d289c2baSAndroid Build Coastguard Worker }
472*d289c2baSAndroid Build Coastguard Worker
my_ops_validate_public_key_for_partition(AvbOps * ops,const char * partition,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_key_is_trusted,uint32_t * out_rollback_index_location)473*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_validate_public_key_for_partition(
474*d289c2baSAndroid Build Coastguard Worker AvbOps* ops,
475*d289c2baSAndroid Build Coastguard Worker const char* partition,
476*d289c2baSAndroid Build Coastguard Worker const uint8_t* public_key_data,
477*d289c2baSAndroid Build Coastguard Worker size_t public_key_length,
478*d289c2baSAndroid Build Coastguard Worker const uint8_t* public_key_metadata,
479*d289c2baSAndroid Build Coastguard Worker size_t public_key_metadata_length,
480*d289c2baSAndroid Build Coastguard Worker bool* out_key_is_trusted,
481*d289c2baSAndroid Build Coastguard Worker uint32_t* out_rollback_index_location) {
482*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
483*d289c2baSAndroid Build Coastguard Worker ->delegate()
484*d289c2baSAndroid Build Coastguard Worker ->validate_public_key_for_partition(ops,
485*d289c2baSAndroid Build Coastguard Worker partition,
486*d289c2baSAndroid Build Coastguard Worker public_key_data,
487*d289c2baSAndroid Build Coastguard Worker public_key_length,
488*d289c2baSAndroid Build Coastguard Worker public_key_metadata,
489*d289c2baSAndroid Build Coastguard Worker public_key_metadata_length,
490*d289c2baSAndroid Build Coastguard Worker out_key_is_trusted,
491*d289c2baSAndroid Build Coastguard Worker out_rollback_index_location);
492*d289c2baSAndroid Build Coastguard Worker }
493*d289c2baSAndroid Build Coastguard Worker
my_ops_read_rollback_index(AvbOps * ops,size_t rollback_index_location,uint64_t * out_rollback_index)494*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_read_rollback_index(AvbOps* ops,
495*d289c2baSAndroid Build Coastguard Worker size_t rollback_index_location,
496*d289c2baSAndroid Build Coastguard Worker uint64_t* out_rollback_index) {
497*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
498*d289c2baSAndroid Build Coastguard Worker ->delegate()
499*d289c2baSAndroid Build Coastguard Worker ->read_rollback_index(ops, rollback_index_location, out_rollback_index);
500*d289c2baSAndroid Build Coastguard Worker }
501*d289c2baSAndroid Build Coastguard Worker
my_ops_write_rollback_index(AvbOps * ops,size_t rollback_index_location,uint64_t rollback_index)502*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_write_rollback_index(AvbOps* ops,
503*d289c2baSAndroid Build Coastguard Worker size_t rollback_index_location,
504*d289c2baSAndroid Build Coastguard Worker uint64_t rollback_index) {
505*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
506*d289c2baSAndroid Build Coastguard Worker ->delegate()
507*d289c2baSAndroid Build Coastguard Worker ->write_rollback_index(ops, rollback_index_location, rollback_index);
508*d289c2baSAndroid Build Coastguard Worker }
509*d289c2baSAndroid Build Coastguard Worker
my_ops_read_is_device_unlocked(AvbOps * ops,bool * out_is_device_unlocked)510*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_read_is_device_unlocked(
511*d289c2baSAndroid Build Coastguard Worker AvbOps* ops, bool* out_is_device_unlocked) {
512*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
513*d289c2baSAndroid Build Coastguard Worker ->delegate()
514*d289c2baSAndroid Build Coastguard Worker ->read_is_device_unlocked(ops, out_is_device_unlocked);
515*d289c2baSAndroid Build Coastguard Worker }
516*d289c2baSAndroid Build Coastguard Worker
my_ops_get_unique_guid_for_partition(AvbOps * ops,const char * partition,char * guid_buf,size_t guid_buf_size)517*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_get_unique_guid_for_partition(AvbOps* ops,
518*d289c2baSAndroid Build Coastguard Worker const char* partition,
519*d289c2baSAndroid Build Coastguard Worker char* guid_buf,
520*d289c2baSAndroid Build Coastguard Worker size_t guid_buf_size) {
521*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
522*d289c2baSAndroid Build Coastguard Worker ->delegate()
523*d289c2baSAndroid Build Coastguard Worker ->get_unique_guid_for_partition(ops, partition, guid_buf, guid_buf_size);
524*d289c2baSAndroid Build Coastguard Worker }
525*d289c2baSAndroid Build Coastguard Worker
my_ops_get_size_of_partition(AvbOps * ops,const char * partition,uint64_t * out_size)526*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_get_size_of_partition(AvbOps* ops,
527*d289c2baSAndroid Build Coastguard Worker const char* partition,
528*d289c2baSAndroid Build Coastguard Worker uint64_t* out_size) {
529*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
530*d289c2baSAndroid Build Coastguard Worker ->delegate()
531*d289c2baSAndroid Build Coastguard Worker ->get_size_of_partition(ops, partition, out_size);
532*d289c2baSAndroid Build Coastguard Worker }
533*d289c2baSAndroid Build Coastguard Worker
my_ops_read_persistent_value(AvbOps * ops,const char * name,size_t buffer_size,uint8_t * out_buffer,size_t * out_num_bytes_read)534*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_read_persistent_value(AvbOps* ops,
535*d289c2baSAndroid Build Coastguard Worker const char* name,
536*d289c2baSAndroid Build Coastguard Worker size_t buffer_size,
537*d289c2baSAndroid Build Coastguard Worker uint8_t* out_buffer,
538*d289c2baSAndroid Build Coastguard Worker size_t* out_num_bytes_read) {
539*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
540*d289c2baSAndroid Build Coastguard Worker ->delegate()
541*d289c2baSAndroid Build Coastguard Worker ->read_persistent_value(
542*d289c2baSAndroid Build Coastguard Worker name, buffer_size, out_buffer, out_num_bytes_read);
543*d289c2baSAndroid Build Coastguard Worker }
544*d289c2baSAndroid Build Coastguard Worker
my_ops_write_persistent_value(AvbOps * ops,const char * name,size_t value_size,const uint8_t * value)545*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_write_persistent_value(AvbOps* ops,
546*d289c2baSAndroid Build Coastguard Worker const char* name,
547*d289c2baSAndroid Build Coastguard Worker size_t value_size,
548*d289c2baSAndroid Build Coastguard Worker const uint8_t* value) {
549*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(ops)
550*d289c2baSAndroid Build Coastguard Worker ->delegate()
551*d289c2baSAndroid Build Coastguard Worker ->write_persistent_value(name, value_size, value);
552*d289c2baSAndroid Build Coastguard Worker }
553*d289c2baSAndroid Build Coastguard Worker
my_ops_read_permanent_attributes(AvbCertOps * cert_ops,AvbCertPermanentAttributes * attributes)554*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_read_permanent_attributes(
555*d289c2baSAndroid Build Coastguard Worker AvbCertOps* cert_ops, AvbCertPermanentAttributes* attributes) {
556*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(cert_ops->ops)
557*d289c2baSAndroid Build Coastguard Worker ->delegate()
558*d289c2baSAndroid Build Coastguard Worker ->read_permanent_attributes(attributes);
559*d289c2baSAndroid Build Coastguard Worker }
560*d289c2baSAndroid Build Coastguard Worker
my_ops_read_permanent_attributes_hash(AvbCertOps * cert_ops,uint8_t hash[AVB_SHA256_DIGEST_SIZE])561*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_read_permanent_attributes_hash(
562*d289c2baSAndroid Build Coastguard Worker AvbCertOps* cert_ops, uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
563*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(cert_ops->ops)
564*d289c2baSAndroid Build Coastguard Worker ->delegate()
565*d289c2baSAndroid Build Coastguard Worker ->read_permanent_attributes_hash(hash);
566*d289c2baSAndroid Build Coastguard Worker }
567*d289c2baSAndroid Build Coastguard Worker
my_ops_set_key_version(AvbCertOps * cert_ops,size_t rollback_index_location,uint64_t key_version)568*d289c2baSAndroid Build Coastguard Worker static void my_ops_set_key_version(AvbCertOps* cert_ops,
569*d289c2baSAndroid Build Coastguard Worker size_t rollback_index_location,
570*d289c2baSAndroid Build Coastguard Worker uint64_t key_version) {
571*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(cert_ops->ops)
572*d289c2baSAndroid Build Coastguard Worker ->delegate()
573*d289c2baSAndroid Build Coastguard Worker ->set_key_version(rollback_index_location, key_version);
574*d289c2baSAndroid Build Coastguard Worker }
575*d289c2baSAndroid Build Coastguard Worker
my_ops_get_random(AvbCertOps * cert_ops,size_t num_bytes,uint8_t * output)576*d289c2baSAndroid Build Coastguard Worker static AvbIOResult my_ops_get_random(AvbCertOps* cert_ops,
577*d289c2baSAndroid Build Coastguard Worker size_t num_bytes,
578*d289c2baSAndroid Build Coastguard Worker uint8_t* output) {
579*d289c2baSAndroid Build Coastguard Worker return FakeAvbOps::GetInstanceFromAvbOps(cert_ops->ops)
580*d289c2baSAndroid Build Coastguard Worker ->delegate()
581*d289c2baSAndroid Build Coastguard Worker ->get_random(num_bytes, output);
582*d289c2baSAndroid Build Coastguard Worker }
583*d289c2baSAndroid Build Coastguard Worker
FakeAvbOps()584*d289c2baSAndroid Build Coastguard Worker FakeAvbOps::FakeAvbOps() {
585*d289c2baSAndroid Build Coastguard Worker memset(&avb_ops_, 0, sizeof(avb_ops_));
586*d289c2baSAndroid Build Coastguard Worker avb_ops_.ab_ops = &avb_ab_ops_;
587*d289c2baSAndroid Build Coastguard Worker avb_ops_.cert_ops = &avb_cert_ops_;
588*d289c2baSAndroid Build Coastguard Worker avb_ops_.user_data = this;
589*d289c2baSAndroid Build Coastguard Worker avb_ops_.read_from_partition = my_ops_read_from_partition;
590*d289c2baSAndroid Build Coastguard Worker avb_ops_.write_to_partition = my_ops_write_to_partition;
591*d289c2baSAndroid Build Coastguard Worker avb_ops_.validate_vbmeta_public_key = my_ops_validate_vbmeta_public_key;
592*d289c2baSAndroid Build Coastguard Worker avb_ops_.read_rollback_index = my_ops_read_rollback_index;
593*d289c2baSAndroid Build Coastguard Worker avb_ops_.write_rollback_index = my_ops_write_rollback_index;
594*d289c2baSAndroid Build Coastguard Worker avb_ops_.read_is_device_unlocked = my_ops_read_is_device_unlocked;
595*d289c2baSAndroid Build Coastguard Worker avb_ops_.get_unique_guid_for_partition = my_ops_get_unique_guid_for_partition;
596*d289c2baSAndroid Build Coastguard Worker avb_ops_.get_size_of_partition = my_ops_get_size_of_partition;
597*d289c2baSAndroid Build Coastguard Worker avb_ops_.read_persistent_value = my_ops_read_persistent_value;
598*d289c2baSAndroid Build Coastguard Worker avb_ops_.write_persistent_value = my_ops_write_persistent_value;
599*d289c2baSAndroid Build Coastguard Worker avb_ops_.validate_public_key_for_partition =
600*d289c2baSAndroid Build Coastguard Worker my_ops_validate_public_key_for_partition;
601*d289c2baSAndroid Build Coastguard Worker
602*d289c2baSAndroid Build Coastguard Worker // Just use the built-in A/B metadata read/write routines.
603*d289c2baSAndroid Build Coastguard Worker avb_ab_ops_.ops = &avb_ops_;
604*d289c2baSAndroid Build Coastguard Worker avb_ab_ops_.read_ab_metadata = avb_ab_data_read;
605*d289c2baSAndroid Build Coastguard Worker avb_ab_ops_.write_ab_metadata = avb_ab_data_write;
606*d289c2baSAndroid Build Coastguard Worker
607*d289c2baSAndroid Build Coastguard Worker avb_cert_ops_.ops = &avb_ops_;
608*d289c2baSAndroid Build Coastguard Worker avb_cert_ops_.read_permanent_attributes = my_ops_read_permanent_attributes;
609*d289c2baSAndroid Build Coastguard Worker avb_cert_ops_.read_permanent_attributes_hash =
610*d289c2baSAndroid Build Coastguard Worker my_ops_read_permanent_attributes_hash;
611*d289c2baSAndroid Build Coastguard Worker avb_cert_ops_.set_key_version = my_ops_set_key_version;
612*d289c2baSAndroid Build Coastguard Worker avb_cert_ops_.get_random = my_ops_get_random;
613*d289c2baSAndroid Build Coastguard Worker
614*d289c2baSAndroid Build Coastguard Worker delegate_ = this;
615*d289c2baSAndroid Build Coastguard Worker }
616*d289c2baSAndroid Build Coastguard Worker
~FakeAvbOps()617*d289c2baSAndroid Build Coastguard Worker FakeAvbOps::~FakeAvbOps() {
618*d289c2baSAndroid Build Coastguard Worker std::map<std::string, uint8_t*>::iterator it;
619*d289c2baSAndroid Build Coastguard Worker for (it = preloaded_partitions_.begin(); it != preloaded_partitions_.end();
620*d289c2baSAndroid Build Coastguard Worker it++) {
621*d289c2baSAndroid Build Coastguard Worker free(it->second);
622*d289c2baSAndroid Build Coastguard Worker }
623*d289c2baSAndroid Build Coastguard Worker }
624*d289c2baSAndroid Build Coastguard Worker
enable_get_preloaded_partition()625*d289c2baSAndroid Build Coastguard Worker void FakeAvbOps::enable_get_preloaded_partition() {
626*d289c2baSAndroid Build Coastguard Worker avb_ops_.get_preloaded_partition = my_ops_get_preloaded_partition;
627*d289c2baSAndroid Build Coastguard Worker }
628*d289c2baSAndroid Build Coastguard Worker
629*d289c2baSAndroid Build Coastguard Worker } // namespace avb
630