Loading keymaster/4.0/support/Android.bp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,8 @@ cc_library { "attestation_record.cpp", "attestation_record.cpp", "authorization_set.cpp", "authorization_set.cpp", "key_param_output.cpp", "key_param_output.cpp", "keymaster_utils.cpp", "Keymaster.cpp", "Keymaster3.cpp", "Keymaster3.cpp", "Keymaster4.cpp", "Keymaster4.cpp", ], ], Loading keymaster/4.0/support/Keymaster.cpp 0 → 100644 +90 −0 Original line number Original line Diff line number Diff line /* ** Copyright 2018, 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. */ #include <keymasterV4_0/Keymaster.h> #include <android-base/logging.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <keymasterV4_0/Keymaster3.h> #include <keymasterV4_0/Keymaster4.h> namespace android { namespace hardware { namespace keymaster { namespace V4_0 { namespace support { using ::android::sp; using ::android::hidl::manager::V1_0::IServiceManager; template <typename Wrapper> std::vector<std::unique_ptr<Keymaster>> enumerateDevices( const sp<IServiceManager>& serviceManager) { std::vector<std::unique_ptr<Keymaster>> result; bool foundDefault = false; auto& descriptor = Wrapper::WrappedIKeymasterDevice::descriptor; serviceManager->listByInterface(descriptor, [&](const hidl_vec<hidl_string>& names) { for (auto& name : names) { if (name == "default") foundDefault = true; auto device = Wrapper::WrappedIKeymasterDevice::getService(); CHECK(device) << "Failed to get service for " << descriptor << " with interface name " << name; result.push_back(std::unique_ptr<Keymaster>(new Wrapper(device, name))); } }); if (!foundDefault) { // "default" wasn't provided by listByInterface. Maybe there's a passthrough // implementation. auto device = Wrapper::WrappedIKeymasterDevice::getService("default"); if (device) result.push_back(std::unique_ptr<Keymaster>(new Wrapper(device, "default"))); } return result; } std::vector<std::unique_ptr<Keymaster>> Keymaster::enumerateAvailableDevices() { auto serviceManager = IServiceManager::getService(); CHECK(serviceManager) << "Could not retrieve ServiceManager"; auto km4s = enumerateDevices<Keymaster4>(serviceManager); auto km3s = enumerateDevices<Keymaster3>(serviceManager); auto result = std::move(km4s); result.insert(result.end(), std::make_move_iterator(km3s.begin()), std::make_move_iterator(km3s.end())); std::sort(result.begin(), result.end(), [](auto& a, auto& b) { return a->halVersion() > b->halVersion(); }); size_t i = 1; LOG(INFO) << "List of Keymaster HALs found:"; for (auto& hal : result) { auto& version = hal->halVersion(); LOG(INFO) << "Keymaster HAL #" << i << ": " << version.keymasterName << " from " << version.authorName << " SecurityLevel: " << toString(version.securityLevel) << " HAL : " << hal->descriptor() << " instance " << hal->instanceName(); } return result; } } // namespace support } // namespace V4_0 } // namespace keymaster } // namespace hardware }; // namespace android keymaster/4.0/support/Keymaster3.cpp +12 −46 Original line number Original line Diff line number Diff line Loading @@ -18,7 +18,7 @@ #include <keymasterV4_0/Keymaster3.h> #include <keymasterV4_0/Keymaster3.h> #include <android-base/logging.h> #include <android-base/logging.h> #include <hardware/hw_auth_token.h> #include <keymasterV4_0/keymaster_utils.h> namespace android { namespace android { namespace hardware { namespace hardware { Loading Loading @@ -82,35 +82,6 @@ inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) { return std::copy(value_ptr, value_ptr + sizeof(value), dest); return std::copy(value_ptr, value_ptr + sizeof(value), dest); } } constexpr size_t kHmacSize = 32; inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) { static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) + sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + sizeof(token.timestamp) + kHmacSize == sizeof(hw_auth_token_t), "HardwareAuthToken content size does not match hw_auth_token_t size"); hidl_vec<uint8_t> result; result.resize(sizeof(hw_auth_token_t)); auto pos = result.begin(); *pos++ = 0; // Version byte pos = copy_bytes_to_iterator(token.challenge, pos); pos = copy_bytes_to_iterator(token.userId, pos); pos = copy_bytes_to_iterator(token.authenticatorId, pos); auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType)); pos = copy_bytes_to_iterator(auth_type, pos); auto timestamp = htonq(token.timestamp); pos = copy_bytes_to_iterator(timestamp, pos); if (token.mac.size() != kHmacSize) { std::fill(pos, pos + kHmacSize, 0); } else { std::copy(token.mac.begin(), token.mac.end(), pos); } return result; } hidl_vec<V3_0::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params, hidl_vec<V3_0::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params, const HardwareAuthToken& authToken) { const HardwareAuthToken& authToken) { hidl_vec<V3_0::KeyParameter> converted(params.size() + 1); hidl_vec<V3_0::KeyParameter> converted(params.size() + 1); Loading Loading @@ -139,37 +110,32 @@ void Keymaster3::getVersionIfNeeded() { [&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography, [&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography, bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName, bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName, const hidl_string& keymasterAuthorName) { const hidl_string& keymasterAuthorName) { securityLevel_ = version_ = {keymasterName, keymasterAuthorName, 0 /* major version, filled below */, isSecure ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE; isSecure ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE, supportsEllipticCurve_ = supportsEllipticCurve; supportsEllipticCurve}; supportsSymmetricCryptography_ = supportsSymmetricCryptography; supportsSymmetricCryptography_ = supportsSymmetricCryptography; supportsAttestation_ = supportsAttestation; supportsAttestation_ = supportsAttestation; supportsAllDigests_ = supportsAllDigests; supportsAllDigests_ = supportsAllDigests; keymasterName_ = keymasterName; authorName_ = keymasterAuthorName; }); }); CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features"; CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features"; if (securityLevel_ == SecurityLevel::SOFTWARE) { if (version_.securityLevel == SecurityLevel::SOFTWARE) { majorVersion_ = 3; version_.majorVersion = 3; } else if (supportsAttestation_) { } else if (supportsAttestation_) { majorVersion_ = 3; // Could be 2, doesn't matter. version_.majorVersion = 3; // Could be 2, doesn't matter. } else if (supportsSymmetricCryptography_) { } else if (supportsSymmetricCryptography_) { majorVersion_ = 1; version_.majorVersion = 1; } else { } else { majorVersion_ = 0; version_.majorVersion = 0; } } } Keymaster::VersionResult Keymaster3::halVersion() { getVersionIfNeeded(); return {ErrorCode::OK, majorVersion_, securityLevel_, supportsEllipticCurve_}; } } Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) { Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) { getVersionIfNeeded(); getVersionIfNeeded(); _hidl_cb(securityLevel_, keymasterName_ + " (wrapped by keystore::Keymaster3)", authorName_); _hidl_cb(version_.securityLevel, std::string(version_.keymasterName) + " (wrapped by keystore::Keymaster3)", version_.authorName); return Void(); return Void(); } } Loading keymaster/4.0/support/Keymaster4.cpp +7 −9 Original line number Original line Diff line number Diff line Loading @@ -28,19 +28,17 @@ namespace support { void Keymaster4::getVersionIfNeeded() { void Keymaster4::getVersionIfNeeded() { if (haveVersion_) return; if (haveVersion_) return; auto rc = dev_->getHardwareInfo([&](SecurityLevel securityLevel, auto...) { auto rc = securityLevel_ = securityLevel; dev_->getHardwareInfo([&](SecurityLevel securityLevel, const hidl_string& keymasterName, const hidl_string& authorName) { version_ = {keymasterName, authorName, 4 /* major version */, securityLevel, true /* supportsEc */}; haveVersion_ = true; haveVersion_ = true; }); }); CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware info"; CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware info"; } } Keymaster::VersionResult Keymaster4::halVersion() { getVersionIfNeeded(); return {ErrorCode::OK, halMajorVersion(), securityLevel_, true}; } } // namespace support } // namespace support } // namespace V4_0 } // namespace V4_0 } // namespace keymaster } // namespace keymaster Loading keymaster/4.0/support/authorization_set.cpp +20 −0 Original line number Original line Diff line number Diff line Loading @@ -503,6 +503,18 @@ AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() { return Authorization(TAG_BLOCK_MODE, BlockMode::ECB); return Authorization(TAG_BLOCK_MODE, BlockMode::ECB); } } AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMinMacLen(uint32_t minMacLength) { return BlockMode(BlockMode::GCM) .Padding(PaddingMode::NONE) .Authorization(TAG_MIN_MAC_LENGTH, minMacLength); } AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMacLen(uint32_t macLength) { return BlockMode(BlockMode::GCM) .Padding(PaddingMode::NONE) .Authorization(TAG_MAC_LENGTH, macLength); } AuthorizationSetBuilder& AuthorizationSetBuilder::BlockMode( AuthorizationSetBuilder& AuthorizationSetBuilder::BlockMode( std::initializer_list<V4_0::BlockMode> blockModes) { std::initializer_list<V4_0::BlockMode> blockModes) { for (auto mode : blockModes) { for (auto mode : blockModes) { Loading @@ -519,6 +531,14 @@ AuthorizationSetBuilder& AuthorizationSetBuilder::Digest( return *this; return *this; } } AuthorizationSetBuilder& AuthorizationSetBuilder::Padding( std::initializer_list<V4_0::PaddingMode> paddingModes) { for (auto paddingMode : paddingModes) { push_back(TAG_PADDING, paddingMode); } return *this; } } // namespace V4_0 } // namespace V4_0 } // namespace keymaster } // namespace keymaster } // namespace hardware } // namespace hardware Loading Loading
keymaster/4.0/support/Android.bp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,8 @@ cc_library { "attestation_record.cpp", "attestation_record.cpp", "authorization_set.cpp", "authorization_set.cpp", "key_param_output.cpp", "key_param_output.cpp", "keymaster_utils.cpp", "Keymaster.cpp", "Keymaster3.cpp", "Keymaster3.cpp", "Keymaster4.cpp", "Keymaster4.cpp", ], ], Loading
keymaster/4.0/support/Keymaster.cpp 0 → 100644 +90 −0 Original line number Original line Diff line number Diff line /* ** Copyright 2018, 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. */ #include <keymasterV4_0/Keymaster.h> #include <android-base/logging.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <keymasterV4_0/Keymaster3.h> #include <keymasterV4_0/Keymaster4.h> namespace android { namespace hardware { namespace keymaster { namespace V4_0 { namespace support { using ::android::sp; using ::android::hidl::manager::V1_0::IServiceManager; template <typename Wrapper> std::vector<std::unique_ptr<Keymaster>> enumerateDevices( const sp<IServiceManager>& serviceManager) { std::vector<std::unique_ptr<Keymaster>> result; bool foundDefault = false; auto& descriptor = Wrapper::WrappedIKeymasterDevice::descriptor; serviceManager->listByInterface(descriptor, [&](const hidl_vec<hidl_string>& names) { for (auto& name : names) { if (name == "default") foundDefault = true; auto device = Wrapper::WrappedIKeymasterDevice::getService(); CHECK(device) << "Failed to get service for " << descriptor << " with interface name " << name; result.push_back(std::unique_ptr<Keymaster>(new Wrapper(device, name))); } }); if (!foundDefault) { // "default" wasn't provided by listByInterface. Maybe there's a passthrough // implementation. auto device = Wrapper::WrappedIKeymasterDevice::getService("default"); if (device) result.push_back(std::unique_ptr<Keymaster>(new Wrapper(device, "default"))); } return result; } std::vector<std::unique_ptr<Keymaster>> Keymaster::enumerateAvailableDevices() { auto serviceManager = IServiceManager::getService(); CHECK(serviceManager) << "Could not retrieve ServiceManager"; auto km4s = enumerateDevices<Keymaster4>(serviceManager); auto km3s = enumerateDevices<Keymaster3>(serviceManager); auto result = std::move(km4s); result.insert(result.end(), std::make_move_iterator(km3s.begin()), std::make_move_iterator(km3s.end())); std::sort(result.begin(), result.end(), [](auto& a, auto& b) { return a->halVersion() > b->halVersion(); }); size_t i = 1; LOG(INFO) << "List of Keymaster HALs found:"; for (auto& hal : result) { auto& version = hal->halVersion(); LOG(INFO) << "Keymaster HAL #" << i << ": " << version.keymasterName << " from " << version.authorName << " SecurityLevel: " << toString(version.securityLevel) << " HAL : " << hal->descriptor() << " instance " << hal->instanceName(); } return result; } } // namespace support } // namespace V4_0 } // namespace keymaster } // namespace hardware }; // namespace android
keymaster/4.0/support/Keymaster3.cpp +12 −46 Original line number Original line Diff line number Diff line Loading @@ -18,7 +18,7 @@ #include <keymasterV4_0/Keymaster3.h> #include <keymasterV4_0/Keymaster3.h> #include <android-base/logging.h> #include <android-base/logging.h> #include <hardware/hw_auth_token.h> #include <keymasterV4_0/keymaster_utils.h> namespace android { namespace android { namespace hardware { namespace hardware { Loading Loading @@ -82,35 +82,6 @@ inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) { return std::copy(value_ptr, value_ptr + sizeof(value), dest); return std::copy(value_ptr, value_ptr + sizeof(value), dest); } } constexpr size_t kHmacSize = 32; inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) { static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) + sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + sizeof(token.timestamp) + kHmacSize == sizeof(hw_auth_token_t), "HardwareAuthToken content size does not match hw_auth_token_t size"); hidl_vec<uint8_t> result; result.resize(sizeof(hw_auth_token_t)); auto pos = result.begin(); *pos++ = 0; // Version byte pos = copy_bytes_to_iterator(token.challenge, pos); pos = copy_bytes_to_iterator(token.userId, pos); pos = copy_bytes_to_iterator(token.authenticatorId, pos); auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType)); pos = copy_bytes_to_iterator(auth_type, pos); auto timestamp = htonq(token.timestamp); pos = copy_bytes_to_iterator(timestamp, pos); if (token.mac.size() != kHmacSize) { std::fill(pos, pos + kHmacSize, 0); } else { std::copy(token.mac.begin(), token.mac.end(), pos); } return result; } hidl_vec<V3_0::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params, hidl_vec<V3_0::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params, const HardwareAuthToken& authToken) { const HardwareAuthToken& authToken) { hidl_vec<V3_0::KeyParameter> converted(params.size() + 1); hidl_vec<V3_0::KeyParameter> converted(params.size() + 1); Loading Loading @@ -139,37 +110,32 @@ void Keymaster3::getVersionIfNeeded() { [&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography, [&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography, bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName, bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName, const hidl_string& keymasterAuthorName) { const hidl_string& keymasterAuthorName) { securityLevel_ = version_ = {keymasterName, keymasterAuthorName, 0 /* major version, filled below */, isSecure ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE; isSecure ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE, supportsEllipticCurve_ = supportsEllipticCurve; supportsEllipticCurve}; supportsSymmetricCryptography_ = supportsSymmetricCryptography; supportsSymmetricCryptography_ = supportsSymmetricCryptography; supportsAttestation_ = supportsAttestation; supportsAttestation_ = supportsAttestation; supportsAllDigests_ = supportsAllDigests; supportsAllDigests_ = supportsAllDigests; keymasterName_ = keymasterName; authorName_ = keymasterAuthorName; }); }); CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features"; CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features"; if (securityLevel_ == SecurityLevel::SOFTWARE) { if (version_.securityLevel == SecurityLevel::SOFTWARE) { majorVersion_ = 3; version_.majorVersion = 3; } else if (supportsAttestation_) { } else if (supportsAttestation_) { majorVersion_ = 3; // Could be 2, doesn't matter. version_.majorVersion = 3; // Could be 2, doesn't matter. } else if (supportsSymmetricCryptography_) { } else if (supportsSymmetricCryptography_) { majorVersion_ = 1; version_.majorVersion = 1; } else { } else { majorVersion_ = 0; version_.majorVersion = 0; } } } Keymaster::VersionResult Keymaster3::halVersion() { getVersionIfNeeded(); return {ErrorCode::OK, majorVersion_, securityLevel_, supportsEllipticCurve_}; } } Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) { Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) { getVersionIfNeeded(); getVersionIfNeeded(); _hidl_cb(securityLevel_, keymasterName_ + " (wrapped by keystore::Keymaster3)", authorName_); _hidl_cb(version_.securityLevel, std::string(version_.keymasterName) + " (wrapped by keystore::Keymaster3)", version_.authorName); return Void(); return Void(); } } Loading
keymaster/4.0/support/Keymaster4.cpp +7 −9 Original line number Original line Diff line number Diff line Loading @@ -28,19 +28,17 @@ namespace support { void Keymaster4::getVersionIfNeeded() { void Keymaster4::getVersionIfNeeded() { if (haveVersion_) return; if (haveVersion_) return; auto rc = dev_->getHardwareInfo([&](SecurityLevel securityLevel, auto...) { auto rc = securityLevel_ = securityLevel; dev_->getHardwareInfo([&](SecurityLevel securityLevel, const hidl_string& keymasterName, const hidl_string& authorName) { version_ = {keymasterName, authorName, 4 /* major version */, securityLevel, true /* supportsEc */}; haveVersion_ = true; haveVersion_ = true; }); }); CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware info"; CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware info"; } } Keymaster::VersionResult Keymaster4::halVersion() { getVersionIfNeeded(); return {ErrorCode::OK, halMajorVersion(), securityLevel_, true}; } } // namespace support } // namespace support } // namespace V4_0 } // namespace V4_0 } // namespace keymaster } // namespace keymaster Loading
keymaster/4.0/support/authorization_set.cpp +20 −0 Original line number Original line Diff line number Diff line Loading @@ -503,6 +503,18 @@ AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() { return Authorization(TAG_BLOCK_MODE, BlockMode::ECB); return Authorization(TAG_BLOCK_MODE, BlockMode::ECB); } } AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMinMacLen(uint32_t minMacLength) { return BlockMode(BlockMode::GCM) .Padding(PaddingMode::NONE) .Authorization(TAG_MIN_MAC_LENGTH, minMacLength); } AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMacLen(uint32_t macLength) { return BlockMode(BlockMode::GCM) .Padding(PaddingMode::NONE) .Authorization(TAG_MAC_LENGTH, macLength); } AuthorizationSetBuilder& AuthorizationSetBuilder::BlockMode( AuthorizationSetBuilder& AuthorizationSetBuilder::BlockMode( std::initializer_list<V4_0::BlockMode> blockModes) { std::initializer_list<V4_0::BlockMode> blockModes) { for (auto mode : blockModes) { for (auto mode : blockModes) { Loading @@ -519,6 +531,14 @@ AuthorizationSetBuilder& AuthorizationSetBuilder::Digest( return *this; return *this; } } AuthorizationSetBuilder& AuthorizationSetBuilder::Padding( std::initializer_list<V4_0::PaddingMode> paddingModes) { for (auto paddingMode : paddingModes) { push_back(TAG_PADDING, paddingMode); } return *this; } } // namespace V4_0 } // namespace V4_0 } // namespace keymaster } // namespace keymaster } // namespace hardware } // namespace hardware Loading