xref: /aosp_15_r20/system/extras/libfec/fec_private.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_PRIVATE_H__
18*288bf522SAndroid Build Coastguard Worker #define __FEC_PRIVATE_H__
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <errno.h>
21*288bf522SAndroid Build Coastguard Worker #include <fcntl.h>
22*288bf522SAndroid Build Coastguard Worker #include <pthread.h>
23*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
24*288bf522SAndroid Build Coastguard Worker #include <string.h>
25*288bf522SAndroid Build Coastguard Worker #include <sys/syscall.h>
26*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker #include <memory>
29*288bf522SAndroid Build Coastguard Worker #include <string>
30*288bf522SAndroid Build Coastguard Worker #include <vector>
31*288bf522SAndroid Build Coastguard Worker 
32*288bf522SAndroid Build Coastguard Worker #include <android-base/threads.h>
33*288bf522SAndroid Build Coastguard Worker #include <crypto_utils/android_pubkey.h>
34*288bf522SAndroid Build Coastguard Worker #include <fec/ecc.h>
35*288bf522SAndroid Build Coastguard Worker #include <fec/io.h>
36*288bf522SAndroid Build Coastguard Worker #include <openssl/obj_mac.h>
37*288bf522SAndroid Build Coastguard Worker #include <openssl/sha.h>
38*288bf522SAndroid Build Coastguard Worker #include <utils/Compat.h>
39*288bf522SAndroid Build Coastguard Worker 
40*288bf522SAndroid Build Coastguard Worker /* processing parameters */
41*288bf522SAndroid Build Coastguard Worker #define WORK_MIN_THREADS 1
42*288bf522SAndroid Build Coastguard Worker #define WORK_MAX_THREADS 64
43*288bf522SAndroid Build Coastguard Worker 
44*288bf522SAndroid Build Coastguard Worker /* verity parameters */
45*288bf522SAndroid Build Coastguard Worker #define VERITY_CACHE_BLOCKS 4096
46*288bf522SAndroid Build Coastguard Worker #define VERITY_NO_CACHE UINT64_MAX
47*288bf522SAndroid Build Coastguard Worker 
48*288bf522SAndroid Build Coastguard Worker /* verity definitions */
49*288bf522SAndroid Build Coastguard Worker #define VERITY_METADATA_SIZE (8 * FEC_BLOCKSIZE)
50*288bf522SAndroid Build Coastguard Worker #define VERITY_TABLE_ARGS 10 /* mandatory arguments */
51*288bf522SAndroid Build Coastguard Worker #define VERITY_MIN_TABLE_SIZE (VERITY_TABLE_ARGS * 2) /* for quick validation */
52*288bf522SAndroid Build Coastguard Worker #define VERITY_MAX_TABLE_SIZE (VERITY_METADATA_SIZE - sizeof(verity_header))
53*288bf522SAndroid Build Coastguard Worker 
54*288bf522SAndroid Build Coastguard Worker /* verity header and metadata */
55*288bf522SAndroid Build Coastguard Worker #define VERITY_MAGIC 0xB001B001
56*288bf522SAndroid Build Coastguard Worker #define VERITY_MAGIC_DISABLE 0x46464F56
57*288bf522SAndroid Build Coastguard Worker #define VERITY_VERSION 0
58*288bf522SAndroid Build Coastguard Worker #define VERITY_TABLE_FIELDS 10
59*288bf522SAndroid Build Coastguard Worker #define VERITY_TABLE_VERSION 1
60*288bf522SAndroid Build Coastguard Worker 
61*288bf522SAndroid Build Coastguard Worker struct verity_header {
62*288bf522SAndroid Build Coastguard Worker     uint32_t magic;
63*288bf522SAndroid Build Coastguard Worker     uint32_t version;
64*288bf522SAndroid Build Coastguard Worker     uint8_t signature[ANDROID_PUBKEY_MODULUS_SIZE];
65*288bf522SAndroid Build Coastguard Worker     uint32_t length;
66*288bf522SAndroid Build Coastguard Worker };
67*288bf522SAndroid Build Coastguard Worker 
68*288bf522SAndroid Build Coastguard Worker /* file handle */
69*288bf522SAndroid Build Coastguard Worker struct ecc_info {
70*288bf522SAndroid Build Coastguard Worker     bool valid;
71*288bf522SAndroid Build Coastguard Worker     int roots;
72*288bf522SAndroid Build Coastguard Worker     int rsn;
73*288bf522SAndroid Build Coastguard Worker     uint32_t size;
74*288bf522SAndroid Build Coastguard Worker     uint64_t blocks;
75*288bf522SAndroid Build Coastguard Worker     uint64_t rounds;
76*288bf522SAndroid Build Coastguard Worker     uint64_t start; /* offset in file */
77*288bf522SAndroid Build Coastguard Worker };
78*288bf522SAndroid Build Coastguard Worker 
79*288bf522SAndroid Build Coastguard Worker struct hashtree_info {
80*288bf522SAndroid Build Coastguard Worker     // The number of the input data blocks to compute the hashtree.
81*288bf522SAndroid Build Coastguard Worker     uint64_t data_blocks;
82*288bf522SAndroid Build Coastguard Worker     // The offset of hashtree in the final image.
83*288bf522SAndroid Build Coastguard Worker     uint64_t hash_start;
84*288bf522SAndroid Build Coastguard Worker     // The hash concatenation of the input data, i.e. lowest level of the
85*288bf522SAndroid Build Coastguard Worker     // hashtree.
86*288bf522SAndroid Build Coastguard Worker     std::vector<uint8_t> hash_data;
87*288bf522SAndroid Build Coastguard Worker     std::vector<uint8_t> salt;
88*288bf522SAndroid Build Coastguard Worker     std::vector<uint8_t> zero_hash;
89*288bf522SAndroid Build Coastguard Worker 
90*288bf522SAndroid Build Coastguard Worker     // Initialize the hashtree offsets and properties with the input parameters.
91*288bf522SAndroid Build Coastguard Worker     int initialize(uint64_t hash_start, uint64_t data_blocks,
92*288bf522SAndroid Build Coastguard Worker                    const std::vector<uint8_t> &salt, int nid);
93*288bf522SAndroid Build Coastguard Worker 
94*288bf522SAndroid Build Coastguard Worker     // Checks if the bytes in 'block' has the expected hash. And the 'index' is
95*288bf522SAndroid Build Coastguard Worker     // the block number of is the input block in the filesystem.
96*288bf522SAndroid Build Coastguard Worker     bool check_block_hash_with_index(uint64_t index, const uint8_t *block);
97*288bf522SAndroid Build Coastguard Worker 
98*288bf522SAndroid Build Coastguard Worker     // Reads the verity hash tree, validates it against the root hash in `root',
99*288bf522SAndroid Build Coastguard Worker     // corrects errors if necessary, and copies valid data blocks for later use
100*288bf522SAndroid Build Coastguard Worker     // to 'hashtree'.
101*288bf522SAndroid Build Coastguard Worker     int verify_tree(const fec_handle *f, const uint8_t *root);
102*288bf522SAndroid Build Coastguard Worker 
103*288bf522SAndroid Build Coastguard Worker    private:
104*288bf522SAndroid Build Coastguard Worker     bool ecc_read_hashes(fec_handle *f, uint64_t hash_offset, uint8_t *hash,
105*288bf522SAndroid Build Coastguard Worker                          uint64_t data_offset, uint8_t *data);
106*288bf522SAndroid Build Coastguard Worker 
107*288bf522SAndroid Build Coastguard Worker     // Computes the hash for FEC_BLOCKSIZE bytes from buffer 'block' and
108*288bf522SAndroid Build Coastguard Worker     // compares it to the expected value in 'expected'.
109*288bf522SAndroid Build Coastguard Worker     bool check_block_hash(const uint8_t *expected, const uint8_t *block);
110*288bf522SAndroid Build Coastguard Worker 
111*288bf522SAndroid Build Coastguard Worker     // Computes the hash of 'block' and put the result in 'hash'.
112*288bf522SAndroid Build Coastguard Worker     int get_hash(const uint8_t *block, uint8_t *hash);
113*288bf522SAndroid Build Coastguard Worker 
114*288bf522SAndroid Build Coastguard Worker     int nid_;  // NID for the hash algorithm.
115*288bf522SAndroid Build Coastguard Worker     uint32_t digest_length_;
116*288bf522SAndroid Build Coastguard Worker     uint32_t padded_digest_length_;
117*288bf522SAndroid Build Coastguard Worker };
118*288bf522SAndroid Build Coastguard Worker 
119*288bf522SAndroid Build Coastguard Worker struct verity_info {
120*288bf522SAndroid Build Coastguard Worker     bool disabled;
121*288bf522SAndroid Build Coastguard Worker     std::string table;
122*288bf522SAndroid Build Coastguard Worker     uint64_t metadata_start; /* offset in file */
123*288bf522SAndroid Build Coastguard Worker     hashtree_info hashtree;
124*288bf522SAndroid Build Coastguard Worker     verity_header header;
125*288bf522SAndroid Build Coastguard Worker     verity_header ecc_header;
126*288bf522SAndroid Build Coastguard Worker };
127*288bf522SAndroid Build Coastguard Worker 
128*288bf522SAndroid Build Coastguard Worker struct avb_info {
129*288bf522SAndroid Build Coastguard Worker     bool valid = false;
130*288bf522SAndroid Build Coastguard Worker     std::vector<uint8_t> vbmeta;
131*288bf522SAndroid Build Coastguard Worker     hashtree_info hashtree;
132*288bf522SAndroid Build Coastguard Worker };
133*288bf522SAndroid Build Coastguard Worker 
134*288bf522SAndroid Build Coastguard Worker struct fec_handle {
135*288bf522SAndroid Build Coastguard Worker     ecc_info ecc;
136*288bf522SAndroid Build Coastguard Worker     int fd;
137*288bf522SAndroid Build Coastguard Worker     int flags; /* additional flags passed to fec_open */
138*288bf522SAndroid Build Coastguard Worker     int mode;  /* mode for open(2) */
139*288bf522SAndroid Build Coastguard Worker     uint64_t errors;
140*288bf522SAndroid Build Coastguard Worker     uint64_t data_size;
141*288bf522SAndroid Build Coastguard Worker     uint64_t pos;
142*288bf522SAndroid Build Coastguard Worker     uint64_t size;
143*288bf522SAndroid Build Coastguard Worker     // TODO(xunchang) switch to std::optional
144*288bf522SAndroid Build Coastguard Worker     verity_info verity;
145*288bf522SAndroid Build Coastguard Worker     avb_info avb;
146*288bf522SAndroid Build Coastguard Worker 
hashtreefec_handle147*288bf522SAndroid Build Coastguard Worker     hashtree_info hashtree() const {
148*288bf522SAndroid Build Coastguard Worker         return avb.valid ? avb.hashtree : verity.hashtree;
149*288bf522SAndroid Build Coastguard Worker     }
150*288bf522SAndroid Build Coastguard Worker };
151*288bf522SAndroid Build Coastguard Worker 
152*288bf522SAndroid Build Coastguard Worker /* I/O helpers */
153*288bf522SAndroid Build Coastguard Worker extern bool raw_pread(int fd, void *buf, size_t count, uint64_t offset);
154*288bf522SAndroid Build Coastguard Worker extern bool raw_pwrite(int fd, const void *buf, size_t count, uint64_t offset);
155*288bf522SAndroid Build Coastguard Worker 
156*288bf522SAndroid Build Coastguard Worker /* processing functions */
157*288bf522SAndroid Build Coastguard Worker typedef ssize_t (*read_func)(fec_handle *f, uint8_t *dest, size_t count,
158*288bf522SAndroid Build Coastguard Worker         uint64_t offset, size_t *errors);
159*288bf522SAndroid Build Coastguard Worker 
160*288bf522SAndroid Build Coastguard Worker extern ssize_t process(fec_handle *f, uint8_t *buf, size_t count,
161*288bf522SAndroid Build Coastguard Worker         uint64_t offset, read_func func);
162*288bf522SAndroid Build Coastguard Worker 
163*288bf522SAndroid Build Coastguard Worker /* verity functions */
164*288bf522SAndroid Build Coastguard Worker extern uint64_t verity_get_size(uint64_t file_size, uint32_t *verity_levels,
165*288bf522SAndroid Build Coastguard Worker                                 uint32_t *level_hashes,
166*288bf522SAndroid Build Coastguard Worker                                 uint32_t padded_digest_size);
167*288bf522SAndroid Build Coastguard Worker 
168*288bf522SAndroid Build Coastguard Worker extern int verity_parse_header(fec_handle *f, uint64_t offset);
169*288bf522SAndroid Build Coastguard Worker 
170*288bf522SAndroid Build Coastguard Worker /* helper macros */
171*288bf522SAndroid Build Coastguard Worker #ifndef unlikely
172*288bf522SAndroid Build Coastguard Worker     #define unlikely(x) __builtin_expect(!!(x), 0)
173*288bf522SAndroid Build Coastguard Worker     #define likely(x)   __builtin_expect(!!(x), 1)
174*288bf522SAndroid Build Coastguard Worker #endif
175*288bf522SAndroid Build Coastguard Worker 
176*288bf522SAndroid Build Coastguard Worker #ifndef stringify
177*288bf522SAndroid Build Coastguard Worker     #define __stringify(x) #x
178*288bf522SAndroid Build Coastguard Worker     #define stringify(x) __stringify(x)
179*288bf522SAndroid Build Coastguard Worker #endif
180*288bf522SAndroid Build Coastguard Worker 
181*288bf522SAndroid Build Coastguard Worker /*  warnings, errors, debug output */
182*288bf522SAndroid Build Coastguard Worker #ifdef FEC_NO_KLOG
183*288bf522SAndroid Build Coastguard Worker     #define __log(func, type, format, args...) \
184*288bf522SAndroid Build Coastguard Worker         fprintf(stderr, "fec: <%" PRIu64 "> " type ": %s: " format "\n", \
185*288bf522SAndroid Build Coastguard Worker             android::base::GetThreadId(), __FUNCTION__,  ##args)
186*288bf522SAndroid Build Coastguard Worker #else
187*288bf522SAndroid Build Coastguard Worker     #include <cutils/klog.h>
188*288bf522SAndroid Build Coastguard Worker 
189*288bf522SAndroid Build Coastguard Worker     #define __log(func, type, format, args...) \
190*288bf522SAndroid Build Coastguard Worker         KLOG_##func("fec", "<%d> " type ": %s: " format "\n", \
191*288bf522SAndroid Build Coastguard Worker             (int)syscall(SYS_gettid), __FUNCTION__, ##args)
192*288bf522SAndroid Build Coastguard Worker #endif
193*288bf522SAndroid Build Coastguard Worker 
194*288bf522SAndroid Build Coastguard Worker #ifdef NDEBUG
195*288bf522SAndroid Build Coastguard Worker     #define debug(format, args...)
196*288bf522SAndroid Build Coastguard Worker #else
197*288bf522SAndroid Build Coastguard Worker     #define debug(format, args...) __log(DEBUG, "debug", format, ##args)
198*288bf522SAndroid Build Coastguard Worker #endif
199*288bf522SAndroid Build Coastguard Worker 
200*288bf522SAndroid Build Coastguard Worker #define warn(format, args...) __log(WARNING, "warning", format, ##args)
201*288bf522SAndroid Build Coastguard Worker #define error(format, args...) __log(ERROR, "error", format, ##args)
202*288bf522SAndroid Build Coastguard Worker 
203*288bf522SAndroid Build Coastguard Worker #define check(p) \
204*288bf522SAndroid Build Coastguard Worker     if (unlikely(!(p))) { \
205*288bf522SAndroid Build Coastguard Worker         error("`%s' failed", #p); \
206*288bf522SAndroid Build Coastguard Worker         errno = EFAULT; \
207*288bf522SAndroid Build Coastguard Worker         return -1; \
208*288bf522SAndroid Build Coastguard Worker     }
209*288bf522SAndroid Build Coastguard Worker 
210*288bf522SAndroid Build Coastguard Worker #endif /* __FEC_PRIVATE_H__ */
211