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 <functional> 21 #include <vector> 22 23 #include <keymasterV4_0/keymaster_tags.h> 24 25 namespace android { 26 namespace hardware { 27 namespace keymaster { 28 namespace V4_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 */ AuthorizationSet()44 AuthorizationSet(){}; 45 46 // Copy constructor. AuthorizationSet(const AuthorizationSet & other)47 AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {} 48 49 // Move constructor. AuthorizationSet(AuthorizationSet && other)50 AuthorizationSet(AuthorizationSet&& other) noexcept : data_(std::move(other.data_)) {} 51 52 // Constructor from hidl_vec<KeyParameter> AuthorizationSet(const hidl_vec<KeyParameter> & other)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) noexcept { 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 */ size()89 size_t size() const { return data_.size(); } 90 91 /** 92 * Returns true if the set is empty. 93 */ empty()94 bool empty() const { return size() == 0; } 95 96 /** 97 * Returns the data in the set, directly. Be careful with this. 98 */ data()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 */ begin()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 */ end()143 std::vector<KeyParameter>::const_iterator end() const { return data_.end(); } 144 145 /** 146 * Modifies this Authorization set such that it only keeps the entries for which doKeep 147 * returns true. 148 */ 149 void Filter(std::function<bool(const KeyParameter&)> doKeep); 150 /** 151 * Returns the nth element of the set. 152 * Like for std::vector::operator[] there is no range check performed. Use of out of range 153 * indices is undefined. 154 */ 155 KeyParameter& operator[](int n); 156 157 /** 158 * Returns the nth element of the set. 159 * Like for std::vector::operator[] there is no range check performed. Use of out of range 160 * indices is undefined. 161 */ 162 const KeyParameter& operator[](int n) const; 163 164 /** 165 * Returns true if the set contains at least one instance of \p tag 166 */ Contains(Tag tag)167 bool Contains(Tag tag) const { return find(tag) != -1; } 168 169 template <TagType tag_type, Tag tag, typename ValueT, typename Comparator = std::equal_to<>> 170 bool Contains(TypedTag<tag_type, tag> ttag, const ValueT& value, 171 Comparator cmp = Comparator()) const { 172 for (const auto& param : data_) { 173 auto entry = authorizationValue(ttag, param); 174 if (entry.isOk() && cmp(static_cast<ValueT>(entry.value()), value)) return true; 175 } 176 return false; 177 } 178 /** 179 * Returns the number of \p tag entries. 180 */ 181 size_t GetTagCount(Tag tag) const; 182 183 template <typename T> GetTagValue(T tag)184 inline NullOr<const typename TypedTag2ValueType<T>::type&> GetTagValue(T tag) const { 185 auto entry = GetEntry(tag); 186 if (entry.isOk()) return authorizationValue(tag, entry.value()); 187 return {}; 188 } 189 push_back(const KeyParameter & param)190 void push_back(const KeyParameter& param) { data_.push_back(param); } push_back(KeyParameter && param)191 void push_back(KeyParameter&& param) { data_.push_back(std::move(param)); } push_back(const AuthorizationSet & set)192 void push_back(const AuthorizationSet& set) { 193 for (auto& entry : set) { 194 push_back(entry); 195 } 196 } push_back(AuthorizationSet && set)197 void push_back(AuthorizationSet&& set) { 198 std::move(set.begin(), set.end(), std::back_inserter(*this)); 199 } 200 201 /** 202 * Append the tag and enumerated value to the set. 203 * "val" may be exactly one parameter unless a boolean parameter is added. 204 * In this case "val" is omitted. This condition is checked at compile time by Authorization() 205 */ 206 template <typename TypedTagT, typename... Value> push_back(TypedTagT tag,Value &&...val)207 void push_back(TypedTagT tag, Value&&... val) { 208 push_back(Authorization(tag, std::forward<Value>(val)...)); 209 } 210 211 template <typename Iterator> append(Iterator begin,Iterator end)212 void append(Iterator begin, Iterator end) { 213 while (begin != end) { 214 push_back(*begin); 215 ++begin; 216 } 217 } 218 hidl_data()219 hidl_vec<KeyParameter> hidl_data() const { 220 hidl_vec<KeyParameter> result(begin(), end()); 221 return result; 222 } 223 224 void Serialize(std::ostream* out) const; 225 void Deserialize(std::istream* in); 226 227 private: 228 NullOr<const KeyParameter&> GetEntry(Tag tag) const; 229 230 std::vector<KeyParameter> data_; 231 }; 232 233 class AuthorizationSetBuilder : public AuthorizationSet { 234 public: 235 template <typename TagType, typename... ValueType> Authorization(TagType ttag,ValueType &&...value)236 AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) { 237 push_back(ttag, std::forward<ValueType>(value)...); 238 return *this; 239 } 240 241 template <Tag tag> Authorization(TypedTag<TagType::BYTES,tag> ttag,const uint8_t * data,size_t data_length)242 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data, 243 size_t data_length) { 244 hidl_vec<uint8_t> new_blob; 245 new_blob.setToExternal(const_cast<uint8_t*>(data), data_length); 246 push_back(ttag, new_blob); 247 return *this; 248 } 249 250 template <Tag tag> Authorization(TypedTag<TagType::BYTES,tag> ttag,const char * data,size_t data_length)251 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data, 252 size_t data_length) { 253 return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length); 254 } 255 256 template <Tag tag> Authorization(TypedTag<TagType::BYTES,tag> ttag,char * data,size_t data_length)257 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, char* data, 258 size_t data_length) { 259 return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length); 260 } 261 Authorizations(const AuthorizationSet & set)262 AuthorizationSetBuilder& Authorizations(const AuthorizationSet& set) { 263 for (const auto& entry : set) { 264 push_back(entry); 265 } 266 return *this; 267 } 268 269 AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent); 270 AuthorizationSetBuilder& EcdsaKey(uint32_t key_size); 271 AuthorizationSetBuilder& EcdsaKey(EcCurve curve); 272 AuthorizationSetBuilder& AesKey(uint32_t key_size); 273 AuthorizationSetBuilder& TripleDesKey(uint32_t key_size); 274 AuthorizationSetBuilder& HmacKey(uint32_t key_size); 275 276 AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent); 277 AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent); 278 AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size); 279 AuthorizationSetBuilder& EcdsaSigningKey(EcCurve curve); 280 AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size); 281 AuthorizationSetBuilder& TripleDesEncryptionKey(uint32_t key_size); 282 283 AuthorizationSetBuilder& SigningKey(); 284 AuthorizationSetBuilder& EncryptionKey(); 285 286 AuthorizationSetBuilder& NoDigestOrPadding(); 287 288 AuthorizationSetBuilder& EcbMode(); 289 AuthorizationSetBuilder& GcmModeMinMacLen(uint32_t minMacLength); 290 AuthorizationSetBuilder& GcmModeMacLen(uint32_t macLength); 291 292 AuthorizationSetBuilder& BlockMode(std::initializer_list<BlockMode> blockModes); 293 AuthorizationSetBuilder& Digest(std::vector<Digest> digests); 294 AuthorizationSetBuilder& Padding(std::initializer_list<PaddingMode> paddings); 295 296 template <typename... T> BlockMode(T &&...a)297 AuthorizationSetBuilder& BlockMode(T&&... a) { 298 return BlockMode({std::forward<T>(a)...}); 299 } 300 template <typename... T> Digest(T &&...a)301 AuthorizationSetBuilder& Digest(T&&... a) { 302 return Digest({std::forward<T>(a)...}); 303 } 304 template <typename... T> Padding(T &&...a)305 AuthorizationSetBuilder& Padding(T&&... a) { 306 return Padding({std::forward<T>(a)...}); 307 } 308 }; 309 310 } // namespace V4_0 311 } // namespace keymaster 312 } // namespace hardware 313 } // namespace android 314 315 #endif // SYSTEM_SECURITY_KEYSTORE_KM4_AUTHORIZATION_SET_H_ 316