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