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