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