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