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, &param->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, &param->enumerated);
377c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden    case KM_UINT:
378c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden    case KM_UINT_REP:
379172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        return copy_uint32_from_buf(buf_ptr, end, &param->integer);
380c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden    case KM_ULONG:
381c3ac84f04c4d6d74fa36abfd1cc2e5ac763a8af3Shawn Willden    case KM_ULONG_REP:
382172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        return copy_uint64_from_buf(buf_ptr, end, &param->long_integer);
3838d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_DATE:
384172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        return copy_uint64_from_buf(buf_ptr, end, &param->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, &param->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