xref: /aosp_15_r20/system/extras/libfec/include/fec/io.h (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #ifndef ___FEC_IO_H___
18*288bf522SAndroid Build Coastguard Worker #define ___FEC_IO_H___
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <fcntl.h>
21*288bf522SAndroid Build Coastguard Worker #include <inttypes.h>
22*288bf522SAndroid Build Coastguard Worker #include <limits.h>
23*288bf522SAndroid Build Coastguard Worker #include <stdbool.h>
24*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
25*288bf522SAndroid Build Coastguard Worker #include <sys/types.h>
26*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker #include <crypto_utils/android_pubkey.h>
29*288bf522SAndroid Build Coastguard Worker 
30*288bf522SAndroid Build Coastguard Worker #ifdef __cplusplus
31*288bf522SAndroid Build Coastguard Worker extern "C" {
32*288bf522SAndroid Build Coastguard Worker #endif
33*288bf522SAndroid Build Coastguard Worker 
34*288bf522SAndroid Build Coastguard Worker #ifndef SHA256_DIGEST_LENGTH
35*288bf522SAndroid Build Coastguard Worker #define SHA256_DIGEST_LENGTH 32
36*288bf522SAndroid Build Coastguard Worker #endif
37*288bf522SAndroid Build Coastguard Worker 
38*288bf522SAndroid Build Coastguard Worker #define FEC_BLOCKSIZE 4096
39*288bf522SAndroid Build Coastguard Worker #define FEC_DEFAULT_ROOTS 2
40*288bf522SAndroid Build Coastguard Worker 
41*288bf522SAndroid Build Coastguard Worker #define FEC_MAGIC 0xFECFECFE
42*288bf522SAndroid Build Coastguard Worker #define FEC_VERSION 0
43*288bf522SAndroid Build Coastguard Worker 
44*288bf522SAndroid Build Coastguard Worker /* disk format for the header */
45*288bf522SAndroid Build Coastguard Worker struct fec_header {
46*288bf522SAndroid Build Coastguard Worker     uint32_t magic;
47*288bf522SAndroid Build Coastguard Worker     uint32_t version;
48*288bf522SAndroid Build Coastguard Worker     uint32_t size;
49*288bf522SAndroid Build Coastguard Worker     uint32_t roots;
50*288bf522SAndroid Build Coastguard Worker     uint32_t fec_size;
51*288bf522SAndroid Build Coastguard Worker     uint64_t inp_size;
52*288bf522SAndroid Build Coastguard Worker     uint8_t hash[SHA256_DIGEST_LENGTH];
53*288bf522SAndroid Build Coastguard Worker } __attribute__ ((packed));
54*288bf522SAndroid Build Coastguard Worker 
55*288bf522SAndroid Build Coastguard Worker struct fec_status {
56*288bf522SAndroid Build Coastguard Worker     int flags;
57*288bf522SAndroid Build Coastguard Worker     int mode;
58*288bf522SAndroid Build Coastguard Worker     uint64_t errors;
59*288bf522SAndroid Build Coastguard Worker     uint64_t data_size;
60*288bf522SAndroid Build Coastguard Worker     uint64_t size;
61*288bf522SAndroid Build Coastguard Worker };
62*288bf522SAndroid Build Coastguard Worker 
63*288bf522SAndroid Build Coastguard Worker struct fec_ecc_metadata {
64*288bf522SAndroid Build Coastguard Worker     bool valid;
65*288bf522SAndroid Build Coastguard Worker     uint32_t roots;
66*288bf522SAndroid Build Coastguard Worker     uint64_t blocks;
67*288bf522SAndroid Build Coastguard Worker     uint64_t rounds;
68*288bf522SAndroid Build Coastguard Worker     uint64_t start;
69*288bf522SAndroid Build Coastguard Worker };
70*288bf522SAndroid Build Coastguard Worker 
71*288bf522SAndroid Build Coastguard Worker struct fec_verity_metadata {
72*288bf522SAndroid Build Coastguard Worker     bool disabled;
73*288bf522SAndroid Build Coastguard Worker     uint64_t data_size;
74*288bf522SAndroid Build Coastguard Worker     uint8_t signature[ANDROID_PUBKEY_MODULUS_SIZE];
75*288bf522SAndroid Build Coastguard Worker     uint8_t ecc_signature[ANDROID_PUBKEY_MODULUS_SIZE];
76*288bf522SAndroid Build Coastguard Worker     const char *table;
77*288bf522SAndroid Build Coastguard Worker     uint32_t table_length;
78*288bf522SAndroid Build Coastguard Worker };
79*288bf522SAndroid Build Coastguard Worker 
80*288bf522SAndroid Build Coastguard Worker /* flags for fec_open */
81*288bf522SAndroid Build Coastguard Worker enum {
82*288bf522SAndroid Build Coastguard Worker     FEC_FS_EXT4 = 1 << 0,
83*288bf522SAndroid Build Coastguard Worker     FEC_FS_SQUASH = 1 << 1,
84*288bf522SAndroid Build Coastguard Worker     FEC_VERITY_DISABLE = 1 << 8
85*288bf522SAndroid Build Coastguard Worker };
86*288bf522SAndroid Build Coastguard Worker 
87*288bf522SAndroid Build Coastguard Worker struct fec_handle;
88*288bf522SAndroid Build Coastguard Worker 
89*288bf522SAndroid Build Coastguard Worker /* file access */
90*288bf522SAndroid Build Coastguard Worker extern int fec_open(struct fec_handle **f, const char *path, int mode,
91*288bf522SAndroid Build Coastguard Worker         int flags, int roots);
92*288bf522SAndroid Build Coastguard Worker 
93*288bf522SAndroid Build Coastguard Worker extern int fec_close(struct fec_handle *f);
94*288bf522SAndroid Build Coastguard Worker 
95*288bf522SAndroid Build Coastguard Worker extern int fec_verity_set_status(struct fec_handle *f, bool enabled);
96*288bf522SAndroid Build Coastguard Worker 
97*288bf522SAndroid Build Coastguard Worker extern int fec_verity_get_metadata(struct fec_handle *f,
98*288bf522SAndroid Build Coastguard Worker         struct fec_verity_metadata *data);
99*288bf522SAndroid Build Coastguard Worker 
100*288bf522SAndroid Build Coastguard Worker extern int fec_ecc_get_metadata(struct fec_handle *f,
101*288bf522SAndroid Build Coastguard Worker         struct fec_ecc_metadata *data);
102*288bf522SAndroid Build Coastguard Worker 
103*288bf522SAndroid Build Coastguard Worker extern int fec_get_status(struct fec_handle *f, struct fec_status *s);
104*288bf522SAndroid Build Coastguard Worker 
105*288bf522SAndroid Build Coastguard Worker extern int fec_seek(struct fec_handle *f, int64_t offset, int whence);
106*288bf522SAndroid Build Coastguard Worker 
107*288bf522SAndroid Build Coastguard Worker extern ssize_t fec_read(struct fec_handle *f, void *buf, size_t count);
108*288bf522SAndroid Build Coastguard Worker 
109*288bf522SAndroid Build Coastguard Worker extern ssize_t fec_pread(struct fec_handle *f, void *buf, size_t count,
110*288bf522SAndroid Build Coastguard Worker         uint64_t offset);
111*288bf522SAndroid Build Coastguard Worker 
112*288bf522SAndroid Build Coastguard Worker #ifdef __cplusplus
113*288bf522SAndroid Build Coastguard Worker } /* extern "C" */
114*288bf522SAndroid Build Coastguard Worker 
115*288bf522SAndroid Build Coastguard Worker #include <memory>
116*288bf522SAndroid Build Coastguard Worker #include <string>
117*288bf522SAndroid Build Coastguard Worker 
118*288bf522SAndroid Build Coastguard Worker /* C++ wrappers for fec_handle and operations */
119*288bf522SAndroid Build Coastguard Worker namespace fec {
120*288bf522SAndroid Build Coastguard Worker     using handle = std::unique_ptr<fec_handle, decltype(&fec_close)>;
121*288bf522SAndroid Build Coastguard Worker 
122*288bf522SAndroid Build Coastguard Worker     class io {
123*288bf522SAndroid Build Coastguard Worker     public:
io()124*288bf522SAndroid Build Coastguard Worker         io() : handle_(nullptr, fec_close) {}
125*288bf522SAndroid Build Coastguard Worker 
126*288bf522SAndroid Build Coastguard Worker         explicit io(const std::string& fn, int mode = O_RDONLY, int flags = 0,
handle_(nullptr,fec_close)127*288bf522SAndroid Build Coastguard Worker                 int roots = FEC_DEFAULT_ROOTS) : handle_(nullptr, fec_close) {
128*288bf522SAndroid Build Coastguard Worker             open(fn, mode, flags, roots);
129*288bf522SAndroid Build Coastguard Worker         }
130*288bf522SAndroid Build Coastguard Worker 
131*288bf522SAndroid Build Coastguard Worker         explicit operator bool() const {
132*288bf522SAndroid Build Coastguard Worker             return !!handle_;
133*288bf522SAndroid Build Coastguard Worker         }
134*288bf522SAndroid Build Coastguard Worker 
135*288bf522SAndroid Build Coastguard Worker         bool open(const std::string& fn, int mode = O_RDONLY, int flags = 0,
136*288bf522SAndroid Build Coastguard Worker                     int roots = FEC_DEFAULT_ROOTS)
137*288bf522SAndroid Build Coastguard Worker         {
138*288bf522SAndroid Build Coastguard Worker             fec_handle *fh = nullptr;
139*288bf522SAndroid Build Coastguard Worker             int rc = fec_open(&fh, fn.c_str(), mode, flags, roots);
140*288bf522SAndroid Build Coastguard Worker             if (!rc) {
141*288bf522SAndroid Build Coastguard Worker                 handle_.reset(fh);
142*288bf522SAndroid Build Coastguard Worker             }
143*288bf522SAndroid Build Coastguard Worker             return !rc;
144*288bf522SAndroid Build Coastguard Worker         }
145*288bf522SAndroid Build Coastguard Worker 
close()146*288bf522SAndroid Build Coastguard Worker         bool close() {
147*288bf522SAndroid Build Coastguard Worker             return !fec_close(handle_.release());
148*288bf522SAndroid Build Coastguard Worker         }
149*288bf522SAndroid Build Coastguard Worker 
seek(int64_t offset,int whence)150*288bf522SAndroid Build Coastguard Worker         bool seek(int64_t offset, int whence) {
151*288bf522SAndroid Build Coastguard Worker             return !fec_seek(handle_.get(), offset, whence);
152*288bf522SAndroid Build Coastguard Worker         }
153*288bf522SAndroid Build Coastguard Worker 
read(void * buf,size_t count)154*288bf522SAndroid Build Coastguard Worker         ssize_t read(void *buf, size_t count) {
155*288bf522SAndroid Build Coastguard Worker             return fec_read(handle_.get(), buf, count);
156*288bf522SAndroid Build Coastguard Worker         }
157*288bf522SAndroid Build Coastguard Worker 
pread(void * buf,size_t count,uint64_t offset)158*288bf522SAndroid Build Coastguard Worker         ssize_t pread(void *buf, size_t count, uint64_t offset) {
159*288bf522SAndroid Build Coastguard Worker             return fec_pread(handle_.get(), buf, count, offset);
160*288bf522SAndroid Build Coastguard Worker         }
161*288bf522SAndroid Build Coastguard Worker 
get_status(fec_status & status)162*288bf522SAndroid Build Coastguard Worker         bool get_status(fec_status& status) {
163*288bf522SAndroid Build Coastguard Worker             return !fec_get_status(handle_.get(), &status);
164*288bf522SAndroid Build Coastguard Worker         }
165*288bf522SAndroid Build Coastguard Worker 
get_verity_metadata(fec_verity_metadata & data)166*288bf522SAndroid Build Coastguard Worker         bool get_verity_metadata(fec_verity_metadata& data) {
167*288bf522SAndroid Build Coastguard Worker             return !fec_verity_get_metadata(handle_.get(), &data);
168*288bf522SAndroid Build Coastguard Worker         }
169*288bf522SAndroid Build Coastguard Worker 
has_verity()170*288bf522SAndroid Build Coastguard Worker         bool has_verity() {
171*288bf522SAndroid Build Coastguard Worker             fec_verity_metadata data;
172*288bf522SAndroid Build Coastguard Worker             return get_verity_metadata(data);
173*288bf522SAndroid Build Coastguard Worker         }
174*288bf522SAndroid Build Coastguard Worker 
get_ecc_metadata(fec_ecc_metadata & data)175*288bf522SAndroid Build Coastguard Worker         bool get_ecc_metadata(fec_ecc_metadata& data) {
176*288bf522SAndroid Build Coastguard Worker             return !fec_ecc_get_metadata(handle_.get(), &data);
177*288bf522SAndroid Build Coastguard Worker         }
178*288bf522SAndroid Build Coastguard Worker 
has_ecc()179*288bf522SAndroid Build Coastguard Worker         bool has_ecc() {
180*288bf522SAndroid Build Coastguard Worker             fec_ecc_metadata data;
181*288bf522SAndroid Build Coastguard Worker             return get_ecc_metadata(data) && data.valid;
182*288bf522SAndroid Build Coastguard Worker         }
183*288bf522SAndroid Build Coastguard Worker 
set_verity_status(bool enabled)184*288bf522SAndroid Build Coastguard Worker         bool set_verity_status(bool enabled) {
185*288bf522SAndroid Build Coastguard Worker             return !fec_verity_set_status(handle_.get(), enabled);
186*288bf522SAndroid Build Coastguard Worker         }
187*288bf522SAndroid Build Coastguard Worker 
188*288bf522SAndroid Build Coastguard Worker     private:
189*288bf522SAndroid Build Coastguard Worker         handle handle_;
190*288bf522SAndroid Build Coastguard Worker     };
191*288bf522SAndroid Build Coastguard Worker }
192*288bf522SAndroid Build Coastguard Worker #endif
193*288bf522SAndroid Build Coastguard Worker 
194*288bf522SAndroid Build Coastguard Worker #endif /* ___FEC_IO_H___ */
195