blob: c229f590facc5769e08690eaaec2237bf14686b5 [file] [log] [blame]
Shawn Willden1615f2e2014-08-13 10:37:40 -06001/*
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 "google_keymaster_utils.h"
18
19namespace keymaster {
20
Shawn Willdenda8485e2014-08-17 08:00:01 -060021uint8_t* dup_buffer(const void* buf, size_t size) {
22 uint8_t* retval = new uint8_t[size];
23 if (retval != NULL)
24 memcpy(retval, buf, size);
25 return retval;
26}
27
Shawn Willdend67afae2014-08-19 12:36:27 -060028bool Buffer::reserve(size_t size) {
29 if (available_write() < size) {
30 size_t new_size = buffer_size_ + size - available_write();
31 uint8_t* new_buffer = new uint8_t[new_size];
32 if (!new_buffer)
33 return false;
Shawn Willdenf2282b32014-08-25 06:49:54 -060034 memcpy(new_buffer, buffer_.get() + read_position_, available_read());
35 memset_s(buffer_.get(), 0, buffer_size_);
36 buffer_.reset(new_buffer);
Shawn Willdend67afae2014-08-19 12:36:27 -060037 buffer_size_ = new_size;
38 write_position_ -= read_position_;
39 read_position_ = 0;
40 }
41 return true;
42}
43
Shawn Willden1615f2e2014-08-13 10:37:40 -060044bool Buffer::Reinitialize(size_t size) {
Shawn Willdenf2282b32014-08-25 06:49:54 -060045 Clear();
46 buffer_.reset(new uint8_t[size]);
47 if (buffer_.get() == NULL)
Shawn Willden1615f2e2014-08-13 10:37:40 -060048 return false;
49 buffer_size_ = size;
50 read_position_ = 0;
51 write_position_ = 0;
52 return true;
53}
54
55bool Buffer::Reinitialize(const void* data, size_t data_len) {
Shawn Willdenf2282b32014-08-25 06:49:54 -060056 Clear();
57 buffer_.reset(new uint8_t[data_len]);
58 if (buffer_.get() == NULL)
Shawn Willden1615f2e2014-08-13 10:37:40 -060059 return false;
60 buffer_size_ = data_len;
Shawn Willdenf2282b32014-08-25 06:49:54 -060061 memcpy(buffer_.get(), data, data_len);
Shawn Willden1615f2e2014-08-13 10:37:40 -060062 read_position_ = 0;
63 write_position_ = buffer_size_;
64 return true;
65}
66
67size_t Buffer::available_write() const {
68 return buffer_size_ - write_position_;
69}
70
71size_t Buffer::available_read() const {
72 return write_position_ - read_position_;
73}
74
75bool Buffer::write(const uint8_t* src, size_t write_length) {
76 if (available_write() < write_length)
77 return false;
Shawn Willdenf2282b32014-08-25 06:49:54 -060078 memcpy(buffer_.get() + write_position_, src, write_length);
Shawn Willden1615f2e2014-08-13 10:37:40 -060079 write_position_ += write_length;
80 return true;
81}
82
83bool Buffer::read(uint8_t* dest, size_t read_length) {
84 if (available_read() < read_length)
85 return false;
Shawn Willdenf2282b32014-08-25 06:49:54 -060086 memcpy(dest, buffer_.get() + read_position_, read_length);
Shawn Willden1615f2e2014-08-13 10:37:40 -060087 read_position_ += read_length;
88 return true;
89}
90
Shawn Willdenda8485e2014-08-17 08:00:01 -060091size_t Buffer::SerializedSize() const {
92 return sizeof(uint32_t) + available_read();
93}
94
95uint8_t* Buffer::Serialize(uint8_t* buf, const uint8_t* end) const {
96 return append_size_and_data_to_buf(buf, end, peek_read(), available_read());
97}
98
99bool Buffer::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
Shawn Willdenf2282b32014-08-25 06:49:54 -0600100 Clear();
101 if (!copy_size_and_data_from_buf(buf_ptr, end, &buffer_size_, &buffer_)) {
102 buffer_.reset();
103 buffer_size_ = 0;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600104 return false;
Shawn Willdenf2282b32014-08-25 06:49:54 -0600105 }
Shawn Willdenda8485e2014-08-17 08:00:01 -0600106 write_position_ = buffer_size_;
107 return true;
108}
109
Shawn Willdenf2282b32014-08-25 06:49:54 -0600110void Buffer::Clear() {
111 if (buffer_.get())
112 memset_s(buffer_.get(), 0, buffer_size_);
113 buffer_.reset();
114 read_position_ = 0;
115 write_position_ = 0;
116 buffer_size_ = 0;
117}
118
Shawn Willden43e999e2014-08-13 13:29:50 -0600119int memcmp_s(const void* p1, const void* p2, size_t length) {
120 const uint8_t* s1 = static_cast<const uint8_t*>(p1);
121 const uint8_t* s2 = static_cast<const uint8_t*>(p2);
122 uint8_t result = 0;
123 while (length-- > 0)
124 result |= *s1++ ^ *s2++;
125 return result == 0 ? 0 : 1;
126}
127
Shawn Willden1615f2e2014-08-13 10:37:40 -0600128} // namespace keymaster