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 
     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:
    124         io() : handle_(nullptr, fec_close) {}
    125 
    126         explicit io(const std::string& fn, int mode = O_RDONLY, int flags = 0,
    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 
    146         bool close() {
    147             return !fec_close(handle_.release());
    148         }
    149 
    150         bool seek(int64_t offset, int whence) {
    151             return !fec_seek(handle_.get(), offset, whence);
    152         }
    153 
    154         ssize_t read(void *buf, size_t count) {
    155             return fec_read(handle_.get(), buf, count);
    156         }
    157 
    158         ssize_t pread(void *buf, size_t count, uint64_t offset) {
    159             return fec_pread(handle_.get(), buf, count, offset);
    160         }
    161 
    162         bool get_status(fec_status& status) {
    163             return !fec_get_status(handle_.get(), &status);
    164         }
    165 
    166         bool get_verity_metadata(fec_verity_metadata& data) {
    167             return !fec_verity_get_metadata(handle_.get(), &data);
    168         }
    169 
    170         bool has_verity() {
    171             fec_verity_metadata data;
    172             return get_verity_metadata(data);
    173         }
    174 
    175         bool get_ecc_metadata(fec_ecc_metadata& data) {
    176             return !fec_ecc_get_metadata(handle_.get(), &data);
    177         }
    178 
    179         bool has_ecc() {
    180             fec_ecc_metadata data;
    181             return get_ecc_metadata(data) && data.valid;
    182         }
    183 
    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