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