• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
AuthorizationSet()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      */
AuthorizationSet(const keymaster_key_param_t * elems,size_t count)51     AuthorizationSet(const keymaster_key_param_t* elems, size_t count)
52         : elems_(NULL), indirect_data_(NULL) {
53         Reinitialize(elems, count);
54     }
55 
AuthorizationSet(const uint8_t * serialized_set,size_t serialized_size)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 
Reinitialize(const AuthorizationSet & set)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 
is_valid()84     Error is_valid() const { return error_; }
85 
86     /**
87      * Returns the size of the set.
88      */
size()89     size_t size() const { return elems_size_; }
90 
91     /**
92      * Returns the total size of all indirect data referenced by set elements.
93      */
indirect_size()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>
GetTagValue(TypedTag<KM_INT,T> tag,uint32_t * val)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>
GetTagValue(TypedTag<KM_INT_REP,Tag> tag,size_t instance,uint32_t * val)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>
GetTagValue(TypedTag<KM_LONG,T> tag,uint64_t * val)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>
GetTagValue(TypedEnumTag<KM_ENUM,Tag,T> tag,T * val)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>
GetTagValue(TypedEnumTag<KM_ENUM_REP,Tag,T> tag,size_t instance,T * val)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>
GetTagValue(TypedTag<KM_INT_REP,Tag> tag,size_t instance,typename TypedTag<KM_INT_REP,Tag>::value_type * val)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>
GetTagValue(TypedTag<KM_BYTES,Tag> tag,keymaster_blob_t * val)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>
GetTagValue(TypedTag<KM_BIGNUM,Tag> tag,keymaster_blob_t * val)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>
GetTagValue(TypedTag<Type,Tag> tag,typename TagValueType<Type>::value_type * val)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>
push_back(TypedEnumTag<Type,Tag,KeymasterEnum> tag,KeymasterEnum val)213     bool push_back(TypedEnumTag<Type, Tag, KeymasterEnum> tag, KeymasterEnum val) {
214         return push_back(Authorization(tag, val));
215     }
216 
push_back(TypedTag<KM_BOOL,Tag> tag)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>
push_back(TypedTag<KM_BYTES,Tag> tag,const void * bytes,size_t bytes_len)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>
push_back(TypedTag<KM_BIGNUM,Tag> tag,const void * bytes,size_t bytes_len)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>
push_back(TypedTag<Type,Tag> tag,typename TypedTag<Type,Tag>::value_type val)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>
push_back(TypedTag<Type,Tag> tag,const void * bytes,size_t bytes_len)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