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