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