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, 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(begin(), end());
229         return result;
230     }
231 
232     void Serialize(std::ostream* out) const;
233     void Deserialize(std::istream* in);
234 
235   private:
236     NullOr<const KeyParameter&> GetEntry(Tag tag) const;
237 
238     std::vector<KeyParameter> data_;
239 };
240 
241 class AuthorizationSetBuilder : public AuthorizationSet {
242   public:
243     template <typename TagType, typename... ValueType>
Authorization(TagType ttag,ValueType &&...value)244     AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) {
245         push_back(ttag, std::forward<ValueType>(value)...);
246         return *this;
247     }
248 
249     template <Tag tag>
Authorization(TypedTag<TagType::BYTES,tag> ttag,const uint8_t * data,size_t data_length)250     AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data,
251                                            size_t data_length) {
252         hidl_vec<uint8_t> new_blob;
253         new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
254         push_back(ttag, new_blob);
255         return *this;
256     }
257 
258     template <Tag tag>
Authorization(TypedTag<TagType::BYTES,tag> ttag,const char * data,size_t data_length)259     AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data,
260                                            size_t data_length) {
261         return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length);
262     }
263 
264     template <Tag tag>
Authorization(TypedTag<TagType::BYTES,tag> ttag,char * data,size_t data_length)265     AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, char* data,
266                                            size_t data_length) {
267         return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length);
268     }
269 
270     AuthorizationSetBuilder& Authorizations(AuthorizationSet&& set);
271     AuthorizationSetBuilder& Authorizations(const AuthorizationSet& set);
272 
273     AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
274     AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
275     AuthorizationSetBuilder& EcdsaKey(EcCurve curve);
276     AuthorizationSetBuilder& AesKey(uint32_t key_size);
277     AuthorizationSetBuilder& HmacKey(uint32_t key_size);
278 
279     AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent);
280     AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent);
281     AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size);
282     AuthorizationSetBuilder& EcdsaSigningKey(EcCurve curve);
283     AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size);
284 
285     AuthorizationSetBuilder& SigningKey();
286     AuthorizationSetBuilder& EncryptionKey();
287     AuthorizationSetBuilder& NoDigestOrPadding();
288     AuthorizationSetBuilder& EcbMode();
289 
290     AuthorizationSetBuilder& BlockMode(std::initializer_list<BlockMode> block_modes);
291     AuthorizationSetBuilder& Digest(std::initializer_list<Digest> digests);
292     AuthorizationSetBuilder& Padding(std::initializer_list<PaddingMode> padding_modes);
293 
294     // The following forwarding templates enable BlockMode,Digest and Padding to be called with a
295     // variable number of arguments; no need to wrap them in braces to make them an initalizer_list.
BlockMode(T &&...a)296     template <typename... T> AuthorizationSetBuilder& BlockMode(T&&... a) {
297         return BlockMode({std::forward<T>(a)...});
298     }
Digest(T &&...a)299     template <typename... T> AuthorizationSetBuilder& Digest(T&&... a) {
300         return Digest({std::forward<T>(a)...});
301     }
Padding(T &&...a)302     template <typename... T> AuthorizationSetBuilder& Padding(T&&... a) {
303         return Padding({std::forward<T>(a)...});
304     }
305 };
306 
Authorizations(AuthorizationSet && set)307 inline AuthorizationSetBuilder& AuthorizationSetBuilder::Authorizations(AuthorizationSet&& set) {
308     move(set.begin(), set.end());
309     set.Clear();
310     return *this;
311 }
312 
313 inline AuthorizationSetBuilder&
Authorizations(const AuthorizationSet & set)314 AuthorizationSetBuilder::Authorizations(const AuthorizationSet& set) {
315     push_back(set.begin(), set.end());
316     return *this;
317 }
318 
RsaKey(uint32_t key_size,uint64_t public_exponent)319 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
320                                                                 uint64_t public_exponent) {
321     Authorization(TAG_ALGORITHM, Algorithm::RSA);
322     Authorization(TAG_KEY_SIZE, key_size);
323     Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
324     return *this;
325 }
326 
EcdsaKey(uint32_t key_size)327 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
328     Authorization(TAG_ALGORITHM, Algorithm::EC);
329     Authorization(TAG_KEY_SIZE, key_size);
330     return *this;
331 }
332 
EcdsaKey(EcCurve curve)333 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) {
334     Authorization(TAG_ALGORITHM, Algorithm::EC);
335     Authorization(TAG_EC_CURVE, curve);
336     return *this;
337 }
338 
AesKey(uint32_t key_size)339 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
340     Authorization(TAG_ALGORITHM, Algorithm::AES);
341     return Authorization(TAG_KEY_SIZE, key_size);
342 }
343 
HmacKey(uint32_t key_size)344 inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
345     Authorization(TAG_ALGORITHM, Algorithm::HMAC);
346     Authorization(TAG_KEY_SIZE, key_size);
347     return SigningKey();
348 }
349 
RsaSigningKey(uint32_t key_size,uint64_t public_exponent)350 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
351                                                                        uint64_t public_exponent) {
352     RsaKey(key_size, public_exponent);
353     return SigningKey();
354 }
355 
356 inline AuthorizationSetBuilder&
RsaEncryptionKey(uint32_t key_size,uint64_t public_exponent)357 AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) {
358     RsaKey(key_size, public_exponent);
359     return EncryptionKey();
360 }
361 
EcdsaSigningKey(uint32_t key_size)362 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
363     EcdsaKey(key_size);
364     return SigningKey();
365 }
366 
EcdsaSigningKey(EcCurve curve)367 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) {
368     EcdsaKey(curve);
369     return SigningKey();
370 }
371 
AesEncryptionKey(uint32_t key_size)372 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
373     AesKey(key_size);
374     return EncryptionKey();
375 }
376 
SigningKey()377 inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
378     Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
379     return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
380 }
381 
EncryptionKey()382 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
383     Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
384     return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
385 }
386 
NoDigestOrPadding()387 inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
388     Authorization(TAG_DIGEST, Digest::NONE);
389     return Authorization(TAG_PADDING, PaddingMode::NONE);
390 }
391 
EcbMode()392 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
393     return BlockMode(BlockMode::ECB);
394 }
395 
396 inline AuthorizationSetBuilder&
BlockMode(std::initializer_list<V3_0::BlockMode> block_modes)397 AuthorizationSetBuilder::BlockMode(std::initializer_list<V3_0::BlockMode> block_modes) {
398     for (auto block_mode : block_modes) {
399         Authorization(TAG_BLOCK_MODE, block_mode);
400     }
401     return *this;
402 }
403 
404 inline AuthorizationSetBuilder&
Digest(std::initializer_list<V3_0::Digest> digests)405 AuthorizationSetBuilder::Digest(std::initializer_list<V3_0::Digest> digests) {
406     for (auto digest : digests) {
407         Authorization(TAG_DIGEST, digest);
408     }
409     return *this;
410 }
411 
412 inline AuthorizationSetBuilder&
Padding(std::initializer_list<V3_0::PaddingMode> padding_modes)413 AuthorizationSetBuilder::Padding(std::initializer_list<V3_0::PaddingMode> padding_modes) {
414     for (auto padding : padding_modes) {
415         Authorization(TAG_PADDING, padding);
416     }
417     return *this;
418 }
419 
420 }  // namespace V3_0
421 }  // namespace keymaster
422 }  // namespace hardware
423 }  // namespace android
424 
425 #endif  // HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_
426