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