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