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 HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_
18 #define HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_
19 
20 #include "keymaster_tags.h"
21 
22 #include <utility>
23 #include <vector>
24 
25 namespace android {
26 namespace hardware {
27 namespace keymaster {
28 namespace V3_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) : 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) {
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      * Returns the nth element of the set.
147      * Like for std::vector::operator[] there is no range check performed. Use of out of range
148      * indices is undefined.
149      */
150     KeyParameter& operator[](int n);
151 
152     /**
153      * Returns the nth element of the set.
154      * Like for std::vector::operator[] there is no range check performed. Use of out of range
155      * indices is undefined.
156      */
157     const KeyParameter& operator[](int n) const;
158 
159     /**
160      * Returns true if the set contains at least one instance of \p tag
161      */
Contains(Tag tag)162     bool Contains(Tag tag) const { return find(tag) != -1; }
163 
Contains(T tag)164     template <typename T> bool Contains(T tag) const { return find(tag) != -1; }
165 
166     template <TagType tag_type, Tag tag, typename ValueT>
Contains(TypedTag<tag_type,tag> ttag,const ValueT & value)167     bool Contains(TypedTag<tag_type, tag> ttag, const ValueT& value) const {
168         for (const auto& param : data_) {
169             auto entry = authorizationValue(ttag, param);
170             if (entry.isOk() && static_cast<ValueT>(entry.value()) == value) return true;
171         }
172         return false;
173     }
174     /**
175      * Returns the number of \p tag entries.
176      */
177     size_t GetTagCount(Tag tag) const;
178 
179     template <typename T>
GetTagValue(T tag)180     inline NullOr<const typename TypedTag2ValueType<T>::type&> GetTagValue(T tag) const {
181         auto entry = GetEntry(tag);
182         if (entry.isOk()) return authorizationValue(tag, entry.value());
183         return {};
184     }
185 
push_back(const KeyParameter & param)186     void push_back(const KeyParameter& param) { data_.push_back(param); }
push_back(KeyParameter && param)187     void push_back(KeyParameter&& param) { data_.push_back(std::move(param)); }
188 
push_back(const AuthorizationSet & set)189     void push_back(const AuthorizationSet& set) {
190         for (auto& entry : set) {
191             push_back(entry);
192         }
193     }
194 
push_back(AuthorizationSet && set)195     void push_back(AuthorizationSet&& set) {
196         move(set.begin(), set.end());
197         set.Clear();
198     }
199 
200     template <Tag tag>
push_back(TypedTag<TagType::BYTES,tag> ttag,const uint8_t * data,size_t data_length)201     void push_back(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data, size_t data_length) {
202         hidl_vec<uint8_t> new_blob;
203         new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
204         push_back(ttag, std::move(new_blob));
205     }
206 
207     /**
208      * Append the tag and enumerated value to the set.
209      * "val" may be exactly one parameter unless a boolean parameter is added.
210      * In this case "val" is omitted. This condition is checked at compile time by Authorization()
211      */
push_back(TypedTagT tag,Value &&...val)212     template <typename TypedTagT, typename... Value> void push_back(TypedTagT tag, Value&&... val) {
213         push_back(Authorization(tag, std::forward<Value>(val)...));
214     }
215 
push_back(Iterator begin,Iterator end)216     template <typename Iterator> void push_back(Iterator begin, Iterator end) {
217         while (begin != end) {
218             push_back(*begin);
219             ++begin;
220         }
221     }
222 
move(Iterator begin,Iterator end)223     template <typename Iterator> void move(Iterator begin, Iterator end) {
224         std::move(begin, end, std::back_inserter(data_));
225     }
226 
hidl_data()227     hidl_vec<KeyParameter> hidl_data() const {
228         hidl_vec<KeyParameter> result;
229         result.setToExternal(const_cast<KeyParameter*>(data()), size());
230         return result;
231     }
232 
233     void Serialize(std::ostream* out) const;
234     void Deserialize(std::istream* in);
235 
236   private:
237     NullOr<const KeyParameter&> GetEntry(Tag tag) const;
238 
239     std::vector<KeyParameter> data_;
240 };
241 
242 class AuthorizationSetBuilder : public AuthorizationSet {
243   public:
244     template <typename TagType, typename... ValueType>
Authorization(TagType ttag,ValueType &&...value)245     AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) {
246         push_back(ttag, std::forward<ValueType>(value)...);
247         return *this;
248     }
249 
250     template <Tag tag>
Authorization(TypedTag<TagType::BYTES,tag> ttag,const uint8_t * data,size_t data_length)251     AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data,
252                                            size_t data_length) {
253         hidl_vec<uint8_t> new_blob;
254         new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
255         push_back(ttag, std::move(new_blob));
256         return *this;
257     }
258 
259     template <Tag tag>
Authorization(TypedTag<TagType::BYTES,tag> ttag,const char * data,size_t data_length)260     AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data,
261                                            size_t data_length) {
262         return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length);
263     }
264 
265     AuthorizationSetBuilder& Authorizations(AuthorizationSet&& set);
266     AuthorizationSetBuilder& Authorizations(const AuthorizationSet& set);
267 
268     AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
269     AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
270     AuthorizationSetBuilder& EcdsaKey(EcCurve curve);
271     AuthorizationSetBuilder& AesKey(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 
280     AuthorizationSetBuilder& SigningKey();
281     AuthorizationSetBuilder& EncryptionKey();
282     AuthorizationSetBuilder& NoDigestOrPadding();
283     AuthorizationSetBuilder& EcbMode();
284 
285     AuthorizationSetBuilder& BlockMode(std::initializer_list<BlockMode> block_modes);
286     AuthorizationSetBuilder& Digest(std::initializer_list<Digest> digests);
287     AuthorizationSetBuilder& Padding(std::initializer_list<PaddingMode> padding_modes);
288 
289     // The following forwarding templates enable BlockMode,Digest and Padding to be called with a
290     // variable number of arguments; no need to wrap them in braces to make them an initalizer_list.
BlockMode(T &&...a)291     template <typename... T> AuthorizationSetBuilder& BlockMode(T&&... a) {
292         return BlockMode({std::forward<T>(a)...});
293     }
Digest(T &&...a)294     template <typename... T> AuthorizationSetBuilder& Digest(T&&... a) {
295         return Digest({std::forward<T>(a)...});
296     }
Padding(T &&...a)297     template <typename... T> AuthorizationSetBuilder& Padding(T&&... a) {
298         return Padding({std::forward<T>(a)...});
299     }
300 };
301 
Authorizations(AuthorizationSet && set)302 inline AuthorizationSetBuilder& AuthorizationSetBuilder::Authorizations(AuthorizationSet&& set) {
303     move(set.begin(), set.end());
304     set.Clear();
305     return *this;
306 }
307 
308 inline AuthorizationSetBuilder&
Authorizations(const AuthorizationSet & set)309 AuthorizationSetBuilder::Authorizations(const AuthorizationSet& set) {
310     push_back(set.begin(), set.end());
311     return *this;
312 }
313 
RsaKey(uint32_t key_size,uint64_t public_exponent)314 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
315                                                                 uint64_t public_exponent) {
316     Authorization(TAG_ALGORITHM, Algorithm::RSA);
317     Authorization(TAG_KEY_SIZE, key_size);
318     Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
319     return *this;
320 }
321 
EcdsaKey(uint32_t key_size)322 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
323     Authorization(TAG_ALGORITHM, Algorithm::EC);
324     Authorization(TAG_KEY_SIZE, key_size);
325     return *this;
326 }
327 
EcdsaKey(EcCurve curve)328 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) {
329     Authorization(TAG_ALGORITHM, Algorithm::EC);
330     Authorization(TAG_EC_CURVE, curve);
331     return *this;
332 }
333 
AesKey(uint32_t key_size)334 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
335     Authorization(TAG_ALGORITHM, Algorithm::AES);
336     return Authorization(TAG_KEY_SIZE, key_size);
337 }
338 
HmacKey(uint32_t key_size)339 inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
340     Authorization(TAG_ALGORITHM, Algorithm::HMAC);
341     Authorization(TAG_KEY_SIZE, key_size);
342     return SigningKey();
343 }
344 
RsaSigningKey(uint32_t key_size,uint64_t public_exponent)345 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
346                                                                        uint64_t public_exponent) {
347     RsaKey(key_size, public_exponent);
348     return SigningKey();
349 }
350 
351 inline AuthorizationSetBuilder&
RsaEncryptionKey(uint32_t key_size,uint64_t public_exponent)352 AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) {
353     RsaKey(key_size, public_exponent);
354     return EncryptionKey();
355 }
356 
EcdsaSigningKey(uint32_t key_size)357 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
358     EcdsaKey(key_size);
359     return SigningKey();
360 }
361 
EcdsaSigningKey(EcCurve curve)362 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) {
363     EcdsaKey(curve);
364     return SigningKey();
365 }
366 
AesEncryptionKey(uint32_t key_size)367 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
368     AesKey(key_size);
369     return EncryptionKey();
370 }
371 
SigningKey()372 inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
373     Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
374     return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
375 }
376 
EncryptionKey()377 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
378     Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
379     return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
380 }
381 
NoDigestOrPadding()382 inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
383     Authorization(TAG_DIGEST, Digest::NONE);
384     return Authorization(TAG_PADDING, PaddingMode::NONE);
385 }
386 
EcbMode()387 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
388     return BlockMode(BlockMode::ECB);
389 }
390 
391 inline AuthorizationSetBuilder&
BlockMode(std::initializer_list<V3_0::BlockMode> block_modes)392 AuthorizationSetBuilder::BlockMode(std::initializer_list<V3_0::BlockMode> block_modes) {
393     for (auto block_mode : block_modes) {
394         Authorization(TAG_BLOCK_MODE, block_mode);
395     }
396     return *this;
397 }
398 
399 inline AuthorizationSetBuilder&
Digest(std::initializer_list<V3_0::Digest> digests)400 AuthorizationSetBuilder::Digest(std::initializer_list<V3_0::Digest> digests) {
401     for (auto digest : digests) {
402         Authorization(TAG_DIGEST, digest);
403     }
404     return *this;
405 }
406 
407 inline AuthorizationSetBuilder&
Padding(std::initializer_list<V3_0::PaddingMode> padding_modes)408 AuthorizationSetBuilder::Padding(std::initializer_list<V3_0::PaddingMode> padding_modes) {
409     for (auto padding : padding_modes) {
410         Authorization(TAG_PADDING, padding);
411     }
412     return *this;
413 }
414 
415 }  // namespace V3_0
416 }  // namespace keymaster
417 }  // namespace hardware
418 }  // namespace android
419 
420 #endif  // HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_
421