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
25namespace android {
26namespace hardware {
27namespace keymaster {
28namespace V3_0 {
29
30class 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 */
37class AuthorizationSet {
38  public:
39    typedef KeyParameter value_type;
40
41    /**
42     * Construct an empty, dynamically-allocated, growable AuthorizationSet.
43     */
44    AuthorizationSet(){};
45
46    // Copy constructor.
47    AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {}
48
49    // Move constructor.
50    AuthorizationSet(AuthorizationSet&& other) : data_(std::move(other.data_)) {}
51
52    // Constructor from hidl_vec<KeyParameter>
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     */
89    size_t size() const { return data_.size(); }
90
91    /**
92     * Returns true if the set is empty.
93     */
94    bool empty() const { return size() == 0; }
95
96    /**
97     * Returns the data in the set, directly. Be careful with this.
98     */
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     */
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     */
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     */
162    bool Contains(Tag tag) const { return find(tag) != -1; }
163
164    template <typename T> bool Contains(T tag) const { return find(tag) != -1; }
165
166    template <TagType tag_type, Tag tag, typename ValueT>
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>
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
186    void push_back(const KeyParameter& param) { data_.push_back(param); }
187    void push_back(KeyParameter&& param) { data_.push_back(std::move(param)); }
188
189    void push_back(const AuthorizationSet& set) {
190        for (auto& entry : set) {
191            push_back(entry);
192        }
193    }
194
195    void push_back(AuthorizationSet&& set) {
196        move(set.begin(), set.end());
197        set.Clear();
198    }
199
200    template <Tag tag>
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     */
212    template <typename TypedTagT, typename... Value> void push_back(TypedTagT tag, Value&&... val) {
213        push_back(Authorization(tag, std::forward<Value>(val)...));
214    }
215
216    template <typename Iterator> void push_back(Iterator begin, Iterator end) {
217        while (begin != end) {
218            push_back(*begin);
219            ++begin;
220        }
221    }
222
223    template <typename Iterator> void move(Iterator begin, Iterator end) {
224        std::move(begin, end, std::back_inserter(data_));
225    }
226
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
242class AuthorizationSetBuilder : public AuthorizationSet {
243  public:
244    template <typename TagType, typename... ValueType>
245    AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) {
246        push_back(ttag, std::forward<ValueType>(value)...);
247        return *this;
248    }
249
250    template <Tag tag>
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>
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.
291    template <typename... T> AuthorizationSetBuilder& BlockMode(T&&... a) {
292        return BlockMode({std::forward<T>(a)...});
293    }
294    template <typename... T> AuthorizationSetBuilder& Digest(T&&... a) {
295        return Digest({std::forward<T>(a)...});
296    }
297    template <typename... T> AuthorizationSetBuilder& Padding(T&&... a) {
298        return Padding({std::forward<T>(a)...});
299    }
300};
301
302inline AuthorizationSetBuilder& AuthorizationSetBuilder::Authorizations(AuthorizationSet&& set) {
303    move(set.begin(), set.end());
304    set.Clear();
305    return *this;
306}
307
308inline AuthorizationSetBuilder&
309AuthorizationSetBuilder::Authorizations(const AuthorizationSet& set) {
310    push_back(set.begin(), set.end());
311    return *this;
312}
313
314inline 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
322inline 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
328inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) {
329    Authorization(TAG_ALGORITHM, Algorithm::EC);
330    Authorization(TAG_EC_CURVE, curve);
331    return *this;
332}
333
334inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
335    Authorization(TAG_ALGORITHM, Algorithm::AES);
336    return Authorization(TAG_KEY_SIZE, key_size);
337}
338
339inline 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
345inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
346                                                                       uint64_t public_exponent) {
347    RsaKey(key_size, public_exponent);
348    return SigningKey();
349}
350
351inline AuthorizationSetBuilder&
352AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) {
353    RsaKey(key_size, public_exponent);
354    return EncryptionKey();
355}
356
357inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
358    EcdsaKey(key_size);
359    return SigningKey();
360}
361
362inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) {
363    EcdsaKey(curve);
364    return SigningKey();
365}
366
367inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
368    AesKey(key_size);
369    return EncryptionKey();
370}
371
372inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
373    Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
374    return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
375}
376
377inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
378    Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
379    return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
380}
381
382inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
383    Authorization(TAG_DIGEST, Digest::NONE);
384    return Authorization(TAG_PADDING, PaddingMode::NONE);
385}
386
387inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
388    return BlockMode(BlockMode::ECB);
389}
390
391inline AuthorizationSetBuilder&
392AuthorizationSetBuilder::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
399inline AuthorizationSetBuilder&
400AuthorizationSetBuilder::Digest(std::initializer_list<V3_0::Digest> digests) {
401    for (auto digest : digests) {
402        Authorization(TAG_DIGEST, digest);
403    }
404    return *this;
405}
406
407inline AuthorizationSetBuilder&
408AuthorizationSetBuilder::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