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 <keymaster/keymaster_defs.h>
     23 #include <keymaster/keymaster_tags.h>
     24 #include <keymaster/serializable.h>
     25 
     26 namespace keymaster {
     27 
     28 /**
     29  * A container that manages a set of keymaster_key_param_t objects, providing serialization,
     30  * de-serialization and accessors.
     31  */
     32 class AuthorizationSet : public Serializable {
     33   public:
     34     /**
     35      * Construct an empty, dynamically-allocated, growable AuthorizationSet.  Does not actually
     36      * allocate any storage until elements are added, so there is no cost to creating an
     37      * AuthorizationSet with this constructor and then reinitializing it to point at pre-allocated
     38      * buffers, with \p Reinitialize.
     39      */
     40     AuthorizationSet()
     41         : elems_(NULL), elems_size_(0), elems_capacity_(0), indirect_data_(NULL),
     42           indirect_data_size_(0), indirect_data_capacity_(0), error_(OK) {}
     43 
     44     /**
     45      * Construct an AuthorizationSet from the provided array.  The AuthorizationSet copies the data
     46      * from the provided array (and the data referenced by its embedded pointers, if any) into
     47      * dynamically-allocated storage.  If allocation of the needed storage fails, \p is_valid() will
     48      * return ALLOCATION_FAILURE. It is the responsibility of the caller to check before using the
     49      * set, if allocations might fail.
     50      */
     51     AuthorizationSet(const keymaster_key_param_t* elems, size_t count)
     52         : elems_(NULL), indirect_data_(NULL) {
     53         Reinitialize(elems, count);
     54     }
     55 
     56     AuthorizationSet(const uint8_t* serialized_set, size_t serialized_size)
     57         : elems_(NULL), indirect_data_(NULL) {
     58         Deserialize(&serialized_set, serialized_set + serialized_size);
     59     }
     60 
     61     // Copy constructor.
     62     AuthorizationSet(const AuthorizationSet&);
     63 
     64     /**
     65      * Reinitialize an AuthorizationSet as a dynamically-allocated, growable copy of the data in the
     66      * provided array (and the data referenced by its embedded pointers, if any).  If the allocation
     67      * of the needed storage fails this method will return false and \p is_valid() will return
     68      * ALLOCATION_FAILURE.
     69      */
     70     bool Reinitialize(const keymaster_key_param_t* elems, size_t count);
     71 
     72     bool Reinitialize(const AuthorizationSet& set) {
     73         return Reinitialize(set.elems_, set.elems_size_);
     74     }
     75 
     76     ~AuthorizationSet();
     77 
     78     enum Error {
     79         OK,
     80         ALLOCATION_FAILURE,
     81         MALFORMED_DATA,
     82     };
     83 
     84     Error is_valid() const { return error_; }
     85 
     86     /**
     87      * Returns the size of the set.
     88      */
     89     size_t size() const { return elems_size_; }
     90 
     91     /**
     92      * Returns the total size of all indirect data referenced by set elements.
     93      */
     94     size_t indirect_size() const { return indirect_data_size_; }
     95 
     96     /**
     97      * Returns the data in the set, directly. Be careful with this.
     98      */
     99     const keymaster_key_param_t* data() const;
    100 
    101     /**
    102      * Returns the offset of the next entry that matches \p tag, starting from the element after \p
    103      * begin.  If not found, returns -1.
    104      */
    105     int find(keymaster_tag_t tag, int begin = -1) const;
    106 
    107     /**
    108      * Returns the nth element of the set.
    109      */
    110     keymaster_key_param_t operator[](int n) const;
    111 
    112     /**
    113      * If the specified integer-typed \p tag exists, places its value in \p val and returns true.
    114      * If \p tag is not present, leaves \p val unmodified and returns false.
    115      */
    116     template <keymaster_tag_t T>
    117     inline bool GetTagValue(TypedTag<KM_INT, T> tag, uint32_t* val) const {
    118         return GetTagValueInt(tag, val);
    119     }
    120 
    121     /**
    122      * If the specified instance of the specified integer-typed \p tag exists, places its value
    123      * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
    124      * false.
    125      */
    126     template <keymaster_tag_t Tag>
    127     bool GetTagValue(TypedTag<KM_INT_REP, Tag> tag, size_t instance, uint32_t* val) const {
    128         return GetTagValueIntRep(tag, instance, val);
    129     }
    130 
    131     /**
    132      * If the specified long-typed \p tag exists, places its value in \p val and returns true.
    133      * If \p tag is not present, leaves \p val unmodified and returns false.
    134      */
    135     template <keymaster_tag_t T>
    136     inline bool GetTagValue(TypedTag<KM_LONG, T> tag, uint64_t* val) const {
    137         return GetTagValueLong(tag, val);
    138     }
    139 
    140     /**
    141      * If the specified enumeration-typed \p tag exists, places its value in \p val and returns
    142      * true.  If \p tag is not present, leaves \p val unmodified and returns false.
    143      */
    144     template <keymaster_tag_t Tag, typename T>
    145     bool GetTagValue(TypedEnumTag<KM_ENUM, Tag, T> tag, T* val) const {
    146         return GetTagValueEnum(tag, reinterpret_cast<uint32_t*>(val));
    147     }
    148 
    149     /**
    150      * If the specified instance of the specified enumeration-typed \p tag exists, places its value
    151      * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
    152      * false.
    153      */
    154     template <keymaster_tag_t Tag, typename T>
    155     bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, size_t instance, T* val) const {
    156         return GetTagValueEnumRep(tag, instance, reinterpret_cast<uint32_t*>(val));
    157     }
    158 
    159     /**
    160      * If the specified date-typed \p tag exists, places its value in \p val and returns
    161      * true.  If \p tag is not present, leaves \p val unmodified and returns false.
    162      */
    163     template <keymaster_tag_t Tag>
    164     bool GetTagValue(TypedTag<KM_INT_REP, Tag> tag, size_t instance,
    165                      typename TypedTag<KM_INT_REP, Tag>::value_type* val) const {
    166         return GetTagValueIntRep(tag, instance, val);
    167     }
    168 
    169     /**
    170      * If the specified bytes-typed \p tag exists, places its value in \p val and returns
    171      * true.  If \p tag is not present, leaves \p val unmodified and returns false.
    172      */
    173     template <keymaster_tag_t Tag>
    174     bool GetTagValue(TypedTag<KM_BYTES, Tag> tag, keymaster_blob_t* val) const {
    175         return GetTagValueBlob(tag, val);
    176     }
    177 
    178     /**
    179      * If the specified bignum-typed \p tag exists, places its value in \p val and returns
    180      * true.  If \p tag is not present, leaves \p val unmodified and returns false.
    181      */
    182     template <keymaster_tag_t Tag>
    183     bool GetTagValue(TypedTag<KM_BIGNUM, Tag> tag, keymaster_blob_t* val) const {
    184         return GetTagValueBlob(tag, val);
    185     }
    186 
    187     /**
    188      * If the specified \p tag exists, places its value in \p val and returns true.  If \p tag is
    189      * not present, leaves \p val unmodified and returns false.
    190      */
    191     template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
    192     bool GetTagValue(TypedTag<Type, Tag> tag, typename TagValueType<Type>::value_type* val) const {
    193         return GetTagValueLong(tag, val);
    194     }
    195 
    196     bool push_back(keymaster_key_param_t elem);
    197 
    198     /**
    199      * Grow the elements array to ensure it can contain \p count entries.  Preserves any existing
    200      * entries.
    201      */
    202     bool reserve_elems(size_t count);
    203 
    204     /**
    205      * Grow the indirect data array to ensure it can contain \p length bytes.  Preserves any
    206      * existing indirect data.
    207      */
    208     bool reserve_indirect(size_t length);
    209 
    210     bool push_back(const AuthorizationSet& set);
    211 
    212     template <keymaster_tag_t Tag, keymaster_tag_type_t Type, typename KeymasterEnum>
    213     bool push_back(TypedEnumTag<Type, Tag, KeymasterEnum> tag, KeymasterEnum val) {
    214         return push_back(Authorization(tag, val));
    215     }
    216 
    217     template <keymaster_tag_t Tag> bool push_back(TypedTag<KM_BOOL, Tag> tag) {
    218         return push_back(Authorization(tag));
    219     }
    220 
    221     template <keymaster_tag_t Tag>
    222     bool push_back(TypedTag<KM_BYTES, Tag> tag, const void* bytes, size_t bytes_len) {
    223         return push_back(keymaster_param_blob(tag, static_cast<const uint8_t*>(bytes), bytes_len));
    224     }
    225 
    226     template <keymaster_tag_t Tag>
    227     bool push_back(TypedTag<KM_BIGNUM, Tag> tag, const void* bytes, size_t bytes_len) {
    228         return push_back(keymaster_param_blob(tag, static_cast<const uint8_t*>(bytes), bytes_len));
    229     }
    230 
    231     template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
    232     bool push_back(TypedTag<Type, Tag> tag, typename TypedTag<Type, Tag>::value_type val) {
    233         return push_back(Authorization(tag, val));
    234     }
    235 
    236     template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
    237     bool push_back(TypedTag<Type, Tag> tag, const void* bytes, size_t bytes_len) {
    238         return push_back(Authorization(tag, bytes, bytes_len));
    239     }
    240 
    241     /* Virtual methods from Serializable */
    242     size_t SerializedSize() const;
    243     uint8_t* Serialize(uint8_t* serialized_set, const uint8_t* end) const;
    244     bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end);
    245 
    246     size_t SerializedSizeOfElements() const;
    247 
    248   private:
    249     // Disallow assignment
    250     void operator=(const AuthorizationSet&);
    251 
    252     void FreeData();
    253     void set_invalid(Error err);
    254 
    255     static size_t ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count);
    256     void CopyIndirectData();
    257     bool CheckIndirectData();
    258 
    259     bool DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end);
    260     bool DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end);
    261 
    262     bool GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const;
    263     bool GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, uint32_t* val) const;
    264     bool GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const;
    265     bool GetTagValueIntRep(keymaster_tag_t tag, size_t instance, uint32_t* val) const;
    266     bool GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const;
    267     bool GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const;
    268     bool GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const;
    269 
    270     keymaster_key_param_t* elems_;
    271     size_t elems_size_;
    272     size_t elems_capacity_;
    273     uint8_t* indirect_data_;
    274     size_t indirect_data_size_;
    275     size_t indirect_data_capacity_;
    276     Error error_;
    277 };
    278 
    279 }  // namespace keymaster
    280 
    281 #endif  // SYSTEM_KEYMASTER_KEY_AUTHORIZATION_SET_H_
    282