15ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden/* 25ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * Copyright 2014 The Android Open Source Project 35ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * 45ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 55ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * you may not use this file except in compliance with the License. 65ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * You may obtain a copy of the License at 75ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * 85ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * http://www.apache.org/licenses/LICENSE-2.0 95ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * 105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * Unless required by applicable law or agreed to in writing, software 115ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * See the License for the specific language governing permissions and 145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * limitations under the License. 155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden */ 165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden#include <keymaster/serializable.h> 180f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 190f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden#include <assert.h> 200f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 21f38a002624126ca837865826f948edc9100d6e8aJanis Danisevskis#include <keymaster/new> 220f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 23b6837e7a62a1192e33beef586282812239ee8b28Shawn Willden#include <keymaster/android_keymaster_utils.h> 245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdennamespace keymaster { 265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 278d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenuint8_t* append_to_buf(uint8_t* buf, const uint8_t* end, const void* data, size_t data_len) { 28637dd8429285bfdc0b89622476ea94d782b1eb14Sami Tolvanen if (__pval(buf) + data_len < __pval(buf)) // Pointer wrap check 290f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return buf; 300f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 310f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (buf + data_len <= end) { 328d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden memcpy(buf, data, data_len); 330f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return buf + data_len; 340f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden } 350f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return buf; 368d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 378d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 38172f8c9be706e27f43022063bbc7f4b0177583acShawn Willdenbool copy_from_buf(const uint8_t** buf_ptr, const uint8_t* end, void* dest, size_t size) { 39637dd8429285bfdc0b89622476ea94d782b1eb14Sami Tolvanen if (__pval(*buf_ptr) + size < __pval(*buf_ptr)) // Pointer wrap check 400f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return false; 410f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 42172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (end < *buf_ptr + size) 435ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 44172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden memcpy(dest, *buf_ptr, size); 45172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden *buf_ptr += size; 465ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 475ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 485ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 49172f8c9be706e27f43022063bbc7f4b0177583acShawn Willdenbool copy_size_and_data_from_buf(const uint8_t** buf_ptr, const uint8_t* end, size_t* size, 50f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden UniquePtr<uint8_t[]>* dest) { 510f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (!copy_uint32_from_buf(buf_ptr, end, size)) 5258e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden return false; 530f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 54637dd8429285bfdc0b89622476ea94d782b1eb14Sami Tolvanen if (__pval(*buf_ptr) + *size < __pval(*buf_ptr)) // Pointer wrap check 550f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return false; 560f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 570f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (*buf_ptr + *size > end) 580f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return false; 590f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 60172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (*size == 0) { 61f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden dest->reset(); 62172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return true; 63172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden } 640f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden dest->reset(new (std::nothrow) uint8_t[*size]); 650f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (!dest->get()) 668d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 67f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden return copy_from_buf(buf_ptr, end, dest->get(), *size); 6858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden} 6958e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 7098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdenbool Buffer::reserve(size_t size) { 7198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden if (available_write() < size) { 7298d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden size_t new_size = buffer_size_ + size - available_write(); 730f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden uint8_t* new_buffer = new (std::nothrow) uint8_t[new_size]; 7498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden if (!new_buffer) 7598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return false; 7698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden memcpy(new_buffer, buffer_.get() + read_position_, available_read()); 7798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden memset_s(buffer_.get(), 0, buffer_size_); 7898d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden buffer_.reset(new_buffer); 7998d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden buffer_size_ = new_size; 8098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden write_position_ -= read_position_; 8198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden read_position_ = 0; 8298d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden } 8398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return true; 8498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 8598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 8698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdenbool Buffer::Reinitialize(size_t size) { 8798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden Clear(); 880f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden buffer_.reset(new (std::nothrow) uint8_t[size]); 890f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (!buffer_.get()) 9098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return false; 9198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden buffer_size_ = size; 9298d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden read_position_ = 0; 9398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden write_position_ = 0; 9498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return true; 9598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 9698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 9798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdenbool Buffer::Reinitialize(const void* data, size_t data_len) { 9898d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden Clear(); 99637dd8429285bfdc0b89622476ea94d782b1eb14Sami Tolvanen if (__pval(data) + data_len < __pval(data)) // Pointer wrap check 1000f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return false; 1010f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden buffer_.reset(new (std::nothrow) uint8_t[data_len]); 1020f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (!buffer_.get()) 10398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return false; 10498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden buffer_size_ = data_len; 10598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden memcpy(buffer_.get(), data, data_len); 10698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden read_position_ = 0; 10798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden write_position_ = buffer_size_; 10898d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return true; 10998d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 11098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 11198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdensize_t Buffer::available_write() const { 1120f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden assert(buffer_size_ >= write_position_); 11398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return buffer_size_ - write_position_; 11498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 11598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 11698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdensize_t Buffer::available_read() const { 1170f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden assert(buffer_size_ >= write_position_); 1180f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden assert(write_position_ >= read_position_); 11998d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return write_position_ - read_position_; 12098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 12198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 12298d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdenbool Buffer::write(const uint8_t* src, size_t write_length) { 12398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden if (available_write() < write_length) 12498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return false; 12598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden memcpy(buffer_.get() + write_position_, src, write_length); 12698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden write_position_ += write_length; 12798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return true; 12898d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 12998d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 13098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdenbool Buffer::read(uint8_t* dest, size_t read_length) { 13198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden if (available_read() < read_length) 13298d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return false; 13398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden memcpy(dest, buffer_.get() + read_position_, read_length); 13498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden read_position_ += read_length; 13598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return true; 13698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 13798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 13898d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdensize_t Buffer::SerializedSize() const { 13998d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return sizeof(uint32_t) + available_read(); 14098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 14198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 14298d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdenuint8_t* Buffer::Serialize(uint8_t* buf, const uint8_t* end) const { 14398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return append_size_and_data_to_buf(buf, end, peek_read(), available_read()); 14498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 14598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 14698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdenbool Buffer::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { 14798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden Clear(); 14898d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden if (!copy_size_and_data_from_buf(buf_ptr, end, &buffer_size_, &buffer_)) { 14998d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden buffer_.reset(); 15098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden buffer_size_ = 0; 15198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return false; 15298d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden } 15398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden write_position_ = buffer_size_; 15498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden return true; 15598d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 15698d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 15798d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willdenvoid Buffer::Clear() { 1581834d5f82a7ad5884c184fd22c702ac9d915af45Shawn Willden memset_s(buffer_.get(), 0, buffer_size_); 15998d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden buffer_.reset(); 16098d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden read_position_ = 0; 16198d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden write_position_ = 0; 16298d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden buffer_size_ = 0; 16398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden} 16498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden 1655ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} // namespace keymaster 166