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