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 */ 43 AuthorizationSet() 44 : elems_capacity_(0), indirect_data_(NULL), 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 */ 57 AuthorizationSet(const keymaster_key_param_t* elems, size_t count) : indirect_data_(nullptr) { 58 elems_ = nullptr; 59 Reinitialize(elems, count); 60 } 61 62 explicit AuthorizationSet(const keymaster_key_param_set_t& set) : indirect_data_(nullptr) { 63 elems_ = nullptr; 64 Reinitialize(set.params, set.length); 65 } 66 67 explicit AuthorizationSet(const uint8_t* serialized_set, size_t serialized_size) 68 : indirect_data_(nullptr) { 69 elems_ = nullptr; 70 Deserialize(&serialized_set, serialized_set + serialized_size); 71 } 72 73 /** 74 * Construct an AuthorizationSet from the provided builder. This extracts the data from the 75 * builder, rather than copying it, so after this call the builder is empty. 76 */ 77 explicit AuthorizationSet(/* NOT const */ AuthorizationSetBuilder& builder); 78 79 // Copy constructor. 80 AuthorizationSet(const AuthorizationSet& set) : Serializable(), indirect_data_(nullptr) { 81 elems_ = nullptr; 82 error_ = set.error_; 83 if (error_ != OK) return; 84 Reinitialize(set.elems_, set.elems_size_); 85 } 86 87 // Move constructor. 88 AuthorizationSet(AuthorizationSet&& set) : Serializable() { 89 MoveFrom(set); 90 } 91 92 // Copy assignment. 93 AuthorizationSet& operator=(const AuthorizationSet& set) { 94 Reinitialize(set.elems_, set.elems_size_); 95 error_ = set.error_; 96 return *this; 97 } 98 99 // Move assignment. 100 AuthorizationSet& operator=(AuthorizationSet&& set) { 101 FreeData(); 102 MoveFrom(set); 103 return *this; 104 } 105 106 /** 107 * Clear existing authorization set data 108 */ 109 void Clear(); 110 111 /** 112 * Reinitialize an AuthorizationSet as a dynamically-allocated, growable copy of the data in the 113 * provided array (and the data referenced by its embedded pointers, if any). If the allocation 114 * of the needed storage fails this method will return false and \p is_valid() will return 115 * ALLOCATION_FAILURE. 116 */ 117 bool Reinitialize(const keymaster_key_param_t* elems, size_t count); 118 119 bool Reinitialize(const AuthorizationSet& set) { 120 return Reinitialize(set.elems_, set.elems_size_); 121 } 122 123 bool Reinitialize(const keymaster_key_param_set_t& set) { 124 return Reinitialize(set.params, set.length); 125 } 126 127 ~AuthorizationSet(); 128 129 enum Error { 130 OK, 131 ALLOCATION_FAILURE, 132 MALFORMED_DATA, 133 }; 134 135 Error is_valid() const { return error_; } 136 137 /** 138 * Returns the size of the set. 139 */ 140 size_t size() const { return elems_size_; } 141 142 /** 143 * Returns true if the set is empty. 144 */ 145 bool empty() const { return size() == 0; } 146 147 /** 148 * Returns the total size of all indirect data referenced by set elements. 149 */ 150 size_t indirect_size() const { return indirect_data_size_; } 151 152 /** 153 * Returns the data in the set, directly. Be careful with this. 154 */ 155 const keymaster_key_param_t* data() const { return elems_; } 156 157 /** 158 * Sorts the set 159 */ 160 void Sort(); 161 162 /** 163 * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the 164 * AuthorizationSetBuilder). 165 */ 166 void Deduplicate(); 167 168 /** 169 * Adds all elements from \p set that are not already present in this AuthorizationSet. As a 170 * side-effect, if \p set is not null this AuthorizationSet will end up sorted. 171 */ 172 void Union(const keymaster_key_param_set_t& set); 173 174 /** 175 * Removes all elements in \p set from this AuthorizationSet. 176 */ 177 void Difference(const keymaster_key_param_set_t& set); 178 179 /** 180 * Returns the data in a keymaster_key_param_set_t, suitable for returning to C code. For C 181 * compatibility, the contents are malloced, not new'ed, and so must be freed with free(), or 182 * better yet with keymaster_free_param_set, not delete. The caller takes ownership. 183 */ 184 void CopyToParamSet(keymaster_key_param_set_t* set) const; 185 186 /** 187 * Returns the offset of the next entry that matches \p tag, starting from the element after \p 188 * begin. If not found, returns -1. 189 */ 190 int find(keymaster_tag_t tag, int begin = -1) const; 191 192 /** 193 * Removes the entry at the specified index. Returns true if successful, false if the index was 194 * out of bounds. 195 */ 196 bool erase(int index); 197 198 /** 199 * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration 200 */ 201 const keymaster_key_param_t* begin() const { return elems_; } 202 203 /** 204 * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration 205 */ 206 const keymaster_key_param_t* end() const { return elems_ + elems_size_; } 207 208 /** 209 * Returns the nth element of the set. 210 */ 211 keymaster_key_param_t& operator[](int n); 212 213 /** 214 * Returns the nth element of the set. 215 */ 216 const keymaster_key_param_t& operator[](int n) const; 217 218 /** 219 * Returns true if the set contains at least one instance of \p tag 220 */ 221 bool Contains(keymaster_tag_t tag) const { 222 return find(tag) != -1; 223 } 224 225 /** 226 * Returns the number of \p tag entries. 227 */ 228 size_t GetTagCount(keymaster_tag_t tag) const; 229 230 /** 231 * Returns true if the set contains the specified tag and value. 232 */ 233 template <keymaster_tag_t Tag, typename T> 234 bool Contains(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, T val) const { 235 return ContainsEnumValue(tag, val); 236 } 237 238 /** 239 * Returns true if the set contains the specified tag and value. 240 */ 241 template <keymaster_tag_t Tag, typename T> 242 bool Contains(TypedEnumTag<KM_ENUM, Tag, T> tag, T val) const { 243 return ContainsEnumValue(tag, val); 244 } 245 246 /** 247 * Returns true if the set contains the specified tag and value. 248 */ 249 template <keymaster_tag_t Tag> 250 bool Contains(TypedTag<KM_UINT, Tag> tag, uint32_t val) const { 251 return ContainsIntValue(tag, val); 252 } 253 254 /** 255 * If the specified integer-typed \p tag exists, places its value in \p val and returns true. 256 * If \p tag is not present, leaves \p val unmodified and returns false. 257 */ 258 template <keymaster_tag_t T> 259 inline bool GetTagValue(TypedTag<KM_UINT, T> tag, uint32_t* val) const { 260 return GetTagValueInt(tag, val); 261 } 262 263 /** 264 * If the specified instance of the specified integer-typed \p tag exists, places its value 265 * in \p val and returns true. If \p tag is not present, leaves \p val unmodified and returns 266 * false. 267 */ 268 template <keymaster_tag_t Tag> 269 bool GetTagValue(TypedTag<KM_UINT_REP, Tag> tag, size_t instance, uint32_t* val) const { 270 return GetTagValueIntRep(tag, instance, val); 271 } 272 273 /** 274 * If the specified long-typed \p tag exists, places its value in \p val and returns true. 275 * If \p tag is not present, leaves \p val unmodified and returns false. 276 */ 277 template <keymaster_tag_t T> 278 inline bool GetTagValue(TypedTag<KM_ULONG, T> tag, uint64_t* val) const { 279 return GetTagValueLong(tag, val); 280 } 281 282 /** 283 * If the specified instance of the specified integer-typed \p tag exists, places its value 284 * in \p val and returns true. If \p tag is not present, leaves \p val unmodified and returns 285 * false. 286 */ 287 template <keymaster_tag_t Tag> 288 bool GetTagValue(TypedTag<KM_ULONG_REP, Tag> tag, size_t instance, uint64_t* val) const { 289 return GetTagValueLongRep(tag, instance, val); 290 } 291 292 /** 293 * If the specified enumeration-typed \p tag exists, places its value in \p val and returns 294 * true. If \p tag is not present, leaves \p val unmodified and returns false. 295 */ 296 template <keymaster_tag_t Tag, typename T> 297 bool GetTagValue(TypedEnumTag<KM_ENUM, Tag, T> tag, T* val) const { 298 return GetTagValueEnum(tag, reinterpret_cast<uint32_t*>(val)); 299 } 300 301 /** 302 * If the specified instance of the specified enumeration-typed \p tag exists, places its value 303 * in \p val and returns true. If \p tag is not present, leaves \p val unmodified and returns 304 * false. 305 */ 306 template <keymaster_tag_t Tag, typename T> 307 bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, size_t instance, T* val) const { 308 return GetTagValueEnumRep(tag, instance, reinterpret_cast<uint32_t*>(val)); 309 } 310 311 /** 312 * If exactly one instance of the specified enumeration-typed \p tag exists, places its value in 313 * \p val and returns true. If \p tag is not present or if multiple copies are present, leaves 314 * \p val unmodified and returns false. 315 */ 316 template <keymaster_tag_t Tag, typename T> 317 bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, T* val) const { 318 if (GetTagCount(tag) != 1) 319 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> 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> 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> 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 */ 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> 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> 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 */ 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> 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> 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> 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> 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> 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> 483 AuthorizationSetBuilder& Authorization(TagType tag, ValueType value) { 484 set.push_back(tag, value); 485 return *this; 486 } 487 488 template <keymaster_tag_t 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> 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> 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> 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 532 AuthorizationSetBuilder& Digest(keymaster_digest_t digest) { 533 return Authorization(TAG_DIGEST, digest); 534 } 535 536 AuthorizationSetBuilder& BlockMode(keymaster_block_mode_t mode) { 537 return Authorization(TAG_BLOCK_MODE, mode); 538 } 539 540 AuthorizationSetBuilder& Padding(keymaster_padding_t padding) { 541 return Authorization(TAG_PADDING, padding); 542 } 543 544 AuthorizationSetBuilder& Deduplicate() { 545 set.Deduplicate(); 546 return *this; 547 } 548 549 AuthorizationSet build() const { return set; } 550 551 private: 552 friend AuthorizationSet; 553 AuthorizationSet set; 554 }; 555 556 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size, 557 uint64_t public_exponent) { 558 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA); 559 Authorization(TAG_KEY_SIZE, key_size); 560 Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent); 561 return *this; 562 } 563 564 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) { 565 Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC); 566 Authorization(TAG_KEY_SIZE, key_size); 567 return *this; 568 } 569 570 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) { 571 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES); 572 return Authorization(TAG_KEY_SIZE, key_size); 573 } 574 575 inline AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesKey(uint32_t key_size) { 576 Authorization(TAG_ALGORITHM, KM_ALGORITHM_TRIPLE_DES); 577 return Authorization(TAG_KEY_SIZE, key_size); 578 } 579 580 inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) { 581 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC); 582 Authorization(TAG_KEY_SIZE, key_size); 583 return SigningKey(); 584 } 585 586 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size, 587 uint64_t public_exponent) { 588 RsaKey(key_size, public_exponent); 589 return SigningKey(); 590 } 591 592 inline AuthorizationSetBuilder& 593 AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) { 594 RsaKey(key_size, public_exponent); 595 return EncryptionKey(); 596 } 597 598 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) { 599 EcdsaKey(key_size); 600 return SigningKey(); 601 } 602 603 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) { 604 AesKey(key_size); 605 return EncryptionKey(); 606 } 607 608 inline AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesEncryptionKey(uint32_t key_size) { 609 TripleDesKey(key_size); 610 return EncryptionKey(); 611 } 612 613 inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() { 614 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN); 615 return Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY); 616 } 617 618 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() { 619 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT); 620 return Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT); 621 } 622 623 inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() { 624 Authorization(TAG_DIGEST, KM_DIGEST_NONE); 625 return Authorization(TAG_PADDING, KM_PAD_NONE); 626 } 627 628 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() { 629 return Authorization(TAG_BLOCK_MODE, KM_MODE_ECB); 630 } 631 632 class AuthProxyIterator { 633 constexpr static size_t invalid = ~size_t(0); 634 public: 635 AuthProxyIterator() 636 : pos_(invalid), auth_set1_(nullptr), auth_set2_(nullptr) {} 637 AuthProxyIterator(const AuthorizationSet& auth_set1, const AuthorizationSet& auth_set2) 638 : pos_(0), auth_set1_(&auth_set1), auth_set2_(&auth_set2) {} 639 AuthProxyIterator(const AuthProxyIterator& rhs) 640 : pos_(rhs.pos_), auth_set1_(rhs.auth_set1_), auth_set2_(rhs.auth_set2_) {} 641 ~AuthProxyIterator() {}; 642 AuthProxyIterator& operator=(const AuthProxyIterator& rhs) { 643 if (this != &rhs) { 644 pos_ = rhs.pos_; 645 auth_set1_ = rhs.auth_set1_; 646 auth_set2_ = rhs.auth_set2_; 647 } 648 return *this; 649 } 650 AuthProxyIterator& operator++() { 651 if (pos_ == invalid) return *this; 652 ++pos_; 653 if (pos_ == (auth_set1_->size() + auth_set2_->size())) { 654 pos_ = invalid; 655 } 656 return *this; 657 } 658 const keymaster_key_param_t& operator*() const { 659 if (pos_ < auth_set1_->size()) { 660 return (*auth_set1_)[pos_]; 661 } else { 662 return (*auth_set2_)[pos_ - auth_set1_->size()]; 663 } 664 } 665 AuthProxyIterator operator++(int) { 666 AuthProxyIterator dummy(*this); 667 ++(*this); 668 return dummy; 669 } 670 const keymaster_key_param_t* operator->() const { 671 return &(*(*this)); 672 } 673 674 bool operator==(const AuthProxyIterator& rhs) { 675 if (pos_ == rhs.pos_) { 676 return pos_ == invalid || 677 (auth_set1_ == rhs.auth_set1_ && auth_set2_ == rhs.auth_set2_); 678 } else return false; 679 } 680 bool operator!=(const AuthProxyIterator& rhs) { 681 return !operator==(rhs); 682 } 683 private: 684 size_t pos_; 685 const AuthorizationSet* auth_set1_; 686 const AuthorizationSet* auth_set2_; 687 }; 688 689 class AuthProxy { 690 public: 691 AuthProxy(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced) 692 : hw_enforced_(hw_enforced), sw_enforced_(sw_enforced) {} 693 694 template <typename... ARGS> bool Contains(ARGS&&... args) const { 695 return hw_enforced_.Contains(forward<ARGS>(args)...) || 696 sw_enforced_.Contains(forward<ARGS>(args)...); 697 } 698 699 template <typename... ARGS> bool GetTagValue(ARGS&&... args) const { 700 return hw_enforced_.GetTagValue(forward<ARGS>(args)...) || 701 sw_enforced_.GetTagValue(forward<ARGS>(args)...); 702 } 703 704 AuthProxyIterator begin() const { 705 return AuthProxyIterator(hw_enforced_, sw_enforced_); 706 } 707 708 AuthProxyIterator end() const { return AuthProxyIterator(); } 709 710 size_t size() const { return hw_enforced_.size() + sw_enforced_.size(); } 711 712 keymaster_key_param_t operator[](size_t pos) const { 713 if (pos < hw_enforced_.size()) return hw_enforced_[pos]; 714 if (pos < sw_enforced_.size()) return sw_enforced_[pos - hw_enforced_.size()]; 715 return {}; 716 } 717 718 private: 719 const AuthorizationSet& hw_enforced_; 720 const AuthorizationSet& sw_enforced_; 721 }; 722 723 } // namespace keymaster 724 725 #endif // SYSTEM_KEYMASTER_KEY_AUTHORIZATION_SET_H_ 726