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