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