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_IO_H___ 18*288bf522SAndroid Build Coastguard Worker #define ___FEC_IO_H___ 19*288bf522SAndroid Build Coastguard Worker 20*288bf522SAndroid Build Coastguard Worker #include <fcntl.h> 21*288bf522SAndroid Build Coastguard Worker #include <inttypes.h> 22*288bf522SAndroid Build Coastguard Worker #include <limits.h> 23*288bf522SAndroid Build Coastguard Worker #include <stdbool.h> 24*288bf522SAndroid Build Coastguard Worker #include <stdio.h> 25*288bf522SAndroid Build Coastguard Worker #include <sys/types.h> 26*288bf522SAndroid Build Coastguard Worker #include <unistd.h> 27*288bf522SAndroid Build Coastguard Worker 28*288bf522SAndroid Build Coastguard Worker #include <crypto_utils/android_pubkey.h> 29*288bf522SAndroid Build Coastguard Worker 30*288bf522SAndroid Build Coastguard Worker #ifdef __cplusplus 31*288bf522SAndroid Build Coastguard Worker extern "C" { 32*288bf522SAndroid Build Coastguard Worker #endif 33*288bf522SAndroid Build Coastguard Worker 34*288bf522SAndroid Build Coastguard Worker #ifndef SHA256_DIGEST_LENGTH 35*288bf522SAndroid Build Coastguard Worker #define SHA256_DIGEST_LENGTH 32 36*288bf522SAndroid Build Coastguard Worker #endif 37*288bf522SAndroid Build Coastguard Worker 38*288bf522SAndroid Build Coastguard Worker #define FEC_BLOCKSIZE 4096 39*288bf522SAndroid Build Coastguard Worker #define FEC_DEFAULT_ROOTS 2 40*288bf522SAndroid Build Coastguard Worker 41*288bf522SAndroid Build Coastguard Worker #define FEC_MAGIC 0xFECFECFE 42*288bf522SAndroid Build Coastguard Worker #define FEC_VERSION 0 43*288bf522SAndroid Build Coastguard Worker 44*288bf522SAndroid Build Coastguard Worker /* disk format for the header */ 45*288bf522SAndroid Build Coastguard Worker struct fec_header { 46*288bf522SAndroid Build Coastguard Worker uint32_t magic; 47*288bf522SAndroid Build Coastguard Worker uint32_t version; 48*288bf522SAndroid Build Coastguard Worker uint32_t size; 49*288bf522SAndroid Build Coastguard Worker uint32_t roots; 50*288bf522SAndroid Build Coastguard Worker uint32_t fec_size; 51*288bf522SAndroid Build Coastguard Worker uint64_t inp_size; 52*288bf522SAndroid Build Coastguard Worker uint8_t hash[SHA256_DIGEST_LENGTH]; 53*288bf522SAndroid Build Coastguard Worker } __attribute__ ((packed)); 54*288bf522SAndroid Build Coastguard Worker 55*288bf522SAndroid Build Coastguard Worker struct fec_status { 56*288bf522SAndroid Build Coastguard Worker int flags; 57*288bf522SAndroid Build Coastguard Worker int mode; 58*288bf522SAndroid Build Coastguard Worker uint64_t errors; 59*288bf522SAndroid Build Coastguard Worker uint64_t data_size; 60*288bf522SAndroid Build Coastguard Worker uint64_t size; 61*288bf522SAndroid Build Coastguard Worker }; 62*288bf522SAndroid Build Coastguard Worker 63*288bf522SAndroid Build Coastguard Worker struct fec_ecc_metadata { 64*288bf522SAndroid Build Coastguard Worker bool valid; 65*288bf522SAndroid Build Coastguard Worker uint32_t roots; 66*288bf522SAndroid Build Coastguard Worker uint64_t blocks; 67*288bf522SAndroid Build Coastguard Worker uint64_t rounds; 68*288bf522SAndroid Build Coastguard Worker uint64_t start; 69*288bf522SAndroid Build Coastguard Worker }; 70*288bf522SAndroid Build Coastguard Worker 71*288bf522SAndroid Build Coastguard Worker struct fec_verity_metadata { 72*288bf522SAndroid Build Coastguard Worker bool disabled; 73*288bf522SAndroid Build Coastguard Worker uint64_t data_size; 74*288bf522SAndroid Build Coastguard Worker uint8_t signature[ANDROID_PUBKEY_MODULUS_SIZE]; 75*288bf522SAndroid Build Coastguard Worker uint8_t ecc_signature[ANDROID_PUBKEY_MODULUS_SIZE]; 76*288bf522SAndroid Build Coastguard Worker const char *table; 77*288bf522SAndroid Build Coastguard Worker uint32_t table_length; 78*288bf522SAndroid Build Coastguard Worker }; 79*288bf522SAndroid Build Coastguard Worker 80*288bf522SAndroid Build Coastguard Worker /* flags for fec_open */ 81*288bf522SAndroid Build Coastguard Worker enum { 82*288bf522SAndroid Build Coastguard Worker FEC_FS_EXT4 = 1 << 0, 83*288bf522SAndroid Build Coastguard Worker FEC_FS_SQUASH = 1 << 1, 84*288bf522SAndroid Build Coastguard Worker FEC_VERITY_DISABLE = 1 << 8 85*288bf522SAndroid Build Coastguard Worker }; 86*288bf522SAndroid Build Coastguard Worker 87*288bf522SAndroid Build Coastguard Worker struct fec_handle; 88*288bf522SAndroid Build Coastguard Worker 89*288bf522SAndroid Build Coastguard Worker /* file access */ 90*288bf522SAndroid Build Coastguard Worker extern int fec_open(struct fec_handle **f, const char *path, int mode, 91*288bf522SAndroid Build Coastguard Worker int flags, int roots); 92*288bf522SAndroid Build Coastguard Worker 93*288bf522SAndroid Build Coastguard Worker extern int fec_close(struct fec_handle *f); 94*288bf522SAndroid Build Coastguard Worker 95*288bf522SAndroid Build Coastguard Worker extern int fec_verity_set_status(struct fec_handle *f, bool enabled); 96*288bf522SAndroid Build Coastguard Worker 97*288bf522SAndroid Build Coastguard Worker extern int fec_verity_get_metadata(struct fec_handle *f, 98*288bf522SAndroid Build Coastguard Worker struct fec_verity_metadata *data); 99*288bf522SAndroid Build Coastguard Worker 100*288bf522SAndroid Build Coastguard Worker extern int fec_ecc_get_metadata(struct fec_handle *f, 101*288bf522SAndroid Build Coastguard Worker struct fec_ecc_metadata *data); 102*288bf522SAndroid Build Coastguard Worker 103*288bf522SAndroid Build Coastguard Worker extern int fec_get_status(struct fec_handle *f, struct fec_status *s); 104*288bf522SAndroid Build Coastguard Worker 105*288bf522SAndroid Build Coastguard Worker extern int fec_seek(struct fec_handle *f, int64_t offset, int whence); 106*288bf522SAndroid Build Coastguard Worker 107*288bf522SAndroid Build Coastguard Worker extern ssize_t fec_read(struct fec_handle *f, void *buf, size_t count); 108*288bf522SAndroid Build Coastguard Worker 109*288bf522SAndroid Build Coastguard Worker extern ssize_t fec_pread(struct fec_handle *f, void *buf, size_t count, 110*288bf522SAndroid Build Coastguard Worker uint64_t offset); 111*288bf522SAndroid Build Coastguard Worker 112*288bf522SAndroid Build Coastguard Worker #ifdef __cplusplus 113*288bf522SAndroid Build Coastguard Worker } /* extern "C" */ 114*288bf522SAndroid Build Coastguard Worker 115*288bf522SAndroid Build Coastguard Worker #include <memory> 116*288bf522SAndroid Build Coastguard Worker #include <string> 117*288bf522SAndroid Build Coastguard Worker 118*288bf522SAndroid Build Coastguard Worker /* C++ wrappers for fec_handle and operations */ 119*288bf522SAndroid Build Coastguard Worker namespace fec { 120*288bf522SAndroid Build Coastguard Worker using handle = std::unique_ptr<fec_handle, decltype(&fec_close)>; 121*288bf522SAndroid Build Coastguard Worker 122*288bf522SAndroid Build Coastguard Worker class io { 123*288bf522SAndroid Build Coastguard Worker public: io()124*288bf522SAndroid Build Coastguard Worker io() : handle_(nullptr, fec_close) {} 125*288bf522SAndroid Build Coastguard Worker 126*288bf522SAndroid Build Coastguard Worker explicit io(const std::string& fn, int mode = O_RDONLY, int flags = 0, handle_(nullptr,fec_close)127*288bf522SAndroid Build Coastguard Worker int roots = FEC_DEFAULT_ROOTS) : handle_(nullptr, fec_close) { 128*288bf522SAndroid Build Coastguard Worker open(fn, mode, flags, roots); 129*288bf522SAndroid Build Coastguard Worker } 130*288bf522SAndroid Build Coastguard Worker 131*288bf522SAndroid Build Coastguard Worker explicit operator bool() const { 132*288bf522SAndroid Build Coastguard Worker return !!handle_; 133*288bf522SAndroid Build Coastguard Worker } 134*288bf522SAndroid Build Coastguard Worker 135*288bf522SAndroid Build Coastguard Worker bool open(const std::string& fn, int mode = O_RDONLY, int flags = 0, 136*288bf522SAndroid Build Coastguard Worker int roots = FEC_DEFAULT_ROOTS) 137*288bf522SAndroid Build Coastguard Worker { 138*288bf522SAndroid Build Coastguard Worker fec_handle *fh = nullptr; 139*288bf522SAndroid Build Coastguard Worker int rc = fec_open(&fh, fn.c_str(), mode, flags, roots); 140*288bf522SAndroid Build Coastguard Worker if (!rc) { 141*288bf522SAndroid Build Coastguard Worker handle_.reset(fh); 142*288bf522SAndroid Build Coastguard Worker } 143*288bf522SAndroid Build Coastguard Worker return !rc; 144*288bf522SAndroid Build Coastguard Worker } 145*288bf522SAndroid Build Coastguard Worker close()146*288bf522SAndroid Build Coastguard Worker bool close() { 147*288bf522SAndroid Build Coastguard Worker return !fec_close(handle_.release()); 148*288bf522SAndroid Build Coastguard Worker } 149*288bf522SAndroid Build Coastguard Worker seek(int64_t offset,int whence)150*288bf522SAndroid Build Coastguard Worker bool seek(int64_t offset, int whence) { 151*288bf522SAndroid Build Coastguard Worker return !fec_seek(handle_.get(), offset, whence); 152*288bf522SAndroid Build Coastguard Worker } 153*288bf522SAndroid Build Coastguard Worker read(void * buf,size_t count)154*288bf522SAndroid Build Coastguard Worker ssize_t read(void *buf, size_t count) { 155*288bf522SAndroid Build Coastguard Worker return fec_read(handle_.get(), buf, count); 156*288bf522SAndroid Build Coastguard Worker } 157*288bf522SAndroid Build Coastguard Worker pread(void * buf,size_t count,uint64_t offset)158*288bf522SAndroid Build Coastguard Worker ssize_t pread(void *buf, size_t count, uint64_t offset) { 159*288bf522SAndroid Build Coastguard Worker return fec_pread(handle_.get(), buf, count, offset); 160*288bf522SAndroid Build Coastguard Worker } 161*288bf522SAndroid Build Coastguard Worker get_status(fec_status & status)162*288bf522SAndroid Build Coastguard Worker bool get_status(fec_status& status) { 163*288bf522SAndroid Build Coastguard Worker return !fec_get_status(handle_.get(), &status); 164*288bf522SAndroid Build Coastguard Worker } 165*288bf522SAndroid Build Coastguard Worker get_verity_metadata(fec_verity_metadata & data)166*288bf522SAndroid Build Coastguard Worker bool get_verity_metadata(fec_verity_metadata& data) { 167*288bf522SAndroid Build Coastguard Worker return !fec_verity_get_metadata(handle_.get(), &data); 168*288bf522SAndroid Build Coastguard Worker } 169*288bf522SAndroid Build Coastguard Worker has_verity()170*288bf522SAndroid Build Coastguard Worker bool has_verity() { 171*288bf522SAndroid Build Coastguard Worker fec_verity_metadata data; 172*288bf522SAndroid Build Coastguard Worker return get_verity_metadata(data); 173*288bf522SAndroid Build Coastguard Worker } 174*288bf522SAndroid Build Coastguard Worker get_ecc_metadata(fec_ecc_metadata & data)175*288bf522SAndroid Build Coastguard Worker bool get_ecc_metadata(fec_ecc_metadata& data) { 176*288bf522SAndroid Build Coastguard Worker return !fec_ecc_get_metadata(handle_.get(), &data); 177*288bf522SAndroid Build Coastguard Worker } 178*288bf522SAndroid Build Coastguard Worker has_ecc()179*288bf522SAndroid Build Coastguard Worker bool has_ecc() { 180*288bf522SAndroid Build Coastguard Worker fec_ecc_metadata data; 181*288bf522SAndroid Build Coastguard Worker return get_ecc_metadata(data) && data.valid; 182*288bf522SAndroid Build Coastguard Worker } 183*288bf522SAndroid Build Coastguard Worker set_verity_status(bool enabled)184*288bf522SAndroid Build Coastguard Worker bool set_verity_status(bool enabled) { 185*288bf522SAndroid Build Coastguard Worker return !fec_verity_set_status(handle_.get(), enabled); 186*288bf522SAndroid Build Coastguard Worker } 187*288bf522SAndroid Build Coastguard Worker 188*288bf522SAndroid Build Coastguard Worker private: 189*288bf522SAndroid Build Coastguard Worker handle handle_; 190*288bf522SAndroid Build Coastguard Worker }; 191*288bf522SAndroid Build Coastguard Worker } 192*288bf522SAndroid Build Coastguard Worker #endif 193*288bf522SAndroid Build Coastguard Worker 194*288bf522SAndroid Build Coastguard Worker #endif /* ___FEC_IO_H___ */ 195