diff options
author | Shawn Willden <swillden@google.com> | 2017-12-06 19:35:28 -0700 |
---|---|---|
committer | Janis Danisevskis <jdanis@google.com> | 2017-12-27 09:24:19 -0800 |
commit | bb22a6c50d609dffc7002f906f4d385d7c7cbfdc (patch) | |
tree | 6be3fc97010ed92c84e68066e914dd28df26ab54 /keystore/include | |
parent | 2e0282a08da498711e9ff89517465f15d262c23b (diff) | |
download | security-bb22a6c50d609dffc7002f906f4d385d7c7cbfdc.tar.gz |
Use libkeymaster4support in keystore.
Test: CTS
Change-Id: Iee8f308a5255a03b02fce162cc4184d45f75fd1b
Diffstat (limited to 'keystore/include')
-rw-r--r-- | keystore/include/keystore/KeymasterArguments.h | 2 | ||||
-rw-r--r-- | keystore/include/keystore/OperationResult.h | 2 | ||||
-rw-r--r-- | keystore/include/keystore/authorization_set.h | 336 | ||||
-rw-r--r-- | keystore/include/keystore/keymaster_tags.h | 352 | ||||
-rw-r--r-- | keystore/include/keystore/keymaster_types.h | 67 | ||||
-rw-r--r-- | keystore/include/keystore/keystore_client.h | 2 | ||||
-rw-r--r-- | keystore/include/keystore/keystore_hidl_support.h | 2 |
7 files changed, 71 insertions, 692 deletions
diff --git a/keystore/include/keystore/KeymasterArguments.h b/keystore/include/keystore/KeymasterArguments.h index 329579aa..99074f8c 100644 --- a/keystore/include/keystore/KeymasterArguments.h +++ b/keystore/include/keystore/KeymasterArguments.h @@ -17,7 +17,7 @@ #include <binder/Parcelable.h> -#include "keymaster_tags.h" +#include <keystore/keymaster_types.h> namespace android { namespace security { diff --git a/keystore/include/keystore/OperationResult.h b/keystore/include/keystore/OperationResult.h index 6dd5aef3..2ceda9a4 100644 --- a/keystore/include/keystore/OperationResult.h +++ b/keystore/include/keystore/OperationResult.h @@ -18,7 +18,7 @@ #include <binder/Parcel.h> #include <binder/Parcelable.h> -#include "keymaster_tags.h" +#include "keymaster_types.h" #include "keystore_return_types.h" namespace android { diff --git a/keystore/include/keystore/authorization_set.h b/keystore/include/keystore/authorization_set.h deleted file mode 100644 index 0e57a196..00000000 --- a/keystore/include/keystore/authorization_set.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SYSTEM_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_ -#define SYSTEM_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_ - -#include "keymaster_tags.h" -#include <vector> - -namespace keystore { - -class AuthorizationSetBuilder; - -/** - * An ordered collection of KeyParameters. It provides memory ownership and some convenient - * functionality for sorting, deduplicating, joining, and subtracting sets of KeyParameters. - * For serialization, wrap the backing store of this structure in a hidl_vec<KeyParameter>. - */ -class AuthorizationSet { - public: - /** - * Construct an empty, dynamically-allocated, growable AuthorizationSet. - */ - AuthorizationSet() {}; - - // Copy constructor. - AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {} - - // Move constructor. - AuthorizationSet(AuthorizationSet&& other) : data_(std::move(other.data_)) {} - - // Constructor from hidl_vec<KeyParameter> - AuthorizationSet(const hidl_vec<KeyParameter>& other) { - *this = other; - } - - // Copy assignment. - AuthorizationSet& operator=(const AuthorizationSet& other) { - data_ = other.data_; - return *this; - } - - // Move assignment. - AuthorizationSet& operator=(AuthorizationSet&& other) { - data_ = std::move(other.data_); - return *this; - } - - AuthorizationSet& operator=(const hidl_vec<KeyParameter>& other) { - if (other.size() > 0) { - data_.resize(other.size()); - for (size_t i = 0; i < data_.size(); ++i) { - /* This makes a deep copy even of embedded blobs. - * See assignment operator/copy constructor of hidl_vec.*/ - data_[i] = other[i]; - } - } - return *this; - } - - /** - * Clear existing authorization set data - */ - void Clear(); - - ~AuthorizationSet() = default; - - /** - * Returns the size of the set. - */ - size_t size() const { return data_.size(); } - - /** - * Returns true if the set is empty. - */ - bool empty() const { return size() == 0; } - - /** - * Returns the data in the set, directly. Be careful with this. - */ - const KeyParameter* data() const { return data_.data(); } - - /** - * Sorts the set - */ - void Sort(); - - /** - * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the - * AuthorizationSetBuilder). - */ - void Deduplicate(); - - /** - * Adds all elements from \p set that are not already present in this AuthorizationSet. As a - * side-effect, if \p set is not null this AuthorizationSet will end up sorted. - */ - void Union(const AuthorizationSet& set); - - /** - * Removes all elements in \p set from this AuthorizationSet. - */ - void Subtract(const AuthorizationSet& set); - - /** - * Returns the offset of the next entry that matches \p tag, starting from the element after \p - * begin. If not found, returns -1. - */ - int find(Tag tag, int begin = -1) const; - - /** - * Removes the entry at the specified index. Returns true if successful, false if the index was - * out of bounds. - */ - bool erase(int index); - - /** - * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration - */ - std::vector<KeyParameter>::const_iterator begin() const { return data_.begin(); } - - /** - * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration - */ - std::vector<KeyParameter>::const_iterator end() const { return data_.end(); } - - /** - * Returns the nth element of the set. - * Like for std::vector::operator[] there is no range check performed. Use of out of range - * indices is undefined. - */ - KeyParameter& operator[](int n); - - /** - * Returns the nth element of the set. - * Like for std::vector::operator[] there is no range check performed. Use of out of range - * indices is undefined. - */ - const KeyParameter& operator[](int n) const; - - /** - * Returns true if the set contains at least one instance of \p tag - */ - bool Contains(Tag tag) const { - return find(tag) != -1; - } - - template <TagType tag_type, Tag tag, typename ValueT> - bool Contains(TypedTag<tag_type, tag> ttag, const ValueT& value) const { - for (const auto& param: data_) { - auto entry = authorizationValue(ttag, param); - if (entry.isOk() && entry.value() == value) return true; - } - return false; - } - /** - * Returns the number of \p tag entries. - */ - size_t GetTagCount(Tag tag) const; - - template <typename T> - inline NullOr<const typename TypedTag2ValueType<T>::type&> GetTagValue(T tag) const { - auto entry = GetEntry(tag); - if (entry.isOk()) return authorizationValue(tag, entry.value()); - return {}; - } - - void push_back(const KeyParameter& param) { - data_.push_back(param); - } - void push_back(KeyParameter&& param) { - data_.push_back(std::move(param)); - } - - /** - * Append the tag and enumerated value to the set. - * "val" may be exactly one parameter unless a boolean parameter is added. - * In this case "val" is omitted. This condition is checked at compile time by Authorization() - */ - template <typename TypedTagT, typename... Value> - void push_back(TypedTagT tag, Value&&... val) { - push_back(Authorization(tag, std::forward<Value>(val)...)); - } - - template <typename Iterator> - void append(Iterator begin, Iterator end) { - while (begin != end) { - push_back(*begin); - ++begin; - } - } - - hidl_vec<KeyParameter> hidl_data() const { - hidl_vec<KeyParameter> result; - result.setToExternal(const_cast<KeyParameter*>(data()), size()); - return result; - } - - void Serialize(std::ostream* out) const; - void Deserialize(std::istream* in); - - private: - NullOr<const KeyParameter&> GetEntry(Tag tag) const; - - std::vector<KeyParameter> data_; -}; - -class AuthorizationSetBuilder: public AuthorizationSet { - public: - template <typename TagType, typename... ValueType> - AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) { - push_back(ttag, std::forward<ValueType>(value)...); - return *this; - } - - template <Tag tag> - AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data, - size_t data_length) { - hidl_vec<uint8_t> new_blob; - new_blob.setToExternal(const_cast<uint8_t*>(data), data_length); - push_back(ttag, std::move(new_blob)); - return *this; - } - - template <Tag tag> - AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data, - size_t data_length) { - return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length); - } - - AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent); - AuthorizationSetBuilder& EcdsaKey(uint32_t key_size); - AuthorizationSetBuilder& AesKey(uint32_t key_size); - AuthorizationSetBuilder& HmacKey(uint32_t key_size); - - AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent); - AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent); - AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size); - AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size); - - AuthorizationSetBuilder& SigningKey(); - AuthorizationSetBuilder& EncryptionKey(); - AuthorizationSetBuilder& NoDigestOrPadding(); - AuthorizationSetBuilder& EcbMode(); - - AuthorizationSetBuilder& Digest(Digest digest) { - return Authorization(TAG_DIGEST, digest); - } - - AuthorizationSetBuilder& Padding(PaddingMode padding) { - return Authorization(TAG_PADDING, padding); - } -}; - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size, - uint64_t public_exponent) { - Authorization(TAG_ALGORITHM, Algorithm::RSA); - Authorization(TAG_KEY_SIZE, key_size); - Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent); - return *this; -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) { - Authorization(TAG_ALGORITHM, Algorithm::EC); - Authorization(TAG_KEY_SIZE, key_size); - return *this; -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) { - Authorization(TAG_ALGORITHM, Algorithm::AES); - return Authorization(TAG_KEY_SIZE, key_size); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) { - Authorization(TAG_ALGORITHM, Algorithm::HMAC); - Authorization(TAG_KEY_SIZE, key_size); - return SigningKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size, - uint64_t public_exponent) { - RsaKey(key_size, public_exponent); - return SigningKey(); -} - -inline AuthorizationSetBuilder& -AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) { - RsaKey(key_size, public_exponent); - return EncryptionKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) { - EcdsaKey(key_size); - return SigningKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) { - AesKey(key_size); - return EncryptionKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() { - Authorization(TAG_PURPOSE, KeyPurpose::SIGN); - return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() { - Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT); - return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() { - Authorization(TAG_DIGEST, Digest::NONE); - return Authorization(TAG_PADDING, PaddingMode::NONE); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() { - return Authorization(TAG_BLOCK_MODE, BlockMode::ECB); -} - -} // namespace keystore - -#endif // SYSTEM_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_ diff --git a/keystore/include/keystore/keymaster_tags.h b/keystore/include/keystore/keymaster_tags.h deleted file mode 100644 index 6d2048ad..00000000 --- a/keystore/include/keystore/keymaster_tags.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_ -#define SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_ - -/** - * This header contains various definitions that make working with keymaster tags safer and easier. - * - * It makes use of a fair amount of template metaprogramming. The metaprogramming serves the purpose - * of making it impossible to make certain classes of mistakes when operating on keymaster - * authorizations. For example, it's an error to create a KeyParameter with tag == Tag::PURPOSE - * and then to assign Algorithm::RSA to algorithm element of its union. But because the user - * must choose the union field, there could be a mismatch which the compiler has now way to - * diagnose. - * - * The machinery in this header solves these problems by describing which union field corresponds - * to which Tag. Central to this mechanism is the template TypedTag. It has zero size and binds a - * numeric Tag to a type that the compiler understands. By means of the macro DECLARE_TYPED_TAG, - * we declare types for each of the tags defined in hardware/interfaces/keymaster/2.0/types.hal. - * - * The macro DECLARE_TYPED_TAG(name) generates a typename TAG_name_t and a zero sized instance - * TAG_name. Once these typed tags have been declared we define metafunctions mapping the each tag - * to its value c++ type and the correct union element of KeyParameter. This is done by means of - * the macros MAKE_TAG_*VALUE_ACCESSOR, which generates TypedTag2ValueType, a metafunction mapping - * a typed tag to the corresponding c++ type, and access function, accessTagValue returning a - * reference to the correct element of KeyParameter. - * E.g.: - * given "KeyParameter param;" then "accessTagValue(TAG_PURPOSE, param)" - * yields a reference to param.f.purpose - * If used in an assignment the compiler can now check the compatibility of the assigned value. - * - * For convenience we also provide the constructor like function Authorization(). - * Authorization takes a typed tag and a value and checks at compile time whether the value given - * is suitable for the given tag. At runtime it creates a new KeyParameter initialized with the - * given tag and value and returns it by value. - * - * The second convenience function, authorizationValue, allows access to the KeyParameter value in - * a safe way. It takes a typed tag and a KeyParameter and returns a reference to the value wrapped - * by NullOr. NullOr has out-of-band information about whether it is save to access the wrapped - * reference. - * E.g.: - * auto param = Authorization(TAG_ALGORITM, Algorithm::RSA); - * auto value1 = authorizationValue(TAG_PURPOSE, param); - * auto value2 = authorizationValue(TAG_ALGORITM, param); - * value1.isOk() yields false, but value2.isOk() yields true, thus value2.value() is save to access. - */ - -#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h> -#include <type_traits> - -#include "keymaster_types.h" - -namespace keystore { - -// This namespace alias is temporary. This file will be removed in favor of the KM4 support -// library version. -namespace oldkeymaster = android::hardware::keymaster::V3_0; - -using keymaster::ErrorCode; -using keymaster::HardwareAuthToken; -using keymaster::HmacSharingParameters; -using keymaster::IKeymasterDevice; -using keymaster::KeyCharacteristics; -using keymaster::KeyOrigin; -using keymaster::KeyParameter; -using keymaster::KeyPurpose; -using keymaster::OperationHandle; -using keymaster::SecurityLevel; -using keymaster::Tag; -using keymaster::VerificationToken; -using oldkeymaster::Algorithm; -using oldkeymaster::BlockMode; -using oldkeymaster::Digest; -using oldkeymaster::EcCurve; -using oldkeymaster::HardwareAuthenticatorType; -using oldkeymaster::KeyBlobUsageRequirements; -using oldkeymaster::KeyDerivationFunction; -using oldkeymaster::KeyFormat; -using oldkeymaster::PaddingMode; -using oldkeymaster::TagType; - -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; - -// The following create the numeric values that KM_TAG_PADDING and KM_TAG_DIGEST used to have. We -// need these old values to be able to support old keys that use them. -static const int32_t KM_TAG_DIGEST_OLD = static_cast<int32_t>(TagType::ENUM) | 5; -static const int32_t KM_TAG_PADDING_OLD = static_cast<int32_t>(TagType::ENUM) | 7; - -constexpr TagType typeFromTag(Tag tag) { - return static_cast<TagType>(static_cast<uint32_t>(tag) & static_cast<uint32_t>(0xf0000000)); -} - -/** - * TypedTag is a templatized version of Tag, which provides compile-time checking of - * keymaster tag types. Instances are convertible to Tag, so they can be used wherever - * Tag is expected, and because they encode the tag type it's possible to create - * function overloads that only operate on tags with a particular type. - */ -template <TagType tag_type, Tag tag> struct TypedTag { - inline TypedTag() { - // Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type - // 'tag_type'. Attempting to instantiate a tag with the wrong type will result in a compile - // error (no match for template specialization StaticAssert<false>), with no run-time cost. - static_assert(typeFromTag(tag) == tag_type, "mismatch between tag and tag_type"); - } - operator Tag() const { return tag; } -}; - -template <Tag tag> struct Tag2TypedTag { typedef TypedTag<typeFromTag(tag), tag> type; }; - -template <Tag tag> struct Tag2String; - -#define _TAGS_STRINGIFY(x) #x -#define TAGS_STRINGIFY(x) _TAGS_STRINGIFY(x) - -#define DECLARE_TYPED_TAG(name) \ - typedef typename Tag2TypedTag<Tag::name>::type TAG_##name##_t; \ - extern TAG_##name##_t TAG_##name; \ - template <> struct Tag2String<Tag::name> { \ - static const char* value() { return "Tag::" TAGS_STRINGIFY(name); } \ - } - -DECLARE_TYPED_TAG(INVALID); -DECLARE_TYPED_TAG(KEY_SIZE); -DECLARE_TYPED_TAG(MAC_LENGTH); -DECLARE_TYPED_TAG(CALLER_NONCE); -DECLARE_TYPED_TAG(MIN_MAC_LENGTH); -DECLARE_TYPED_TAG(RSA_PUBLIC_EXPONENT); -DECLARE_TYPED_TAG(INCLUDE_UNIQUE_ID); -DECLARE_TYPED_TAG(ACTIVE_DATETIME); -DECLARE_TYPED_TAG(ORIGINATION_EXPIRE_DATETIME); -DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME); -DECLARE_TYPED_TAG(MIN_SECONDS_BETWEEN_OPS); -DECLARE_TYPED_TAG(MAX_USES_PER_BOOT); -DECLARE_TYPED_TAG(USER_SECURE_ID); -DECLARE_TYPED_TAG(NO_AUTH_REQUIRED); -DECLARE_TYPED_TAG(AUTH_TIMEOUT); -DECLARE_TYPED_TAG(ALLOW_WHILE_ON_BODY); -DECLARE_TYPED_TAG(APPLICATION_ID); -DECLARE_TYPED_TAG(APPLICATION_DATA); -DECLARE_TYPED_TAG(CREATION_DATETIME); -DECLARE_TYPED_TAG(ROLLBACK_RESISTANCE); -DECLARE_TYPED_TAG(ROOT_OF_TRUST); -DECLARE_TYPED_TAG(ASSOCIATED_DATA); -DECLARE_TYPED_TAG(NONCE); -DECLARE_TYPED_TAG(BOOTLOADER_ONLY); -DECLARE_TYPED_TAG(OS_VERSION); -DECLARE_TYPED_TAG(OS_PATCHLEVEL); -DECLARE_TYPED_TAG(UNIQUE_ID); -DECLARE_TYPED_TAG(ATTESTATION_CHALLENGE); -DECLARE_TYPED_TAG(ATTESTATION_APPLICATION_ID); -DECLARE_TYPED_TAG(RESET_SINCE_ID_ROTATION); - -DECLARE_TYPED_TAG(PURPOSE); -DECLARE_TYPED_TAG(ALGORITHM); -DECLARE_TYPED_TAG(BLOCK_MODE); -DECLARE_TYPED_TAG(DIGEST); -DECLARE_TYPED_TAG(PADDING); -DECLARE_TYPED_TAG(BLOB_USAGE_REQUIREMENTS); -DECLARE_TYPED_TAG(ORIGIN); -DECLARE_TYPED_TAG(USER_AUTH_TYPE); -DECLARE_TYPED_TAG(EC_CURVE); - -template <typename... Elems> struct MetaList {}; - -using all_tags_t = MetaList< - TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t, TAG_MIN_MAC_LENGTH_t, - TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t, TAG_ACTIVE_DATETIME_t, - TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t, TAG_MIN_SECONDS_BETWEEN_OPS_t, - TAG_MAX_USES_PER_BOOT_t, TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t, - TAG_ALLOW_WHILE_ON_BODY_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t, - TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t, TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, - TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t, TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, - TAG_ATTESTATION_CHALLENGE_t, TAG_ATTESTATION_APPLICATION_ID_t, TAG_RESET_SINCE_ID_ROTATION_t, - TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t, TAG_DIGEST_t, TAG_PADDING_t, - TAG_BLOB_USAGE_REQUIREMENTS_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t>; - -/* implementation in keystore_utils.cpp */ -extern const char* stringifyTag(Tag tag); - -template <typename TypedTagType> struct TypedTag2ValueType; - -#define MAKE_TAG_VALUE_ACCESSOR(tag_type, field_name) \ - template <Tag tag> struct TypedTag2ValueType<TypedTag<tag_type, tag>> { \ - typedef decltype(static_cast<KeyParameter*>(nullptr)->field_name) type; \ - }; \ - template <Tag tag> \ - inline auto accessTagValue(TypedTag<tag_type, tag>, const KeyParameter& param) \ - ->const decltype(param.field_name)& { \ - return param.field_name; \ - } \ - template <Tag tag> \ - inline auto accessTagValue(TypedTag<tag_type, tag>, KeyParameter& param) \ - ->decltype(param.field_name)& { \ - return param.field_name; \ - } - -MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG, f.longInteger) -MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG_REP, f.longInteger) -MAKE_TAG_VALUE_ACCESSOR(TagType::DATE, f.dateTime) -MAKE_TAG_VALUE_ACCESSOR(TagType::UINT, f.integer) -MAKE_TAG_VALUE_ACCESSOR(TagType::UINT_REP, f.integer) -MAKE_TAG_VALUE_ACCESSOR(TagType::BOOL, f.boolValue) -MAKE_TAG_VALUE_ACCESSOR(TagType::BYTES, blob) -MAKE_TAG_VALUE_ACCESSOR(TagType::BIGNUM, blob) - -#define MAKE_TAG_ENUM_VALUE_ACCESSOR(typed_tag, field_name) \ - template <> struct TypedTag2ValueType<decltype(typed_tag)> { \ - typedef decltype(static_cast<KeyParameter*>(nullptr)->field_name) type; \ - }; \ - inline auto accessTagValue(decltype(typed_tag), const KeyParameter& param) \ - ->const decltype(param.field_name)& { \ - return param.field_name; \ - } \ - inline auto accessTagValue(decltype(typed_tag), KeyParameter& param) \ - ->decltype(param.field_name)& { \ - return param.field_name; \ - } - -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ALGORITHM, f.algorithm) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOB_USAGE_REQUIREMENTS, f.keyBlobUsageRequirements) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOCK_MODE, f.blockMode) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_DIGEST, f.digest) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_EC_CURVE, f.ecCurve) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ORIGIN, f.origin) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PADDING, f.paddingMode) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PURPOSE, f.purpose) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_USER_AUTH_TYPE, f.hardwareAuthenticatorType) - -template <TagType tag_type, Tag tag, typename ValueT> -inline KeyParameter makeKeyParameter(TypedTag<tag_type, tag> ttag, ValueT&& value) { - KeyParameter param; - param.tag = tag; - param.f.longInteger = 0; - accessTagValue(ttag, param) = std::forward<ValueT>(value); - return param; -} - -// the boolean case -template <Tag tag> inline KeyParameter makeKeyParameter(TypedTag<TagType::BOOL, tag>) { - KeyParameter param; - param.tag = tag; - param.f.boolValue = true; - return param; -} - -template <typename... Pack> struct FirstOrNoneHelper; -template <typename First> struct FirstOrNoneHelper<First> { typedef First type; }; -template <> struct FirstOrNoneHelper<> { - struct type {}; -}; - -template <typename... Pack> using FirstOrNone = typename FirstOrNoneHelper<Pack...>::type; - -template <TagType tag_type, Tag tag, typename... Args> -inline KeyParameter Authorization(TypedTag<tag_type, tag> ttag, Args&&... args) { - static_assert(tag_type != TagType::BOOL || (sizeof...(args) == 0), - "TagType::BOOL Authorizations do not take parameters. Presence is truth."); - static_assert(tag_type == TagType::BOOL || (sizeof...(args) == 1), - "Authorization other then TagType::BOOL take exactly one parameter."); - static_assert( - tag_type == TagType::BOOL || - std::is_convertible<std::remove_cv_t<std::remove_reference_t<FirstOrNone<Args...>>>, - typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type>::value, - "Invalid argument type for given tag."); - - return makeKeyParameter(ttag, std::forward<Args>(args)...); -} - -/** - * This class wraps a (mostly return) value and stores whether or not the wrapped value is valid out - * of band. Note that if the wrapped value is a reference it is unsafe to access the value if - * !isOk(). If the wrapped type is a pointer or value and !isOk(), it is still safe to access the - * wrapped value. In this case the pointer will be NULL though, and the value will be default - * constructed. - */ -template <typename ValueT> class NullOr { - template <typename T> struct reference_initializer { - static T&& init() { return *static_cast<std::remove_reference_t<T>*>(nullptr); } - }; - template <typename T> struct pointer_initializer { - static T init() { return nullptr; } - }; - template <typename T> struct value_initializer { - static T init() { return T(); } - }; - template <typename T> - using initializer_t = - std::conditional_t<std::is_lvalue_reference<T>::value, reference_initializer<T>, - std::conditional_t<std::is_pointer<T>::value, pointer_initializer<T>, - value_initializer<T>>>; - - public: - NullOr() : value_(initializer_t<ValueT>::init()), null_(true) {} - NullOr(ValueT&& value) : value_(std::forward<ValueT>(value)), null_(false) {} - - bool isOk() const { return !null_; } - - const ValueT& value() const & { return value_; } - ValueT& value() & { return value_; } - ValueT&& value() && { return std::move(value_); } - - private: - ValueT value_; - bool null_; -}; - -template <typename T> std::remove_reference_t<T> NullOrOr(T&& v) { - if (v.isOk()) return v; - return {}; -} - -template <typename Head, typename... Tail> -std::remove_reference_t<Head> NullOrOr(Head&& head, Tail&&... tail) { - if (head.isOk()) return head; - return NullOrOr(std::forward<Tail>(tail)...); -} - -template <typename Default, typename Wrapped> -std::remove_reference_t<Wrapped> defaultOr(NullOr<Wrapped>&& optional, Default&& def) { - static_assert(std::is_convertible<std::remove_reference_t<Default>, - std::remove_reference_t<Wrapped>>::value, - "Type of default value must match the type wrapped by NullOr"); - if (optional.isOk()) return optional.value(); - return def; -} - -template <TagType tag_type, Tag tag> -inline NullOr<const typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type&> -authorizationValue(TypedTag<tag_type, tag> ttag, const KeyParameter& param) { - if (tag != param.tag) return {}; - return accessTagValue(ttag, param); -} - -} // namespace keystore - -#endif // SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_ diff --git a/keystore/include/keystore/keymaster_types.h b/keystore/include/keystore/keymaster_types.h index 272105f6..d3671369 100644 --- a/keystore/include/keystore/keymaster_types.h +++ b/keystore/include/keystore/keymaster_types.h @@ -12,22 +12,89 @@ // See the License for the specific language governing permissions and // limitations under the License. +#ifndef SECURITY_KEYSTORE_INCLUDE_KEYSTORE_KEYMASTER_TYPES_H_ +#define SECURITY_KEYSTORE_INCLUDE_KEYSTORE_KEYMASTER_TYPES_H_ + #include <android/hardware/keymaster/4.0/IKeymasterDevice.h> #include <android/hardware/keymaster/4.0/types.h> +#include <keymasterV4_0/authorization_set.h> +#include <keymasterV4_0/keymaster_tags.h> + /** * This header lifts the types from the current Keymaster version into the keystore namespace. */ namespace keystore { +// Changing this namespace alias will change the keymaster version. namespace keymaster = ::android::hardware::keymaster::V4_0; +using android::hardware::hidl_vec; +using android::hardware::Return; + using keymaster::IKeymasterDevice; using keymaster::SecurityLevel; +using keymaster::AuthorizationSet; +using keymaster::AuthorizationSetBuilder; + +using keymaster::Algorithm; +using keymaster::BlockMode; +using keymaster::Digest; +using keymaster::EcCurve; +using keymaster::ErrorCode; +using keymaster::HardwareAuthenticatorType; +using keymaster::HardwareAuthToken; +using keymaster::HmacSharingParameters; +using keymaster::KeyCharacteristics; +using keymaster::KeyFormat; +using keymaster::KeyParameter; +using keymaster::KeyPurpose; +using keymaster::OperationHandle; +using keymaster::PaddingMode; +using keymaster::SecurityLevel; +using keymaster::Tag; +using keymaster::TagType; +using keymaster::VerificationToken; + +using keymaster::TAG_ACTIVE_DATETIME; +using keymaster::TAG_ALGORITHM; +using keymaster::TAG_ALLOW_WHILE_ON_BODY; +using keymaster::TAG_APPLICATION_DATA; +using keymaster::TAG_APPLICATION_ID; +using keymaster::TAG_ATTESTATION_APPLICATION_ID; +using keymaster::TAG_AUTH_TIMEOUT; +using keymaster::TAG_BLOCK_MODE; +using keymaster::TAG_DIGEST; +using keymaster::TAG_EC_CURVE; +using keymaster::TAG_KEY_SIZE; +using keymaster::TAG_MAC_LENGTH; +using keymaster::TAG_MAX_USES_PER_BOOT; +using keymaster::TAG_MIN_MAC_LENGTH; +using keymaster::TAG_MIN_SECONDS_BETWEEN_OPS; +using keymaster::TAG_NO_AUTH_REQUIRED; +using keymaster::TAG_NONCE; +using keymaster::TAG_ORIGINATION_EXPIRE_DATETIME; +using keymaster::TAG_PADDING; +using keymaster::TAG_PURPOSE; +using keymaster::TAG_RESET_SINCE_ID_ROTATION; +using keymaster::TAG_RSA_PUBLIC_EXPONENT; +using keymaster::TAG_USAGE_EXPIRE_DATETIME; +using keymaster::TAG_USER_AUTH_TYPE; +using keymaster::TAG_USER_SECURE_ID; + +using keymaster::NullOr; + using Km3HardwareAuthToken = ::android::hardware::keymaster::V3_0::HardwareAuthToken; using Km3HardwareAuthenticatorType = ::android::hardware::keymaster::V3_0::HardwareAuthenticatorType; +// The following create the numeric values that KM_TAG_PADDING and KM_TAG_DIGEST used to have. We +// need these old values to be able to support old keys that use them. +constexpr int32_t KM_TAG_DIGEST_OLD = static_cast<int32_t>(TagType::ENUM) | 5; +constexpr int32_t KM_TAG_PADDING_OLD = static_cast<int32_t>(TagType::ENUM) | 7; + } // namespace keystore + +#endif // SYSTEM_SECURITY_KEYSTORE_KM4_AUTHORIZATION_SET_H_ diff --git a/keystore/include/keystore/keystore_client.h b/keystore/include/keystore/keystore_client.h index 928b2e6f..67ebad39 100644 --- a/keystore/include/keystore/keystore_client.h +++ b/keystore/include/keystore/keystore_client.h @@ -21,7 +21,7 @@ #include <android-base/macros.h> -#include "authorization_set.h" +#include "keymaster_types.h" #include "keystore.h" #include "keystore_return_types.h" diff --git a/keystore/include/keystore/keystore_hidl_support.h b/keystore/include/keystore/keystore_hidl_support.h index 944c3f6e..7a3723e2 100644 --- a/keystore/include/keystore/keystore_hidl_support.h +++ b/keystore/include/keystore/keystore_hidl_support.h @@ -27,7 +27,7 @@ #include <hardware/hw_auth_token.h> #include <hidl/Status.h> -#include <keystore/keymaster_tags.h> +#include <keystore/keymaster_types.h> namespace keystore { |