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