Home | History | Annotate | Download | only in keymaster
      1 /*
      2  * Copyright 2014 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 SYSTEM_KEYMASTER_SERIALIZABLE_H_
     18 #define SYSTEM_KEYMASTER_SERIALIZABLE_H_
     19 
     20 #include <stdint.h>
     21 #include <stdlib.h>
     22 #include <string.h>
     23 
     24 #include <cstddef>
     25 
     26 #include <UniquePtr.h>
     27 
     28 namespace keymaster {
     29 
     30 class Serializable {
     31   public:
     32     Serializable() {}
     33     virtual ~Serializable() {}
     34 
     35     /**
     36      * Return the size of the serialized representation of this object.
     37      */
     38     virtual size_t SerializedSize() const = 0;
     39 
     40     /**
     41      * Serialize this object into the provided buffer.  Returns a pointer to the byte after the last
     42      * written.  Will not write past \p end, which should point to \p buf + size of the buffer
     43      * (i.e. one past the end of the buffer).
     44      */
     45     virtual uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const = 0;
     46 
     47     /**
     48      * Deserialize from the provided buffer, copying the data into newly-allocated storage.  Returns
     49      * true if successful, and advances *buf past the bytes read.
     50      */
     51     virtual bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) = 0;
     52 
     53   private:
     54     // Disallow copying and assignment.
     55     Serializable(const Serializable&);
     56     void operator=(const Serializable&);
     57 };
     58 
     59 /*
     60  * Utility functions for writing Serialize() methods
     61  */
     62 
     63 /**
     64  * Append a byte array to a buffer.  Note that by itself this function isn't very useful, because it
     65  * provides no indication in the serialized buffer of what the array size is.  For writing arrays,
     66  * see \p append_size_and_data_to_buf().
     67  *
     68  * Returns a pointer to the first byte after the data written.
     69  */
     70 uint8_t* append_to_buf(uint8_t* buf, const uint8_t* end, const void* data, size_t data_len);
     71 
     72 /**
     73  * Append some type of value convertible to a uint32_t to a buffer.  This is primarily used for
     74  * writing enumerated values, and uint32_ts.
     75  *
     76  * Returns a pointer to the first byte after the data written.
     77  */
     78 template <typename T>
     79 inline uint8_t* append_uint32_to_buf(uint8_t* buf, const uint8_t* end, T value) {
     80     uint32_t val = static_cast<uint32_t>(value);
     81     return append_to_buf(buf, end, &val, sizeof(val));
     82 }
     83 
     84 /**
     85  * Append a uint64_t to a buffer.  Returns a pointer to the first byte after the data written.
     86  */
     87 inline uint8_t* append_uint64_to_buf(uint8_t* buf, const uint8_t* end, uint64_t value) {
     88     return append_to_buf(buf, end, &value, sizeof(value));
     89 }
     90 
     91 /**
     92  * Appends a byte array to a buffer, prefixing it with a 32-bit size field.  Returns a pointer to
     93  * the first byte after the data written.
     94  *
     95  * See copy_size_and_data_from_buf().
     96  */
     97 inline uint8_t* append_size_and_data_to_buf(uint8_t* buf, const uint8_t* end, const void* data,
     98                                             size_t data_len) {
     99     buf = append_uint32_to_buf(buf, end, data_len);
    100     return append_to_buf(buf, end, data, data_len);
    101 }
    102 
    103 /**
    104  * Appends an array of values that are convertible to uint32_t as uint32ts to a buffer, prefixing a
    105  * count so deserialization knows how many values to read.
    106  *
    107  * See copy_uint32_array_from_buf().
    108  */
    109 template <typename T>
    110 inline uint8_t* append_uint32_array_to_buf(uint8_t* buf, const uint8_t* end, const T* data,
    111                                            size_t count) {
    112     buf = append_uint32_to_buf(buf, end, count);
    113     for (size_t i = 0; i < count; ++i)
    114         buf = append_uint32_to_buf(buf, end, static_cast<uint32_t>(data[i]));
    115     return buf;
    116 }
    117 
    118 /*
    119  * Utility functions for writing Deserialize() methods.
    120  */
    121 
    122 /**
    123  * Copy \p size bytes from \p *buf_ptr into \p dest.  If there are fewer than \p size bytes to read,
    124  * returns false.  Advances *buf_ptr to the next byte to be read.
    125  */
    126 bool copy_from_buf(const uint8_t** buf_ptr, const uint8_t* end, void* dest, size_t size);
    127 
    128 /**
    129  * Extracts a uint32_t size from *buf_ptr, placing it in \p *size, and then reads *size bytes from
    130  * *buf_ptr, placing them in newly-allocated storage in *dest.  If there aren't enough bytes in
    131  * *buf_ptr, returns false.  Advances \p *buf_ptr to the next byte to be read.
    132  *
    133  * See \p append_size_and_data_to_buf().
    134  */
    135 bool copy_size_and_data_from_buf(const uint8_t** buf_ptr, const uint8_t* end, size_t* size,
    136                                  UniquePtr<uint8_t[]>* dest);
    137 
    138 /**
    139  * Copies a value convertible from uint32_t from \p *buf_ptr.  Returns false if there are less than
    140  * four bytes remaining in \p *buf_ptr.  Advances \p *buf_ptr to the next byte to be read.
    141  */
    142 template <typename T>
    143 inline bool copy_uint32_from_buf(const uint8_t** buf_ptr, const uint8_t* end, T* value) {
    144     uint32_t val;
    145     if (!copy_from_buf(buf_ptr, end, &val, sizeof(val)))
    146         return false;
    147     *value = static_cast<T>(val);
    148     return true;
    149 }
    150 
    151 /**
    152  * Copies a uint64_t from \p *buf_ptr.  Returns false if there are less than eight bytes remaining
    153  * in \p *buf_ptr.  Advances \p *buf_ptr to the next byte to be read.
    154  */
    155 inline bool copy_uint64_from_buf(const uint8_t** buf_ptr, const uint8_t* end, uint64_t* value) {
    156     return copy_from_buf(buf_ptr, end, value, sizeof(*value));
    157 }
    158 
    159 /**
    160  * Copies an array of values convertible to uint32_t from \p *buf_ptr, first reading a count of
    161  * values to read. The count is returned in \p *count and the values returned in newly-allocated
    162  * storage at *data.  Returns false if there are insufficient bytes at \p *buf_ptr.  Advances \p
    163  * *buf_ptr to the next byte to be read.
    164  */
    165 template <typename T>
    166 inline bool copy_uint32_array_from_buf(const uint8_t** buf_ptr, const uint8_t* end,
    167                                        UniquePtr<T[]>* data, size_t* count) {
    168     if (!copy_uint32_from_buf(buf_ptr, end, count) || *buf_ptr + *count * sizeof(uint32_t) > end)
    169         return false;
    170     data->reset(new T[*count]);
    171     for (size_t i = 0; i < *count; ++i)
    172         if (!copy_uint32_from_buf(buf_ptr, end, &(*data)[i]))
    173             return false;
    174     return true;
    175 }
    176 
    177 /**
    178  * A simple buffer that supports reading and writing.  Manages its own memory.
    179  */
    180 class Buffer : public Serializable {
    181   public:
    182     Buffer() : buffer_(NULL), buffer_size_(0), read_position_(0), write_position_(0) {}
    183     Buffer(size_t size) : buffer_(NULL) { Reinitialize(size); }
    184     Buffer(const void* buf, size_t size) : buffer_(NULL) { Reinitialize(buf, size); }
    185 
    186     // Grow the buffer so that at least \p size bytes can be written.
    187     bool reserve(size_t size);
    188 
    189     bool Reinitialize(size_t size);
    190     bool Reinitialize(const void* buf, size_t size);
    191 
    192     // Reinitialize with a copy of the provided buffer's readable data.
    193     bool Reinitialize(const Buffer& buffer) {
    194         return Reinitialize(buffer.peek_read(), buffer.available_read());
    195     }
    196 
    197     void Clear();
    198 
    199     size_t available_write() const;
    200     size_t available_read() const;
    201     size_t buffer_size() const { return buffer_size_; }
    202 
    203     bool write(const uint8_t* src, size_t write_length);
    204     bool read(uint8_t* dest, size_t read_length);
    205     const uint8_t* peek_read() const { return buffer_.get() + read_position_; }
    206     void advance_read(int distance) { read_position_ += distance; }
    207     uint8_t* peek_write() { return buffer_.get() + write_position_; }
    208     void advance_write(int distance) { write_position_ += distance; }
    209 
    210     size_t SerializedSize() const;
    211     uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const;
    212     bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end);
    213 
    214   private:
    215     // Disallow copy construction and assignment.
    216     void operator=(const Buffer& other);
    217     Buffer(const Buffer&);
    218 
    219     UniquePtr<uint8_t[]> buffer_;
    220     size_t buffer_size_;
    221     int read_position_;
    222     int write_position_;
    223 };
    224 
    225 }  // namespace keymaster
    226 
    227 #endif  // SYSTEM_KEYMASTER_SERIALIZABLE_H_
    228