blob: 01e66a5c3349002cc97191e11e05d70ff2ed0586 [file] [log] [blame]
Shawn Willden5ada7b62014-07-29 09:44:17 -06001/*
2 * Copyright (C) 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 <stdlib.h>
18#include <string.h>
19#include <stddef.h>
20
21#include <assert.h>
22
Shawn Willden98d9b922014-08-26 08:14:10 -060023#include <keymaster/authorization_set.h>
24#include <keymaster/google_keymaster_utils.h>
Shawn Willden5ada7b62014-07-29 09:44:17 -060025
26namespace keymaster {
27
28static inline bool is_blob_tag(keymaster_tag_t tag) {
29 return (keymaster_tag_get_type(tag) == KM_BYTES || keymaster_tag_get_type(tag) == KM_BIGNUM);
30}
31
32const size_t STARTING_ELEMS_CAPACITY = 8;
33
Shawn Willden58e1a542014-08-08 21:58:29 -060034AuthorizationSet::AuthorizationSet(const AuthorizationSet& set)
Shawn Willden62de2662014-08-20 14:14:49 -060035 : Serializable(), elems_(NULL), indirect_data_(NULL) {
Shawn Willden76364712014-08-11 17:48:04 -060036 Reinitialize(set.elems_, set.elems_size_);
Shawn Willden5ada7b62014-07-29 09:44:17 -060037}
38
Shawn Willden8d336ae2014-08-09 15:47:05 -060039AuthorizationSet::~AuthorizationSet() {
40 FreeData();
41}
Shawn Willden58e1a542014-08-08 21:58:29 -060042
Shawn Willden37012132014-08-19 08:15:57 -060043bool AuthorizationSet::reserve_elems(size_t count) {
Shawn Willden437fbd12014-08-20 11:59:49 -060044 if (is_valid() != OK)
45 return false;
46
Shawn Willden37012132014-08-19 08:15:57 -060047 if (count >= elems_capacity_) {
48 keymaster_key_param_t* new_elems = new keymaster_key_param_t[count];
49 if (new_elems == NULL) {
50 set_invalid(ALLOCATION_FAILURE);
51 return false;
52 }
53 memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_);
54 delete[] elems_;
55 elems_ = new_elems;
56 elems_capacity_ = count;
57 }
58 return true;
59}
60
61bool AuthorizationSet::reserve_indirect(size_t length) {
Shawn Willden437fbd12014-08-20 11:59:49 -060062 if (is_valid() != OK)
63 return false;
64
Shawn Willden37012132014-08-19 08:15:57 -060065 if (length > indirect_data_capacity_) {
66 uint8_t* new_data = new uint8_t[length];
67 if (new_data == NULL) {
68 set_invalid(ALLOCATION_FAILURE);
69 return false;
70 }
71 memcpy(new_data, indirect_data_, indirect_data_size_);
72
73 // Fix up the data pointers to point into the new region.
74 for (size_t i = 0; i < elems_size_; ++i) {
75 if (is_blob_tag(elems_[i].tag))
76 elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_);
77 }
78 delete[] indirect_data_;
79 indirect_data_ = new_data;
80 indirect_data_capacity_ = length;
81 }
82 return true;
83}
84
Shawn Willden5ada7b62014-07-29 09:44:17 -060085bool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) {
86 FreeData();
87
Shawn Willden37012132014-08-19 08:15:57 -060088 if (!reserve_elems(count))
Shawn Willden5ada7b62014-07-29 09:44:17 -060089 return false;
Shawn Willden5ada7b62014-07-29 09:44:17 -060090
Shawn Willden37012132014-08-19 08:15:57 -060091 if (!reserve_indirect(ComputeIndirectDataSize(elems, count)))
92 return false;
93
94 memcpy(elems_, elems, sizeof(keymaster_key_param_t) * count);
95 elems_size_ = count;
Shawn Willden5ada7b62014-07-29 09:44:17 -060096 CopyIndirectData();
Shawn Willden37012132014-08-19 08:15:57 -060097 error_ = OK;
Shawn Willden5ada7b62014-07-29 09:44:17 -060098 return true;
99}
100
Shawn Willden5ada7b62014-07-29 09:44:17 -0600101void AuthorizationSet::set_invalid(Error error) {
Shawn Willden5ada7b62014-07-29 09:44:17 -0600102 FreeData();
Shawn Willden37012132014-08-19 08:15:57 -0600103 error_ = error;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600104}
105
Shawn Willdencb0d64b2015-01-22 10:23:42 -0700106void AuthorizationSet::CopyToParamSet(keymaster_key_param_set_t* set) const {
107 assert(set);
108
109 set->length = size();
110 set->params =
111 reinterpret_cast<keymaster_key_param_t*>(malloc(sizeof(keymaster_key_param_t) * size()));
112
113 for (size_t i = 0; i < size(); ++i) {
114 const keymaster_key_param_t src = (*this)[i];
115 keymaster_key_param_t& dst(set->params[i]);
116
117 dst = src;
118 keymaster_tag_type_t type = keymaster_tag_get_type(src.tag);
119 if (type == KM_BIGNUM || type == KM_BYTES) {
120 void* tmp = malloc(src.blob.data_length);
121 memcpy(tmp, src.blob.data, src.blob.data_length);
122 dst.blob.data = reinterpret_cast<uint8_t*>(tmp);
123 }
124 }
125}
126
Shawn Willden5ada7b62014-07-29 09:44:17 -0600127int AuthorizationSet::find(keymaster_tag_t tag, int begin) const {
Shawn Willden437fbd12014-08-20 11:59:49 -0600128 if (is_valid() != OK)
129 return -1;
130
Shawn Willden5ada7b62014-07-29 09:44:17 -0600131 int i = ++begin;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600132 while (i < (int)elems_size_ && elems_[i].tag != tag)
133 ++i;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600134 if (i == (int)elems_size_)
135 return -1;
136 else
137 return i;
138}
139
140keymaster_key_param_t empty;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600141keymaster_key_param_t AuthorizationSet::operator[](int at) const {
Shawn Willden437fbd12014-08-20 11:59:49 -0600142 if (is_valid() == OK && at < (int)elems_size_) {
Shawn Willden8d336ae2014-08-09 15:47:05 -0600143 return elems_[at];
Shawn Willden5ada7b62014-07-29 09:44:17 -0600144 }
145 memset(&empty, 0, sizeof(empty));
146 return empty;
147}
148
Shawn Willden37012132014-08-19 08:15:57 -0600149bool AuthorizationSet::push_back(const AuthorizationSet& set) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600150 if (is_valid() != OK)
151 return false;
152
Shawn Willden37012132014-08-19 08:15:57 -0600153 if (!reserve_elems(elems_size_ + set.elems_size_))
154 return false;
155
156 if (!reserve_indirect(indirect_data_size_ + set.indirect_data_size_))
157 return false;
158
159 for (size_t i = 0; i < set.size(); ++i)
160 if (!push_back(set[i]))
Shawn Willden5ada7b62014-07-29 09:44:17 -0600161 return false;
Shawn Willden37012132014-08-19 08:15:57 -0600162
163 return true;
164}
165
166bool AuthorizationSet::push_back(keymaster_key_param_t elem) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600167 if (is_valid() != OK)
168 return false;
169
Shawn Willden37012132014-08-19 08:15:57 -0600170 if (elems_size_ >= elems_capacity_)
171 if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY))
172 return false;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600173
174 if (is_blob_tag(elem.tag)) {
Shawn Willden37012132014-08-19 08:15:57 -0600175 if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length)
176 if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length)))
Shawn Willden5ada7b62014-07-29 09:44:17 -0600177 return false;
Shawn Willden58e1a542014-08-08 21:58:29 -0600178
Shawn Willden5ada7b62014-07-29 09:44:17 -0600179 memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600180 elem.blob.data = indirect_data_ + indirect_data_size_;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600181 indirect_data_size_ += elem.blob.data_length;
182 }
183
184 elems_[elems_size_++] = elem;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600185 return true;
186}
187
Shawn Willden8d336ae2014-08-09 15:47:05 -0600188static size_t serialized_size(const keymaster_key_param_t& param) {
189 switch (keymaster_tag_get_type(param.tag)) {
190 case KM_INVALID:
191 default:
192 return sizeof(uint32_t);
193 case KM_ENUM:
194 case KM_ENUM_REP:
195 case KM_INT:
196 case KM_INT_REP:
197 return sizeof(uint32_t) * 2;
198 case KM_LONG:
199 case KM_DATE:
200 return sizeof(uint32_t) + sizeof(uint64_t);
201 case KM_BOOL:
202 return sizeof(uint32_t) + 1;
203 break;
204 case KM_BIGNUM:
205 case KM_BYTES:
206 return sizeof(uint32_t) * 3;
207 }
Shawn Willden58e1a542014-08-08 21:58:29 -0600208}
209
Shawn Willden8d336ae2014-08-09 15:47:05 -0600210static uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end,
211 const uint8_t* indirect_base) {
Shawn Willden172f8c92014-08-17 07:50:34 -0600212 buf = append_uint32_to_buf(buf, end, param.tag);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600213 switch (keymaster_tag_get_type(param.tag)) {
214 case KM_INVALID:
215 break;
216 case KM_ENUM:
217 case KM_ENUM_REP:
Shawn Willden172f8c92014-08-17 07:50:34 -0600218 buf = append_uint32_to_buf(buf, end, param.enumerated);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600219 break;
220 case KM_INT:
221 case KM_INT_REP:
Shawn Willden172f8c92014-08-17 07:50:34 -0600222 buf = append_uint32_to_buf(buf, end, param.integer);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600223 break;
224 case KM_LONG:
Shawn Willden172f8c92014-08-17 07:50:34 -0600225 buf = append_uint64_to_buf(buf, end, param.long_integer);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600226 break;
227 case KM_DATE:
Shawn Willden172f8c92014-08-17 07:50:34 -0600228 buf = append_uint64_to_buf(buf, end, param.date_time);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600229 break;
230 case KM_BOOL:
231 if (buf < end)
232 *buf = static_cast<uint8_t>(param.boolean);
233 buf++;
234 break;
235 case KM_BIGNUM:
236 case KM_BYTES:
Shawn Willden172f8c92014-08-17 07:50:34 -0600237 buf = append_uint32_to_buf(buf, end, param.blob.data_length);
238 buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600239 break;
240 }
241 return buf;
242}
243
Shawn Willden172f8c92014-08-17 07:50:34 -0600244static bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end,
Shawn Willden8d336ae2014-08-09 15:47:05 -0600245 const uint8_t* indirect_base, const uint8_t* indirect_end) {
Shawn Willden172f8c92014-08-17 07:50:34 -0600246 if (!copy_uint32_from_buf(buf_ptr, end, &param->tag))
Shawn Willden8d336ae2014-08-09 15:47:05 -0600247 return false;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600248
249 switch (keymaster_tag_get_type(param->tag)) {
250 default:
251 case KM_INVALID:
252 return false;
253 case KM_ENUM:
254 case KM_ENUM_REP:
Shawn Willden172f8c92014-08-17 07:50:34 -0600255 return copy_uint32_from_buf(buf_ptr, end, &param->enumerated);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600256 case KM_INT:
257 case KM_INT_REP:
Shawn Willden172f8c92014-08-17 07:50:34 -0600258 return copy_uint32_from_buf(buf_ptr, end, &param->integer);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600259 case KM_LONG:
Shawn Willden172f8c92014-08-17 07:50:34 -0600260 return copy_uint64_from_buf(buf_ptr, end, &param->long_integer);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600261 case KM_DATE:
Shawn Willden172f8c92014-08-17 07:50:34 -0600262 return copy_uint64_from_buf(buf_ptr, end, &param->date_time);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600263 break;
264 case KM_BOOL:
Shawn Willden172f8c92014-08-17 07:50:34 -0600265 if (*buf_ptr < end) {
266 param->boolean = static_cast<bool>(**buf_ptr);
267 (*buf_ptr)++;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600268 return true;
269 }
270 return false;
271
272 case KM_BIGNUM:
273 case KM_BYTES: {
Shawn Willden8d336ae2014-08-09 15:47:05 -0600274 uint32_t offset;
Shawn Willden172f8c92014-08-17 07:50:34 -0600275 if (!copy_uint32_from_buf(buf_ptr, end, &param->blob.data_length) ||
276 !copy_uint32_from_buf(buf_ptr, end, &offset))
Shawn Willden8d336ae2014-08-09 15:47:05 -0600277 return false;
278 if (static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base ||
Shawn Willden172f8c92014-08-17 07:50:34 -0600279 static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base)
Shawn Willden8d336ae2014-08-09 15:47:05 -0600280 return false;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600281 param->blob.data = indirect_base + offset;
282 return true;
283 }
284 }
285}
286
287size_t AuthorizationSet::SerializedSizeOfElements() const {
288 size_t size = 0;
289 for (size_t i = 0; i < elems_size_; ++i) {
290 size += serialized_size(elems_[i]);
291 }
292 return size;
293}
294
295size_t AuthorizationSet::SerializedSize() const {
296 return sizeof(uint32_t) + // Size of indirect_data_
297 indirect_data_size_ + // indirect_data_
298 sizeof(uint32_t) + // Number of elems_
299 sizeof(uint32_t) + // Size of elems_
300 SerializedSizeOfElements(); // elems_
301}
302
303uint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const {
304 buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_);
Shawn Willden172f8c92014-08-17 07:50:34 -0600305 buf = append_uint32_to_buf(buf, end, elems_size_);
306 buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements());
Shawn Willden8d336ae2014-08-09 15:47:05 -0600307 for (size_t i = 0; i < elems_size_; ++i) {
308 buf = serialize(elems_[i], buf, end, indirect_data_);
309 }
310 return buf;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600311}
312
Shawn Willden37012132014-08-19 08:15:57 -0600313bool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) {
Shawn Willdenf2282b32014-08-25 06:49:54 -0600314 UniquePtr<uint8_t[]> indirect_buf;
315 if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_buf)) {
Shawn Willden37012132014-08-19 08:15:57 -0600316 set_invalid(MALFORMED_DATA);
317 return false;
318 }
Shawn Willdenf2282b32014-08-25 06:49:54 -0600319 indirect_data_ = indirect_buf.release();
Shawn Willden37012132014-08-19 08:15:57 -0600320 return true;
321}
Shawn Willden5ada7b62014-07-29 09:44:17 -0600322
Shawn Willden37012132014-08-19 08:15:57 -0600323bool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) {
Shawn Willden8d336ae2014-08-09 15:47:05 -0600324 uint32_t elements_count;
325 uint32_t elements_size;
Shawn Willden37012132014-08-19 08:15:57 -0600326 if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) ||
Shawn Willden172f8c92014-08-17 07:50:34 -0600327 !copy_uint32_from_buf(buf_ptr, end, &elements_size)) {
Shawn Willden58e1a542014-08-08 21:58:29 -0600328 set_invalid(MALFORMED_DATA);
Shawn Willden5ada7b62014-07-29 09:44:17 -0600329 return false;
330 }
331
Shawn Willden834e8072014-08-09 16:38:53 -0600332 // Note that the following validation of elements_count is weak, but it prevents allocation of
333 // elems_ arrays which are clearly too large to be reasonable.
Shawn Willden62de2662014-08-20 14:14:49 -0600334 if (static_cast<ptrdiff_t>(elements_size) > end - *buf_ptr ||
335 elements_count * sizeof(uint32_t) > elements_size) {
Shawn Willden834e8072014-08-09 16:38:53 -0600336 set_invalid(MALFORMED_DATA);
337 return false;
338 }
339
Shawn Willden37012132014-08-19 08:15:57 -0600340 if (!reserve_elems(elements_count))
Shawn Willden5ada7b62014-07-29 09:44:17 -0600341 return false;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600342
Shawn Willden8d336ae2014-08-09 15:47:05 -0600343 uint8_t* indirect_end = indirect_data_ + indirect_data_size_;
Shawn Willden172f8c92014-08-17 07:50:34 -0600344 const uint8_t* elements_end = *buf_ptr + elements_size;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600345 for (size_t i = 0; i < elements_count; ++i) {
Shawn Willden172f8c92014-08-17 07:50:34 -0600346 if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) {
Shawn Willden8d336ae2014-08-09 15:47:05 -0600347 set_invalid(MALFORMED_DATA);
348 return false;
349 }
350 }
Shawn Willden37012132014-08-19 08:15:57 -0600351 elems_size_ = elements_count;
352 return true;
353}
Shawn Willden8d336ae2014-08-09 15:47:05 -0600354
Shawn Willden37012132014-08-19 08:15:57 -0600355bool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
356 FreeData();
357
358 if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end))
359 return false;
360
361 if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) {
Shawn Willden58e1a542014-08-08 21:58:29 -0600362 set_invalid(MALFORMED_DATA);
Shawn Willden5ada7b62014-07-29 09:44:17 -0600363 return false;
Shawn Willden58e1a542014-08-08 21:58:29 -0600364 }
Shawn Willden8d336ae2014-08-09 15:47:05 -0600365 return true;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600366}
367
Shawn Willden941d1c42014-12-11 13:57:02 -0700368void AuthorizationSet::Clear() {
Shawn Willden1834d5f2014-12-08 12:41:59 -0700369 memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t));
370 memset_s(indirect_data_, 0, indirect_data_size_);
Shawn Willden941d1c42014-12-11 13:57:02 -0700371 elems_size_ = 0;
372 indirect_data_size_ = 0;
373}
374
375void AuthorizationSet::FreeData() {
376 Clear();
Shawn Willden58e1a542014-08-08 21:58:29 -0600377
378 delete[] elems_;
379 delete[] indirect_data_;
380
Shawn Willden5ada7b62014-07-29 09:44:17 -0600381 elems_ = NULL;
382 indirect_data_ = NULL;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600383 elems_capacity_ = 0;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600384 indirect_data_capacity_ = 0;
Shawn Willden37012132014-08-19 08:15:57 -0600385 error_ = OK;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600386}
387
388/* static */
389size_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) {
390 size_t size = 0;
391 for (size_t i = 0; i < count; ++i) {
392 if (is_blob_tag(elems[i].tag)) {
393 size += elems[i].blob.data_length;
394 }
395 }
396 return size;
397}
398
399void AuthorizationSet::CopyIndirectData() {
Shawn Willden37012132014-08-19 08:15:57 -0600400 memset_s(indirect_data_, 0, indirect_data_capacity_);
Shawn Willden5ada7b62014-07-29 09:44:17 -0600401
402 uint8_t* indirect_data_pos = indirect_data_;
403 for (size_t i = 0; i < elems_size_; ++i) {
Shawn Willden37012132014-08-19 08:15:57 -0600404 assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_);
Shawn Willden5ada7b62014-07-29 09:44:17 -0600405 if (is_blob_tag(elems_[i].tag)) {
406 memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length);
407 elems_[i].blob.data = indirect_data_pos;
408 indirect_data_pos += elems_[i].blob.data_length;
409 }
410 }
Shawn Willden37012132014-08-19 08:15:57 -0600411 assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_);
412 indirect_data_size_ = indirect_data_pos - indirect_data_;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600413}
414
Shawn Willden5ada7b62014-07-29 09:44:17 -0600415bool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const {
416 int pos = find(tag);
417 if (pos == -1) {
418 return false;
419 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600420 *val = elems_[pos].enumerated;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600421 return true;
422}
423
424bool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance,
425 uint32_t* val) const {
426 size_t count = 0;
427 int pos = -1;
428 while (count <= instance) {
429 pos = find(tag, pos);
430 if (pos == -1) {
431 return false;
432 }
433 ++count;
434 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600435 *val = elems_[pos].enumerated;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600436 return true;
437}
438
439bool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const {
440 int pos = find(tag);
441 if (pos == -1) {
442 return false;
443 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600444 *val = elems_[pos].integer;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600445 return true;
446}
447
448bool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance,
449 uint32_t* val) const {
450 size_t count = 0;
451 int pos = -1;
452 while (count <= instance) {
453 pos = find(tag, pos);
454 if (pos == -1) {
455 return false;
456 }
457 ++count;
458 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600459 *val = elems_[pos].integer;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600460 return true;
461}
462
463bool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const {
464 int pos = find(tag);
465 if (pos == -1) {
466 return false;
467 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600468 *val = elems_[pos].long_integer;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600469 return true;
470}
471
472bool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const {
473 int pos = find(tag);
474 if (pos == -1) {
475 return false;
476 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600477 *val = elems_[pos].date_time;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600478 return true;
479}
480
481bool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const {
482 int pos = find(tag);
483 if (pos == -1) {
484 return false;
485 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600486 *val = elems_[pos].blob;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600487 return true;
488}
489
490} // namespace keymaster