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