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