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