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