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