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