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