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