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