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#include <keymaster/serializable.h> 18#include <keymaster/google_keymaster_utils.h> 19 20namespace keymaster { 21 22uint8_t* append_to_buf(uint8_t* buf, const uint8_t* end, const void* data, size_t data_len) { 23 if (buf + data_len <= end) 24 memcpy(buf, data, data_len); 25 return buf + data_len; 26} 27 28bool copy_from_buf(const uint8_t** buf_ptr, const uint8_t* end, void* dest, size_t size) { 29 if (end < *buf_ptr + size) 30 return false; 31 memcpy(dest, *buf_ptr, size); 32 *buf_ptr += size; 33 return true; 34} 35 36bool copy_size_and_data_from_buf(const uint8_t** buf_ptr, const uint8_t* end, size_t* size, 37 UniquePtr<uint8_t[]>* dest) { 38 if (!copy_uint32_from_buf(buf_ptr, end, size) || *buf_ptr + *size > end) { 39 return false; 40 } 41 if (*size == 0) { 42 dest->reset(); 43 return true; 44 } 45 dest->reset(new uint8_t[*size]); 46 if (dest->get() == NULL) 47 return false; 48 return copy_from_buf(buf_ptr, end, dest->get(), *size); 49} 50 51bool Buffer::reserve(size_t size) { 52 if (available_write() < size) { 53 size_t new_size = buffer_size_ + size - available_write(); 54 uint8_t* new_buffer = new uint8_t[new_size]; 55 if (!new_buffer) 56 return false; 57 memcpy(new_buffer, buffer_.get() + read_position_, available_read()); 58 memset_s(buffer_.get(), 0, buffer_size_); 59 buffer_.reset(new_buffer); 60 buffer_size_ = new_size; 61 write_position_ -= read_position_; 62 read_position_ = 0; 63 } 64 return true; 65} 66 67bool Buffer::Reinitialize(size_t size) { 68 Clear(); 69 buffer_.reset(new uint8_t[size]); 70 if (buffer_.get() == NULL) 71 return false; 72 buffer_size_ = size; 73 read_position_ = 0; 74 write_position_ = 0; 75 return true; 76} 77 78bool Buffer::Reinitialize(const void* data, size_t data_len) { 79 Clear(); 80 buffer_.reset(new uint8_t[data_len]); 81 if (buffer_.get() == NULL) 82 return false; 83 buffer_size_ = data_len; 84 memcpy(buffer_.get(), data, data_len); 85 read_position_ = 0; 86 write_position_ = buffer_size_; 87 return true; 88} 89 90size_t Buffer::available_write() const { 91 return buffer_size_ - write_position_; 92} 93 94size_t Buffer::available_read() const { 95 return write_position_ - read_position_; 96} 97 98bool Buffer::write(const uint8_t* src, size_t write_length) { 99 if (available_write() < write_length) 100 return false; 101 memcpy(buffer_.get() + write_position_, src, write_length); 102 write_position_ += write_length; 103 return true; 104} 105 106bool Buffer::read(uint8_t* dest, size_t read_length) { 107 if (available_read() < read_length) 108 return false; 109 memcpy(dest, buffer_.get() + read_position_, read_length); 110 read_position_ += read_length; 111 return true; 112} 113 114size_t Buffer::SerializedSize() const { 115 return sizeof(uint32_t) + available_read(); 116} 117 118uint8_t* Buffer::Serialize(uint8_t* buf, const uint8_t* end) const { 119 return append_size_and_data_to_buf(buf, end, peek_read(), available_read()); 120} 121 122bool Buffer::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { 123 Clear(); 124 if (!copy_size_and_data_from_buf(buf_ptr, end, &buffer_size_, &buffer_)) { 125 buffer_.reset(); 126 buffer_size_ = 0; 127 return false; 128 } 129 write_position_ = buffer_size_; 130 return true; 131} 132 133void Buffer::Clear() { 134 if (buffer_.get()) 135 memset_s(buffer_.get(), 0, buffer_size_); 136 buffer_.reset(); 137 read_position_ = 0; 138 write_position_ = 0; 139 buffer_size_ = 0; 140} 141 142} // namespace keymaster 143