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