authorization_set.cpp revision 62de26672193373972f2ce968b51cf8335f118f9
15ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden/* 25ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * Copyright (C) 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 175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <stdlib.h> 185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <string.h> 195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <stddef.h> 205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <assert.h> 225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include "authorization_set.h" 2474aff357261879dfa8366528a42c59b042c7bd05Shawn Willden#include "google_keymaster_utils.h" 255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdennamespace keymaster { 275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenstatic inline bool is_blob_tag(keymaster_tag_t tag) { 295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return (keymaster_tag_get_type(tag) == KM_BYTES || keymaster_tag_get_type(tag) == KM_BIGNUM); 305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenconst size_t STARTING_ELEMS_CAPACITY = 8; 335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3458e1a5486219a1be9264d4e863a9dd3e393906c3Shawn WilldenAuthorizationSet::AuthorizationSet(const AuthorizationSet& set) 3562de26672193373972f2ce968b51cf8335f118f9Shawn Willden : Serializable(), elems_(NULL), indirect_data_(NULL) { 367636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden Reinitialize(set.elems_, set.elems_size_); 375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 398d336ae10df66da4c0433f17c2d42e85baea32c5Shawn WilldenAuthorizationSet::~AuthorizationSet() { 408d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden FreeData(); 418d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 4258e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 43370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::reserve_elems(size_t count) { 44437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 45437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 46437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 47370121346777e13437c275fbe7a975d899cc325cShawn Willden if (count >= elems_capacity_) { 48370121346777e13437c275fbe7a975d899cc325cShawn Willden keymaster_key_param_t* new_elems = new keymaster_key_param_t[count]; 49370121346777e13437c275fbe7a975d899cc325cShawn Willden if (new_elems == NULL) { 50370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(ALLOCATION_FAILURE); 51370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 52370121346777e13437c275fbe7a975d899cc325cShawn Willden } 53370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_); 54370121346777e13437c275fbe7a975d899cc325cShawn Willden delete[] elems_; 55370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_ = new_elems; 56370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_capacity_ = count; 57370121346777e13437c275fbe7a975d899cc325cShawn Willden } 58370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 59370121346777e13437c275fbe7a975d899cc325cShawn Willden} 60370121346777e13437c275fbe7a975d899cc325cShawn Willden 61370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::reserve_indirect(size_t length) { 62437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 63437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 64437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 65370121346777e13437c275fbe7a975d899cc325cShawn Willden if (length > indirect_data_capacity_) { 66370121346777e13437c275fbe7a975d899cc325cShawn Willden uint8_t* new_data = new uint8_t[length]; 67370121346777e13437c275fbe7a975d899cc325cShawn Willden if (new_data == NULL) { 68370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(ALLOCATION_FAILURE); 69370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 70370121346777e13437c275fbe7a975d899cc325cShawn Willden } 71370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(new_data, indirect_data_, indirect_data_size_); 72370121346777e13437c275fbe7a975d899cc325cShawn Willden 73370121346777e13437c275fbe7a975d899cc325cShawn Willden // Fix up the data pointers to point into the new region. 74370121346777e13437c275fbe7a975d899cc325cShawn Willden for (size_t i = 0; i < elems_size_; ++i) { 75370121346777e13437c275fbe7a975d899cc325cShawn Willden if (is_blob_tag(elems_[i].tag)) 76370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_); 77370121346777e13437c275fbe7a975d899cc325cShawn Willden } 78370121346777e13437c275fbe7a975d899cc325cShawn Willden delete[] indirect_data_; 79370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_ = new_data; 80370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_capacity_ = length; 81370121346777e13437c275fbe7a975d899cc325cShawn Willden } 82370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 83370121346777e13437c275fbe7a975d899cc325cShawn Willden} 84370121346777e13437c275fbe7a975d899cc325cShawn Willden 855ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) { 865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden FreeData(); 875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 88370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(count)) 89370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 905ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 91370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(ComputeIndirectDataSize(elems, count))) 925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 94370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(elems_, elems, sizeof(keymaster_key_param_t) * count); 95370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_size_ = count; 965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden CopyIndirectData(); 97370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = OK; 985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::set_invalid(Error error) { 1025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden FreeData(); 103370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = error; 1045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1065ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenint AuthorizationSet::find(keymaster_tag_t tag, int begin) const { 107437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 108437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return -1; 109437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 1105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int i = ++begin; 1118d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden while (i < (int)elems_size_ && elems_[i].tag != tag) 1128d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden ++i; 1135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (i == (int)elems_size_) 1145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return -1; 1155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden else 1165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return i; 1175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenkeymaster_key_param_t empty; 1205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenkeymaster_key_param_t AuthorizationSet::operator[](int at) const { 121437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() == OK && at < (int)elems_size_) { 1228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return elems_[at]; 1235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 1245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memset(&empty, 0, sizeof(empty)); 1255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return empty; 1265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1287636471bd1c553ac179f0dddc17133491d0e1fafShawn Willdentemplate <typename T> int comparator(const T& a, const T& b) { 1297636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (a < b) 1307636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return -1; 1317636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden else if (a > b) 1327636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return 1; 1337636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden else 1347636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return 0; 1357636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden} 1367636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden 1377636471bd1c553ac179f0dddc17133491d0e1fafShawn Willdenstatic int param_comparator(const void* a, const void* b) { 1387636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden const keymaster_key_param_t* lhs = static_cast<const keymaster_key_param_t*>(a); 1397636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden const keymaster_key_param_t* rhs = static_cast<const keymaster_key_param_t*>(b); 1407636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden 1417636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (lhs->tag < rhs->tag) 1427636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return -1; 1437636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden else if (lhs->tag > rhs->tag) 1447636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return 1; 1457636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden else 1467636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden switch (keymaster_tag_get_type(lhs->tag)) { 1477636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden default: 1487636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_INVALID: 1497636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return 0; 1507636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_ENUM: 1517636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_ENUM_REP: 1527636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->enumerated, rhs->enumerated); 1537636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_INT: 1547636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_INT_REP: 1557636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->integer, rhs->integer); 1567636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_LONG: 1577636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->long_integer, rhs->long_integer); 1587636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_DATE: 1597636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->date_time, rhs->date_time); 1607636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_BOOL: 1617636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->boolean, rhs->boolean); 1627636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_BIGNUM: 1637636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_BYTES: { 1647636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden size_t min_len = lhs->blob.data_length; 1657636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (rhs->blob.data_length < min_len) 1667636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden min_len = rhs->blob.data_length; 1677636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden 1687636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (lhs->blob.data_length == rhs->blob.data_length && min_len > 0) 1697636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return memcmp(lhs->blob.data, rhs->blob.data, min_len); 1707636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden int cmp_result = memcmp(lhs->blob.data, rhs->blob.data, min_len); 1717636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (cmp_result == 0) { 1727636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden // The blobs are equal up to the length of the shortest (which may have length 0), 1737636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden // so the shorter is less, the longer is greater and if they have the same length 1747636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden // they're identical. 1757636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->blob.data_length, rhs->blob.data_length); 1767636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden } 1777636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return cmp_result; 1787636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden } break; 1797636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden } 1807636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden} 1817636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden 182370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::push_back(const AuthorizationSet& set) { 183437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 184437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 185437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 186370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elems_size_ + set.elems_size_)) 187370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 188370121346777e13437c275fbe7a975d899cc325cShawn Willden 189370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(indirect_data_size_ + set.indirect_data_size_)) 190370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 191370121346777e13437c275fbe7a975d899cc325cShawn Willden 192370121346777e13437c275fbe7a975d899cc325cShawn Willden for (size_t i = 0; i < set.size(); ++i) 193370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!push_back(set[i])) 194370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 195370121346777e13437c275fbe7a975d899cc325cShawn Willden 196370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 197370121346777e13437c275fbe7a975d899cc325cShawn Willden} 198370121346777e13437c275fbe7a975d899cc325cShawn Willden 1995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::push_back(keymaster_key_param_t elem) { 200437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 201437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 202437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 203370121346777e13437c275fbe7a975d899cc325cShawn Willden if (elems_size_ >= elems_capacity_) 204370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY)) 2055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 2065ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2075ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elem.tag)) { 208370121346777e13437c275fbe7a975d899cc325cShawn Willden if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length) 209370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length))) 2105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 21158e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 2125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length); 2138d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden elem.blob.data = indirect_data_ + indirect_data_size_; 2145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_size_ += elem.blob.data_length; 2155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 2165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_[elems_size_++] = elem; 2185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 2195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 2205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2218d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic size_t serialized_size(const keymaster_key_param_t& param) { 2228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param.tag)) { 2238d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 2248d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden default: 2258d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t); 2268d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 2278d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 2288d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 2298d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 2308d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) * 2; 2318d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 2328d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 2338d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + sizeof(uint64_t); 2348d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 2358d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + 1; 2368d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2378d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 2388d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: 2398d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) * 3; 2408d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 2418d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 2428d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 2438d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end, 2448d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden const uint8_t* indirect_base) { 245172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.tag); 2468d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param.tag)) { 2478d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 2488d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2498d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 2508d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 251172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.enumerated); 2528d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2538d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 2548d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 255172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.integer); 2568d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2578d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 258172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint64_to_buf(buf, end, param.long_integer); 2598d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2608d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 261172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint64_to_buf(buf, end, param.date_time); 2628d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2638d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 2648d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden if (buf < end) 2658d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden *buf = static_cast<uint8_t>(param.boolean); 2668d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf++; 2678d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2688d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 2698d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: 270172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.blob.data_length); 271172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base); 2728d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2738d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 2748d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return buf; 2758d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 2768d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 277172f8c9be706e27f43022063bbc7f4b0177583acShawn Willdenstatic bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end, 2788d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden const uint8_t* indirect_base, const uint8_t* indirect_end) { 279172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, ¶m->tag)) 2808d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 2818d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 2828d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param->tag)) { 2838d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden default: 2848d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 2858d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 2868d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 2878d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 288172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint32_from_buf(buf_ptr, end, ¶m->enumerated); 2898d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 2908d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 291172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint32_from_buf(buf_ptr, end, ¶m->integer); 2928d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 293172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint64_from_buf(buf_ptr, end, ¶m->long_integer); 2948d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 295172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint64_from_buf(buf_ptr, end, ¶m->date_time); 2968d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2978d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 298172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (*buf_ptr < end) { 299172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden param->boolean = static_cast<bool>(**buf_ptr); 300172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden (*buf_ptr)++; 3018d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 3028d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3038d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3048d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 3058d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 3068d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: { 3078d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t offset; 308172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, ¶m->blob.data_length) || 309172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden !copy_uint32_from_buf(buf_ptr, end, &offset)) 3108d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3118d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden if (static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base || 312172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base) 3138d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3148d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden param->blob.data = indirect_base + offset; 3158d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 3168d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3178d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3188d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 3198d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 3208d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdensize_t AuthorizationSet::SerializedSizeOfElements() const { 3218d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden size_t size = 0; 3228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elems_size_; ++i) { 3238d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden size += serialized_size(elems_[i]); 3248d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3258d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return size; 3268d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 3278d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 32858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willdensize_t AuthorizationSet::SerializedSize() const { 3298d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + // Size of indirect_data_ 3308d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden indirect_data_size_ + // indirect_data_ 3318d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden sizeof(uint32_t) + // Number of elems_ 3328d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden sizeof(uint32_t) + // Size of elems_ 3338d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden SerializedSizeOfElements(); // elems_ 3345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3368d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenuint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const { 3378d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_); 338172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, elems_size_); 339172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements()); 3408d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elems_size_; ++i) { 3418d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf = serialize(elems_[i], buf, end, indirect_data_); 3428d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3438d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return buf; 3445ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 346370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) { 347370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_data_)) { 348370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(MALFORMED_DATA); 349370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 350370121346777e13437c275fbe7a975d899cc325cShawn Willden } 351370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 352370121346777e13437c275fbe7a975d899cc325cShawn Willden} 3535ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 354370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) { 3558d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t elements_count; 3568d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t elements_size; 357370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) || 358172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden !copy_uint32_from_buf(buf_ptr, end, &elements_size)) { 35958e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden set_invalid(MALFORMED_DATA); 3605ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 3615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 3625ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 363834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden // Note that the following validation of elements_count is weak, but it prevents allocation of 364834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden // elems_ arrays which are clearly too large to be reasonable. 36562de26672193373972f2ce968b51cf8335f118f9Shawn Willden if (static_cast<ptrdiff_t>(elements_size) > end - *buf_ptr || 36662de26672193373972f2ce968b51cf8335f118f9Shawn Willden elements_count * sizeof(uint32_t) > elements_size) { 367834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden set_invalid(MALFORMED_DATA); 368834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden return false; 369834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden } 370834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden 371370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elements_count)) 3725ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 3735ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3748d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint8_t* indirect_end = indirect_data_ + indirect_data_size_; 375172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden const uint8_t* elements_end = *buf_ptr + elements_size; 3768d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elements_count; ++i) { 377172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) { 3788d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden set_invalid(MALFORMED_DATA); 3798d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3808d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 38158e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden } 382370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_size_ = elements_count; 383370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 384370121346777e13437c275fbe7a975d899cc325cShawn Willden} 3855ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 386370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { 387370121346777e13437c275fbe7a975d899cc325cShawn Willden FreeData(); 388370121346777e13437c275fbe7a975d899cc325cShawn Willden 389370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end)) 390370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 391370121346777e13437c275fbe7a975d899cc325cShawn Willden 392370121346777e13437c275fbe7a975d899cc325cShawn Willden if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) { 3938d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden set_invalid(MALFORMED_DATA); 3945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 3955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 3968d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 3975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::FreeData() { 40058e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden if (elems_ != NULL) 40174aff357261879dfa8366528a42c59b042c7bd05Shawn Willden memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t)); 40258e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden if (indirect_data_ != NULL) 40374aff357261879dfa8366528a42c59b042c7bd05Shawn Willden memset_s(indirect_data_, 0, indirect_data_size_); 40458e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 40558e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden delete[] elems_; 40658e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden delete[] indirect_data_; 40758e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 4085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_ = NULL; 4095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_ = NULL; 4105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_size_ = 0; 4115ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_capacity_ = 0; 4125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_size_ = 0; 4135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_capacity_ = 0; 414370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = OK; 4155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden/* static */ 4185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdensize_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) { 4195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t size = 0; 4205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden for (size_t i = 0; i < count; ++i) { 4215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elems[i].tag)) { 4225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size += elems[i].blob.data_length; 4235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return size; 4265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::CopyIndirectData() { 429370121346777e13437c275fbe7a975d899cc325cShawn Willden memset_s(indirect_data_, 0, indirect_data_capacity_); 4305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint8_t* indirect_data_pos = indirect_data_; 4325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden for (size_t i = 0; i < elems_size_; ++i) { 433370121346777e13437c275fbe7a975d899cc325cShawn Willden assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_); 4345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elems_[i].tag)) { 4355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length); 4365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_[i].blob.data = indirect_data_pos; 4375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_pos += elems_[i].blob.data_length; 4385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4395ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 440370121346777e13437c275fbe7a975d899cc325cShawn Willden assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_); 441370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_size_ = indirect_data_pos - indirect_data_; 4425ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4435ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4445ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const { 4455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4465ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4475ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4485ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 449ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].enumerated; 4505ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4515ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4525ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4535ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, 4545ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint32_t* val) const { 4555ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t count = 0; 4565ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = -1; 4575ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden while (count <= instance) { 4585ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden pos = find(tag, pos); 4595ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4605ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4625ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden ++count; 4635ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 464ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].enumerated; 4655ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4665ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4675ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4685ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const { 4695ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4705ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4715ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4725ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 473ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].integer; 4745ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4755ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4765ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4775ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance, 4785ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint32_t* val) const { 4795ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t count = 0; 4805ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = -1; 4815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden while (count <= instance) { 4825ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden pos = find(tag, pos); 4835ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4845ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4855ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden ++count; 4875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 488ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].integer; 4895ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4905ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4915ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const { 4935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 497ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].long_integer; 4985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const { 5025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 5035ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 506ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].date_time; 5075ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const { 5115ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 5125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 515ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].blob; 5165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} // namespace keymaster 520