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