Home | History | Annotate | Download | only in keymaster
      1 /*
      2  * Copyright 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SYSTEM_KEYMASTER_AUTHORIZATION_SET_H_
     18 #define SYSTEM_KEYMASTER_AUTHORIZATION_SET_H_
     19 
     20 #include <keymaster/UniquePtr.h>
     21 
     22 #include <hardware/keymaster_defs.h>
     23 #include <keymaster/android_keymaster_utils.h>
     24 #include <keymaster/keymaster_tags.h>
     25 #include <keymaster/serializable.h>
     26 
     27 namespace keymaster {
     28 
     29 class AuthorizationSetBuilder;
     30 
     31 /**
     32  * An extension of the keymaster_key_param_set_t struct, which provides serialization memory
     33  * management and methods for easy manipulation and construction.
     34  */
     35 class AuthorizationSet : public Serializable, public keymaster_key_param_set_t {
     36   public:
     37     /**
     38      * Construct an empty, dynamically-allocated, growable AuthorizationSet.  Does not actually
     39      * allocate any storage until elements are added, so there is no cost to creating an
     40      * AuthorizationSet with this constructor and then reinitializing it to point at pre-allocated
     41      * buffers, with \p Reinitialize.
     42      */
     43     AuthorizationSet()
     44         : elems_capacity_(0), indirect_data_(NULL), indirect_data_size_(0),
     45           indirect_data_capacity_(0), error_(OK) {
     46         elems_ = nullptr;
     47         elems_size_ = 0;
     48     }
     49 
     50     /**
     51      * Construct an AuthorizationSet from the provided array.  The AuthorizationSet copies the data
     52      * from the provided array (and the data referenced by its embedded pointers, if any) into
     53      * dynamically-allocated storage.  If allocation of the needed storage fails, \p is_valid() will
     54      * return ALLOCATION_FAILURE. It is the responsibility of the caller to check before using the
     55      * set, if allocations might fail.
     56      */
     57     AuthorizationSet(const keymaster_key_param_t* elems, size_t count) : indirect_data_(nullptr) {
     58         elems_ = nullptr;
     59         Reinitialize(elems, count);
     60     }
     61 
     62     explicit AuthorizationSet(const keymaster_key_param_set_t& set) : indirect_data_(nullptr) {
     63         elems_ = nullptr;
     64         Reinitialize(set.params, set.length);
     65     }
     66 
     67     explicit AuthorizationSet(const uint8_t* serialized_set, size_t serialized_size)
     68         : indirect_data_(nullptr) {
     69         elems_ = nullptr;
     70         Deserialize(&serialized_set, serialized_set + serialized_size);
     71     }
     72 
     73     /**
     74      * Construct an AuthorizationSet from the provided builder.  This extracts the data from the
     75      * builder, rather than copying it, so after this call the builder is empty.
     76      */
     77     explicit AuthorizationSet(/* NOT const */ AuthorizationSetBuilder& builder);
     78 
     79     // Copy constructor.
     80     AuthorizationSet(const AuthorizationSet& set) : Serializable(), indirect_data_(nullptr) {
     81         elems_ = nullptr;
     82         error_ = set.error_;
     83         if (error_ != OK) return;
     84         Reinitialize(set.elems_, set.elems_size_);
     85     }
     86 
     87     // Move constructor.
     88     AuthorizationSet(AuthorizationSet&& set) : Serializable() {
     89         MoveFrom(set);
     90     }
     91 
     92     // Copy assignment.
     93     AuthorizationSet& operator=(const AuthorizationSet& set) {
     94         Reinitialize(set.elems_, set.elems_size_);
     95         error_ = set.error_;
     96         return *this;
     97     }
     98 
     99     // Move assignment.
    100     AuthorizationSet& operator=(AuthorizationSet&& set) {
    101         FreeData();
    102         MoveFrom(set);
    103         return *this;
    104     }
    105 
    106     /**
    107      * Clear existing authorization set data
    108      */
    109     void Clear();
    110 
    111     /**
    112      * Reinitialize an AuthorizationSet as a dynamically-allocated, growable copy of the data in the
    113      * provided array (and the data referenced by its embedded pointers, if any).  If the allocation
    114      * of the needed storage fails this method will return false and \p is_valid() will return
    115      * ALLOCATION_FAILURE.
    116      */
    117     bool Reinitialize(const keymaster_key_param_t* elems, size_t count);
    118 
    119     bool Reinitialize(const AuthorizationSet& set) {
    120         return Reinitialize(set.elems_, set.elems_size_);
    121     }
    122 
    123     bool Reinitialize(const keymaster_key_param_set_t& set) {
    124         return Reinitialize(set.params, set.length);
    125     }
    126 
    127     ~AuthorizationSet();
    128 
    129     enum Error {
    130         OK,
    131         ALLOCATION_FAILURE,
    132         MALFORMED_DATA,
    133     };
    134 
    135     Error is_valid() const { return error_; }
    136 
    137     /**
    138      * Returns the size of the set.
    139      */
    140     size_t size() const { return elems_size_; }
    141 
    142     /**
    143      * Returns true if the set is empty.
    144      */
    145     bool empty() const { return size() == 0; }
    146 
    147     /**
    148      * Returns the total size of all indirect data referenced by set elements.
    149      */
    150     size_t indirect_size() const { return indirect_data_size_; }
    151 
    152     /**
    153      * Returns the data in the set, directly. Be careful with this.
    154      */
    155     const keymaster_key_param_t* data() const { return elems_; }
    156 
    157     /**
    158      * Sorts the set
    159      */
    160     void Sort();
    161 
    162     /**
    163      * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the
    164      * AuthorizationSetBuilder).
    165      */
    166     void Deduplicate();
    167 
    168     /**
    169      * Adds all elements from \p set that are not already present in this AuthorizationSet.  As a
    170      * side-effect, if \p set is not null this AuthorizationSet will end up sorted.
    171      */
    172     void Union(const keymaster_key_param_set_t& set);
    173 
    174     /**
    175      * Removes all elements in \p set from this AuthorizationSet.
    176      */
    177     void Difference(const keymaster_key_param_set_t& set);
    178 
    179     /**
    180      * Returns the data in a keymaster_key_param_set_t, suitable for returning to C code.  For C
    181      * compatibility, the contents are malloced, not new'ed, and so must be freed with free(), or
    182      * better yet with keymaster_free_param_set, not delete.  The caller takes ownership.
    183      */
    184     void CopyToParamSet(keymaster_key_param_set_t* set) const;
    185 
    186     /**
    187      * Returns the offset of the next entry that matches \p tag, starting from the element after \p
    188      * begin.  If not found, returns -1.
    189      */
    190     int find(keymaster_tag_t tag, int begin = -1) const;
    191 
    192     /**
    193      * Removes the entry at the specified index. Returns true if successful, false if the index was
    194      * out of bounds.
    195      */
    196     bool erase(int index);
    197 
    198     /**
    199      * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration
    200      */
    201     const keymaster_key_param_t* begin() const { return elems_; }
    202 
    203     /**
    204      * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration
    205      */
    206     const keymaster_key_param_t* end() const { return elems_ + elems_size_; }
    207 
    208     /**
    209      * Returns the nth element of the set.
    210      */
    211     keymaster_key_param_t& operator[](int n);
    212 
    213     /**
    214      * Returns the nth element of the set.
    215      */
    216     const keymaster_key_param_t& operator[](int n) const;
    217 
    218     /**
    219      * Returns true if the set contains at least one instance of \p tag
    220      */
    221     bool Contains(keymaster_tag_t tag) const {
    222         return find(tag) != -1;
    223     }
    224 
    225     /**
    226      * Returns the number of \p tag entries.
    227      */
    228     size_t GetTagCount(keymaster_tag_t tag) const;
    229 
    230     /**
    231      * Returns true if the set contains the specified tag and value.
    232      */
    233     template <keymaster_tag_t Tag, typename T>
    234     bool Contains(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, T val) const {
    235         return ContainsEnumValue(tag, val);
    236     }
    237 
    238     /**
    239      * Returns true if the set contains the specified tag and value.
    240      */
    241     template <keymaster_tag_t Tag, typename T>
    242     bool Contains(TypedEnumTag<KM_ENUM, Tag, T> tag, T val) const {
    243         return ContainsEnumValue(tag, val);
    244     }
    245 
    246     /**
    247      * Returns true if the set contains the specified tag and value.
    248      */
    249     template <keymaster_tag_t Tag>
    250     bool Contains(TypedTag<KM_UINT, Tag> tag, uint32_t val) const {
    251         return ContainsIntValue(tag, val);
    252     }
    253 
    254     /**
    255      * If the specified integer-typed \p tag exists, places its value in \p val and returns true.
    256      * If \p tag is not present, leaves \p val unmodified and returns false.
    257      */
    258     template <keymaster_tag_t T>
    259     inline bool GetTagValue(TypedTag<KM_UINT, T> tag, uint32_t* val) const {
    260         return GetTagValueInt(tag, val);
    261     }
    262 
    263     /**
    264      * If the specified instance of the specified integer-typed \p tag exists, places its value
    265      * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
    266      * false.
    267      */
    268     template <keymaster_tag_t Tag>
    269     bool GetTagValue(TypedTag<KM_UINT_REP, Tag> tag, size_t instance, uint32_t* val) const {
    270         return GetTagValueIntRep(tag, instance, val);
    271     }
    272 
    273     /**
    274      * If the specified long-typed \p tag exists, places its value in \p val and returns true.
    275      * If \p tag is not present, leaves \p val unmodified and returns false.
    276      */
    277     template <keymaster_tag_t T>
    278     inline bool GetTagValue(TypedTag<KM_ULONG, T> tag, uint64_t* val) const {
    279         return GetTagValueLong(tag, val);
    280     }
    281 
    282     /**
    283      * If the specified instance of the specified integer-typed \p tag exists, places its value
    284      * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
    285      * false.
    286      */
    287     template <keymaster_tag_t Tag>
    288     bool GetTagValue(TypedTag<KM_ULONG_REP, Tag> tag, size_t instance, uint64_t* val) const {
    289         return GetTagValueLongRep(tag, instance, val);
    290     }
    291 
    292     /**
    293      * If the specified enumeration-typed \p tag exists, places its value in \p val and returns
    294      * true.  If \p tag is not present, leaves \p val unmodified and returns false.
    295      */
    296     template <keymaster_tag_t Tag, typename T>
    297     bool GetTagValue(TypedEnumTag<KM_ENUM, Tag, T> tag, T* val) const {
    298         return GetTagValueEnum(tag, reinterpret_cast<uint32_t*>(val));
    299     }
    300 
    301     /**
    302      * If the specified instance of the specified enumeration-typed \p tag exists, places its value
    303      * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
    304      * false.
    305      */
    306     template <keymaster_tag_t Tag, typename T>
    307     bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, size_t instance, T* val) const {
    308         return GetTagValueEnumRep(tag, instance, reinterpret_cast<uint32_t*>(val));
    309     }
    310 
    311     /**
    312      * If exactly one instance of the specified enumeration-typed \p tag exists, places its value in
    313      * \p val and returns true.  If \p tag is not present or if multiple copies are present, leaves
    314      * \p val unmodified and returns false.
    315      */
    316     template <keymaster_tag_t Tag, typename T>
    317     bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, T* val) const {
    318         if (GetTagCount(tag) != 1)
    319             return false;
    320         return GetTagValueEnumRep(tag, 0, reinterpret_cast<uint32_t*>(val));
    321     }
    322 
    323     /**
    324      * If the specified date-typed \p tag exists, places its value in \p val and returns
    325      * true.  If \p tag is not present, leaves \p val unmodified and returns false.
    326      */
    327     template <keymaster_tag_t Tag>
    328     bool GetTagValue(TypedTag<KM_UINT_REP, Tag> tag, size_t instance,
    329                      typename TypedTag<KM_UINT_REP, Tag>::value_type* val) const {
    330         return GetTagValueIntRep(tag, instance, val);
    331     }
    332 
    333     /**
    334      * If the specified bytes-typed \p tag exists, places its value in \p val and returns
    335      * true.  If \p tag is not present, leaves \p val unmodified and returns false.
    336      */
    337     template <keymaster_tag_t Tag>
    338     bool GetTagValue(TypedTag<KM_BYTES, Tag> tag, keymaster_blob_t* val) const {
    339         return GetTagValueBlob(tag, val);
    340     }
    341 
    342     /**
    343      * If the specified bignum-typed \p tag exists, places its value in \p val and returns
    344      * true.  If \p tag is not present, leaves \p val unmodified and returns false.
    345      */
    346     template <keymaster_tag_t Tag>
    347     bool GetTagValue(TypedTag<KM_BIGNUM, Tag> tag, keymaster_blob_t* val) const {
    348         return GetTagValueBlob(tag, val);
    349     }
    350 
    351     /**
    352      * Returns true if the specified tag is present, and therefore has the value 'true'.
    353      */
    354     template <keymaster_tag_t Tag> bool GetTagValue(TypedTag<KM_BOOL, Tag> tag) const {
    355         return GetTagValueBool(tag);
    356     }
    357 
    358     /**
    359      * If the specified \p tag exists, places its value in \p val and returns true.  If \p tag is
    360      * not present, leaves \p val unmodified and returns false.
    361      */
    362     template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
    363     bool GetTagValue(TypedTag<Type, Tag> tag, typename TagValueType<Type>::value_type* val) const {
    364         return GetTagValueLong(tag, val);
    365     }
    366 
    367     bool push_back(keymaster_key_param_t elem);
    368 
    369     /**
    370      * Grow the elements array to ensure it can contain \p count entries.  Preserves any existing
    371      * entries.
    372      */
    373     bool reserve_elems(size_t count);
    374 
    375     /**
    376      * Grow the indirect data array to ensure it can contain \p length bytes.  Preserves any
    377      * existing indirect data.
    378      */
    379     bool reserve_indirect(size_t length);
    380 
    381     bool push_back(const keymaster_key_param_set_t& set);
    382 
    383     /**
    384      * Append the tag and enumerated value to the set.
    385      */
    386     template <keymaster_tag_t Tag, keymaster_tag_type_t Type, typename KeymasterEnum>
    387     bool push_back(TypedEnumTag<Type, Tag, KeymasterEnum> tag, KeymasterEnum val) {
    388         return push_back(Authorization(tag, val));
    389     }
    390 
    391     /**
    392      * Append the boolean tag (value "true") to the set.
    393      */
    394     template <keymaster_tag_t Tag> bool push_back(TypedTag<KM_BOOL, Tag> tag) {
    395         return push_back(Authorization(tag));
    396     }
    397 
    398     /**
    399      * Append the tag and byte array to the set.  Copies the array into internal storage; does not
    400      * take ownership of the passed-in array.
    401      */
    402     template <keymaster_tag_t Tag>
    403     bool push_back(TypedTag<KM_BYTES, Tag> tag, const void* bytes, size_t bytes_len) {
    404         return push_back(keymaster_param_blob(tag, static_cast<const uint8_t*>(bytes), bytes_len));
    405     }
    406 
    407     /**
    408      * Append the tag and blob to the set.  Copies the blob contents into internal storage; does not
    409      * take ownership of the blob's data.
    410      */
    411     template <keymaster_tag_t Tag>
    412     bool push_back(TypedTag<KM_BYTES, Tag> tag, const keymaster_blob_t& blob) {
    413         return push_back(tag, blob.data, blob.data_length);
    414     }
    415 
    416     /**
    417      * Append the tag and bignum array to the set.  Copies the array into internal storage; does not
    418      * take ownership of the passed-in array.
    419      */
    420     template <keymaster_tag_t Tag>
    421     bool push_back(TypedTag<KM_BIGNUM, Tag> tag, const void* bytes, size_t bytes_len) {
    422         return push_back(keymaster_param_blob(tag, static_cast<const uint8_t*>(bytes), bytes_len));
    423     }
    424 
    425     template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
    426     bool push_back(TypedTag<Type, Tag> tag, typename TypedTag<Type, Tag>::value_type val) {
    427         return push_back(Authorization(tag, val));
    428     }
    429 
    430     template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
    431     bool push_back(TypedTag<Type, Tag> tag, const void* bytes, size_t bytes_len) {
    432         return push_back(Authorization(tag, bytes, bytes_len));
    433     }
    434 
    435     /* Virtual methods from Serializable */
    436     size_t SerializedSize() const;
    437     uint8_t* Serialize(uint8_t* serialized_set, const uint8_t* end) const;
    438     bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end);
    439 
    440     size_t SerializedSizeOfElements() const;
    441 
    442   private:
    443     void FreeData();
    444     void MoveFrom(AuthorizationSet& set);
    445 
    446     void set_invalid(Error err);
    447 
    448     static size_t ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count);
    449     void CopyIndirectData();
    450     bool CheckIndirectData();
    451 
    452     bool DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end);
    453     bool DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end);
    454 
    455     bool GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const;
    456     bool GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, uint32_t* val) const;
    457     bool GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const;
    458     bool GetTagValueIntRep(keymaster_tag_t tag, size_t instance, uint32_t* val) const;
    459     bool GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const;
    460     bool GetTagValueLongRep(keymaster_tag_t tag, size_t instance, uint64_t* val) const;
    461     bool GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const;
    462     bool GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const;
    463     bool GetTagValueBool(keymaster_tag_t tag) const;
    464 
    465     bool ContainsEnumValue(keymaster_tag_t tag, uint32_t val) const;
    466     bool ContainsIntValue(keymaster_tag_t tag, uint32_t val) const;
    467 
    468     // Define elems_ and elems_size_ as aliases to params and length, respectively.  This is to
    469     // avoid using the variables without the trailing underscore in the implementation.
    470     keymaster_key_param_t*& elems_ = keymaster_key_param_set_t::params;
    471     size_t& elems_size_ = keymaster_key_param_set_t::length;
    472 
    473     size_t elems_capacity_;
    474     uint8_t* indirect_data_;
    475     size_t indirect_data_size_;
    476     size_t indirect_data_capacity_;
    477     Error error_;
    478 };
    479 
    480 class AuthorizationSetBuilder {
    481   public:
    482     template <typename TagType, typename ValueType>
    483     AuthorizationSetBuilder& Authorization(TagType tag, ValueType value) {
    484         set.push_back(tag, value);
    485         return *this;
    486     }
    487 
    488     template <keymaster_tag_t Tag>
    489     AuthorizationSetBuilder& Authorization(TypedTag<KM_BOOL, Tag> tag) {
    490         set.push_back(tag);
    491         return *this;
    492     }
    493 
    494     template <keymaster_tag_t Tag>
    495     AuthorizationSetBuilder& Authorization(TypedTag<KM_INVALID, Tag> tag) {
    496         keymaster_key_param_t param;
    497         param.tag = tag;
    498         set.push_back(param);
    499         return *this;
    500     }
    501 
    502     template <keymaster_tag_t Tag>
    503     AuthorizationSetBuilder& Authorization(TypedTag<KM_BYTES, Tag> tag, const uint8_t* data,
    504                                            size_t data_length) {
    505         set.push_back(tag, data, data_length);
    506         return *this;
    507     }
    508 
    509     template <keymaster_tag_t Tag>
    510     AuthorizationSetBuilder& Authorization(TypedTag<KM_BYTES, Tag> tag, const char* data,
    511                                            size_t data_length) {
    512         return Authorization(tag, reinterpret_cast<const uint8_t*>(data), data_length);
    513     }
    514 
    515     AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
    516     AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
    517     AuthorizationSetBuilder& AesKey(uint32_t key_size);
    518     AuthorizationSetBuilder& TripleDesKey(uint32_t key_size);
    519     AuthorizationSetBuilder& HmacKey(uint32_t key_size);
    520 
    521     AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent);
    522     AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent);
    523     AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size);
    524     AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size);
    525     AuthorizationSetBuilder& TripleDesEncryptionKey(uint32_t key_size);
    526 
    527     AuthorizationSetBuilder& SigningKey();
    528     AuthorizationSetBuilder& EncryptionKey();
    529     AuthorizationSetBuilder& NoDigestOrPadding();
    530     AuthorizationSetBuilder& EcbMode();
    531 
    532     AuthorizationSetBuilder& Digest(keymaster_digest_t digest) {
    533         return Authorization(TAG_DIGEST, digest);
    534     }
    535 
    536     AuthorizationSetBuilder& BlockMode(keymaster_block_mode_t mode) {
    537         return Authorization(TAG_BLOCK_MODE, mode);
    538     }
    539 
    540     AuthorizationSetBuilder& Padding(keymaster_padding_t padding) {
    541         return Authorization(TAG_PADDING, padding);
    542     }
    543 
    544     AuthorizationSetBuilder& Deduplicate() {
    545         set.Deduplicate();
    546         return *this;
    547     }
    548 
    549     AuthorizationSet build() const { return set; }
    550 
    551   private:
    552     friend AuthorizationSet;
    553     AuthorizationSet set;
    554 };
    555 
    556 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
    557                                                                 uint64_t public_exponent) {
    558     Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA);
    559     Authorization(TAG_KEY_SIZE, key_size);
    560     Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
    561     return *this;
    562 }
    563 
    564 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
    565     Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC);
    566     Authorization(TAG_KEY_SIZE, key_size);
    567     return *this;
    568 }
    569 
    570 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
    571     Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES);
    572     return Authorization(TAG_KEY_SIZE, key_size);
    573 }
    574 
    575 inline AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesKey(uint32_t key_size) {
    576     Authorization(TAG_ALGORITHM, KM_ALGORITHM_TRIPLE_DES);
    577     return Authorization(TAG_KEY_SIZE, key_size);
    578 }
    579 
    580 inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
    581     Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC);
    582     Authorization(TAG_KEY_SIZE, key_size);
    583     return SigningKey();
    584 }
    585 
    586 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
    587                                                                        uint64_t public_exponent) {
    588     RsaKey(key_size, public_exponent);
    589     return SigningKey();
    590 }
    591 
    592 inline AuthorizationSetBuilder&
    593 AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) {
    594     RsaKey(key_size, public_exponent);
    595     return EncryptionKey();
    596 }
    597 
    598 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
    599     EcdsaKey(key_size);
    600     return SigningKey();
    601 }
    602 
    603 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
    604     AesKey(key_size);
    605     return EncryptionKey();
    606 }
    607 
    608 inline AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesEncryptionKey(uint32_t key_size) {
    609     TripleDesKey(key_size);
    610     return EncryptionKey();
    611 }
    612 
    613 inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
    614     Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN);
    615     return Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY);
    616 }
    617 
    618 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
    619     Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
    620     return Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
    621 }
    622 
    623 inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
    624     Authorization(TAG_DIGEST, KM_DIGEST_NONE);
    625     return Authorization(TAG_PADDING, KM_PAD_NONE);
    626 }
    627 
    628 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
    629     return Authorization(TAG_BLOCK_MODE, KM_MODE_ECB);
    630 }
    631 
    632 class AuthProxyIterator {
    633     constexpr static size_t invalid = ~size_t(0);
    634 public:
    635     AuthProxyIterator()
    636         : pos_(invalid), auth_set1_(nullptr), auth_set2_(nullptr) {}
    637     AuthProxyIterator(const AuthorizationSet& auth_set1, const AuthorizationSet& auth_set2)
    638         : pos_(0), auth_set1_(&auth_set1), auth_set2_(&auth_set2) {}
    639     AuthProxyIterator(const AuthProxyIterator& rhs)
    640         : pos_(rhs.pos_), auth_set1_(rhs.auth_set1_), auth_set2_(rhs.auth_set2_) {}
    641     ~AuthProxyIterator() {};
    642     AuthProxyIterator& operator=(const AuthProxyIterator& rhs) {
    643         if (this != &rhs) {
    644             pos_ = rhs.pos_;
    645             auth_set1_ = rhs.auth_set1_;
    646             auth_set2_ = rhs.auth_set2_;
    647         }
    648         return *this;
    649     }
    650     AuthProxyIterator& operator++() {
    651         if (pos_ == invalid) return *this;
    652         ++pos_;
    653         if (pos_ == (auth_set1_->size() + auth_set2_->size())) {
    654             pos_ = invalid;
    655         }
    656         return *this;
    657     }
    658     const keymaster_key_param_t& operator*() const {
    659         if (pos_ < auth_set1_->size()) {
    660             return (*auth_set1_)[pos_];
    661         } else {
    662             return (*auth_set2_)[pos_ - auth_set1_->size()];
    663         }
    664     }
    665     AuthProxyIterator operator++(int) {
    666         AuthProxyIterator dummy(*this);
    667         ++(*this);
    668         return dummy;
    669     }
    670     const keymaster_key_param_t* operator->() const {
    671         return &(*(*this));
    672     }
    673 
    674     bool operator==(const AuthProxyIterator& rhs) {
    675         if (pos_ == rhs.pos_) {
    676             return pos_ == invalid ||
    677                     (auth_set1_ == rhs.auth_set1_ && auth_set2_ == rhs.auth_set2_);
    678         } else return false;
    679     }
    680     bool operator!=(const AuthProxyIterator& rhs) {
    681         return !operator==(rhs);
    682     }
    683 private:
    684     size_t pos_;
    685     const AuthorizationSet* auth_set1_;
    686     const AuthorizationSet* auth_set2_;
    687 };
    688 
    689 class AuthProxy {
    690   public:
    691     AuthProxy(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced)
    692         : hw_enforced_(hw_enforced), sw_enforced_(sw_enforced) {}
    693 
    694     template <typename... ARGS> bool Contains(ARGS&&... args) const {
    695         return hw_enforced_.Contains(forward<ARGS>(args)...) ||
    696                sw_enforced_.Contains(forward<ARGS>(args)...);
    697     }
    698 
    699     template <typename... ARGS> bool GetTagValue(ARGS&&... args) const {
    700         return hw_enforced_.GetTagValue(forward<ARGS>(args)...) ||
    701                sw_enforced_.GetTagValue(forward<ARGS>(args)...);
    702     }
    703 
    704     AuthProxyIterator begin() const {
    705         return AuthProxyIterator(hw_enforced_, sw_enforced_);
    706     }
    707 
    708     AuthProxyIterator end() const { return AuthProxyIterator(); }
    709 
    710     size_t size() const { return hw_enforced_.size() + sw_enforced_.size(); }
    711 
    712     keymaster_key_param_t operator[](size_t pos) const {
    713         if (pos < hw_enforced_.size()) return hw_enforced_[pos];
    714         if (pos < sw_enforced_.size()) return sw_enforced_[pos - hw_enforced_.size()];
    715         return {};
    716     }
    717 
    718   private:
    719     const AuthorizationSet& hw_enforced_;
    720     const AuthorizationSet& sw_enforced_;
    721 };
    722 
    723 }  // namespace keymaster
    724 
    725 #endif  // SYSTEM_KEYMASTER_KEY_AUTHORIZATION_SET_H_
    726