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