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