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 170f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden#include <keymaster/authorization_set.h> 180f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 190f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden#include <assert.h> 20f21afff128ac22479c49bdda84f13335ae17d009Shawn Willden#include <stddef.h> 215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <stdlib.h> 225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <string.h> 235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 24f38a002624126ca837865826f948edc9100d6e8aJanis Danisevskis#include <keymaster/new> 255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 26b6837e7a62a1192e33beef586282812239ee8b28Shawn Willden#include <keymaster/android_keymaster_utils.h> 27f01329d8692edde9a9ffb88f29f5d684eab481e2Shawn Willden#include <keymaster/logger.h> 285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdennamespace keymaster { 305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenstatic inline bool is_blob_tag(keymaster_tag_t tag) { 325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return (keymaster_tag_get_type(tag) == KM_BYTES || keymaster_tag_get_type(tag) == KM_BIGNUM); 335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenconst size_t STARTING_ELEMS_CAPACITY = 8; 365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 372c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn WilldenAuthorizationSet::AuthorizationSet(AuthorizationSetBuilder& builder) { 382c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_ = builder.set.elems_; 392c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.elems_ = NULL; 402c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 412c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_size_ = builder.set.elems_size_; 422c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.elems_size_ = 0; 432c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 442c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_capacity_ = builder.set.elems_capacity_; 452c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.elems_capacity_ = 0; 462c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 472c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden indirect_data_ = builder.set.indirect_data_; 482c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.indirect_data_ = NULL; 492c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 502c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden indirect_data_capacity_ = builder.set.indirect_data_capacity_; 512c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.indirect_data_capacity_ = 0; 522c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 532c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden indirect_data_size_ = builder.set.indirect_data_size_; 542c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.indirect_data_size_ = 0; 552c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 562c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden error_ = builder.set.error_; 572c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden builder.set.error_ = OK; 582c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden} 592c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 608d336ae10df66da4c0433f17c2d42e85baea32c5Shawn WilldenAuthorizationSet::~AuthorizationSet() { 618d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden FreeData(); 628d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 6358e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 64370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::reserve_elems(size_t count) { 65437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 66437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 67437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 683560f7be392fa7f59844b8c5c54c2d75a62aad7bShawn Willden if (count > elems_capacity_) { 690f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden keymaster_key_param_t* new_elems = new (std::nothrow) keymaster_key_param_t[count]; 70370121346777e13437c275fbe7a975d899cc325cShawn Willden if (new_elems == NULL) { 71370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(ALLOCATION_FAILURE); 72370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 73370121346777e13437c275fbe7a975d899cc325cShawn Willden } 74370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_); 75370121346777e13437c275fbe7a975d899cc325cShawn Willden delete[] elems_; 76370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_ = new_elems; 77370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_capacity_ = count; 78370121346777e13437c275fbe7a975d899cc325cShawn Willden } 79370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 80370121346777e13437c275fbe7a975d899cc325cShawn Willden} 81370121346777e13437c275fbe7a975d899cc325cShawn Willden 82370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::reserve_indirect(size_t length) { 83437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 84437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 85437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 86370121346777e13437c275fbe7a975d899cc325cShawn Willden if (length > indirect_data_capacity_) { 87c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden uint8_t* new_data = new (std::nothrow) uint8_t[length]; 88370121346777e13437c275fbe7a975d899cc325cShawn Willden if (new_data == NULL) { 89370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(ALLOCATION_FAILURE); 90370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 91370121346777e13437c275fbe7a975d899cc325cShawn Willden } 92370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(new_data, indirect_data_, indirect_data_size_); 93370121346777e13437c275fbe7a975d899cc325cShawn Willden 94370121346777e13437c275fbe7a975d899cc325cShawn Willden // Fix up the data pointers to point into the new region. 95370121346777e13437c275fbe7a975d899cc325cShawn Willden for (size_t i = 0; i < elems_size_; ++i) { 96370121346777e13437c275fbe7a975d899cc325cShawn Willden if (is_blob_tag(elems_[i].tag)) 97370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_); 98370121346777e13437c275fbe7a975d899cc325cShawn Willden } 99370121346777e13437c275fbe7a975d899cc325cShawn Willden delete[] indirect_data_; 100370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_ = new_data; 101370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_capacity_ = length; 102370121346777e13437c275fbe7a975d899cc325cShawn Willden } 103370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 104370121346777e13437c275fbe7a975d899cc325cShawn Willden} 105370121346777e13437c275fbe7a975d899cc325cShawn Willden 10643786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowleyvoid AuthorizationSet::MoveFrom(AuthorizationSet& set) { 10743786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley elems_ = set.elems_; 10843786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley elems_size_ = set.elems_size_; 10943786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley elems_capacity_ = set.elems_capacity_; 11043786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley indirect_data_ = set.indirect_data_; 11143786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley indirect_data_size_ = set.indirect_data_size_; 11243786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley indirect_data_capacity_ = set.indirect_data_capacity_; 11343786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley error_ = set.error_; 11443786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley set.elems_ = nullptr; 11543786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley set.elems_size_ = 0; 11643786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley set.elems_capacity_ = 0; 11743786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley set.indirect_data_ = nullptr; 11843786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley set.indirect_data_size_ = 0; 11943786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley set.indirect_data_capacity_ = 0; 12043786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley set.error_ = OK; 12143786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley} 12243786c8ca4e9034b5aa1528b52f9eaaa7551b05fPaul Crowley 1235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) { 1245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden FreeData(); 1255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 126b58dcde804dc9f69f89c620592b910083f32b01cShawn Willden if (elems == NULL || count == 0) { 127b58dcde804dc9f69f89c620592b910083f32b01cShawn Willden error_ = OK; 128b58dcde804dc9f69f89c620592b910083f32b01cShawn Willden return true; 129b58dcde804dc9f69f89c620592b910083f32b01cShawn Willden } 130b58dcde804dc9f69f89c620592b910083f32b01cShawn Willden 131370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(count)) 132370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 1335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 134370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(ComputeIndirectDataSize(elems, count))) 1355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 1365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 137370121346777e13437c275fbe7a975d899cc325cShawn Willden memcpy(elems_, elems, sizeof(keymaster_key_param_t) * count); 138370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_size_ = count; 1395ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden CopyIndirectData(); 140370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = OK; 1415ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 1425ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1435ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 1445ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::set_invalid(Error error) { 1455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden FreeData(); 146370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = error; 1475ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 1485ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 149f21afff128ac22479c49bdda84f13335ae17d009Shawn Willdenvoid AuthorizationSet::Sort() { 1502c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden qsort(elems_, elems_size_, sizeof(*elems_), 1512c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden reinterpret_cast<int (*)(const void*, const void*)>(keymaster_param_compare)); 152f21afff128ac22479c49bdda84f13335ae17d009Shawn Willden} 153f21afff128ac22479c49bdda84f13335ae17d009Shawn Willden 154f21afff128ac22479c49bdda84f13335ae17d009Shawn Willdenvoid AuthorizationSet::Deduplicate() { 155f21afff128ac22479c49bdda84f13335ae17d009Shawn Willden Sort(); 1562c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 1572c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden size_t invalid_count = 0; 1582c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden for (size_t i = 1; i < size(); ++i) { 1592c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden if (elems_[i - 1].tag == KM_TAG_INVALID) 1602c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden ++invalid_count; 1612c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden else if (keymaster_param_compare(elems_ + i - 1, elems_ + i) == 0) { 1622c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden // Mark dups as invalid. Note that this "leaks" the data referenced by KM_BYTES and 1632c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden // KM_BIGNUM entries, but those are just pointers into indirect_data_, so it will all 1642c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden // get cleaned up. 1652c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_[i - 1].tag = KM_TAG_INVALID; 1662c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden ++invalid_count; 1672c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden } 1682c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden } 1692c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden if (size() > 0 && elems_[size() - 1].tag == KM_TAG_INVALID) 1702c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden ++invalid_count; 1712c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 1722c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden if (invalid_count == 0) 1732c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden return; 1742c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 175f21afff128ac22479c49bdda84f13335ae17d009Shawn Willden Sort(); 176f21afff128ac22479c49bdda84f13335ae17d009Shawn Willden 1772c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden // Since KM_TAG_INVALID == 0, all of the invalid entries are first. 1782c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden elems_size_ -= invalid_count; 1792c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden memmove(elems_, elems_ + invalid_count, size() * sizeof(*elems_)); 1802c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden} 1812c242009007a38b5c8003137fb8ba5a1fdb73b70Shawn Willden 182391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestrovoid AuthorizationSet::Union(const keymaster_key_param_set_t& set) { 183391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro if (set.length == 0) 184391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro return; 185391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro 186391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro push_back(set); 187391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro Deduplicate(); 188391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro} 189391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro 190391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestrovoid AuthorizationSet::Difference(const keymaster_key_param_set_t& set) { 191391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro if (set.length == 0) 192391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro return; 193391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro 194391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro Deduplicate(); 195391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro 196391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro for (size_t i = 0; i < set.length; i++) { 197391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro int index = -1; 198391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro do { 199391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro index = find(set.params[i].tag, index); 200391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro if (index != -1 && keymaster_param_compare(&elems_[index], &set.params[i]) == 0) { 201391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro erase(index); 202391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro break; 203391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro } 204391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro } while (index != -1); 205391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro } 206391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro} 207391a367df2352bed7e70885493421892a1cdaffcTucker Sylvestro 208cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willdenvoid AuthorizationSet::CopyToParamSet(keymaster_key_param_set_t* set) const { 209cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden assert(set); 210cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden 211cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden set->length = size(); 212cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden set->params = 213cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden reinterpret_cast<keymaster_key_param_t*>(malloc(sizeof(keymaster_key_param_t) * size())); 214cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden 215cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden for (size_t i = 0; i < size(); ++i) { 216cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden const keymaster_key_param_t src = (*this)[i]; 217cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden keymaster_key_param_t& dst(set->params[i]); 218cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden 219cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden dst = src; 220cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden keymaster_tag_type_t type = keymaster_tag_get_type(src.tag); 221cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden if (type == KM_BIGNUM || type == KM_BYTES) { 222cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden void* tmp = malloc(src.blob.data_length); 223cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden memcpy(tmp, src.blob.data, src.blob.data_length); 224cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden dst.blob.data = reinterpret_cast<uint8_t*>(tmp); 225cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden } 226cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden } 227cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden} 228cb0d64b02d0df2b9eb692c5b0ea5c36db1000e9aShawn Willden 2295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenint AuthorizationSet::find(keymaster_tag_t tag, int begin) const { 230437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 231437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return -1; 232437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 2335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int i = ++begin; 2348d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden while (i < (int)elems_size_ && elems_[i].tag != tag) 2358d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden ++i; 2365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (i == (int)elems_size_) 2375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return -1; 2385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden else 2395ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return i; 2405ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 2415ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 242c15af1910d8f451341d0068b5533816ace5defecShawn Willdenbool AuthorizationSet::erase(int index) { 243c15af1910d8f451341d0068b5533816ace5defecShawn Willden if (index < 0 || index >= static_cast<int>(size())) 244cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden return false; 245cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden 246cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden --elems_size_; 247cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden for (size_t i = index; i < elems_size_; ++i) 248cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden elems_[i] = elems_[i + 1]; 249cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden return true; 250cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden} 251cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden 252c15af1910d8f451341d0068b5533816ace5defecShawn Willdenkeymaster_key_param_t empty_param = {KM_TAG_INVALID, {}}; 253d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdenkeymaster_key_param_t& AuthorizationSet::operator[](int at) { 254d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden if (is_valid() == OK && at < (int)elems_size_) { 255d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden return elems_[at]; 256d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden } 257c15af1910d8f451341d0068b5533816ace5defecShawn Willden empty_param = {KM_TAG_INVALID, {}}; 258c15af1910d8f451341d0068b5533816ace5defecShawn Willden return empty_param; 259d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden} 260d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden 2615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenkeymaster_key_param_t AuthorizationSet::operator[](int at) const { 262437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() == OK && at < (int)elems_size_) { 2638d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return elems_[at]; 2645ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 265c15af1910d8f451341d0068b5533816ace5defecShawn Willden empty_param = {KM_TAG_INVALID, {}}; 266c15af1910d8f451341d0068b5533816ace5defecShawn Willden return empty_param; 2675ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 2685ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 269b5508298cdb1d42eaf8c81aa8a6ac2cbfdeef3c7Shawn Willdenbool AuthorizationSet::push_back(const keymaster_key_param_set_t& set) { 270437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 271437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 272437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 273b5508298cdb1d42eaf8c81aa8a6ac2cbfdeef3c7Shawn Willden if (!reserve_elems(elems_size_ + set.length)) 274370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 275370121346777e13437c275fbe7a975d899cc325cShawn Willden 276b5508298cdb1d42eaf8c81aa8a6ac2cbfdeef3c7Shawn Willden if (!reserve_indirect(indirect_data_size_ + ComputeIndirectDataSize(set.params, set.length))) 277370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 278370121346777e13437c275fbe7a975d899cc325cShawn Willden 279b5508298cdb1d42eaf8c81aa8a6ac2cbfdeef3c7Shawn Willden for (size_t i = 0; i < set.length; ++i) 280b5508298cdb1d42eaf8c81aa8a6ac2cbfdeef3c7Shawn Willden if (!push_back(set.params[i])) 281370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 282370121346777e13437c275fbe7a975d899cc325cShawn Willden 283370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 284370121346777e13437c275fbe7a975d899cc325cShawn Willden} 285370121346777e13437c275fbe7a975d899cc325cShawn Willden 2865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::push_back(keymaster_key_param_t elem) { 287437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden if (is_valid() != OK) 288437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden return false; 289437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden 290370121346777e13437c275fbe7a975d899cc325cShawn Willden if (elems_size_ >= elems_capacity_) 291370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY)) 2925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 2935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 2945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elem.tag)) { 295370121346777e13437c275fbe7a975d899cc325cShawn Willden if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length) 296370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length))) 2975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 29858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 2995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length); 3008d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden elem.blob.data = indirect_data_ + indirect_data_size_; 3015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_size_ += elem.blob.data_length; 3025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 3035ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_[elems_size_++] = elem; 3055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 3065ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 3075ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 3088d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic size_t serialized_size(const keymaster_key_param_t& param) { 3098d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param.tag)) { 3108d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 3118d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t); 3128d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 3138d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 314c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_UINT: 315c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_UINT_REP: 3168d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) * 2; 317c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_ULONG: 318c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_ULONG_REP: 3198d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 3208d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + sizeof(uint64_t); 3218d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 3228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + 1; 3238d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 3248d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: 3258d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) * 3; 3268d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 32782114e7cbf97f65348d32b2685dd52427525146dShawn Willden 32882114e7cbf97f65348d32b2685dd52427525146dShawn Willden return sizeof(uint32_t); 3298d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 3308d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 3318d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end, 3328d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden const uint8_t* indirect_base) { 333172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.tag); 3348d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param.tag)) { 3358d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 3368d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 3378d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 3388d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 339172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.enumerated); 3408d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 341c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_UINT: 342c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_UINT_REP: 343172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.integer); 3448d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 345c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_ULONG: 346c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_ULONG_REP: 347172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint64_to_buf(buf, end, param.long_integer); 3488d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 3498d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 350172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint64_to_buf(buf, end, param.date_time); 3518d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 3528d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 3538d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden if (buf < end) 3548d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden *buf = static_cast<uint8_t>(param.boolean); 3558d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf++; 3568d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 3578d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 3588d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: 359172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.blob.data_length); 360172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base); 3618d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 3628d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3638d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return buf; 3648d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 3658d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 366172f8c9be706e27f43022063bbc7f4b0177583acShawn Willdenstatic bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end, 3678d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden const uint8_t* indirect_base, const uint8_t* indirect_end) { 368172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, ¶m->tag)) 3698d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3708d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 3718d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden switch (keymaster_tag_get_type(param->tag)) { 3728d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_INVALID: 3738d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3748d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM: 3758d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_ENUM_REP: 376172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint32_from_buf(buf_ptr, end, ¶m->enumerated); 377c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_UINT: 378c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_UINT_REP: 379172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint32_from_buf(buf_ptr, end, ¶m->integer); 380c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_ULONG: 381c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden case KM_ULONG_REP: 382172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint64_from_buf(buf_ptr, end, ¶m->long_integer); 3838d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_DATE: 384172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden return copy_uint64_from_buf(buf_ptr, end, ¶m->date_time); 3858d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden break; 3868d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BOOL: 387172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (*buf_ptr < end) { 388172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden param->boolean = static_cast<bool>(**buf_ptr); 389172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden (*buf_ptr)++; 3908d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 3918d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 3928d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 3938d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 3948d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BIGNUM: 3958d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden case KM_BYTES: { 3968d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t offset; 397172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, ¶m->blob.data_length) || 398172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden !copy_uint32_from_buf(buf_ptr, end, &offset)) 3998d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 40028f2e72909a73788cf636b637f7403984ede3b74Shawn Willden if (param->blob.data_length + offset < param->blob.data_length || // Overflow check 40128f2e72909a73788cf636b637f7403984ede3b74Shawn Willden static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base || 402172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base) 4038d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 4048d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden param->blob.data = indirect_base + offset; 4058d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 4068d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 4078d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 40882114e7cbf97f65348d32b2685dd52427525146dShawn Willden 40982114e7cbf97f65348d32b2685dd52427525146dShawn Willden return false; 4108d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 4118d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 4128d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdensize_t AuthorizationSet::SerializedSizeOfElements() const { 4138d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden size_t size = 0; 4148d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elems_size_; ++i) { 4158d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden size += serialized_size(elems_[i]); 4168d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 4178d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return size; 4188d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden} 4198d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden 42058e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willdensize_t AuthorizationSet::SerializedSize() const { 4218d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return sizeof(uint32_t) + // Size of indirect_data_ 4228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden indirect_data_size_ + // indirect_data_ 4238d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden sizeof(uint32_t) + // Number of elems_ 4248d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden sizeof(uint32_t) + // Size of elems_ 4258d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden SerializedSizeOfElements(); // elems_ 4265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4288d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenuint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const { 4298d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_); 430172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, elems_size_); 431172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements()); 4328d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elems_size_; ++i) { 4338d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden buf = serialize(elems_[i], buf, end, indirect_data_); 4348d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 4358d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return buf; 4365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 438370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) { 439f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden UniquePtr<uint8_t[]> indirect_buf; 440f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_buf)) { 441f01329d8692edde9a9ffb88f29f5d684eab481e2Shawn Willden LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 442370121346777e13437c275fbe7a975d899cc325cShawn Willden set_invalid(MALFORMED_DATA); 443370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 444370121346777e13437c275fbe7a975d899cc325cShawn Willden } 445f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden indirect_data_ = indirect_buf.release(); 446370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 447370121346777e13437c275fbe7a975d899cc325cShawn Willden} 4485ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 449370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) { 4508d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t elements_count; 4518d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint32_t elements_size; 452370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) || 453172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden !copy_uint32_from_buf(buf_ptr, end, &elements_size)) { 454f01329d8692edde9a9ffb88f29f5d684eab481e2Shawn Willden LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 45558e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden set_invalid(MALFORMED_DATA); 4565ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4575ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4585ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 459834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden // Note that the following validation of elements_count is weak, but it prevents allocation of 460834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden // elems_ arrays which are clearly too large to be reasonable. 46162de26672193373972f2ce968b51cf8335f118f9Shawn Willden if (static_cast<ptrdiff_t>(elements_size) > end - *buf_ptr || 4620f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden elements_count * sizeof(uint32_t) > elements_size || 4630f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden *buf_ptr + (elements_count * sizeof(*elems_)) < *buf_ptr) { 464f01329d8692edde9a9ffb88f29f5d684eab481e2Shawn Willden LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 465834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden set_invalid(MALFORMED_DATA); 466834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden return false; 467834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden } 468834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden 469370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!reserve_elems(elements_count)) 4705ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4715ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 4728d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden uint8_t* indirect_end = indirect_data_ + indirect_data_size_; 473172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden const uint8_t* elements_end = *buf_ptr + elements_size; 4748d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden for (size_t i = 0; i < elements_count; ++i) { 475172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) { 476f01329d8692edde9a9ffb88f29f5d684eab481e2Shawn Willden LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 4778d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden set_invalid(MALFORMED_DATA); 4788d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return false; 4798d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden } 48058e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden } 481370121346777e13437c275fbe7a975d899cc325cShawn Willden elems_size_ = elements_count; 482370121346777e13437c275fbe7a975d899cc325cShawn Willden return true; 483370121346777e13437c275fbe7a975d899cc325cShawn Willden} 4845ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 485370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { 486370121346777e13437c275fbe7a975d899cc325cShawn Willden FreeData(); 487370121346777e13437c275fbe7a975d899cc325cShawn Willden 488370121346777e13437c275fbe7a975d899cc325cShawn Willden if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end)) 489370121346777e13437c275fbe7a975d899cc325cShawn Willden return false; 490370121346777e13437c275fbe7a975d899cc325cShawn Willden 491370121346777e13437c275fbe7a975d899cc325cShawn Willden if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) { 492f01329d8692edde9a9ffb88f29f5d684eab481e2Shawn Willden LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 4938d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden set_invalid(MALFORMED_DATA); 4945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 4955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 4968d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden return true; 4975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 4985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 499941d1c4ad4422a796d90010191c11aef0580295eShawn Willdenvoid AuthorizationSet::Clear() { 5001834d5f82a7ad5884c184fd22c702ac9d915af45Shawn Willden memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t)); 5011834d5f82a7ad5884c184fd22c702ac9d915af45Shawn Willden memset_s(indirect_data_, 0, indirect_data_size_); 502941d1c4ad4422a796d90010191c11aef0580295eShawn Willden elems_size_ = 0; 503941d1c4ad4422a796d90010191c11aef0580295eShawn Willden indirect_data_size_ = 0; 504941d1c4ad4422a796d90010191c11aef0580295eShawn Willden} 505941d1c4ad4422a796d90010191c11aef0580295eShawn Willden 506941d1c4ad4422a796d90010191c11aef0580295eShawn Willdenvoid AuthorizationSet::FreeData() { 507941d1c4ad4422a796d90010191c11aef0580295eShawn Willden Clear(); 50858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 50958e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden delete[] elems_; 51058e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden delete[] indirect_data_; 51158e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden 5125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_ = NULL; 5135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_ = NULL; 5145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_capacity_ = 0; 5155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_capacity_ = 0; 516370121346777e13437c275fbe7a975d899cc325cShawn Willden error_ = OK; 5175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden/* static */ 5205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdensize_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) { 5215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t size = 0; 5225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden for (size_t i = 0; i < count; ++i) { 5235ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elems[i].tag)) { 5245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size += elems[i].blob.data_length; 5255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 5265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 5275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return size; 5285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::CopyIndirectData() { 531370121346777e13437c275fbe7a975d899cc325cShawn Willden memset_s(indirect_data_, 0, indirect_data_capacity_); 5325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint8_t* indirect_data_pos = indirect_data_; 5345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden for (size_t i = 0; i < elems_size_; ++i) { 535370121346777e13437c275fbe7a975d899cc325cShawn Willden assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_); 5365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (is_blob_tag(elems_[i].tag)) { 5375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length); 5385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden elems_[i].blob.data = indirect_data_pos; 5395ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden indirect_data_pos += elems_[i].blob.data_length; 5405ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 5415ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 542370121346777e13437c275fbe7a975d899cc325cShawn Willden assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_); 543370121346777e13437c275fbe7a975d899cc325cShawn Willden indirect_data_size_ = indirect_data_pos - indirect_data_; 5445ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5461fa5d591fe6807665092753a5628d8d470888da4Shawn Willdensize_t AuthorizationSet::GetTagCount(keymaster_tag_t tag) const { 5471fa5d591fe6807665092753a5628d8d470888da4Shawn Willden size_t count = 0; 5481fa5d591fe6807665092753a5628d8d470888da4Shawn Willden for (int pos = -1; (pos = find(tag, pos)) != -1;) 5491fa5d591fe6807665092753a5628d8d470888da4Shawn Willden ++count; 5501fa5d591fe6807665092753a5628d8d470888da4Shawn Willden return count; 5511fa5d591fe6807665092753a5628d8d470888da4Shawn Willden} 5521fa5d591fe6807665092753a5628d8d470888da4Shawn Willden 5535ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const { 5545ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 5555ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5565ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5575ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 558ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].enumerated; 5595ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5605ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5625ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, 5635ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint32_t* val) const { 5645ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t count = 0; 5655ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = -1; 5665ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden while (count <= instance) { 5675ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden pos = find(tag, pos); 5685ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5695ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5705ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 5715ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden ++count; 5725ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 573ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].enumerated; 5745ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5755ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5765ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5775ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const { 5785ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 5795ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5805ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 582ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].integer; 5835ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5845ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 5855ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 5865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance, 5875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden uint32_t* val) const { 5885ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden size_t count = 0; 5895ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = -1; 5905ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden while (count <= instance) { 5915ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden pos = find(tag, pos); 5925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 5935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 5945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 5955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden ++count; 5965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 597ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].integer; 5985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 5995ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 6005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 6015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const { 6025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 6035ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 6045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 6055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 606ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].long_integer; 6075ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 6085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 6095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 610eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willdenbool AuthorizationSet::GetTagValueLongRep(keymaster_tag_t tag, size_t instance, 611eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden uint64_t* val) const { 612eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden size_t count = 0; 613eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden int pos = -1; 614eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden while (count <= instance) { 615eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden pos = find(tag, pos); 616eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden if (pos == -1) { 617eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden return false; 618eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden } 619eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden ++count; 620eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden } 621eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden *val = elems_[pos].long_integer; 622eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden return true; 623eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden} 624eb63b9799eadcaa6ef206f8b804d7432e0dab14aShawn Willden 6255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const { 6265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 6275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 6285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 6295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 630ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].date_time; 6315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 6325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 6335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 6345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const { 6355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden int pos = find(tag); 6365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden if (pos == -1) { 6375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return false; 6385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden } 639ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden *val = elems_[pos].blob; 6405ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden return true; 6415ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} 6425ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden 643dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willdenbool AuthorizationSet::GetTagValueBool(keymaster_tag_t tag) const { 644dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden int pos = find(tag); 645dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden if (pos == -1) { 646dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden return false; 647dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden } 648dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden assert(elems_[pos].boolean); 649dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden return elems_[pos].boolean; 650dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden} 651dfa1c030e941cba4e66b362854d84b19298353c9Shawn Willden 652edb7994f7d5764fcf06188dc005743f4209deb0fShawn Willdenbool AuthorizationSet::ContainsEnumValue(keymaster_tag_t tag, uint32_t value) const { 653edb7994f7d5764fcf06188dc005743f4209deb0fShawn Willden for (auto& entry : *this) 654edb7994f7d5764fcf06188dc005743f4209deb0fShawn Willden if (entry.tag == tag && entry.enumerated == value) 655edb7994f7d5764fcf06188dc005743f4209deb0fShawn Willden return true; 656edb7994f7d5764fcf06188dc005743f4209deb0fShawn Willden return false; 657edb7994f7d5764fcf06188dc005743f4209deb0fShawn Willden} 658edb7994f7d5764fcf06188dc005743f4209deb0fShawn Willden 659ba0d5d01bde427b7d7a22cec84cd9304c00b4e14Shawn Willdenbool AuthorizationSet::ContainsIntValue(keymaster_tag_t tag, uint32_t value) const { 660ba0d5d01bde427b7d7a22cec84cd9304c00b4e14Shawn Willden for (auto& entry : *this) 661ba0d5d01bde427b7d7a22cec84cd9304c00b4e14Shawn Willden if (entry.tag == tag && entry.integer == value) 662ba0d5d01bde427b7d7a22cec84cd9304c00b4e14Shawn Willden return true; 663ba0d5d01bde427b7d7a22cec84cd9304c00b4e14Shawn Willden return false; 664ba0d5d01bde427b7d7a22cec84cd9304c00b4e14Shawn Willden} 665ba0d5d01bde427b7d7a22cec84cd9304c00b4e14Shawn Willden 6665ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden} // namespace keymaster 667