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