1 /* 2 * Copyright 2017 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 HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_ 18 #define HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_ 19 20 #include "keymaster_tags.h" 21 22 #include <utility> 23 #include <vector> 24 25 namespace android { 26 namespace hardware { 27 namespace keymaster { 28 namespace V3_0 { 29 30 class AuthorizationSetBuilder; 31 32 /** 33 * An ordered collection of KeyParameters. It provides memory ownership and some convenient 34 * functionality for sorting, deduplicating, joining, and subtracting sets of KeyParameters. 35 * For serialization, wrap the backing store of this structure in a hidl_vec<KeyParameter>. 36 */ 37 class AuthorizationSet { 38 public: 39 typedef KeyParameter value_type; 40 41 /** 42 * Construct an empty, dynamically-allocated, growable AuthorizationSet. 43 */ 44 AuthorizationSet(){}; 45 46 // Copy constructor. 47 AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {} 48 49 // Move constructor. 50 AuthorizationSet(AuthorizationSet&& other) : data_(std::move(other.data_)) {} 51 52 // Constructor from hidl_vec<KeyParameter> 53 AuthorizationSet(const hidl_vec<KeyParameter>& other) { *this = other; } 54 55 // Copy assignment. 56 AuthorizationSet& operator=(const AuthorizationSet& other) { 57 data_ = other.data_; 58 return *this; 59 } 60 61 // Move assignment. 62 AuthorizationSet& operator=(AuthorizationSet&& other) { 63 data_ = std::move(other.data_); 64 return *this; 65 } 66 67 AuthorizationSet& operator=(const hidl_vec<KeyParameter>& other) { 68 if (other.size() > 0) { 69 data_.resize(other.size()); 70 for (size_t i = 0; i < data_.size(); ++i) { 71 /* This makes a deep copy even of embedded blobs. 72 * See assignment operator/copy constructor of hidl_vec.*/ 73 data_[i] = other[i]; 74 } 75 } 76 return *this; 77 } 78 79 /** 80 * Clear existing authorization set data 81 */ 82 void Clear(); 83 84 ~AuthorizationSet() = default; 85 86 /** 87 * Returns the size of the set. 88 */ 89 size_t size() const { return data_.size(); } 90 91 /** 92 * Returns true if the set is empty. 93 */ 94 bool empty() const { return size() == 0; } 95 96 /** 97 * Returns the data in the set, directly. Be careful with this. 98 */ 99 const KeyParameter* data() const { return data_.data(); } 100 101 /** 102 * Sorts the set 103 */ 104 void Sort(); 105 106 /** 107 * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the 108 * AuthorizationSetBuilder). 109 */ 110 void Deduplicate(); 111 112 /** 113 * Adds all elements from \p set that are not already present in this AuthorizationSet. As a 114 * side-effect, if \p set is not null this AuthorizationSet will end up sorted. 115 */ 116 void Union(const AuthorizationSet& set); 117 118 /** 119 * Removes all elements in \p set from this AuthorizationSet. 120 */ 121 void Subtract(const AuthorizationSet& set); 122 123 /** 124 * Returns the offset of the next entry that matches \p tag, starting from the element after \p 125 * begin. If not found, returns -1. 126 */ 127 int find(Tag tag, int begin = -1) const; 128 129 /** 130 * Removes the entry at the specified index. Returns true if successful, false if the index was 131 * out of bounds. 132 */ 133 bool erase(int index); 134 135 /** 136 * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration 137 */ 138 std::vector<KeyParameter>::const_iterator begin() const { return data_.begin(); } 139 140 /** 141 * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration 142 */ 143 std::vector<KeyParameter>::const_iterator end() const { return data_.end(); } 144 145 /** 146 * Returns the nth element of the set. 147 * Like for std::vector::operator[] there is no range check performed. Use of out of range 148 * indices is undefined. 149 */ 150 KeyParameter& operator[](int n); 151 152 /** 153 * Returns the nth element of the set. 154 * Like for std::vector::operator[] there is no range check performed. Use of out of range 155 * indices is undefined. 156 */ 157 const KeyParameter& operator[](int n) const; 158 159 /** 160 * Returns true if the set contains at least one instance of \p tag 161 */ 162 bool Contains(Tag tag) const { return find(tag) != -1; } 163 164 template <typename T> bool Contains(T tag) const { return find(tag) != -1; } 165 166 template <TagType tag_type, Tag tag, typename ValueT> 167 bool Contains(TypedTag<tag_type, tag> ttag, const ValueT& value) const { 168 for (const auto& param : data_) { 169 auto entry = authorizationValue(ttag, param); 170 if (entry.isOk() && static_cast<ValueT>(entry.value()) == value) return true; 171 } 172 return false; 173 } 174 /** 175 * Returns the number of \p tag entries. 176 */ 177 size_t GetTagCount(Tag tag) const; 178 179 template <typename T> 180 inline NullOr<const typename TypedTag2ValueType<T>::type&> GetTagValue(T tag) const { 181 auto entry = GetEntry(tag); 182 if (entry.isOk()) return authorizationValue(tag, entry.value()); 183 return {}; 184 } 185 186 void push_back(const KeyParameter& param) { data_.push_back(param); } 187 void push_back(KeyParameter&& param) { data_.push_back(std::move(param)); } 188 189 void push_back(const AuthorizationSet& set) { 190 for (auto& entry : set) { 191 push_back(entry); 192 } 193 } 194 195 void push_back(AuthorizationSet&& set) { 196 move(set.begin(), set.end()); 197 set.Clear(); 198 } 199 200 template <Tag tag> 201 void push_back(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data, size_t data_length) { 202 hidl_vec<uint8_t> new_blob; 203 new_blob.setToExternal(const_cast<uint8_t*>(data), data_length); 204 push_back(ttag, std::move(new_blob)); 205 } 206 207 /** 208 * Append the tag and enumerated value to the set. 209 * "val" may be exactly one parameter unless a boolean parameter is added. 210 * In this case "val" is omitted. This condition is checked at compile time by Authorization() 211 */ 212 template <typename TypedTagT, typename... Value> void push_back(TypedTagT tag, Value&&... val) { 213 push_back(Authorization(tag, std::forward<Value>(val)...)); 214 } 215 216 template <typename Iterator> void push_back(Iterator begin, Iterator end) { 217 while (begin != end) { 218 push_back(*begin); 219 ++begin; 220 } 221 } 222 223 template <typename Iterator> void move(Iterator begin, Iterator end) { 224 std::move(begin, end, std::back_inserter(data_)); 225 } 226 227 hidl_vec<KeyParameter> hidl_data() const { 228 hidl_vec<KeyParameter> result; 229 result.setToExternal(const_cast<KeyParameter*>(data()), size()); 230 return result; 231 } 232 233 void Serialize(std::ostream* out) const; 234 void Deserialize(std::istream* in); 235 236 private: 237 NullOr<const KeyParameter&> GetEntry(Tag tag) const; 238 239 std::vector<KeyParameter> data_; 240 }; 241 242 class AuthorizationSetBuilder : public AuthorizationSet { 243 public: 244 template <typename TagType, typename... ValueType> 245 AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) { 246 push_back(ttag, std::forward<ValueType>(value)...); 247 return *this; 248 } 249 250 template <Tag tag> 251 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data, 252 size_t data_length) { 253 hidl_vec<uint8_t> new_blob; 254 new_blob.setToExternal(const_cast<uint8_t*>(data), data_length); 255 push_back(ttag, std::move(new_blob)); 256 return *this; 257 } 258 259 template <Tag tag> 260 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data, 261 size_t data_length) { 262 return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length); 263 } 264 265 AuthorizationSetBuilder& Authorizations(AuthorizationSet&& set); 266 AuthorizationSetBuilder& Authorizations(const AuthorizationSet& set); 267 268 AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent); 269 AuthorizationSetBuilder& EcdsaKey(uint32_t key_size); 270 AuthorizationSetBuilder& EcdsaKey(EcCurve curve); 271 AuthorizationSetBuilder& AesKey(uint32_t key_size); 272 AuthorizationSetBuilder& HmacKey(uint32_t key_size); 273 274 AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent); 275 AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent); 276 AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size); 277 AuthorizationSetBuilder& EcdsaSigningKey(EcCurve curve); 278 AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size); 279 280 AuthorizationSetBuilder& SigningKey(); 281 AuthorizationSetBuilder& EncryptionKey(); 282 AuthorizationSetBuilder& NoDigestOrPadding(); 283 AuthorizationSetBuilder& EcbMode(); 284 285 AuthorizationSetBuilder& BlockMode(std::initializer_list<BlockMode> block_modes); 286 AuthorizationSetBuilder& Digest(std::initializer_list<Digest> digests); 287 AuthorizationSetBuilder& Padding(std::initializer_list<PaddingMode> padding_modes); 288 289 // The following forwarding templates enable BlockMode,Digest and Padding to be called with a 290 // variable number of arguments; no need to wrap them in braces to make them an initalizer_list. 291 template <typename... T> AuthorizationSetBuilder& BlockMode(T&&... a) { 292 return BlockMode({std::forward<T>(a)...}); 293 } 294 template <typename... T> AuthorizationSetBuilder& Digest(T&&... a) { 295 return Digest({std::forward<T>(a)...}); 296 } 297 template <typename... T> AuthorizationSetBuilder& Padding(T&&... a) { 298 return Padding({std::forward<T>(a)...}); 299 } 300 }; 301 302 inline AuthorizationSetBuilder& AuthorizationSetBuilder::Authorizations(AuthorizationSet&& set) { 303 move(set.begin(), set.end()); 304 set.Clear(); 305 return *this; 306 } 307 308 inline AuthorizationSetBuilder& 309 AuthorizationSetBuilder::Authorizations(const AuthorizationSet& set) { 310 push_back(set.begin(), set.end()); 311 return *this; 312 } 313 314 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size, 315 uint64_t public_exponent) { 316 Authorization(TAG_ALGORITHM, Algorithm::RSA); 317 Authorization(TAG_KEY_SIZE, key_size); 318 Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent); 319 return *this; 320 } 321 322 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) { 323 Authorization(TAG_ALGORITHM, Algorithm::EC); 324 Authorization(TAG_KEY_SIZE, key_size); 325 return *this; 326 } 327 328 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) { 329 Authorization(TAG_ALGORITHM, Algorithm::EC); 330 Authorization(TAG_EC_CURVE, curve); 331 return *this; 332 } 333 334 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) { 335 Authorization(TAG_ALGORITHM, Algorithm::AES); 336 return Authorization(TAG_KEY_SIZE, key_size); 337 } 338 339 inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) { 340 Authorization(TAG_ALGORITHM, Algorithm::HMAC); 341 Authorization(TAG_KEY_SIZE, key_size); 342 return SigningKey(); 343 } 344 345 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size, 346 uint64_t public_exponent) { 347 RsaKey(key_size, public_exponent); 348 return SigningKey(); 349 } 350 351 inline AuthorizationSetBuilder& 352 AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) { 353 RsaKey(key_size, public_exponent); 354 return EncryptionKey(); 355 } 356 357 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) { 358 EcdsaKey(key_size); 359 return SigningKey(); 360 } 361 362 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) { 363 EcdsaKey(curve); 364 return SigningKey(); 365 } 366 367 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) { 368 AesKey(key_size); 369 return EncryptionKey(); 370 } 371 372 inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() { 373 Authorization(TAG_PURPOSE, KeyPurpose::SIGN); 374 return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY); 375 } 376 377 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() { 378 Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT); 379 return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT); 380 } 381 382 inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() { 383 Authorization(TAG_DIGEST, Digest::NONE); 384 return Authorization(TAG_PADDING, PaddingMode::NONE); 385 } 386 387 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() { 388 return BlockMode(BlockMode::ECB); 389 } 390 391 inline AuthorizationSetBuilder& 392 AuthorizationSetBuilder::BlockMode(std::initializer_list<V3_0::BlockMode> block_modes) { 393 for (auto block_mode : block_modes) { 394 Authorization(TAG_BLOCK_MODE, block_mode); 395 } 396 return *this; 397 } 398 399 inline AuthorizationSetBuilder& 400 AuthorizationSetBuilder::Digest(std::initializer_list<V3_0::Digest> digests) { 401 for (auto digest : digests) { 402 Authorization(TAG_DIGEST, digest); 403 } 404 return *this; 405 } 406 407 inline AuthorizationSetBuilder& 408 AuthorizationSetBuilder::Padding(std::initializer_list<V3_0::PaddingMode> padding_modes) { 409 for (auto padding : padding_modes) { 410 Authorization(TAG_PADDING, padding); 411 } 412 return *this; 413 } 414 415 } // namespace V3_0 416 } // namespace keymaster 417 } // namespace hardware 418 } // namespace android 419 420 #endif // HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_ 421