authorization_set.cpp revision 370121346777e13437c275fbe7a975d899cc325c
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) 3558e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden : 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) { 44370121346777e13437c275fbe7a975d899cc325cShawn Willden if (count >= elems_capacity_) { 45370121346777e13437c275fbe7a975d899cc325cShawn Willden keymaster_key_param_t* new_elems = new keymaster_key_param_t[count]; 46370121346777e13437c275fbe7a975d899cc325cShawn Willden if (new_elems == NULL) { 47370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(ALLOCATION_FAILURE); 48370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 49370121346777e13437c275fbe7a975d899cc325cShawn Willden } 50370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_); 51370121346777e13437c275fbe7a975d899cc325cShawn Willden delete[] elems_; 52370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_ = new_elems; 53370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_capacity_ = count; 54370121346777e13437c275fbe7a975d899cc325cShawn Willden } 55370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 56370121346777e13437c275fbe7a975d899cc325cShawn Willden} 57370121346777e13437c275fbe7a975d899cc325cShawn Willden 58370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::reserve_indirect(size_t length) { 59370121346777e13437c275fbe7a975d899cc325cShawn Willden if (length > indirect_data_capacity_) { 60370121346777e13437c275fbe7a975d899cc325cShawn Willden uint8_t* new_data = new uint8_t[length]; 61370121346777e13437c275fbe7a975d899cc325cShawn Willden if (new_data == NULL) { 62370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(ALLOCATION_FAILURE); 63370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 64370121346777e13437c275fbe7a975d899cc325cShawn Willden } 65370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(new_data, indirect_data_, indirect_data_size_); 66370121346777e13437c275fbe7a975d899cc325cShawn Willden 67370121346777e13437c275fbe7a975d899cc325cShawn Willden // Fix up the data pointers to point into the new region. 68370121346777e13437c275fbe7a975d899cc325cShawn Willden for (size_t i = 0; i < elems_size_; ++i) { 69370121346777e13437c275fbe7a975d899cc325cShawn Willden if (is_blob_tag(elems_[i].tag)) 70370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_); 71370121346777e13437c275fbe7a975d899cc325cShawn Willden } 72370121346777e13437c275fbe7a975d899cc325cShawn Willden delete[] indirect_data_; 73370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_ = new_data; 74370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_capacity_ = length; 75370121346777e13437c275fbe7a975d899cc325cShawn Willden } 76370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 77370121346777e13437c275fbe7a975d899cc325cShawn Willden} 78370121346777e13437c275fbe7a975d899cc325cShawn Willden 795ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) { 805ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden FreeData(); 815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 82370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(count)) 83370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 845ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 85370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(ComputeIndirectDataSize(elems, count))) 865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 88370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(elems_, elems, sizeof(keymaster_key_param_t) * count); 89370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_size_ = count; 905ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden CopyIndirectData(); 91370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = OK; 925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::set_invalid(Error error) { 965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden FreeData(); 97370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = error; 985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenint AuthorizationSet::find(keymaster_tag_t tag, int begin) const { 1015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int i = ++begin; 1028d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden while (i < (int)elems_size_ && elems_[i].tag != tag) 1038d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden ++i; 1045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (i == (int)elems_size_) 1055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return -1; 1065ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden else 1075ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return i; 1085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenkeymaster_key_param_t empty; 1115ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenkeymaster_key_param_t AuthorizationSet::operator[](int at) const { 1125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (at < (int)elems_size_) { 1138d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return elems_[at]; 1145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 1155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memset(&empty, 0, sizeof(empty)); 1165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return empty; 1175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1197636471bd1c553ac179f0dddc17133491d0e1fafShawn Willdentemplate <typename T> int comparator(const T& a, const T& b) { 1207636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (a < b) 1217636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return -1; 1227636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden else if (a > b) 1237636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return 1; 1247636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden else 1257636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return 0; 1267636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden} 1277636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden 1287636471bd1c553ac179f0dddc17133491d0e1fafShawn Willdenstatic int param_comparator(const void* a, const void* b) { 1297636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden const keymaster_key_param_t* lhs = static_cast<const keymaster_key_param_t*>(a); 1307636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden const keymaster_key_param_t* rhs = static_cast<const keymaster_key_param_t*>(b); 1317636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden 1327636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (lhs->tag < rhs->tag) 1337636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return -1; 1347636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden else if (lhs->tag > rhs->tag) 1357636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return 1; 1367636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden else 1377636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden switch (keymaster_tag_get_type(lhs->tag)) { 1387636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden default: 1397636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_INVALID: 1407636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return 0; 1417636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_ENUM: 1427636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_ENUM_REP: 1437636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->enumerated, rhs->enumerated); 1447636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_INT: 1457636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_INT_REP: 1467636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->integer, rhs->integer); 1477636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_LONG: 1487636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->long_integer, rhs->long_integer); 1497636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_DATE: 1507636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->date_time, rhs->date_time); 1517636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_BOOL: 1527636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->boolean, rhs->boolean); 1537636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_BIGNUM: 1547636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden case KM_BYTES: { 1557636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden size_t min_len = lhs->blob.data_length; 1567636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (rhs->blob.data_length < min_len) 1577636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden min_len = rhs->blob.data_length; 1587636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden 1597636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (lhs->blob.data_length == rhs->blob.data_length && min_len > 0) 1607636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return memcmp(lhs->blob.data, rhs->blob.data, min_len); 1617636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden int cmp_result = memcmp(lhs->blob.data, rhs->blob.data, min_len); 1627636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden if (cmp_result == 0) { 1637636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden // The blobs are equal up to the length of the shortest (which may have length 0), 1647636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden // so the shorter is less, the longer is greater and if they have the same length 1657636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden // they're identical. 1667636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return comparator(lhs->blob.data_length, rhs->blob.data_length); 1677636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden } 1687636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden return cmp_result; 1697636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden } break; 1707636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden } 1717636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden} 1727636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden 173370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::push_back(const AuthorizationSet& set) { 174370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elems_size_ + set.elems_size_)) 175370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 176370121346777e13437c275fbe7a975d899cc325cShawn Willden 177370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(indirect_data_size_ + set.indirect_data_size_)) 178370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 179370121346777e13437c275fbe7a975d899cc325cShawn Willden 180370121346777e13437c275fbe7a975d899cc325cShawn Willden for (size_t i = 0; i < set.size(); ++i) 181370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!push_back(set[i])) 182370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 183370121346777e13437c275fbe7a975d899cc325cShawn Willden 184370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 185370121346777e13437c275fbe7a975d899cc325cShawn Willden} 186370121346777e13437c275fbe7a975d899cc325cShawn Willden 1875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::push_back(keymaster_key_param_t elem) { 188370121346777e13437c275fbe7a975d899cc325cShawn Willden if (elems_size_ >= elems_capacity_) 189370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY)) 1905ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 1915ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elem.tag)) { 193370121346777e13437c275fbe7a975d899cc325cShawn Willden if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length) 194370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length))) 1955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 19658e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 1975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length); 1988d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden elem.blob.data = indirect_data_ + indirect_data_size_; 1995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_size_ += elem.blob.data_length; 2005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 2015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_[elems_size_++] = elem; 2035ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 2045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 2055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2068d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic size_t serialized_size(const keymaster_key_param_t& param) { 2078d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param.tag)) { 2088d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 2098d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden default: 2108d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t); 2118d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 2128d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 2138d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 2148d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 2158d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) * 2; 2168d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 2178d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 2188d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + sizeof(uint64_t); 2198d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 2208d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + 1; 2218d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 2238d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: 2248d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) * 3; 2258d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 2268d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 2278d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 2288d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end, 2298d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden const uint8_t* indirect_base) { 230172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.tag); 2318d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param.tag)) { 2328d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 2338d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2348d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 2358d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 236172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.enumerated); 2378d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2388d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 2398d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 240172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.integer); 2418d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2428d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 243172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint64_to_buf(buf, end, param.long_integer); 2448d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2458d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 246172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint64_to_buf(buf, end, param.date_time); 2478d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2488d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 2498d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden if (buf < end) 2508d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden *buf = static_cast<uint8_t>(param.boolean); 2518d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf++; 2528d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2538d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 2548d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: 255172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.blob.data_length); 256172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base); 2578d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2588d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 2598d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return buf; 2608d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 2618d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 262172f8c9be706e27f43022063bbc7f4b0177583acShawn Willdenstatic bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end, 2638d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden const uint8_t* indirect_base, const uint8_t* indirect_end) { 264172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, ¶m->tag)) 2658d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 2668d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 2678d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param->tag)) { 2688d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden default: 2698d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 2708d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 2718d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 2728d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 273172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint32_from_buf(buf_ptr, end, ¶m->enumerated); 2748d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 2758d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 276172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint32_from_buf(buf_ptr, end, ¶m->integer); 2778d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 278172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint64_from_buf(buf_ptr, end, ¶m->long_integer); 2798d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 280172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint64_from_buf(buf_ptr, end, ¶m->date_time); 2818d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2828d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 283172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (*buf_ptr < end) { 284172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden param->boolean = static_cast<bool>(**buf_ptr); 285172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden (*buf_ptr)++; 2868d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 2878d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 2888d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 2898d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 2908d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 2918d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: { 2928d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t offset; 293172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, ¶m->blob.data_length) || 294172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden !copy_uint32_from_buf(buf_ptr, end, &offset)) 2958d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 2968d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden if (static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base || 297172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base) 2988d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 2998d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden param->blob.data = indirect_base + offset; 3008d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 3018d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3028d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3038d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 3048d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 3058d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdensize_t AuthorizationSet::SerializedSizeOfElements() const { 3068d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden size_t size = 0; 3078d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elems_size_; ++i) { 3088d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden size += serialized_size(elems_[i]); 3098d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3108d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return size; 3118d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 3128d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 31358e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willdensize_t AuthorizationSet::SerializedSize() const { 3148d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + // Size of indirect_data_ 3158d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden indirect_data_size_ + // indirect_data_ 3168d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden sizeof(uint32_t) + // Number of elems_ 3178d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden sizeof(uint32_t) + // Size of elems_ 3188d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden SerializedSizeOfElements(); // elems_ 3195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3218d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenuint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const { 3228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_); 323172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, elems_size_); 324172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements()); 3258d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elems_size_; ++i) { 3268d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf = serialize(elems_[i], buf, end, indirect_data_); 3278d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3288d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return buf; 3295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 331370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) { 332370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_data_)) { 333370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(MALFORMED_DATA); 334370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 335370121346777e13437c275fbe7a975d899cc325cShawn Willden } 336370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 337370121346777e13437c275fbe7a975d899cc325cShawn Willden} 3385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 339370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) { 3408d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t elements_count; 3418d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t elements_size; 342370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) || 343172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden !copy_uint32_from_buf(buf_ptr, end, &elements_size)) { 34458e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden set_invalid(MALFORMED_DATA); 3455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 3465ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 3475ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 348834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden // Note that the following validation of elements_count is weak, but it prevents allocation of 349834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden // elems_ arrays which are clearly too large to be reasonable. 350172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (elements_size > end - *buf_ptr || elements_count * sizeof(uint32_t) > elements_size) { 351834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden set_invalid(MALFORMED_DATA); 352834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden return false; 353834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden } 354834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden 355370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elements_count)) 3565ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 3575ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3588d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint8_t* indirect_end = indirect_data_ + indirect_data_size_; 359172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden const uint8_t* elements_end = *buf_ptr + elements_size; 3608d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elements_count; ++i) { 361172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) { 3628d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden set_invalid(MALFORMED_DATA); 3638d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3648d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 36558e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden } 366370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_size_ = elements_count; 367370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 368370121346777e13437c275fbe7a975d899cc325cShawn Willden} 3695ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 370370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { 371370121346777e13437c275fbe7a975d899cc325cShawn Willden FreeData(); 372370121346777e13437c275fbe7a975d899cc325cShawn Willden 373370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end)) 374370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 375370121346777e13437c275fbe7a975d899cc325cShawn Willden 376370121346777e13437c275fbe7a975d899cc325cShawn Willden if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) { 3778d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden set_invalid(MALFORMED_DATA); 3785ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 3795ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 3808d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 3815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3825ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3835ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::FreeData() { 38458e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden if (elems_ != NULL) 38574aff357261879dfa8366528a42c59b042c7bd05Shawn Willden memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t)); 38658e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden if (indirect_data_ != NULL) 38774aff357261879dfa8366528a42c59b042c7bd05Shawn Willden memset_s(indirect_data_, 0, indirect_data_size_); 38858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 38958e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden delete[] elems_; 39058e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden delete[] indirect_data_; 39158e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 3925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_ = NULL; 3935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_ = NULL; 3945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_size_ = 0; 3955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_capacity_ = 0; 3965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_size_ = 0; 3975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_capacity_ = 0; 398370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = OK; 3995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden/* static */ 4025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdensize_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) { 4035ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t size = 0; 4045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden for (size_t i = 0; i < count; ++i) { 4055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elems[i].tag)) { 4065ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size += elems[i].blob.data_length; 4075ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return size; 4105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4115ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::CopyIndirectData() { 413370121346777e13437c275fbe7a975d899cc325cShawn Willden memset_s(indirect_data_, 0, indirect_data_capacity_); 4145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint8_t* indirect_data_pos = indirect_data_; 4165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden for (size_t i = 0; i < elems_size_; ++i) { 417370121346777e13437c275fbe7a975d899cc325cShawn Willden assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_); 4185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elems_[i].tag)) { 4195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length); 4205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_[i].blob.data = indirect_data_pos; 4215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_pos += elems_[i].blob.data_length; 4225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 424370121346777e13437c275fbe7a975d899cc325cShawn Willden assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_); 425370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_size_ = indirect_data_pos - indirect_data_; 4265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const { 4295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 433ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].enumerated; 4345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, 4385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint32_t* val) const { 4395ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t count = 0; 4405ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = -1; 4415ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden while (count <= instance) { 4425ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden pos = find(tag, pos); 4435ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4445ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4465ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden ++count; 4475ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 448ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].enumerated; 4495ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4505ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4515ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4525ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const { 4535ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4545ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4555ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4565ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 457ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].integer; 4585ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4595ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4605ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance, 4625ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint32_t* val) const { 4635ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t count = 0; 4645ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = -1; 4655ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden while (count <= instance) { 4665ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden pos = find(tag, pos); 4675ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4685ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4695ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4705ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden ++count; 4715ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 472ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].integer; 4735ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4745ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4755ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4765ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const { 4775ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4785ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4795ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4805ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 481ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].long_integer; 4825ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4835ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4845ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4855ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const { 4865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4885ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4895ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 490ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].date_time; 4915ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const { 4955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 499ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].blob; 5005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5035ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} // namespace keymaster 504