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