diff --git a/HAL/Android.bp b/HAL/Android.bp index 22c1d878..c705a012 100644 --- a/HAL/Android.bp +++ b/HAL/Android.bp @@ -52,7 +52,6 @@ cc_library { cc_library { name: "libjc_keymint_transport", - host_supported: true, vendor_available: true, srcs: [ "SocketTransport.cpp", diff --git a/aosp_integration_patches/omapi_patches/JavacardKeymaster.patch b/aosp_integration_patches/omapi_patches/JavacardKeymaster.patch new file mode 100644 index 00000000..1d6bad7a --- /dev/null +++ b/aosp_integration_patches/omapi_patches/JavacardKeymaster.patch @@ -0,0 +1,385 @@ +diff --git a/HAL/Android.bp b/HAL/Android.bp +index c705a01..10dd93e 100644 +--- a/HAL/Android.bp ++++ b/HAL/Android.bp +@@ -55,13 +55,17 @@ cc_library { + vendor_available: true, + srcs: [ + "SocketTransport.cpp", ++ "OmapiTransport.cpp" + ], + export_include_dirs: [ + "." + ], + shared_libs: [ ++ "libbinder", + "libbase", + "liblog", ++ "libbinder_ndk", ++ "android.se.omapi-V1-ndk", + ], + } + +@@ -90,6 +94,7 @@ cc_binary { + "libjc_keymint_transport", + "liblog", + "libutils", ++ "android.se.omapi-V1-ndk", + ], + srcs: [ + "service.cpp", +diff --git a/HAL/OmapiTransport.cpp b/HAL/OmapiTransport.cpp +new file mode 100644 +index 0000000..dd81d3d +--- /dev/null ++++ b/HAL/OmapiTransport.cpp +@@ -0,0 +1,218 @@ ++/* ++ ** ++ ** Copyright 2020, 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "OmapiTransport.h" ++ ++namespace keymint::javacard { ++ ++class SEListener : public ::aidl::android::se::omapi::BnSecureElementListener {}; ++ ++bool OmapiTransport::initialize() { ++ std::vector readers = {}; ++ ++ LOG(DEBUG) << "Initialize the secure element connection"; ++ ++ // Get OMAPI vendor stable service handler ++ ::ndk::SpAIBinder ks2Binder(AServiceManager_getService(omapiServiceName)); ++ omapiSeService = aidl::android::se::omapi::ISecureElementService::fromBinder(ks2Binder); ++ ++ if (omapiSeService == nullptr) { ++ LOG(ERROR) << "Failed to start omapiSeService null"; ++ return false; ++ } ++ ++ // reset readers, clear readers if already existing ++ if (mVSReaders.size() > 0) { ++ closeConnection(); ++ } ++ ++ // Get available readers ++ auto status = omapiSeService->getReaders(&readers); ++ if (!status.isOk()) { ++ LOG(ERROR) << "getReaders failed to get available readers: " << status.getMessage(); ++ return false; ++ } ++ ++ // Get SE readers handlers ++ for (auto readerName : readers) { ++ std::shared_ptr<::aidl::android::se::omapi::ISecureElementReader> reader; ++ status = omapiSeService->getReader(readerName, &reader); ++ if (!status.isOk()) { ++ LOG(ERROR) << "getReader for " << readerName.c_str() << " Failed: " ++ << status.getMessage(); ++ return false; ++ } ++ ++ mVSReaders[readerName] = reader; ++ } ++ ++ // Find eSE reader, as of now assumption is only eSE available on device ++ LOG(DEBUG) << "Finding eSE reader"; ++ eSEReader = nullptr; ++ if (mVSReaders.size() > 0) { ++ for (const auto& [name, reader] : mVSReaders) { ++ if (name.find(ESE_READER_PREFIX, 0) != std::string::npos) { ++ LOG(DEBUG) << "eSE reader found: " << name; ++ eSEReader = reader; ++ } ++ } ++ } ++ ++ if (eSEReader == nullptr) { ++ LOG(ERROR) << "secure element reader " << ESE_READER_PREFIX << " not found"; ++ return false; ++ } ++ ++ return true; ++} ++ ++bool OmapiTransport::internalTransmitApdu( ++ std::shared_ptr reader, ++ std::vector apdu, std::vector& transmitResponse) { ++ std::shared_ptr session; ++ std::shared_ptr channel; ++ auto mSEListener = std::make_shared(); ++ std::vector selectResponse = {}; ++ std::vector SELECTABLE_AID = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, ++ 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x31}; ++ ++ LOG(DEBUG) << "internalTransmitApdu: trasmitting data to secure element"; ++ ++ if (reader == nullptr) { ++ LOG(ERROR) << "eSE reader is null"; ++ return false; ++ } ++ ++ bool status = false; ++ auto res = reader->isSecureElementPresent(&status); ++ if (!res.isOk()) { ++ LOG(ERROR) << "isSecureElementPresent error: " << res.getMessage(); ++ return false; ++ } ++ if (!status) { ++ LOG(ERROR) << "secure element not found"; ++ return false; ++ } ++ ++ res = reader->openSession(&session); ++ if (!res.isOk()) { ++ LOG(ERROR) << "openSession error: " << res.getMessage(); ++ return false; ++ } ++ if (session == nullptr) { ++ LOG(ERROR) << "Could not open session null"; ++ return false; ++ } ++ ++ res = session->openLogicalChannel(SELECTABLE_AID, 0x00, mSEListener, &channel); ++ if (!res.isOk()) { ++ LOG(ERROR) << "openLogicalChannel error: " << res.getMessage(); ++ return false; ++ } ++ if (channel == nullptr) { ++ LOG(ERROR) << "Could not open channel null"; ++ return false; ++ } ++ ++ res = channel->getSelectResponse(&selectResponse); ++ if (!res.isOk()) { ++ LOG(ERROR) << "getSelectResponse error: " << res.getMessage(); ++ return false; ++ } ++ if (selectResponse.size() < 2) { ++ LOG(ERROR) << "getSelectResponse size error"; ++ return false; ++ } ++ ++ res = channel->transmit(apdu, &transmitResponse); ++ if (channel != nullptr) channel->close(); ++ if (session != nullptr) session->close(); ++ ++ LOG(INFO) << "STATUS OF TRNSMIT: " << res.getExceptionCode() << " Message: " ++ << res.getMessage(); ++ if (!res.isOk()) { ++ LOG(ERROR) << "transmit error: " << res.getMessage(); ++ return false; ++ } ++ ++ return true; ++} ++ ++bool OmapiTransport::openConnection() { ++ ++ // if already conection setup done, no need to initialise it again. ++ if (isConnected()) { ++ return true; ++ } ++ ++ return initialize(); ++} ++ ++bool OmapiTransport::sendData(const vector& inData, vector& output) { ++ ++ if (!isConnected()) { ++ // Try to initialize connection to eSE ++ LOG(INFO) << "Failed to send data, try to initialize connection SE connection"; ++ if (!initialize()) { ++ LOG(ERROR) << "Failed to send data, initialization not completed"; ++ closeConnection(); ++ return false; ++ } ++ } ++ ++ if (eSEReader != nullptr) { ++ LOG(DEBUG) << "Sending apdu data to secure element: " << ESE_READER_PREFIX; ++ return internalTransmitApdu(eSEReader, inData, output); ++ } else { ++ LOG(ERROR) << "secure element reader " << ESE_READER_PREFIX << " not found"; ++ return false; ++ } ++} ++ ++bool OmapiTransport::closeConnection() { ++ LOG(DEBUG) << "Closing all connections"; ++ if (omapiSeService != nullptr) { ++ if (mVSReaders.size() > 0) { ++ for (const auto& [name, reader] : mVSReaders) { ++ reader->closeSessions(); ++ } ++ mVSReaders.clear(); ++ } ++ } ++ return true; ++} ++ ++bool OmapiTransport::isConnected() { ++ // Check already initialization completed or not ++ if (omapiSeService != nullptr && eSEReader != nullptr) { ++ LOG(DEBUG) << "Connection initialization already completed"; ++ return true; ++ } ++ ++ LOG(DEBUG) << "Connection initialization not completed"; ++ return false; ++} ++ ++} +diff --git a/HAL/OmapiTransport.h b/HAL/OmapiTransport.h +new file mode 100644 +index 0000000..f7711e7 +--- /dev/null ++++ b/HAL/OmapiTransport.h +@@ -0,0 +1,61 @@ ++#pragma once ++ ++#include "ITransport.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace keymint::javacard { ++using std::vector; ++ ++/** ++ * OmapiTransport is derived from ITransport. This class gets the OMAPI service binder instance and uses IPC to ++ * communicate with OMAPI service. OMAPI inturn communicates with hardware via ISecureElement. ++ */ ++class OmapiTransport : public ITransport { ++ ++public: ++ ++ /** ++ * Gets the binder instance of ISEService, gets the reader corresponding to secure element, establishes a session ++ * and opens a basic channel. ++ */ ++ bool openConnection() override; ++ /** ++ * Transmists the data over the opened basic channel and receives the data back. ++ */ ++ bool sendData(const vector& inData, vector& output) override; ++ ++ /** ++ * Closes the connection. ++ */ ++ bool closeConnection() override; ++ /** ++ * Returns the state of the connection status. Returns true if the connection is active, false if connection is ++ * broken. ++ */ ++ bool isConnected() override; ++ ++private: ++ std::shared_ptr omapiSeService = nullptr; ++ std::shared_ptr eSEReader = nullptr; ++ std::map> ++ mVSReaders = {}; ++ std::string const ESE_READER_PREFIX = "eSE"; ++ constexpr static const char omapiServiceName[] = ++ "android.system.omapi.ISecureElementService/default"; ++ ++ bool initialize(); ++ bool internalTransmitApdu( ++ std::shared_ptr reader, ++ std::vector apdu, std::vector& transmitResponse); ++}; ++ ++} +\ No newline at end of file +diff --git a/HAL/service.cpp b/HAL/service.cpp +index 3d51877..14580f8 100644 +--- a/HAL/service.cpp ++++ b/HAL/service.cpp +@@ -22,18 +22,24 @@ + + #include "JavacardKeyMintDevice.h" + #include +- ++#include + #include "JavacardSecureElement.h" + #include "JavacardSharedSecret.h" + #include "keymint_utils.h" + #include "JavacardRemotelyProvisionedComponentDevice.h" + #include ++#include + + using aidl::android::hardware::security::keymint::JavacardKeyMintDevice; + using aidl::android::hardware::security::keymint::JavacardSharedSecret; + using aidl::android::hardware::security::keymint::SecurityLevel; + using namespace keymint::javacard; + ++#define PROP_BUILD_QEMU "ro.kernel.qemu" ++#define PROP_BUILD_FINGERPRINT "ro.build.fingerprint" ++// Cuttlefish build fingerprint substring. ++#define CUTTLEFISH_FINGERPRINT_SS "aosp_cf_" ++ + template std::shared_ptr addService(Args&&... args) { + std::shared_ptr ser = ndk::SharedRefBase::make(std::forward(args)...); + auto instanceName = std::string(T::descriptor) + "/strongbox"; +@@ -44,11 +50,31 @@ template std::shared_ptr addService(Args&&... arg + return ser; + } + ++std::shared_ptr getTransportInstance() { ++ bool isEmulator = false; ++ // Check if the current build is for emulator or device. ++ isEmulator = android::base::GetBoolProperty(PROP_BUILD_QEMU, false); ++ if (!isEmulator) { ++ std::string fingerprint = android::base::GetProperty(PROP_BUILD_FINGERPRINT, ""); ++ if (!fingerprint.empty()) { ++ if (fingerprint.find(CUTTLEFISH_FINGERPRINT_SS, 0) != std::string::npos) { ++ isEmulator = true; ++ } ++ } ++ } ++ ++ if (!isEmulator) { ++ return std::make_shared(); ++ } else { ++ return std::make_shared(); ++ } ++} ++ + int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + // Javacard Secure Element + std::shared_ptr card = +- std::make_shared(std::make_shared(), getOsVersion(), ++ std::make_shared(getTransportInstance(), getOsVersion(), + getOsPatchlevel(), getVendorPatchlevel()); + // Add Keymint Service + addService(card); diff --git a/aosp_integration_patches/omapi_patches/packages_apps_SecureElement.patch b/aosp_integration_patches/omapi_patches/packages_apps_SecureElement.patch new file mode 100644 index 00000000..68879424 --- /dev/null +++ b/aosp_integration_patches/omapi_patches/packages_apps_SecureElement.patch @@ -0,0 +1,25 @@ +diff --git a/Android.bp b/Android.bp +index f86ad26..afea5c6 100644 +--- a/Android.bp ++++ b/Android.bp +@@ -42,6 +42,9 @@ android_app { + "src/**/*.java", + ":statslog-secure-element-java-gen", + ], ++ vintf_fragments: [ ++ "secure_element-service.xml", ++ ], + platform_apis: true, + certificate: "platform", + static_libs: ["android.hardware.secure_element-V1.0-java", +diff --git a/res/values/config.xml b/res/values/config.xml +index 5811b10..da6e50e 100644 +--- a/res/values/config.xml ++++ b/res/values/config.xml +@@ -6,5 +6,5 @@ + + +- false ++ true +