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