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