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