blob: 8f68bb039d86b190f39dfee1d000c9cd5d5e07af [file] [log] [blame]
Shawn Willdenf4527742017-11-09 15:59:39 -07001/*
2 * Copyright 2014 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 SYSTEM_VOLD_AUTHORIZATION_SET_H_
18#define SYSTEM_VOLD_AUTHORIZATION_SET_H_
19
20#include <vector>
21
22#include "keymaster_tags.h"
23
24namespace keystore {
25
26class AuthorizationSetBuilder;
27
28/**
29 * An ordered collection of KeyParameters. It provides memory ownership and some convenient
30 * functionality for sorting, deduplicating, joining, and subtracting sets of KeyParameters.
31 * For serialization, wrap the backing store of this structure in a hidl_vec<KeyParameter>.
32 */
33class AuthorizationSet {
34 public:
35 /**
36 * Construct an empty, dynamically-allocated, growable AuthorizationSet.
37 */
38 AuthorizationSet(){};
39
40 // Copy constructor.
41 AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {}
42
43 // Move constructor.
44 AuthorizationSet(AuthorizationSet&& other) : data_(std::move(other.data_)) {}
45
46 // Constructor from hidl_vec<KeyParameter>
47 AuthorizationSet(const hidl_vec<KeyParameter>& other) { *this = other; }
48
49 // Copy assignment.
50 AuthorizationSet& operator=(const AuthorizationSet& other) {
51 data_ = other.data_;
52 return *this;
53 }
54
55 // Move assignment.
56 AuthorizationSet& operator=(AuthorizationSet&& other) {
57 data_ = std::move(other.data_);
58 return *this;
59 }
60
61 AuthorizationSet& operator=(const hidl_vec<KeyParameter>& other) {
62 if (other.size() > 0) {
63 data_.resize(other.size());
64 for (size_t i = 0; i < data_.size(); ++i) {
65 /* This makes a deep copy even of embedded blobs.
66 * See assignment operator/copy constructor of hidl_vec.*/
67 data_[i] = other[i];
68 }
69 }
70 return *this;
71 }
72
73 /**
74 * Clear existing authorization set data
75 */
76 void Clear();
77
78 ~AuthorizationSet() = default;
79
80 /**
81 * Returns the size of the set.
82 */
83 size_t size() const { return data_.size(); }
84
85 /**
86 * Returns true if the set is empty.
87 */
88 bool empty() const { return size() == 0; }
89
90 /**
91 * Returns the data in the set, directly. Be careful with this.
92 */
93 const KeyParameter* data() const { return data_.data(); }
94
95 /**
96 * Sorts the set
97 */
98 void Sort();
99
100 /**
101 * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the
102 * AuthorizationSetBuilder).
103 */
104 void Deduplicate();
105
106 /**
107 * Adds all elements from \p set that are not already present in this AuthorizationSet. As a
108 * side-effect, if \p set is not null this AuthorizationSet will end up sorted.
109 */
110 void Union(const AuthorizationSet& set);
111
112 /**
113 * Removes all elements in \p set from this AuthorizationSet.
114 */
115 void Subtract(const AuthorizationSet& set);
116
117 /**
118 * Returns the offset of the next entry that matches \p tag, starting from the element after \p
119 * begin. If not found, returns -1.
120 */
121 int find(Tag tag, int begin = -1) const;
122
123 /**
124 * Removes the entry at the specified index. Returns true if successful, false if the index was
125 * out of bounds.
126 */
127 bool erase(int index);
128
129 /**
130 * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration
131 */
132 std::vector<KeyParameter>::const_iterator begin() const { return data_.begin(); }
133
134 /**
135 * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration
136 */
137 std::vector<KeyParameter>::const_iterator end() const { return data_.end(); }
138
139 /**
140 * Returns the nth element of the set.
141 * Like for std::vector::operator[] there is no range check performed. Use of out of range
142 * indices is undefined.
143 */
144 KeyParameter& operator[](int n);
145
146 /**
147 * Returns the nth element of the set.
148 * Like for std::vector::operator[] there is no range check performed. Use of out of range
149 * indices is undefined.
150 */
151 const KeyParameter& operator[](int n) const;
152
153 /**
154 * Returns true if the set contains at least one instance of \p tag
155 */
156 bool Contains(Tag tag) const { return find(tag) != -1; }
157
158 template <TagType tag_type, Tag tag, typename ValueT>
159 bool Contains(TypedTag<tag_type, tag> ttag, const ValueT& value) const {
160 for (const auto& param : data_) {
161 auto entry = authorizationValue(ttag, param);
162 if (entry.isOk() && entry.value() == value) return true;
163 }
164 return false;
165 }
166 /**
167 * Returns the number of \p tag entries.
168 */
169 size_t GetTagCount(Tag tag) const;
170
171 template <typename T>
172 inline NullOr<const typename TypedTag2ValueType<T>::type&> GetTagValue(T tag) const {
173 auto entry = GetEntry(tag);
174 if (entry.isOk()) return authorizationValue(tag, entry.value());
175 return {};
176 }
177
178 void push_back(const KeyParameter& param) { data_.push_back(param); }
179 void push_back(KeyParameter&& param) { data_.push_back(std::move(param)); }
180
181 /**
182 * Append the tag and enumerated value to the set.
183 * "val" may be exactly one parameter unless a boolean parameter is added.
184 * In this case "val" is omitted. This condition is checked at compile time by Authorization()
185 */
186 template <typename TypedTagT, typename... Value>
187 void push_back(TypedTagT tag, Value&&... val) {
188 push_back(Authorization(tag, std::forward<Value>(val)...));
189 }
190
191 template <typename Iterator>
192 void append(Iterator begin, Iterator end) {
193 while (begin != end) {
194 push_back(*begin);
195 ++begin;
196 }
197 }
198
199 hidl_vec<KeyParameter> hidl_data() const {
200 hidl_vec<KeyParameter> result;
201 result.setToExternal(const_cast<KeyParameter*>(data()), size());
202 return result;
203 }
204
205 void Serialize(std::ostream* out) const;
206 void Deserialize(std::istream* in);
207
208 private:
209 NullOr<const KeyParameter&> GetEntry(Tag tag) const;
210
211 std::vector<KeyParameter> data_;
212};
213
214class AuthorizationSetBuilder : public AuthorizationSet {
215 public:
216 template <typename TagType, typename... ValueType>
217 AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) {
218 push_back(ttag, std::forward<ValueType>(value)...);
219 return *this;
220 }
221
222 template <Tag tag>
223 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data,
224 size_t data_length) {
225 hidl_vec<uint8_t> new_blob;
226 new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
227 push_back(ttag, std::move(new_blob));
228 return *this;
229 }
230
231 template <Tag tag>
232 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data,
233 size_t data_length) {
234 return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length);
235 }
236
237 AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
238 AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
239 AuthorizationSetBuilder& AesKey(uint32_t key_size);
240 AuthorizationSetBuilder& HmacKey(uint32_t key_size);
241
242 AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent);
243 AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent);
244 AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size);
245 AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size);
246
247 AuthorizationSetBuilder& SigningKey();
248 AuthorizationSetBuilder& EncryptionKey();
249 AuthorizationSetBuilder& NoDigestOrPadding();
250 AuthorizationSetBuilder& EcbMode();
251
252 AuthorizationSetBuilder& Digest(Digest digest) { return Authorization(TAG_DIGEST, digest); }
253
254 AuthorizationSetBuilder& Padding(PaddingMode padding) {
255 return Authorization(TAG_PADDING, padding);
256 }
257};
258
259inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
260 uint64_t public_exponent) {
261 Authorization(TAG_ALGORITHM, Algorithm::RSA);
262 Authorization(TAG_KEY_SIZE, key_size);
263 Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
264 return *this;
265}
266
267inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
268 Authorization(TAG_ALGORITHM, Algorithm::EC);
269 Authorization(TAG_KEY_SIZE, key_size);
270 return *this;
271}
272
273inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
274 Authorization(TAG_ALGORITHM, Algorithm::AES);
275 return Authorization(TAG_KEY_SIZE, key_size);
276}
277
278inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
279 Authorization(TAG_ALGORITHM, Algorithm::HMAC);
280 Authorization(TAG_KEY_SIZE, key_size);
281 return SigningKey();
282}
283
284inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
285 uint64_t public_exponent) {
286 RsaKey(key_size, public_exponent);
287 return SigningKey();
288}
289
290inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size,
291 uint64_t public_exponent) {
292 RsaKey(key_size, public_exponent);
293 return EncryptionKey();
294}
295
296inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
297 EcdsaKey(key_size);
298 return SigningKey();
299}
300
301inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
302 AesKey(key_size);
303 return EncryptionKey();
304}
305
306inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
307 Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
308 return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
309}
310
311inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
312 Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
313 return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
314}
315
316inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
317 Authorization(TAG_DIGEST, Digest::NONE);
318 return Authorization(TAG_PADDING, PaddingMode::NONE);
319}
320
321inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
322 return Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
323}
324
325} // namespace keystore
326
327#endif // SYSTEM_VOLD_AUTHORIZATION_SET_H_