authorization_set.cpp revision 941d1c4ad4422a796d90010191c11aef0580295e
15ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden/*
25ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * Copyright (C) 2014 The Android Open Source Project
35ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden *
45ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * Licensed under the Apache License, Version 2.0 (the "License");
55ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * you may not use this file except in compliance with the License.
65ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * You may obtain a copy of the License at
75ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden *
85ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden *      http://www.apache.org/licenses/LICENSE-2.0
95ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden *
105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * Unless required by applicable law or agreed to in writing, software
115ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * distributed under the License is distributed on an "AS IS" BASIS,
125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * See the License for the specific language governing permissions and
145ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden * limitations under the License.
155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden */
165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <stdlib.h>
185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <string.h>
195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <stddef.h>
205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden#include <assert.h>
225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
2398d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden#include <keymaster/authorization_set.h>
2498d9b92547a9a7553b99e3e941a4175926f95b62Shawn Willden#include <keymaster/google_keymaster_utils.h>
255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdennamespace keymaster {
275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenstatic inline bool is_blob_tag(keymaster_tag_t tag) {
295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return (keymaster_tag_get_type(tag) == KM_BYTES || keymaster_tag_get_type(tag) == KM_BIGNUM);
305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenconst size_t STARTING_ELEMS_CAPACITY = 8;
335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
3458e1a5486219a1be9264d4e863a9dd3e393906c3Shawn WilldenAuthorizationSet::AuthorizationSet(const AuthorizationSet& set)
3562de26672193373972f2ce968b51cf8335f118f9Shawn Willden    : Serializable(), elems_(NULL), indirect_data_(NULL) {
367636471bd1c553ac179f0dddc17133491d0e1fafShawn Willden    Reinitialize(set.elems_, set.elems_size_);
375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
385ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
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
128370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::push_back(const AuthorizationSet& set) {
129437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden    if (is_valid() != OK)
130437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden        return false;
131437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden
132370121346777e13437c275fbe7a975d899cc325cShawn Willden    if (!reserve_elems(elems_size_ + set.elems_size_))
133370121346777e13437c275fbe7a975d899cc325cShawn Willden        return false;
134370121346777e13437c275fbe7a975d899cc325cShawn Willden
135370121346777e13437c275fbe7a975d899cc325cShawn Willden    if (!reserve_indirect(indirect_data_size_ + set.indirect_data_size_))
136370121346777e13437c275fbe7a975d899cc325cShawn Willden        return false;
137370121346777e13437c275fbe7a975d899cc325cShawn Willden
138370121346777e13437c275fbe7a975d899cc325cShawn Willden    for (size_t i = 0; i < set.size(); ++i)
139370121346777e13437c275fbe7a975d899cc325cShawn Willden        if (!push_back(set[i]))
140370121346777e13437c275fbe7a975d899cc325cShawn Willden            return false;
141370121346777e13437c275fbe7a975d899cc325cShawn Willden
142370121346777e13437c275fbe7a975d899cc325cShawn Willden    return true;
143370121346777e13437c275fbe7a975d899cc325cShawn Willden}
144370121346777e13437c275fbe7a975d899cc325cShawn Willden
1455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::push_back(keymaster_key_param_t elem) {
146437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden    if (is_valid() != OK)
147437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden        return false;
148437fbd195e7de57b7dc0c449c04458bd90ef50deShawn Willden
149370121346777e13437c275fbe7a975d899cc325cShawn Willden    if (elems_size_ >= elems_capacity_)
150370121346777e13437c275fbe7a975d899cc325cShawn Willden        if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY))
1515ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden            return false;
1525ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
1535ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    if (is_blob_tag(elem.tag)) {
154370121346777e13437c275fbe7a975d899cc325cShawn Willden        if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length)
155370121346777e13437c275fbe7a975d899cc325cShawn Willden            if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length)))
1565ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden                return false;
15758e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden
1585ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length);
1598d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        elem.blob.data = indirect_data_ + indirect_data_size_;
1605ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        indirect_data_size_ += elem.blob.data_length;
1615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
1625ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
1635ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    elems_[elems_size_++] = elem;
1645ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return true;
1655ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
1665ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
1678d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic size_t serialized_size(const keymaster_key_param_t& param) {
1688d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    switch (keymaster_tag_get_type(param.tag)) {
1698d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INVALID:
1708d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    default:
1718d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return sizeof(uint32_t);
1728d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_ENUM:
1738d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_ENUM_REP:
1748d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INT:
1758d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INT_REP:
1768d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return sizeof(uint32_t) * 2;
1778d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_LONG:
1788d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_DATE:
1798d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return sizeof(uint32_t) + sizeof(uint64_t);
1808d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BOOL:
1818d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return sizeof(uint32_t) + 1;
1828d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
1838d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BIGNUM:
1848d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BYTES:
1858d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return sizeof(uint32_t) * 3;
1868d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    }
1878d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden}
1888d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden
1898d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenstatic uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end,
1908d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden                          const uint8_t* indirect_base) {
191172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden    buf = append_uint32_to_buf(buf, end, param.tag);
1928d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    switch (keymaster_tag_get_type(param.tag)) {
1938d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INVALID:
1948d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
1958d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_ENUM:
1968d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_ENUM_REP:
197172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        buf = append_uint32_to_buf(buf, end, param.enumerated);
1988d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
1998d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INT:
2008d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INT_REP:
201172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        buf = append_uint32_to_buf(buf, end, param.integer);
2028d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
2038d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_LONG:
204172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        buf = append_uint64_to_buf(buf, end, param.long_integer);
2058d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
2068d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_DATE:
207172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        buf = append_uint64_to_buf(buf, end, param.date_time);
2088d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
2098d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BOOL:
2108d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        if (buf < end)
2118d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden            *buf = static_cast<uint8_t>(param.boolean);
2128d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        buf++;
2138d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
2148d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BIGNUM:
2158d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BYTES:
216172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        buf = append_uint32_to_buf(buf, end, param.blob.data_length);
217172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base);
2188d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
2198d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    }
2208d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    return buf;
2218d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden}
2228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden
223172f8c9be706e27f43022063bbc7f4b0177583acShawn Willdenstatic bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end,
2248d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden                        const uint8_t* indirect_base, const uint8_t* indirect_end) {
225172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden    if (!copy_uint32_from_buf(buf_ptr, end, &param->tag))
2268d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return false;
2278d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden
2288d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    switch (keymaster_tag_get_type(param->tag)) {
2298d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    default:
2308d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INVALID:
2318d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return false;
2328d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_ENUM:
2338d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_ENUM_REP:
234172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        return copy_uint32_from_buf(buf_ptr, end, &param->enumerated);
2358d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INT:
2368d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_INT_REP:
237172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        return copy_uint32_from_buf(buf_ptr, end, &param->integer);
2388d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_LONG:
239172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        return copy_uint64_from_buf(buf_ptr, end, &param->long_integer);
2408d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_DATE:
241172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        return copy_uint64_from_buf(buf_ptr, end, &param->date_time);
2428d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        break;
2438d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BOOL:
244172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        if (*buf_ptr < end) {
245172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden            param->boolean = static_cast<bool>(**buf_ptr);
246172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden            (*buf_ptr)++;
2478d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden            return true;
2488d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        }
2498d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return false;
2508d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden
2518d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BIGNUM:
2528d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    case KM_BYTES: {
2538d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        uint32_t offset;
254172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        if (!copy_uint32_from_buf(buf_ptr, end, &param->blob.data_length) ||
255172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden            !copy_uint32_from_buf(buf_ptr, end, &offset))
2568d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden            return false;
2578d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        if (static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base ||
258172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden            static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base)
2598d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden            return false;
2608d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        param->blob.data = indirect_base + offset;
2618d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        return true;
2628d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    }
2638d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    }
2648d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden}
2658d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden
2668d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdensize_t AuthorizationSet::SerializedSizeOfElements() const {
2678d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    size_t size = 0;
2688d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    for (size_t i = 0; i < elems_size_; ++i) {
2698d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        size += serialized_size(elems_[i]);
2708d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    }
2718d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    return size;
2728d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden}
2738d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden
27458e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willdensize_t AuthorizationSet::SerializedSize() const {
2758d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    return sizeof(uint32_t) +           // Size of indirect_data_
2768d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden           indirect_data_size_ +        // indirect_data_
2778d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden           sizeof(uint32_t) +           // Number of elems_
2788d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden           sizeof(uint32_t) +           // Size of elems_
2798d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden           SerializedSizeOfElements();  // elems_
2805ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
2815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
2828d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willdenuint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const {
2838d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_);
284172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden    buf = append_uint32_to_buf(buf, end, elems_size_);
285172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden    buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements());
2868d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    for (size_t i = 0; i < elems_size_; ++i) {
2878d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        buf = serialize(elems_[i], buf, end, indirect_data_);
2888d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    }
2898d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    return buf;
2905ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
2915ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
292370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) {
293f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden    UniquePtr<uint8_t[]> indirect_buf;
294f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden    if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_buf)) {
295370121346777e13437c275fbe7a975d899cc325cShawn Willden        set_invalid(MALFORMED_DATA);
296370121346777e13437c275fbe7a975d899cc325cShawn Willden        return false;
297370121346777e13437c275fbe7a975d899cc325cShawn Willden    }
298f2282b3c6690ccfaa7878886f01693ef4f0b3bedShawn Willden    indirect_data_ = indirect_buf.release();
299370121346777e13437c275fbe7a975d899cc325cShawn Willden    return true;
300370121346777e13437c275fbe7a975d899cc325cShawn Willden}
3015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
302370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) {
3038d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    uint32_t elements_count;
3048d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    uint32_t elements_size;
305370121346777e13437c275fbe7a975d899cc325cShawn Willden    if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) ||
306172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        !copy_uint32_from_buf(buf_ptr, end, &elements_size)) {
30758e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden        set_invalid(MALFORMED_DATA);
3085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        return false;
3095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
3105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
311834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden    // Note that the following validation of elements_count is weak, but it prevents allocation of
312834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden    // elems_ arrays which are clearly too large to be reasonable.
31362de26672193373972f2ce968b51cf8335f118f9Shawn Willden    if (static_cast<ptrdiff_t>(elements_size) > end - *buf_ptr ||
31462de26672193373972f2ce968b51cf8335f118f9Shawn Willden        elements_count * sizeof(uint32_t) > elements_size) {
315834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden        set_invalid(MALFORMED_DATA);
316834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden        return false;
317834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden    }
318834e80747cbb960f8a4028c5c8604bf5218ecdb9Shawn Willden
319370121346777e13437c275fbe7a975d899cc325cShawn Willden    if (!reserve_elems(elements_count))
3205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        return false;
3215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
3228d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    uint8_t* indirect_end = indirect_data_ + indirect_data_size_;
323172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden    const uint8_t* elements_end = *buf_ptr + elements_size;
3248d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    for (size_t i = 0; i < elements_count; ++i) {
325172f8c9be706e27f43022063bbc7f4b0177583acShawn Willden        if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) {
3268d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden            set_invalid(MALFORMED_DATA);
3278d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden            return false;
3288d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        }
32958e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden    }
330370121346777e13437c275fbe7a975d899cc325cShawn Willden    elems_size_ = elements_count;
331370121346777e13437c275fbe7a975d899cc325cShawn Willden    return true;
332370121346777e13437c275fbe7a975d899cc325cShawn Willden}
3335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
334370121346777e13437c275fbe7a975d899cc325cShawn Willdenbool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
335370121346777e13437c275fbe7a975d899cc325cShawn Willden    FreeData();
336370121346777e13437c275fbe7a975d899cc325cShawn Willden
337370121346777e13437c275fbe7a975d899cc325cShawn Willden    if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end))
338370121346777e13437c275fbe7a975d899cc325cShawn Willden        return false;
339370121346777e13437c275fbe7a975d899cc325cShawn Willden
340370121346777e13437c275fbe7a975d899cc325cShawn Willden    if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) {
3418d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden        set_invalid(MALFORMED_DATA);
3425ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        return false;
3435ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
3448d336ae10df66da4c0433f17c2d42e85baea32c5Shawn Willden    return true;
3455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
3465ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
347941d1c4ad4422a796d90010191c11aef0580295eShawn Willdenvoid AuthorizationSet::Clear() {
3481834d5f82a7ad5884c184fd22c702ac9d915af45Shawn Willden    memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t));
3491834d5f82a7ad5884c184fd22c702ac9d915af45Shawn Willden    memset_s(indirect_data_, 0, indirect_data_size_);
350941d1c4ad4422a796d90010191c11aef0580295eShawn Willden    elems_size_ = 0;
351941d1c4ad4422a796d90010191c11aef0580295eShawn Willden    indirect_data_size_ = 0;
352941d1c4ad4422a796d90010191c11aef0580295eShawn Willden}
353941d1c4ad4422a796d90010191c11aef0580295eShawn Willden
354941d1c4ad4422a796d90010191c11aef0580295eShawn Willdenvoid AuthorizationSet::FreeData() {
355941d1c4ad4422a796d90010191c11aef0580295eShawn Willden    Clear();
35658e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden
35758e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden    delete[] elems_;
35858e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden    delete[] indirect_data_;
35958e1a5486219a1be9264d4e863a9dd3e393906c3Shawn Willden
3605ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    elems_ = NULL;
3615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    indirect_data_ = NULL;
3625ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    elems_capacity_ = 0;
3635ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    indirect_data_capacity_ = 0;
364370121346777e13437c275fbe7a975d899cc325cShawn Willden    error_ = OK;
3655ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
3665ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
3675ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden/* static */
3685ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdensize_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) {
3695ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    size_t size = 0;
3705ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    for (size_t i = 0; i < count; ++i) {
3715ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        if (is_blob_tag(elems[i].tag)) {
3725ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden            size += elems[i].blob.data_length;
3735ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        }
3745ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
3755ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return size;
3765ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
3775ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
3785ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenvoid AuthorizationSet::CopyIndirectData() {
379370121346777e13437c275fbe7a975d899cc325cShawn Willden    memset_s(indirect_data_, 0, indirect_data_capacity_);
3805ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
3815ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    uint8_t* indirect_data_pos = indirect_data_;
3825ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    for (size_t i = 0; i < elems_size_; ++i) {
383370121346777e13437c275fbe7a975d899cc325cShawn Willden        assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_);
3845ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        if (is_blob_tag(elems_[i].tag)) {
3855ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden            memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length);
3865ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden            elems_[i].blob.data = indirect_data_pos;
3875ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden            indirect_data_pos += elems_[i].blob.data_length;
3885ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        }
3895ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
390370121346777e13437c275fbe7a975d899cc325cShawn Willden    assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_);
391370121346777e13437c275fbe7a975d899cc325cShawn Willden    indirect_data_size_ = indirect_data_pos - indirect_data_;
3925ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
3935ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
3945ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const {
3955ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    int pos = find(tag);
3965ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    if (pos == -1) {
3975ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        return false;
3985ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
399ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden    *val = elems_[pos].enumerated;
4005ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return true;
4015ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
4025ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
4035ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance,
4045ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden                                          uint32_t* val) const {
4055ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    size_t count = 0;
4065ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    int pos = -1;
4075ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    while (count <= instance) {
4085ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        pos = find(tag, pos);
4095ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        if (pos == -1) {
4105ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden            return false;
4115ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        }
4125ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        ++count;
4135ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
414ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden    *val = elems_[pos].enumerated;
4155ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return true;
4165ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
4175ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
4185ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const {
4195ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    int pos = find(tag);
4205ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    if (pos == -1) {
4215ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        return false;
4225ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
423ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden    *val = elems_[pos].integer;
4245ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return true;
4255ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
4265ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
4275ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance,
4285ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden                                         uint32_t* val) const {
4295ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    size_t count = 0;
4305ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    int pos = -1;
4315ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    while (count <= instance) {
4325ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        pos = find(tag, pos);
4335ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        if (pos == -1) {
4345ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden            return false;
4355ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        }
4365ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        ++count;
4375ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
438ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden    *val = elems_[pos].integer;
4395ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return true;
4405ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
4415ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
4425ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const {
4435ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    int pos = find(tag);
4445ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    if (pos == -1) {
4455ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        return false;
4465ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
447ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden    *val = elems_[pos].long_integer;
4485ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return true;
4495ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
4505ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
4515ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const {
4525ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    int pos = find(tag);
4535ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    if (pos == -1) {
4545ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        return false;
4555ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
456ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden    *val = elems_[pos].date_time;
4575ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return true;
4585ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
4595ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
4605ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willdenbool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const {
4615ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    int pos = find(tag);
4625ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    if (pos == -1) {
4635ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden        return false;
4645ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    }
465ebf627f0b50c0979e6cf53668464297703371ebaShawn Willden    *val = elems_[pos].blob;
4665ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden    return true;
4675ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}
4685ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden
4695ada7b6c525d2bfd5b556a698ccb11db23e052bbShawn Willden}  // namespace keymaster
470