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 namespace android {
     22 namespace hardware {
     23 namespace keymaster {
     24 namespace V4_0 {
     25 
     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 
     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 
     84 void AuthorizationSet::Sort() {
     85     std::sort(data_.begin(), data_.end(), keyParamLess);
     86 }
     87 
     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 
    108 void AuthorizationSet::Union(const AuthorizationSet& other) {
    109     data_.insert(data_.end(), other.data_.begin(), other.data_.end());
    110     Deduplicate();
    111 }
    112 
    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 
    130 KeyParameter& AuthorizationSet::operator[](int at) {
    131     return data_[at];
    132 }
    133 
    134 const KeyParameter& AuthorizationSet::operator[](int at) const {
    135     return data_[at];
    136 }
    137 
    138 void AuthorizationSet::Clear() {
    139     data_.clear();
    140 }
    141 
    142 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 
    148 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 
    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 
    166 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 
    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>
    225 OutStreams& serializeParamValue(OutStreams& out, const T& value) {
    226     out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T));
    227     return out;
    228 }
    229 
    230 OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) {
    231     // skip invalid entries.
    232     return out;
    233 }
    234 template <typename T>
    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...>> {
    244     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<> {
    251     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...> {
    256     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 
    265 OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
    266     return choose_serializer<all_tags_t>::serialize(out, param);
    267 }
    268 
    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 
    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>
    327 InStreams& deserializeParamValue(InStreams& in, T* value) {
    328     in.elements.read(reinterpret_cast<char*>(value), sizeof(T));
    329     return in;
    330 }
    331 
    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>
    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...>> {
    346     static InStreams& deserialize(InStreams& in, KeyParameter* param) {
    347         return choose_deserializer<Tags...>::deserialize(in, param);
    348     }
    349 };
    350 template <>
    351 struct choose_deserializer<> {
    352     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...> {
    360     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 
    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 
    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 
    411 void AuthorizationSet::Serialize(std::ostream* out) const {
    412     serialize(*out, data_);
    413 }
    414 
    415 void AuthorizationSet::Deserialize(std::istream* in) {
    416     deserialize(*in, &data_);
    417 }
    418 
    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 
    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 
    433 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) {
    434     Authorization(TAG_ALGORITHM, Algorithm::EC);
    435     Authorization(TAG_EC_CURVE, curve);
    436     return *this;
    437 }
    438 
    439 AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
    440     Authorization(TAG_ALGORITHM, Algorithm::AES);
    441     return Authorization(TAG_KEY_SIZE, key_size);
    442 }
    443 
    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 
    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 
    455 AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
    456                                                                 uint64_t public_exponent) {
    457     RsaKey(key_size, public_exponent);
    458     return SigningKey();
    459 }
    460 
    461 AuthorizationSetBuilder& AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size,
    462                                                                    uint64_t public_exponent) {
    463     RsaKey(key_size, public_exponent);
    464     return EncryptionKey();
    465 }
    466 
    467 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
    468     EcdsaKey(key_size);
    469     return SigningKey();
    470 }
    471 
    472 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) {
    473     EcdsaKey(curve);
    474     return SigningKey();
    475 }
    476 
    477 AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
    478     AesKey(key_size);
    479     return EncryptionKey();
    480 }
    481 
    482 AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesEncryptionKey(uint32_t key_size) {
    483     TripleDesKey(key_size);
    484     return EncryptionKey();
    485 }
    486 
    487 AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
    488     Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
    489     return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
    490 }
    491 
    492 AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
    493     Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
    494     return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
    495 }
    496 
    497 AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
    498     Authorization(TAG_DIGEST, Digest::NONE);
    499     return Authorization(TAG_PADDING, PaddingMode::NONE);
    500 }
    501 
    502 AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
    503     return Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
    504 }
    505 
    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 
    512 AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMacLen(uint32_t macLength) {
    513     return BlockMode(BlockMode::GCM)
    514         .Padding(PaddingMode::NONE)
    515         .Authorization(TAG_MAC_LENGTH, macLength);
    516 }
    517 
    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 
    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 
    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