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