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