blob: 1aaafd5b10062403ce4f14fcb645f29846cf2a1a [file] [log] [blame]
Sen Jiang57f91802017-11-14 17:42:13 -08001//
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#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_VERITY_WRITER_ANDROID_H_
18#define UPDATE_ENGINE_PAYLOAD_CONSUMER_VERITY_WRITER_ANDROID_H_
19
20#include <memory>
Sen Jianga778e5b2018-09-13 11:42:56 -070021#include <string>
Sen Jiang57f91802017-11-14 17:42:13 -080022
23#include <verity/hash_tree_builder.h>
Daniel Zhengbd16b012022-09-28 23:40:05 +000024#include <base/logging.h>
25#include <base/posix/eintr_wrapper.h>
26#include <fec/ecc.h>
27extern "C" {
28#include <fec.h>
29}
Sen Jiang57f91802017-11-14 17:42:13 -080030
Kelvin Zhangb138ab52020-11-06 15:56:41 -050031#include "payload_consumer/file_descriptor.h"
Daniel Zhengbd16b012022-09-28 23:40:05 +000032#include "update_engine/payload_consumer/cached_file_descriptor.h"
Sen Jiang57f91802017-11-14 17:42:13 -080033#include "update_engine/payload_consumer/verity_writer_interface.h"
34
35namespace chromeos_update_engine {
Daniel Zhengbd16b012022-09-28 23:40:05 +000036enum class EncodeFECStep {
37 kInitFDStep,
38 kEncodeRoundStep,
39 kWriteStep,
40 kComplete
41};
42class IncrementalEncodeFEC {
43 public:
44 IncrementalEncodeFEC()
45 : rs_char_(nullptr, &free_rs_char), cache_fd_(nullptr, 1 * (1 << 20)) {}
46 // Initialize all member variables needed to performe FEC Computation
47 bool Init(const uint64_t _data_offset,
48 const uint64_t _data_size,
49 const uint64_t _fec_offset,
50 const uint64_t _fec_size,
51 const uint64_t _fec_roots,
52 const uint64_t _block_size,
53 const bool _verify_mode);
54 bool Compute(FileDescriptor* _read_fd, FileDescriptor* _write_fd);
55 void UpdateState();
56 bool Finished() const;
57 void Reset();
Daniel Zheng3efb3f22022-12-19 22:14:20 +000058 double ReportProgress() const;
Daniel Zhengbd16b012022-09-28 23:40:05 +000059
60 private:
61 brillo::Blob rs_blocks_;
62 brillo::Blob buffer_;
63 brillo::Blob fec_;
64 brillo::Blob fec_read_;
65 EncodeFECStep current_step_;
66 size_t current_round_;
67 size_t num_rounds_;
68 FileDescriptor* read_fd_;
69 FileDescriptor* write_fd_;
70 uint64_t data_offset_;
71 uint64_t data_size_;
72 uint64_t fec_offset_;
73 uint64_t fec_size_;
74 uint64_t fec_roots_;
75 uint64_t block_size_;
76 size_t rs_n_;
77 bool verify_mode_;
78 std::unique_ptr<void, decltype(&free_rs_char)> rs_char_;
79 UnownedCachedFileDescriptor cache_fd_;
80};
Sen Jiang57f91802017-11-14 17:42:13 -080081
82class VerityWriterAndroid : public VerityWriterInterface {
83 public:
84 VerityWriterAndroid() = default;
85 ~VerityWriterAndroid() override = default;
86
Kelvin Zhangb138ab52020-11-06 15:56:41 -050087 bool Init(const InstallPlan::Partition& partition);
Sen Jiang57f91802017-11-14 17:42:13 -080088 bool Update(uint64_t offset, const uint8_t* buffer, size_t size) override;
Kelvin Zhang1a0ed712022-01-26 16:09:05 -080089 bool Finalize(FileDescriptor* read_fd, FileDescriptor* write_fd) override;
Daniel Zhengbd16b012022-09-28 23:40:05 +000090 bool IncrementalFinalize(FileDescriptor* read_fd,
91 FileDescriptor* write_fd) override;
Daniel Zheng3efb3f22022-12-19 22:14:20 +000092 double GetProgress() override;
Daniel Zhengbd16b012022-09-28 23:40:05 +000093 bool FECFinished() const override;
Sen Jianga778e5b2018-09-13 11:42:56 -070094 // Read [data_offset : data_offset + data_size) from |path| and encode FEC
95 // data, if |verify_mode|, then compare the encoded FEC with the one in
96 // |path|, otherwise write the encoded FEC to |path|. We can't encode as we go
97 // in each Update() like hash tree, because for every rs block, its data are
98 // spreaded across entire |data_size|, unless we can cache all data in
99 // memory, we have to re-read them from disk.
Kelvin Zhang1a0ed712022-01-26 16:09:05 -0800100 static bool EncodeFEC(FileDescriptor* read_fd,
101 FileDescriptor* write_fd,
Kelvin Zhangb138ab52020-11-06 15:56:41 -0500102 uint64_t data_offset,
103 uint64_t data_size,
104 uint64_t fec_offset,
105 uint64_t fec_size,
106 uint32_t fec_roots,
107 uint32_t block_size,
108 bool verify_mode);
Sen Jianga778e5b2018-09-13 11:42:56 -0700109 static bool EncodeFEC(const std::string& path,
110 uint64_t data_offset,
111 uint64_t data_size,
112 uint64_t fec_offset,
113 uint64_t fec_size,
114 uint32_t fec_roots,
115 uint32_t block_size,
116 bool verify_mode);
117
Sen Jiang57f91802017-11-14 17:42:13 -0800118 private:
Daniel Zhengbd16b012022-09-28 23:40:05 +0000119 // stores the state of EncodeFEC
120 IncrementalEncodeFEC encodeFEC_;
121 bool hash_tree_written_ = false;
Sen Jiang57f91802017-11-14 17:42:13 -0800122 const InstallPlan::Partition* partition_ = nullptr;
123
Sen Jiang57f91802017-11-14 17:42:13 -0800124 std::unique_ptr<HashTreeBuilder> hash_tree_builder_;
Kelvin Zhangeeec3812021-03-16 14:01:47 -0400125 uint64_t total_offset_ = 0;
Sen Jiang57f91802017-11-14 17:42:13 -0800126 DISALLOW_COPY_AND_ASSIGN(VerityWriterAndroid);
127};
128
129} // namespace chromeos_update_engine
130
131#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_VERITY_WRITER_ANDROID_H_