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