1 /*
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_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_
18 #define SYSTEM_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_
19
20 #include "keymaster_tags.h"
21 #include <vector>
22
23 namespace keymaster {
24 namespace ng {
25
26 class 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 */
33 class AuthorizationSet {
34 public:
35 /**
36 * Construct an empty, dynamically-allocated, growable AuthorizationSet.
37 */
AuthorizationSet()38 AuthorizationSet() {};
39
40 // Copy constructor.
AuthorizationSet(const AuthorizationSet & other)41 AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {}
42
43 // Move constructor.
AuthorizationSet(AuthorizationSet && other)44 AuthorizationSet(AuthorizationSet&& other) : data_(std::move(other.data_)) {}
45
46 // Constructor from hidl_vec<KeyParameter>
AuthorizationSet(const hidl_vec<KeyParameter> & other)47 explicit 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 */
size()83 size_t size() const { return data_.size(); }
84
85 /**
86 * Returns true if the set is empty.
87 */
empty()88 bool empty() const { return size() == 0; }
89
90 /**
91 * Returns the data in the set, directly. Be careful with this.
92 */
data()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 */
begin()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 */
end()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 */
Contains(Tag tag)156 bool Contains(Tag tag) const {
157 return find(tag) != -1;
158 }
159
160 template <TagType tag_type, Tag tag, typename ValueT>
Contains(TypedTag<tag_type,tag> ttag,const ValueT & value)161 bool Contains(TypedTag<tag_type, tag> ttag, const ValueT& value) const {
162 for (const auto& param: data_) {
163 auto entry = authorizationValue(ttag, param);
164 if (entry.isOk() && entry.value() == value) return true;
165 }
166 return false;
167 }
168 /**
169 * Returns the number of \p tag entries.
170 */
171 size_t GetTagCount(Tag tag) const;
172
173 template <typename T>
GetTagValue(T tag)174 inline NullOr<const typename TypedTag2ValueType<T>::type&> GetTagValue(T tag) const {
175 auto entry = GetEntry(tag);
176 if (entry.isOk()) return authorizationValue(tag, entry.value());
177 return {};
178 }
179
push_back(const KeyParameter & param)180 void push_back(const KeyParameter& param) {
181 data_.push_back(param);
182 }
push_back(KeyParameter && param)183 void push_back(KeyParameter&& param) {
184 data_.push_back(std::move(param));
185 }
186
187 /**
188 * Append the tag and enumerated value to the set.
189 * "val" may be exactly one parameter unless a boolean parameter is added.
190 * In this case "val" is omitted. This condition is checked at compile time by Authorization()
191 */
192 template <typename TypedTagT, typename... Value>
push_back(TypedTagT tag,Value &&...val)193 void push_back(TypedTagT tag, Value&&... val) {
194 push_back(Authorization(tag, std::forward<Value>(val)...));
195 }
196
197 template <typename Iterator>
append(Iterator begin,Iterator end)198 void append(Iterator begin, Iterator end) {
199 while (begin != end) {
200 push_back(*begin);
201 ++begin;
202 }
203 }
204
hidl_data()205 hidl_vec<KeyParameter> hidl_data() const {
206 hidl_vec<KeyParameter> result;
207 result.setToExternal(const_cast<KeyParameter*>(data()), size());
208 return result;
209 }
210
211 void Serialize(std::ostream* out) const;
212 void Deserialize(std::istream* in);
213
214 private:
215 NullOr<const KeyParameter&> GetEntry(Tag tag) const;
216
217 std::vector<KeyParameter> data_;
218 };
219
220 class AuthorizationSetBuilder: public AuthorizationSet {
221 public:
222 template <typename TagType, typename... ValueType>
Authorization(TagType ttag,ValueType &&...value)223 AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) {
224 push_back(ttag, std::forward<ValueType>(value)...);
225 return *this;
226 }
227
228 template <Tag tag>
Authorization(TypedTag<TagType::BYTES,tag> ttag,const uint8_t * data,size_t data_length)229 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data,
230 size_t data_length) {
231 hidl_vec<uint8_t> new_blob;
232 new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
233 push_back(ttag, std::move(new_blob));
234 return *this;
235 }
236
237 template <Tag tag>
Authorization(TypedTag<TagType::BYTES,tag> ttag,const char * data,size_t data_length)238 AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data,
239 size_t data_length) {
240 return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length);
241 }
242
243 AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
244 AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
245 AuthorizationSetBuilder& AesKey(uint32_t key_size);
246 AuthorizationSetBuilder& HmacKey(uint32_t key_size);
247
248 AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent);
249 AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent);
250 AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size);
251 AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size);
252
253 AuthorizationSetBuilder& SigningKey();
254 AuthorizationSetBuilder& EncryptionKey();
255 AuthorizationSetBuilder& NoDigestOrPadding();
256 AuthorizationSetBuilder& EcbMode();
257
Digest(Digest digest)258 AuthorizationSetBuilder& Digest(Digest digest) {
259 return Authorization(TAG_DIGEST, digest);
260 }
261
Padding(PaddingMode padding)262 AuthorizationSetBuilder& Padding(PaddingMode padding) {
263 return Authorization(TAG_PADDING, padding);
264 }
265 };
266
RsaKey(uint32_t key_size,uint64_t public_exponent)267 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
268 uint64_t public_exponent) {
269 Authorization(TAG_ALGORITHM, Algorithm::RSA);
270 Authorization(TAG_KEY_SIZE, key_size);
271 Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
272 return *this;
273 }
274
EcdsaKey(uint32_t key_size)275 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
276 Authorization(TAG_ALGORITHM, Algorithm::EC);
277 Authorization(TAG_KEY_SIZE, key_size);
278 return *this;
279 }
280
AesKey(uint32_t key_size)281 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
282 Authorization(TAG_ALGORITHM, Algorithm::AES);
283 return Authorization(TAG_KEY_SIZE, key_size);
284 }
285
HmacKey(uint32_t key_size)286 inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
287 Authorization(TAG_ALGORITHM, Algorithm::HMAC);
288 Authorization(TAG_KEY_SIZE, key_size);
289 return SigningKey();
290 }
291
RsaSigningKey(uint32_t key_size,uint64_t public_exponent)292 inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
293 uint64_t public_exponent) {
294 RsaKey(key_size, public_exponent);
295 return SigningKey();
296 }
297
298 inline AuthorizationSetBuilder&
RsaEncryptionKey(uint32_t key_size,uint64_t public_exponent)299 AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) {
300 RsaKey(key_size, public_exponent);
301 return EncryptionKey();
302 }
303
EcdsaSigningKey(uint32_t key_size)304 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
305 EcdsaKey(key_size);
306 return SigningKey();
307 }
308
AesEncryptionKey(uint32_t key_size)309 inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
310 AesKey(key_size);
311 return EncryptionKey();
312 }
313
SigningKey()314 inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
315 Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
316 return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
317 }
318
EncryptionKey()319 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
320 Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
321 return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
322 }
323
NoDigestOrPadding()324 inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
325 Authorization(TAG_DIGEST, Digest::NONE);
326 return Authorization(TAG_PADDING, PaddingMode::NONE);
327 }
328
EcbMode()329 inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
330 return Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
331 }
332
333 } // namespace ng
334 } // namespace keymaster
335
336 #endif // SYSTEM_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_
337