authorization_set.cpp revision 2c242009007a38b5c8003137fb8ba5a1fdb73b70
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 2398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden#include <keymaster/authorization_set.h> 2498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden#include <keymaster/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 392c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn WilldenAuthorizationSet::AuthorizationSet(AuthorizationSetBuilder& builder) { 402c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_ = builder.set.elems_; 412c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.elems_ = NULL; 422c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 432c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_size_ = builder.set.elems_size_; 442c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.elems_size_ = 0; 452c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 462c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_capacity_ = builder.set.elems_capacity_; 472c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.elems_capacity_ = 0; 482c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 492c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden indirect_data_ = builder.set.indirect_data_; 502c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.indirect_data_ = NULL; 512c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 522c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden indirect_data_capacity_ = builder.set.indirect_data_capacity_; 532c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.indirect_data_capacity_ = 0; 542c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 552c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden indirect_data_size_ = builder.set.indirect_data_size_; 562c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.indirect_data_size_ = 0; 572c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 582c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden error_ = builder.set.error_; 592c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.error_ = OK; 602c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden} 612c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 628d336ae10df66da4c0433f17c2d42e85baea32c5Shawn WilldenAuthorizationSet::~AuthorizationSet() { 638d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden FreeData(); 648d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 6558e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 66370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::reserve_elems(size_t count) { 67437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 68437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 69437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 70370121346777e13437c275fbe7a975d899cc325cShawn Willden if (count >= elems_capacity_) { 71370121346777e13437c275fbe7a975d899cc325cShawn Willden keymaster_key_param_t* new_elems = new keymaster_key_param_t[count]; 72370121346777e13437c275fbe7a975d899cc325cShawn Willden if (new_elems == NULL) { 73370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(ALLOCATION_FAILURE); 74370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 75370121346777e13437c275fbe7a975d899cc325cShawn Willden } 76370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_); 77370121346777e13437c275fbe7a975d899cc325cShawn Willden delete[] elems_; 78370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_ = new_elems; 79370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_capacity_ = count; 80370121346777e13437c275fbe7a975d899cc325cShawn Willden } 81370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 82370121346777e13437c275fbe7a975d899cc325cShawn Willden} 83370121346777e13437c275fbe7a975d899cc325cShawn Willden 84370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::reserve_indirect(size_t length) { 85437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 86437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 87437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 88370121346777e13437c275fbe7a975d899cc325cShawn Willden if (length > indirect_data_capacity_) { 89370121346777e13437c275fbe7a975d899cc325cShawn Willden uint8_t* new_data = new uint8_t[length]; 90370121346777e13437c275fbe7a975d899cc325cShawn Willden if (new_data == NULL) { 91370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(ALLOCATION_FAILURE); 92370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 93370121346777e13437c275fbe7a975d899cc325cShawn Willden } 94370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(new_data, indirect_data_, indirect_data_size_); 95370121346777e13437c275fbe7a975d899cc325cShawn Willden 96370121346777e13437c275fbe7a975d899cc325cShawn Willden // Fix up the data pointers to point into the new region. 97370121346777e13437c275fbe7a975d899cc325cShawn Willden for (size_t i = 0; i < elems_size_; ++i) { 98370121346777e13437c275fbe7a975d899cc325cShawn Willden if (is_blob_tag(elems_[i].tag)) 99370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_); 100370121346777e13437c275fbe7a975d899cc325cShawn Willden } 101370121346777e13437c275fbe7a975d899cc325cShawn Willden delete[] indirect_data_; 102370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_ = new_data; 103370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_capacity_ = length; 104370121346777e13437c275fbe7a975d899cc325cShawn Willden } 105370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 106370121346777e13437c275fbe7a975d899cc325cShawn Willden} 107370121346777e13437c275fbe7a975d899cc325cShawn Willden 1085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) { 1095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden FreeData(); 1105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 111370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(count)) 112370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 1135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 114370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(ComputeIndirectDataSize(elems, count))) 1155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 1165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 117370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(elems_, elems, sizeof(keymaster_key_param_t) * count); 118370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_size_ = count; 1195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden CopyIndirectData(); 120370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = OK; 1215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 1225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::set_invalid(Error error) { 1255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden FreeData(); 126370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = error; 1275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1292c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willdenvoid AuthorizationSet::Deduplicate() { 1302c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden qsort(elems_, elems_size_, sizeof(*elems_), 1312c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden reinterpret_cast<int (*)(const void*, const void*)>(keymaster_param_compare)); 1322c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 1332c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden size_t invalid_count = 0; 1342c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden for (size_t i = 1; i < size(); ++i) { 1352c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden if (elems_[i - 1].tag == KM_TAG_INVALID) 1362c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden ++invalid_count; 1372c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden else if (keymaster_param_compare(elems_ + i - 1, elems_ + i) == 0) { 1382c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden // Mark dups as invalid. Note that this "leaks" the data referenced by KM_BYTES and 1392c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden // KM_BIGNUM entries, but those are just pointers into indirect_data_, so it will all 1402c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden // get cleaned up. 1412c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_[i - 1].tag = KM_TAG_INVALID; 1422c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden ++invalid_count; 1432c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden } 1442c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden } 1452c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden if (size() > 0 && elems_[size() - 1].tag == KM_TAG_INVALID) 1462c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden ++invalid_count; 1472c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 1482c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden if (invalid_count == 0) 1492c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden return; 1502c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 1512c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden // Since KM_TAG_INVALID == 0, all of the invalid entries are first. 1522c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_size_ -= invalid_count; 1532c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden memmove(elems_, elems_ + invalid_count, size() * sizeof(*elems_)); 1542c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden} 1552c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 156cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willdenvoid AuthorizationSet::CopyToParamSet(keymaster_key_param_set_t* set) const { 157cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden assert(set); 158cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden 159cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden set->length = size(); 160cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden set->params = 161cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden reinterpret_cast<keymaster_key_param_t*>(malloc(sizeof(keymaster_key_param_t) * size())); 162cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden 163cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden for (size_t i = 0; i < size(); ++i) { 164cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden const keymaster_key_param_t src = (*this)[i]; 165cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden keymaster_key_param_t& dst(set->params[i]); 166cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden 167cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden dst = src; 168cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden keymaster_tag_type_t type = keymaster_tag_get_type(src.tag); 169cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden if (type == KM_BIGNUM || type == KM_BYTES) { 170cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden void* tmp = malloc(src.blob.data_length); 171cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden memcpy(tmp, src.blob.data, src.blob.data_length); 172cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden dst.blob.data = reinterpret_cast<uint8_t*>(tmp); 173cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden } 174cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden } 175cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden} 176cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden 1775ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenint AuthorizationSet::find(keymaster_tag_t tag, int begin) const { 178437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 179437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return -1; 180437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 1815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int i = ++begin; 1828d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden while (i < (int)elems_size_ && elems_[i].tag != tag) 1838d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden ++i; 1845ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (i == (int)elems_size_) 1855ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return -1; 1865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden else 1875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return i; 1885ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1895ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1905ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenkeymaster_key_param_t empty; 1915ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenkeymaster_key_param_t AuthorizationSet::operator[](int at) const { 192437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() == OK && at < (int)elems_size_) { 1938d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return elems_[at]; 1945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 1955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memset(&empty, 0, sizeof(empty)); 1965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return empty; 1975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 199370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::push_back(const AuthorizationSet& set) { 200437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 201437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 202437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 203370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elems_size_ + set.elems_size_)) 204370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 205370121346777e13437c275fbe7a975d899cc325cShawn Willden 206370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(indirect_data_size_ + set.indirect_data_size_)) 207370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 208370121346777e13437c275fbe7a975d899cc325cShawn Willden 209370121346777e13437c275fbe7a975d899cc325cShawn Willden for (size_t i = 0; i < set.size(); ++i) 210370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!push_back(set[i])) 211370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 212370121346777e13437c275fbe7a975d899cc325cShawn Willden 213370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 214370121346777e13437c275fbe7a975d899cc325cShawn Willden} 215370121346777e13437c275fbe7a975d899cc325cShawn Willden 2165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::push_back(keymaster_key_param_t elem) { 217437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 218437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 219437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 220370121346777e13437c275fbe7a975d899cc325cShawn Willden if (elems_size_ >= elems_capacity_) 221370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY)) 2225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 2235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elem.tag)) { 225370121346777e13437c275fbe7a975d899cc325cShawn Willden if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length) 226370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length))) 2275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 22858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 2295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length); 2308d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden elem.blob.data = indirect_data_ + indirect_data_size_; 2315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_size_ += elem.blob.data_length; 2325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 2335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_[elems_size_++] = elem; 2355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 2365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 2375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2388d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic size_t serialized_size(const keymaster_key_param_t& param) { 2398d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param.tag)) { 2408d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 2418d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden default: 2428d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t); 2438d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 2448d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 2458d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 2468d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 2478d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) * 2; 2488d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 2498d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 2508d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + sizeof(uint64_t); 2518d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 2528d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + 1; 2538d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2548d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 2558d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: 2568d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) * 3; 2578d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 2588d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 2598d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 2608d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end, 2618d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden const uint8_t* indirect_base) { 262172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.tag); 2638d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param.tag)) { 2648d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 2658d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2668d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 2678d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 268172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.enumerated); 2698d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2708d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 2718d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 272172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.integer); 2738d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2748d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 275172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint64_to_buf(buf, end, param.long_integer); 2768d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2778d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 278172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint64_to_buf(buf, end, param.date_time); 2798d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2808d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 2818d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden if (buf < end) 2828d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden *buf = static_cast<uint8_t>(param.boolean); 2838d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf++; 2848d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2858d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 2868d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: 287172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.blob.data_length); 288172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base); 2898d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 2908d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 2918d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return buf; 2928d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 2938d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 294172f8c9be706e27f43022063bbc7f4b0177583acShawn Willdenstatic bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end, 2958d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden const uint8_t* indirect_base, const uint8_t* indirect_end) { 296172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, ¶m->tag)) 2978d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 2988d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 2998d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param->tag)) { 3008d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden default: 3018d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 3028d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3038d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 3048d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 305172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint32_from_buf(buf_ptr, end, ¶m->enumerated); 3068d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT: 3078d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INT_REP: 308172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint32_from_buf(buf_ptr, end, ¶m->integer); 3098d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_LONG: 310172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint64_from_buf(buf_ptr, end, ¶m->long_integer); 3118d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 312172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint64_from_buf(buf_ptr, end, ¶m->date_time); 3138d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 3148d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 315172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (*buf_ptr < end) { 316172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden param->boolean = static_cast<bool>(**buf_ptr); 317172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden (*buf_ptr)++; 3188d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 3198d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3208d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3218d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 3228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 3238d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: { 3248d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t offset; 325172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, ¶m->blob.data_length) || 326172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden !copy_uint32_from_buf(buf_ptr, end, &offset)) 3278d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3288d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden if (static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base || 329172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base) 3308d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3318d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden param->blob.data = indirect_base + offset; 3328d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 3338d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3348d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3358d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 3368d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 3378d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdensize_t AuthorizationSet::SerializedSizeOfElements() const { 3388d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden size_t size = 0; 3398d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elems_size_; ++i) { 3408d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden size += serialized_size(elems_[i]); 3418d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3428d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return size; 3438d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 3448d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 34558e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willdensize_t AuthorizationSet::SerializedSize() const { 3468d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + // Size of indirect_data_ 3478d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden indirect_data_size_ + // indirect_data_ 3488d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden sizeof(uint32_t) + // Number of elems_ 3498d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden sizeof(uint32_t) + // Size of elems_ 3508d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden SerializedSizeOfElements(); // elems_ 3515ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3525ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3538d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenuint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const { 3548d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_); 355172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, elems_size_); 356172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements()); 3578d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elems_size_; ++i) { 3588d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf = serialize(elems_[i], buf, end, indirect_data_); 3598d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3608d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return buf; 3615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3625ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 363370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) { 364f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden UniquePtr<uint8_t[]> indirect_buf; 365f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_buf)) { 366370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(MALFORMED_DATA); 367370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 368370121346777e13437c275fbe7a975d899cc325cShawn Willden } 369f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden indirect_data_ = indirect_buf.release(); 370370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 371370121346777e13437c275fbe7a975d899cc325cShawn Willden} 3725ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 373370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) { 3748d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t elements_count; 3758d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t elements_size; 376370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) || 377172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden !copy_uint32_from_buf(buf_ptr, end, &elements_size)) { 37858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden set_invalid(MALFORMED_DATA); 3795ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 3805ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 3815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 382834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden // Note that the following validation of elements_count is weak, but it prevents allocation of 383834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden // elems_ arrays which are clearly too large to be reasonable. 38462de26672193373972f2ce968b51cf8335f118f9Shawn Willden if (static_cast<ptrdiff_t>(elements_size) > end - *buf_ptr || 38562de26672193373972f2ce968b51cf8335f118f9Shawn Willden elements_count * sizeof(uint32_t) > elements_size) { 386834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden set_invalid(MALFORMED_DATA); 387834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden return false; 388834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden } 389834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden 390370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elements_count)) 3915ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 3925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3938d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint8_t* indirect_end = indirect_data_ + indirect_data_size_; 394172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden const uint8_t* elements_end = *buf_ptr + elements_size; 3958d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elements_count; ++i) { 396172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) { 3978d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden set_invalid(MALFORMED_DATA); 3988d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3998d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 40058e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden } 401370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_size_ = elements_count; 402370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 403370121346777e13437c275fbe7a975d899cc325cShawn Willden} 4045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 405370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { 406370121346777e13437c275fbe7a975d899cc325cShawn Willden FreeData(); 407370121346777e13437c275fbe7a975d899cc325cShawn Willden 408370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end)) 409370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 410370121346777e13437c275fbe7a975d899cc325cShawn Willden 411370121346777e13437c275fbe7a975d899cc325cShawn Willden if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) { 4128d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden set_invalid(MALFORMED_DATA); 4135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4158d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 4165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 418941d1c4ad4422a796d90010191c11aef0580295eShawn Willdenvoid AuthorizationSet::Clear() { 4191834d5f82a7ad5884c184fd22c702ac9d915af45Shawn Willden memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t)); 4201834d5f82a7ad5884c184fd22c702ac9d915af45Shawn Willden memset_s(indirect_data_, 0, indirect_data_size_); 421941d1c4ad4422a796d90010191c11aef0580295eShawn Willden elems_size_ = 0; 422941d1c4ad4422a796d90010191c11aef0580295eShawn Willden indirect_data_size_ = 0; 423941d1c4ad4422a796d90010191c11aef0580295eShawn Willden} 424941d1c4ad4422a796d90010191c11aef0580295eShawn Willden 425941d1c4ad4422a796d90010191c11aef0580295eShawn Willdenvoid AuthorizationSet::FreeData() { 426941d1c4ad4422a796d90010191c11aef0580295eShawn Willden Clear(); 42758e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 42858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden delete[] elems_; 42958e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden delete[] indirect_data_; 43058e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 4315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_ = NULL; 4325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_ = NULL; 4335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_capacity_ = 0; 4345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_capacity_ = 0; 435370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = OK; 4365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden/* static */ 4395ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdensize_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) { 4405ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t size = 0; 4415ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden for (size_t i = 0; i < count; ++i) { 4425ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elems[i].tag)) { 4435ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size += elems[i].blob.data_length; 4445ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4465ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return size; 4475ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4485ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4495ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::CopyIndirectData() { 450370121346777e13437c275fbe7a975d899cc325cShawn Willden memset_s(indirect_data_, 0, indirect_data_capacity_); 4515ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4525ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint8_t* indirect_data_pos = indirect_data_; 4535ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden for (size_t i = 0; i < elems_size_; ++i) { 454370121346777e13437c275fbe7a975d899cc325cShawn Willden assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_); 4555ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elems_[i].tag)) { 4565ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length); 4575ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_[i].blob.data = indirect_data_pos; 4585ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_pos += elems_[i].blob.data_length; 4595ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4605ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 461370121346777e13437c275fbe7a975d899cc325cShawn Willden assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_); 462370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_size_ = indirect_data_pos - indirect_data_; 4635ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4645ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4651fa5d591fe6807665092753a5628d8d470888da4Shawn Willdensize_t AuthorizationSet::GetTagCount(keymaster_tag_t tag) const { 4661fa5d591fe6807665092753a5628d8d470888da4Shawn Willden size_t count = 0; 4671fa5d591fe6807665092753a5628d8d470888da4Shawn Willden for (int pos = -1; (pos = find(tag, pos)) != -1;) 4681fa5d591fe6807665092753a5628d8d470888da4Shawn Willden ++count; 4691fa5d591fe6807665092753a5628d8d470888da4Shawn Willden return count; 4701fa5d591fe6807665092753a5628d8d470888da4Shawn Willden} 4711fa5d591fe6807665092753a5628d8d470888da4Shawn Willden 4725ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const { 4735ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4745ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4755ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4765ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 477ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].enumerated; 4785ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4795ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4805ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, 4825ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint32_t* val) const { 4835ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t count = 0; 4845ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = -1; 4855ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden while (count <= instance) { 4865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden pos = find(tag, pos); 4875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4885ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4895ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4905ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden ++count; 4915ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 492ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].enumerated; 4935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 4945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const { 4975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 4985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 4995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 501ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].integer; 5025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5035ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance, 5065ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint32_t* val) const { 5075ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t count = 0; 5085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = -1; 5095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden while (count <= instance) { 5105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden pos = find(tag, pos); 5115ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 5145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden ++count; 5155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 516ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].integer; 5175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const { 5215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 5225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 525ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].long_integer; 5265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const { 5305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 5315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 534ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].date_time; 5355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const { 5395ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 5405ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5415ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5425ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 543ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].blob; 5445ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5465ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 547dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willdenbool AuthorizationSet::GetTagValueBool(keymaster_tag_t tag) const { 548dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden int pos = find(tag); 549dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden if (pos == -1) { 550dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden return false; 551dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden } 552dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden assert(elems_[pos].boolean); 553dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden return elems_[pos].boolean; 554dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden} 555dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden 5565ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} // namespace keymaster 557