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