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