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