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