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 #include <keymasterV4_0/authorization_set.h>
18 
19 #include <assert.h>
20 
21 namespace android {
22 namespace hardware {
23 namespace keymaster {
24 namespace V4_0 {
25 
keyParamLess(const KeyParameter & a,const KeyParameter & b)26 inline bool keyParamLess(const KeyParameter& a, const KeyParameter& b) {
27     if (a.tag != b.tag) return a.tag < b.tag;
28     int retval;
29     switch (typeFromTag(a.tag)) {
30         case TagType::INVALID:
31         case TagType::BOOL:
32             return false;
33         case TagType::ENUM:
34         case TagType::ENUM_REP:
35         case TagType::UINT:
36         case TagType::UINT_REP:
37             return a.f.integer < b.f.integer;
38         case TagType::ULONG:
39         case TagType::ULONG_REP:
40             return a.f.longInteger < b.f.longInteger;
41         case TagType::DATE:
42             return a.f.dateTime < b.f.dateTime;
43         case TagType::BIGNUM:
44         case TagType::BYTES:
45             // Handle the empty cases.
46             if (a.blob.size() == 0) return b.blob.size() != 0;
47             if (b.blob.size() == 0) return false;
48 
49             retval = memcmp(&a.blob[0], &b.blob[0], std::min(a.blob.size(), b.blob.size()));
50             // if one is the prefix of the other the longer wins
51             if (retval == 0) return a.blob.size() < b.blob.size();
52             // Otherwise a is less if a is less.
53             else
54                 return retval < 0;
55     }
56     return false;
57 }
58 
keyParamEqual(const KeyParameter & a,const KeyParameter & b)59 inline bool keyParamEqual(const KeyParameter& a, const KeyParameter& b) {
60     if (a.tag != b.tag) return false;
61 
62     switch (typeFromTag(a.tag)) {
63         case TagType::INVALID:
64         case TagType::BOOL:
65             return true;
66         case TagType::ENUM:
67         case TagType::ENUM_REP:
68         case TagType::UINT:
69         case TagType::UINT_REP:
70             return a.f.integer == b.f.integer;
71         case TagType::ULONG:
72         case TagType::ULONG_REP:
73             return a.f.longInteger == b.f.longInteger;
74         case TagType::DATE:
75             return a.f.dateTime == b.f.dateTime;
76         case TagType::BIGNUM:
77         case TagType::BYTES:
78             if (a.blob.size() != b.blob.size()) return false;
79             return a.blob.size() == 0 || memcmp(&a.blob[0], &b.blob[0], a.blob.size()) == 0;
80     }
81     return false;
82 }
83 
Sort()84 void AuthorizationSet::Sort() {
85     std::sort(data_.begin(), data_.end(), keyParamLess);
86 }
87 
Deduplicate()88 void AuthorizationSet::Deduplicate() {
89     if (data_.empty()) return;
90 
91     Sort();
92     std::vector<KeyParameter> result;
93 
94     auto curr = data_.begin();
95     auto prev = curr++;
96     for (; curr != data_.end(); ++prev, ++curr) {
97         if (prev->tag == Tag::INVALID) continue;
98 
99         if (!keyParamEqual(*prev, *curr)) {
100             result.emplace_back(std::move(*prev));
101         }
102     }
103     result.emplace_back(std::move(*prev));
104 
105     std::swap(data_, result);
106 }
107 
Union(const AuthorizationSet & other)108 void AuthorizationSet::Union(const AuthorizationSet& other) {
109     data_.insert(data_.end(), other.data_.begin(), other.data_.end());
110     Deduplicate();
111 }
112 
Subtract(const AuthorizationSet & other)113 void AuthorizationSet::Subtract(const AuthorizationSet& other) {
114     Deduplicate();
115 
116     auto i = other.begin();
117     while (i != other.end()) {
118         int pos = -1;
119         do {
120             pos = find(i->tag, pos);
121             if (pos != -1 && keyParamEqual(*i, data_[pos])) {
122                 data_.erase(data_.begin() + pos);
123                 break;
124             }
125         } while (pos != -1);
126         ++i;
127     }
128 }
129 
operator [](int at)130 KeyParameter& AuthorizationSet::operator[](int at) {
131     return data_[at];
132 }
133 
operator [](int at) const134 const KeyParameter& AuthorizationSet::operator[](int at) const {
135     return data_[at];
136 }
137 
Clear()138 void AuthorizationSet::Clear() {
139     data_.clear();
140 }
141 
GetTagCount(Tag tag) const142 size_t AuthorizationSet::GetTagCount(Tag tag) const {
143     size_t count = 0;
144     for (int pos = -1; (pos = find(tag, pos)) != -1;) ++count;
145     return count;
146 }
147 
find(Tag tag,int begin) const148 int AuthorizationSet::find(Tag tag, int begin) const {
149     auto iter = data_.begin() + (1 + begin);
150 
151     while (iter != data_.end() && iter->tag != tag) ++iter;
152 
153     if (iter != data_.end()) return iter - data_.begin();
154     return -1;
155 }
156 
erase(int index)157 bool AuthorizationSet::erase(int index) {
158     auto pos = data_.begin() + index;
159     if (pos != data_.end()) {
160         data_.erase(pos);
161         return true;
162     }
163     return false;
164 }
165 
GetEntry(Tag tag) const166 NullOr<const KeyParameter&> AuthorizationSet::GetEntry(Tag tag) const {
167     int pos = find(tag);
168     if (pos == -1) return {};
169     return data_[pos];
170 }
171 
172 /**
173  * Persistent format is:
174  * | 32 bit indirect_size         |
175  * --------------------------------
176  * | indirect_size bytes of data  | this is where the blob data is stored
177  * --------------------------------
178  * | 32 bit element_count         | number of entries
179  * | 32 bit elements_size         | total bytes used by entries (entries have variable length)
180  * --------------------------------
181  * | elementes_size bytes of data | where the elements are stored
182  */
183 
184 /**
185  * Persistent format of blobs and bignums:
186  * | 32 bit tag             |
187  * | 32 bit blob_length     |
188  * | 32 bit indirect_offset |
189  */
190 
191 struct OutStreams {
192     std::ostream& indirect;
193     std::ostream& elements;
194 };
195 
serializeParamValue(OutStreams & out,const hidl_vec<uint8_t> & blob)196 OutStreams& serializeParamValue(OutStreams& out, const hidl_vec<uint8_t>& blob) {
197     uint32_t buffer;
198 
199     // write blob_length
200     auto blob_length = blob.size();
201     if (blob_length > std::numeric_limits<uint32_t>::max()) {
202         out.elements.setstate(std::ios_base::badbit);
203         return out;
204     }
205     buffer = blob_length;
206     out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
207 
208     // write indirect_offset
209     auto offset = out.indirect.tellp();
210     if (offset < 0 || offset > std::numeric_limits<uint32_t>::max() ||
211         uint32_t(offset) + uint32_t(blob_length) < uint32_t(offset)) {  // overflow check
212         out.elements.setstate(std::ios_base::badbit);
213         return out;
214     }
215     buffer = offset;
216     out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
217 
218     // write blob to indirect stream
219     if (blob_length) out.indirect.write(reinterpret_cast<const char*>(&blob[0]), blob_length);
220 
221     return out;
222 }
223 
224 template <typename T>
serializeParamValue(OutStreams & out,const T & value)225 OutStreams& serializeParamValue(OutStreams& out, const T& value) {
226     out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T));
227     return out;
228 }
229 
serialize(TAG_INVALID_t &&,OutStreams & out,const KeyParameter &)230 OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) {
231     // skip invalid entries.
232     return out;
233 }
234 template <typename T>
serialize(T ttag,OutStreams & out,const KeyParameter & param)235 OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) {
236     out.elements.write(reinterpret_cast<const char*>(&param.tag), sizeof(int32_t));
237     return serializeParamValue(out, accessTagValue(ttag, param));
238 }
239 
240 template <typename... T>
241 struct choose_serializer;
242 template <typename... Tags>
243 struct choose_serializer<MetaList<Tags...>> {
serializeandroid::hardware::keymaster::V4_0::choose_serializer244     static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
245         return choose_serializer<Tags...>::serialize(out, param);
246     }
247 };
248 
249 template <>
250 struct choose_serializer<> {
serializeandroid::hardware::keymaster::V4_0::choose_serializer251     static OutStreams& serialize(OutStreams& out, const KeyParameter&) { return out; }
252 };
253 
254 template <TagType tag_type, Tag tag, typename... Tail>
255 struct choose_serializer<TypedTag<tag_type, tag>, Tail...> {
serializeandroid::hardware::keymaster::V4_0::choose_serializer256     static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
257         if (param.tag == tag) {
258             return V4_0::serialize(TypedTag<tag_type, tag>(), out, param);
259         } else {
260             return choose_serializer<Tail...>::serialize(out, param);
261         }
262     }
263 };
264 
serialize(OutStreams & out,const KeyParameter & param)265 OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
266     return choose_serializer<all_tags_t>::serialize(out, param);
267 }
268 
serialize(std::ostream & out,const std::vector<KeyParameter> & params)269 std::ostream& serialize(std::ostream& out, const std::vector<KeyParameter>& params) {
270     std::stringstream indirect;
271     std::stringstream elements;
272     OutStreams streams = {indirect, elements};
273     for (const auto& param : params) {
274         serialize(streams, param);
275     }
276     if (indirect.bad() || elements.bad()) {
277         out.setstate(std::ios_base::badbit);
278         return out;
279     }
280     auto pos = indirect.tellp();
281     if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
282         out.setstate(std::ios_base::badbit);
283         return out;
284     }
285     uint32_t indirect_size = pos;
286     pos = elements.tellp();
287     if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
288         out.setstate(std::ios_base::badbit);
289         return out;
290     }
291     uint32_t elements_size = pos;
292     uint32_t element_count = params.size();
293 
294     out.write(reinterpret_cast<const char*>(&indirect_size), sizeof(uint32_t));
295 
296     pos = out.tellp();
297     if (indirect_size) out << indirect.rdbuf();
298     assert(out.tellp() - pos == indirect_size);
299 
300     out.write(reinterpret_cast<const char*>(&element_count), sizeof(uint32_t));
301     out.write(reinterpret_cast<const char*>(&elements_size), sizeof(uint32_t));
302 
303     pos = out.tellp();
304     if (elements_size) out << elements.rdbuf();
305     assert(out.tellp() - pos == elements_size);
306 
307     return out;
308 }
309 
310 struct InStreams {
311     std::istream& indirect;
312     std::istream& elements;
313 };
314 
deserializeParamValue(InStreams & in,hidl_vec<uint8_t> * blob)315 InStreams& deserializeParamValue(InStreams& in, hidl_vec<uint8_t>* blob) {
316     uint32_t blob_length = 0;
317     uint32_t offset = 0;
318     in.elements.read(reinterpret_cast<char*>(&blob_length), sizeof(uint32_t));
319     blob->resize(blob_length);
320     in.elements.read(reinterpret_cast<char*>(&offset), sizeof(uint32_t));
321     in.indirect.seekg(offset);
322     in.indirect.read(reinterpret_cast<char*>(&(*blob)[0]), blob->size());
323     return in;
324 }
325 
326 template <typename T>
deserializeParamValue(InStreams & in,T * value)327 InStreams& deserializeParamValue(InStreams& in, T* value) {
328     in.elements.read(reinterpret_cast<char*>(value), sizeof(T));
329     return in;
330 }
331 
deserialize(TAG_INVALID_t &&,InStreams & in,KeyParameter *)332 InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) {
333     // there should be no invalid KeyParamaters but if handle them as zero sized.
334     return in;
335 }
336 
337 template <typename T>
deserialize(T && ttag,InStreams & in,KeyParameter * param)338 InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) {
339     return deserializeParamValue(in, &accessTagValue(ttag, *param));
340 }
341 
342 template <typename... T>
343 struct choose_deserializer;
344 template <typename... Tags>
345 struct choose_deserializer<MetaList<Tags...>> {
deserializeandroid::hardware::keymaster::V4_0::choose_deserializer346     static InStreams& deserialize(InStreams& in, KeyParameter* param) {
347         return choose_deserializer<Tags...>::deserialize(in, param);
348     }
349 };
350 template <>
351 struct choose_deserializer<> {
deserializeandroid::hardware::keymaster::V4_0::choose_deserializer352     static InStreams& deserialize(InStreams& in, KeyParameter*) {
353         // encountered an unknown tag -> fail parsing
354         in.elements.setstate(std::ios_base::badbit);
355         return in;
356     }
357 };
358 template <TagType tag_type, Tag tag, typename... Tail>
359 struct choose_deserializer<TypedTag<tag_type, tag>, Tail...> {
deserializeandroid::hardware::keymaster::V4_0::choose_deserializer360     static InStreams& deserialize(InStreams& in, KeyParameter* param) {
361         if (param->tag == tag) {
362             return V4_0::deserialize(TypedTag<tag_type, tag>(), in, param);
363         } else {
364             return choose_deserializer<Tail...>::deserialize(in, param);
365         }
366     }
367 };
368 
deserialize(InStreams & in,KeyParameter * param)369 InStreams& deserialize(InStreams& in, KeyParameter* param) {
370     in.elements.read(reinterpret_cast<char*>(&param->tag), sizeof(Tag));
371     return choose_deserializer<all_tags_t>::deserialize(in, param);
372 }
373 
deserialize(std::istream & in,std::vector<KeyParameter> * params)374 std::istream& deserialize(std::istream& in, std::vector<KeyParameter>* params) {
375     uint32_t indirect_size = 0;
376     in.read(reinterpret_cast<char*>(&indirect_size), sizeof(uint32_t));
377     std::string indirect_buffer(indirect_size, '\0');
378     if (indirect_buffer.size() != indirect_size) {
379         in.setstate(std::ios_base::badbit);
380         return in;
381     }
382     in.read(&indirect_buffer[0], indirect_buffer.size());
383 
384     uint32_t element_count = 0;
385     in.read(reinterpret_cast<char*>(&element_count), sizeof(uint32_t));
386     uint32_t elements_size = 0;
387     in.read(reinterpret_cast<char*>(&elements_size), sizeof(uint32_t));
388 
389     std::string elements_buffer(elements_size, '\0');
390     if (elements_buffer.size() != elements_size) {
391         in.setstate(std::ios_base::badbit);
392         return in;
393     }
394     in.read(&elements_buffer[0], elements_buffer.size());
395 
396     if (in.bad()) return in;
397 
398     // TODO write one-shot stream buffer to avoid copying here
399     std::stringstream indirect(indirect_buffer);
400     std::stringstream elements(elements_buffer);
401     InStreams streams = {indirect, elements};
402 
403     params->resize(element_count);
404 
405     for (uint32_t i = 0; i < element_count; ++i) {
406         deserialize(streams, &(*params)[i]);
407     }
408     return in;
409 }
410 
Serialize(std::ostream * out) const411 void AuthorizationSet::Serialize(std::ostream* out) const {
412     serialize(*out, data_);
413 }
414 
Deserialize(std::istream * in)415 void AuthorizationSet::Deserialize(std::istream* in) {
416     deserialize(*in, &data_);
417 }
418 
RsaKey(uint32_t key_size,uint64_t public_exponent)419 AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
420                                                          uint64_t public_exponent) {
421     Authorization(TAG_ALGORITHM, Algorithm::RSA);
422     Authorization(TAG_KEY_SIZE, key_size);
423     Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
424     return *this;
425 }
426 
EcdsaKey(uint32_t key_size)427 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
428     Authorization(TAG_ALGORITHM, Algorithm::EC);
429     Authorization(TAG_KEY_SIZE, key_size);
430     return *this;
431 }
432 
EcdsaKey(EcCurve curve)433 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) {
434     Authorization(TAG_ALGORITHM, Algorithm::EC);
435     Authorization(TAG_EC_CURVE, curve);
436     return *this;
437 }
438 
AesKey(uint32_t key_size)439 AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
440     Authorization(TAG_ALGORITHM, Algorithm::AES);
441     return Authorization(TAG_KEY_SIZE, key_size);
442 }
443 
TripleDesKey(uint32_t key_size)444 AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesKey(uint32_t key_size) {
445     Authorization(TAG_ALGORITHM, Algorithm::TRIPLE_DES);
446     return Authorization(TAG_KEY_SIZE, key_size);
447 }
448 
HmacKey(uint32_t key_size)449 AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
450     Authorization(TAG_ALGORITHM, Algorithm::HMAC);
451     Authorization(TAG_KEY_SIZE, key_size);
452     return SigningKey();
453 }
454 
RsaSigningKey(uint32_t key_size,uint64_t public_exponent)455 AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
456                                                                 uint64_t public_exponent) {
457     RsaKey(key_size, public_exponent);
458     return SigningKey();
459 }
460 
RsaEncryptionKey(uint32_t key_size,uint64_t public_exponent)461 AuthorizationSetBuilder& AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size,
462                                                                    uint64_t public_exponent) {
463     RsaKey(key_size, public_exponent);
464     return EncryptionKey();
465 }
466 
EcdsaSigningKey(uint32_t key_size)467 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
468     EcdsaKey(key_size);
469     return SigningKey();
470 }
471 
EcdsaSigningKey(EcCurve curve)472 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) {
473     EcdsaKey(curve);
474     return SigningKey();
475 }
476 
AesEncryptionKey(uint32_t key_size)477 AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
478     AesKey(key_size);
479     return EncryptionKey();
480 }
481 
TripleDesEncryptionKey(uint32_t key_size)482 AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesEncryptionKey(uint32_t key_size) {
483     TripleDesKey(key_size);
484     return EncryptionKey();
485 }
486 
SigningKey()487 AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
488     Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
489     return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
490 }
491 
EncryptionKey()492 AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
493     Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
494     return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
495 }
496 
NoDigestOrPadding()497 AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
498     Authorization(TAG_DIGEST, Digest::NONE);
499     return Authorization(TAG_PADDING, PaddingMode::NONE);
500 }
501 
EcbMode()502 AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
503     return Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
504 }
505 
GcmModeMinMacLen(uint32_t minMacLength)506 AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMinMacLen(uint32_t minMacLength) {
507     return BlockMode(BlockMode::GCM)
508         .Padding(PaddingMode::NONE)
509         .Authorization(TAG_MIN_MAC_LENGTH, minMacLength);
510 }
511 
GcmModeMacLen(uint32_t macLength)512 AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMacLen(uint32_t macLength) {
513     return BlockMode(BlockMode::GCM)
514         .Padding(PaddingMode::NONE)
515         .Authorization(TAG_MAC_LENGTH, macLength);
516 }
517 
BlockMode(std::initializer_list<V4_0::BlockMode> blockModes)518 AuthorizationSetBuilder& AuthorizationSetBuilder::BlockMode(
519     std::initializer_list<V4_0::BlockMode> blockModes) {
520     for (auto mode : blockModes) {
521         push_back(TAG_BLOCK_MODE, mode);
522     }
523     return *this;
524 }
525 
Digest(std::initializer_list<V4_0::Digest> digests)526 AuthorizationSetBuilder& AuthorizationSetBuilder::Digest(
527     std::initializer_list<V4_0::Digest> digests) {
528     for (auto digest : digests) {
529         push_back(TAG_DIGEST, digest);
530     }
531     return *this;
532 }
533 
Padding(std::initializer_list<V4_0::PaddingMode> paddingModes)534 AuthorizationSetBuilder& AuthorizationSetBuilder::Padding(
535     std::initializer_list<V4_0::PaddingMode> paddingModes) {
536     for (auto paddingMode : paddingModes) {
537         push_back(TAG_PADDING, paddingMode);
538     }
539     return *this;
540 }
541 
542 }  // namespace V4_0
543 }  // namespace keymaster
544 }  // namespace hardware
545 }  // namespace android
546