blob: 2111b74606ebf9e976ca4fb6eb667916f0f5428a [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
23#include "authorization_set.h"
Shawn Willden74aff352014-08-11 14:08:31 -060024#include "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)
35 : 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
106int AuthorizationSet::find(keymaster_tag_t tag, int begin) const {
Shawn Willden437fbd12014-08-20 11:59:49 -0600107 if (is_valid() != OK)
108 return -1;
109
Shawn Willden5ada7b62014-07-29 09:44:17 -0600110 int i = ++begin;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600111 while (i < (int)elems_size_ && elems_[i].tag != tag)
112 ++i;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600113 if (i == (int)elems_size_)
114 return -1;
115 else
116 return i;
117}
118
119keymaster_key_param_t empty;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600120keymaster_key_param_t AuthorizationSet::operator[](int at) const {
Shawn Willden437fbd12014-08-20 11:59:49 -0600121 if (is_valid() == OK && at < (int)elems_size_) {
Shawn Willden8d336ae2014-08-09 15:47:05 -0600122 return elems_[at];
Shawn Willden5ada7b62014-07-29 09:44:17 -0600123 }
124 memset(&empty, 0, sizeof(empty));
125 return empty;
126}
127
Shawn Willden76364712014-08-11 17:48:04 -0600128template <typename T> int comparator(const T& a, const T& b) {
129 if (a < b)
130 return -1;
131 else if (a > b)
132 return 1;
133 else
134 return 0;
135}
136
137static int param_comparator(const void* a, const void* b) {
138 const keymaster_key_param_t* lhs = static_cast<const keymaster_key_param_t*>(a);
139 const keymaster_key_param_t* rhs = static_cast<const keymaster_key_param_t*>(b);
140
141 if (lhs->tag < rhs->tag)
142 return -1;
143 else if (lhs->tag > rhs->tag)
144 return 1;
145 else
146 switch (keymaster_tag_get_type(lhs->tag)) {
147 default:
148 case KM_INVALID:
149 return 0;
150 case KM_ENUM:
151 case KM_ENUM_REP:
152 return comparator(lhs->enumerated, rhs->enumerated);
153 case KM_INT:
154 case KM_INT_REP:
155 return comparator(lhs->integer, rhs->integer);
156 case KM_LONG:
157 return comparator(lhs->long_integer, rhs->long_integer);
158 case KM_DATE:
159 return comparator(lhs->date_time, rhs->date_time);
160 case KM_BOOL:
161 return comparator(lhs->boolean, rhs->boolean);
162 case KM_BIGNUM:
163 case KM_BYTES: {
164 size_t min_len = lhs->blob.data_length;
165 if (rhs->blob.data_length < min_len)
166 min_len = rhs->blob.data_length;
167
168 if (lhs->blob.data_length == rhs->blob.data_length && min_len > 0)
169 return memcmp(lhs->blob.data, rhs->blob.data, min_len);
170 int cmp_result = memcmp(lhs->blob.data, rhs->blob.data, min_len);
171 if (cmp_result == 0) {
172 // The blobs are equal up to the length of the shortest (which may have length 0),
173 // so the shorter is less, the longer is greater and if they have the same length
174 // they're identical.
175 return comparator(lhs->blob.data_length, rhs->blob.data_length);
176 }
177 return cmp_result;
178 } break;
179 }
180}
181
Shawn Willden37012132014-08-19 08:15:57 -0600182bool AuthorizationSet::push_back(const AuthorizationSet& set) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600183 if (is_valid() != OK)
184 return false;
185
Shawn Willden37012132014-08-19 08:15:57 -0600186 if (!reserve_elems(elems_size_ + set.elems_size_))
187 return false;
188
189 if (!reserve_indirect(indirect_data_size_ + set.indirect_data_size_))
190 return false;
191
192 for (size_t i = 0; i < set.size(); ++i)
193 if (!push_back(set[i]))
Shawn Willden5ada7b62014-07-29 09:44:17 -0600194 return false;
Shawn Willden37012132014-08-19 08:15:57 -0600195
196 return true;
197}
198
199bool AuthorizationSet::push_back(keymaster_key_param_t elem) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600200 if (is_valid() != OK)
201 return false;
202
Shawn Willden37012132014-08-19 08:15:57 -0600203 if (elems_size_ >= elems_capacity_)
204 if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY))
205 return false;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600206
207 if (is_blob_tag(elem.tag)) {
Shawn Willden37012132014-08-19 08:15:57 -0600208 if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length)
209 if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length)))
Shawn Willden5ada7b62014-07-29 09:44:17 -0600210 return false;
Shawn Willden58e1a542014-08-08 21:58:29 -0600211
Shawn Willden5ada7b62014-07-29 09:44:17 -0600212 memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600213 elem.blob.data = indirect_data_ + indirect_data_size_;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600214 indirect_data_size_ += elem.blob.data_length;
215 }
216
217 elems_[elems_size_++] = elem;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600218 return true;
219}
220
Shawn Willden8d336ae2014-08-09 15:47:05 -0600221static size_t serialized_size(const keymaster_key_param_t& param) {
222 switch (keymaster_tag_get_type(param.tag)) {
223 case KM_INVALID:
224 default:
225 return sizeof(uint32_t);
226 case KM_ENUM:
227 case KM_ENUM_REP:
228 case KM_INT:
229 case KM_INT_REP:
230 return sizeof(uint32_t) * 2;
231 case KM_LONG:
232 case KM_DATE:
233 return sizeof(uint32_t) + sizeof(uint64_t);
234 case KM_BOOL:
235 return sizeof(uint32_t) + 1;
236 break;
237 case KM_BIGNUM:
238 case KM_BYTES:
239 return sizeof(uint32_t) * 3;
240 }
Shawn Willden58e1a542014-08-08 21:58:29 -0600241}
242
Shawn Willden8d336ae2014-08-09 15:47:05 -0600243static uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end,
244 const uint8_t* indirect_base) {
Shawn Willden172f8c92014-08-17 07:50:34 -0600245 buf = append_uint32_to_buf(buf, end, param.tag);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600246 switch (keymaster_tag_get_type(param.tag)) {
247 case KM_INVALID:
248 break;
249 case KM_ENUM:
250 case KM_ENUM_REP:
Shawn Willden172f8c92014-08-17 07:50:34 -0600251 buf = append_uint32_to_buf(buf, end, param.enumerated);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600252 break;
253 case KM_INT:
254 case KM_INT_REP:
Shawn Willden172f8c92014-08-17 07:50:34 -0600255 buf = append_uint32_to_buf(buf, end, param.integer);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600256 break;
257 case KM_LONG:
Shawn Willden172f8c92014-08-17 07:50:34 -0600258 buf = append_uint64_to_buf(buf, end, param.long_integer);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600259 break;
260 case KM_DATE:
Shawn Willden172f8c92014-08-17 07:50:34 -0600261 buf = append_uint64_to_buf(buf, end, param.date_time);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600262 break;
263 case KM_BOOL:
264 if (buf < end)
265 *buf = static_cast<uint8_t>(param.boolean);
266 buf++;
267 break;
268 case KM_BIGNUM:
269 case KM_BYTES:
Shawn Willden172f8c92014-08-17 07:50:34 -0600270 buf = append_uint32_to_buf(buf, end, param.blob.data_length);
271 buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600272 break;
273 }
274 return buf;
275}
276
Shawn Willden172f8c92014-08-17 07:50:34 -0600277static bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end,
Shawn Willden8d336ae2014-08-09 15:47:05 -0600278 const uint8_t* indirect_base, const uint8_t* indirect_end) {
Shawn Willden172f8c92014-08-17 07:50:34 -0600279 if (!copy_uint32_from_buf(buf_ptr, end, &param->tag))
Shawn Willden8d336ae2014-08-09 15:47:05 -0600280 return false;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600281
282 switch (keymaster_tag_get_type(param->tag)) {
283 default:
284 case KM_INVALID:
285 return false;
286 case KM_ENUM:
287 case KM_ENUM_REP:
Shawn Willden172f8c92014-08-17 07:50:34 -0600288 return copy_uint32_from_buf(buf_ptr, end, &param->enumerated);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600289 case KM_INT:
290 case KM_INT_REP:
Shawn Willden172f8c92014-08-17 07:50:34 -0600291 return copy_uint32_from_buf(buf_ptr, end, &param->integer);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600292 case KM_LONG:
Shawn Willden172f8c92014-08-17 07:50:34 -0600293 return copy_uint64_from_buf(buf_ptr, end, &param->long_integer);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600294 case KM_DATE:
Shawn Willden172f8c92014-08-17 07:50:34 -0600295 return copy_uint64_from_buf(buf_ptr, end, &param->date_time);
Shawn Willden8d336ae2014-08-09 15:47:05 -0600296 break;
297 case KM_BOOL:
Shawn Willden172f8c92014-08-17 07:50:34 -0600298 if (*buf_ptr < end) {
299 param->boolean = static_cast<bool>(**buf_ptr);
300 (*buf_ptr)++;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600301 return true;
302 }
303 return false;
304
305 case KM_BIGNUM:
306 case KM_BYTES: {
Shawn Willden8d336ae2014-08-09 15:47:05 -0600307 uint32_t offset;
Shawn Willden172f8c92014-08-17 07:50:34 -0600308 if (!copy_uint32_from_buf(buf_ptr, end, &param->blob.data_length) ||
309 !copy_uint32_from_buf(buf_ptr, end, &offset))
Shawn Willden8d336ae2014-08-09 15:47:05 -0600310 return false;
311 if (static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base ||
Shawn Willden172f8c92014-08-17 07:50:34 -0600312 static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base)
Shawn Willden8d336ae2014-08-09 15:47:05 -0600313 return false;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600314 param->blob.data = indirect_base + offset;
315 return true;
316 }
317 }
318}
319
320size_t AuthorizationSet::SerializedSizeOfElements() const {
321 size_t size = 0;
322 for (size_t i = 0; i < elems_size_; ++i) {
323 size += serialized_size(elems_[i]);
324 }
325 return size;
326}
327
328size_t AuthorizationSet::SerializedSize() const {
329 return sizeof(uint32_t) + // Size of indirect_data_
330 indirect_data_size_ + // indirect_data_
331 sizeof(uint32_t) + // Number of elems_
332 sizeof(uint32_t) + // Size of elems_
333 SerializedSizeOfElements(); // elems_
334}
335
336uint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const {
337 buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_);
Shawn Willden172f8c92014-08-17 07:50:34 -0600338 buf = append_uint32_to_buf(buf, end, elems_size_);
339 buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements());
Shawn Willden8d336ae2014-08-09 15:47:05 -0600340 for (size_t i = 0; i < elems_size_; ++i) {
341 buf = serialize(elems_[i], buf, end, indirect_data_);
342 }
343 return buf;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600344}
345
Shawn Willden37012132014-08-19 08:15:57 -0600346bool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) {
347 if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_data_)) {
348 set_invalid(MALFORMED_DATA);
349 return false;
350 }
351 return true;
352}
Shawn Willden5ada7b62014-07-29 09:44:17 -0600353
Shawn Willden37012132014-08-19 08:15:57 -0600354bool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) {
Shawn Willden8d336ae2014-08-09 15:47:05 -0600355 uint32_t elements_count;
356 uint32_t elements_size;
Shawn Willden37012132014-08-19 08:15:57 -0600357 if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) ||
Shawn Willden172f8c92014-08-17 07:50:34 -0600358 !copy_uint32_from_buf(buf_ptr, end, &elements_size)) {
Shawn Willden58e1a542014-08-08 21:58:29 -0600359 set_invalid(MALFORMED_DATA);
Shawn Willden5ada7b62014-07-29 09:44:17 -0600360 return false;
361 }
362
Shawn Willden834e8072014-08-09 16:38:53 -0600363 // Note that the following validation of elements_count is weak, but it prevents allocation of
364 // elems_ arrays which are clearly too large to be reasonable.
Shawn Willden172f8c92014-08-17 07:50:34 -0600365 if (elements_size > end - *buf_ptr || elements_count * sizeof(uint32_t) > elements_size) {
Shawn Willden834e8072014-08-09 16:38:53 -0600366 set_invalid(MALFORMED_DATA);
367 return false;
368 }
369
Shawn Willden37012132014-08-19 08:15:57 -0600370 if (!reserve_elems(elements_count))
Shawn Willden5ada7b62014-07-29 09:44:17 -0600371 return false;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600372
Shawn Willden8d336ae2014-08-09 15:47:05 -0600373 uint8_t* indirect_end = indirect_data_ + indirect_data_size_;
Shawn Willden172f8c92014-08-17 07:50:34 -0600374 const uint8_t* elements_end = *buf_ptr + elements_size;
Shawn Willden8d336ae2014-08-09 15:47:05 -0600375 for (size_t i = 0; i < elements_count; ++i) {
Shawn Willden172f8c92014-08-17 07:50:34 -0600376 if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) {
Shawn Willden8d336ae2014-08-09 15:47:05 -0600377 set_invalid(MALFORMED_DATA);
378 return false;
379 }
380 }
Shawn Willden37012132014-08-19 08:15:57 -0600381 elems_size_ = elements_count;
382 return true;
383}
Shawn Willden8d336ae2014-08-09 15:47:05 -0600384
Shawn Willden37012132014-08-19 08:15:57 -0600385bool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
386 FreeData();
387
388 if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end))
389 return false;
390
391 if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) {
Shawn Willden58e1a542014-08-08 21:58:29 -0600392 set_invalid(MALFORMED_DATA);
Shawn Willden5ada7b62014-07-29 09:44:17 -0600393 return false;
Shawn Willden58e1a542014-08-08 21:58:29 -0600394 }
Shawn Willden8d336ae2014-08-09 15:47:05 -0600395 return true;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600396}
397
398void AuthorizationSet::FreeData() {
Shawn Willden58e1a542014-08-08 21:58:29 -0600399 if (elems_ != NULL)
Shawn Willden74aff352014-08-11 14:08:31 -0600400 memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t));
Shawn Willden58e1a542014-08-08 21:58:29 -0600401 if (indirect_data_ != NULL)
Shawn Willden74aff352014-08-11 14:08:31 -0600402 memset_s(indirect_data_, 0, indirect_data_size_);
Shawn Willden58e1a542014-08-08 21:58:29 -0600403
404 delete[] elems_;
405 delete[] indirect_data_;
406
Shawn Willden5ada7b62014-07-29 09:44:17 -0600407 elems_ = NULL;
408 indirect_data_ = NULL;
409 elems_size_ = 0;
410 elems_capacity_ = 0;
411 indirect_data_size_ = 0;
412 indirect_data_capacity_ = 0;
Shawn Willden37012132014-08-19 08:15:57 -0600413 error_ = OK;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600414}
415
416/* static */
417size_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) {
418 size_t size = 0;
419 for (size_t i = 0; i < count; ++i) {
420 if (is_blob_tag(elems[i].tag)) {
421 size += elems[i].blob.data_length;
422 }
423 }
424 return size;
425}
426
427void AuthorizationSet::CopyIndirectData() {
Shawn Willden37012132014-08-19 08:15:57 -0600428 memset_s(indirect_data_, 0, indirect_data_capacity_);
Shawn Willden5ada7b62014-07-29 09:44:17 -0600429
430 uint8_t* indirect_data_pos = indirect_data_;
431 for (size_t i = 0; i < elems_size_; ++i) {
Shawn Willden37012132014-08-19 08:15:57 -0600432 assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_);
Shawn Willden5ada7b62014-07-29 09:44:17 -0600433 if (is_blob_tag(elems_[i].tag)) {
434 memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length);
435 elems_[i].blob.data = indirect_data_pos;
436 indirect_data_pos += elems_[i].blob.data_length;
437 }
438 }
Shawn Willden37012132014-08-19 08:15:57 -0600439 assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_);
440 indirect_data_size_ = indirect_data_pos - indirect_data_;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600441}
442
Shawn Willden5ada7b62014-07-29 09:44:17 -0600443bool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const {
444 int pos = find(tag);
445 if (pos == -1) {
446 return false;
447 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600448 *val = elems_[pos].enumerated;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600449 return true;
450}
451
452bool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance,
453 uint32_t* val) const {
454 size_t count = 0;
455 int pos = -1;
456 while (count <= instance) {
457 pos = find(tag, pos);
458 if (pos == -1) {
459 return false;
460 }
461 ++count;
462 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600463 *val = elems_[pos].enumerated;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600464 return true;
465}
466
467bool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const {
468 int pos = find(tag);
469 if (pos == -1) {
470 return false;
471 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600472 *val = elems_[pos].integer;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600473 return true;
474}
475
476bool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance,
477 uint32_t* val) const {
478 size_t count = 0;
479 int pos = -1;
480 while (count <= instance) {
481 pos = find(tag, pos);
482 if (pos == -1) {
483 return false;
484 }
485 ++count;
486 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600487 *val = elems_[pos].integer;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600488 return true;
489}
490
491bool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const {
492 int pos = find(tag);
493 if (pos == -1) {
494 return false;
495 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600496 *val = elems_[pos].long_integer;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600497 return true;
498}
499
500bool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const {
501 int pos = find(tag);
502 if (pos == -1) {
503 return false;
504 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600505 *val = elems_[pos].date_time;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600506 return true;
507}
508
509bool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const {
510 int pos = find(tag);
511 if (pos == -1) {
512 return false;
513 }
Shawn Willdenebf627f2014-08-12 11:15:29 -0600514 *val = elems_[pos].blob;
Shawn Willden5ada7b62014-07-29 09:44:17 -0600515 return true;
516}
517
518} // namespace keymaster