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