Enable Keymint HAL to SE HAL communication
This modification lets KeyMint perform
shared-secret negotiation and send root of trust via
SE HAL in case OMAPI is unavailable. KeyMint closes
the channel once shared-secret and root of trust
operations are performed to let OMAPI connect to
SE HAL.
Bug: 345692361
Test: Build ok
Change-Id: I2b377898ea979bb3744c38cb44d4814bffb08373
diff --git a/KM300/Android.bp b/KM300/Android.bp
index 1c68b01..eb60156 100644
--- a/KM300/Android.bp
+++ b/KM300/Android.bp
@@ -27,7 +27,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-// Copyright 2022-2023 NXP
+// Copyright 2022-2024 NXP
//
package {
@@ -53,6 +53,7 @@
cflags: [
"-O0",
"-DNXP_EXTNS",
+ //"-DINIT_USING_SEHAL_TRANSPORT",
],
shared_libs: [
"android.hardware.security.rkp-V3-ndk",
@@ -68,10 +69,12 @@
"liblog",
"libcrypto",
"libcutils",
+ "libutils",
"libjc_keymint_transport.nxp",
"libbinder_ndk",
"libmemunreachable",
"android.hardware.security.keymint-V3-ndk",
+ "android.hardware.secure_element-V1-ndk",
],
export_include_dirs: [
".",
@@ -115,6 +118,7 @@
"libutils",
"libhidlbase",
"android.hardware.security.keymint-V3-ndk",
+ "android.hardware.secure_element-V1-ndk",
],
srcs: [
"service.cpp",
diff --git a/KM300/JavacardKeyMintDevice.cpp b/KM300/JavacardKeyMintDevice.cpp
index d45957d..544f02a 100644
--- a/KM300/JavacardKeyMintDevice.cpp
+++ b/KM300/JavacardKeyMintDevice.cpp
@@ -14,24 +14,24 @@
* limitations under the License.
*/
/******************************************************************************
-*
-* The original Work has been changed by NXP.
-*
-* 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.
-*
-* Copyright 2022 NXP
-*
-******************************************************************************/
+ *
+ * The original Work has been changed by NXP.
+ *
+ * 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.
+ *
+ * Copyright 2022,2024 NXP
+ *
+ ******************************************************************************/
#define LOG_TAG "javacard.keymint.device.strongbox-impl"
#include "JavacardKeyMintDevice.h"
@@ -91,7 +91,6 @@
LOG(INFO) << "Returning defaultHwInfo in getHardwareInfo.";
return defaultHwInfo(info);
}
- card_->initializeJavacard();
info->keyMintName = std::move(optKeyMintName.value());
info->keyMintAuthorName = std::move(optKeyMintAuthorName.value());
info->timestampTokenRequired = (optTsRequired.value() == 1);
@@ -397,9 +396,16 @@
}
ScopedAStatus JavacardKeyMintDevice::getRootOfTrustChallenge(std::array<uint8_t, 16>* challenge) {
+#ifdef INIT_USING_SEHAL_TRANSPORT
+ auto [item, err] = card_->sendRequestSeHal(Instruction::INS_GET_ROT_CHALLENGE_CMD);
+#else
auto [item, err] = card_->sendRequest(Instruction::INS_GET_ROT_CHALLENGE_CMD);
+#endif
if (err != KM_ERROR_OK) {
LOG(ERROR) << "Error in sending in getRootOfTrustChallenge.";
+#ifdef INIT_USING_SEHAL_TRANSPORT
+ card_->closeSEHal();
+#endif
return km_utils::kmError2ScopedAStatus(err);
}
auto optChallenge = cbor_.getByteArrayVec(item, 1);
@@ -418,8 +424,16 @@
ScopedAStatus JavacardKeyMintDevice::sendRootOfTrust(const std::vector<uint8_t>& rootOfTrust) {
cppbor::Array request;
+ std::unique_ptr<Item> item;
+ keymaster_error_t err;
request.add(EncodedItem(rootOfTrust)); // taggedItem.
- auto [item, err] = card_->sendRequest(Instruction::INS_SEND_ROT_DATA_CMD, request);
+#ifdef INIT_USING_SEHAL_TRANSPORT
+ std::tie(item, err) =
+ card_->sendRequestSeHal(Instruction::INS_SEND_ROT_DATA_CMD, request.encode());
+ card_->closeSEHal();
+#else
+ std::tie(item, err) = card_->sendRequest(Instruction::INS_SEND_ROT_DATA_CMD, request.encode());
+#endif
if (err != KM_ERROR_OK) {
LOG(ERROR) << "Error in sending in sendRootOfTrust.";
return km_utils::kmError2ScopedAStatus(err);
diff --git a/KM300/JavacardKeyMintDevice.h b/KM300/JavacardKeyMintDevice.h
index 94378a1..a73dad3 100644
--- a/KM300/JavacardKeyMintDevice.h
+++ b/KM300/JavacardKeyMintDevice.h
@@ -14,24 +14,24 @@
* limitations under the License.
*/
/******************************************************************************
-*
-* The original Work has been changed by NXP.
-*
-* 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.
-*
-* Copyright 2022-2023 NXP
-*
-******************************************************************************/
+ *
+ * The original Work has been changed by NXP.
+ *
+ * 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.
+ *
+ * Copyright 2022-2024 NXP
+ *
+ ******************************************************************************/
#pragma once
#include <aidl/android/hardware/security/keymint/BnKeyMintDevice.h>
@@ -56,9 +56,7 @@
class JavacardKeyMintDevice : public BnKeyMintDevice {
public:
explicit JavacardKeyMintDevice(shared_ptr<JavacardSecureElement> card)
- : securitylevel_(SecurityLevel::STRONGBOX), card_(std::move(card)) {
- card_->initializeJavacard();
- }
+ : securitylevel_(SecurityLevel::STRONGBOX), card_(std::move(card)) {}
virtual ~JavacardKeyMintDevice() {}
// Methods from ::ndk::ICInterface follow.
diff --git a/KM300/JavacardRemotelyProvisionedComponentDevice.cpp b/KM300/JavacardRemotelyProvisionedComponentDevice.cpp
index 880f316..ba38f21 100644
--- a/KM300/JavacardRemotelyProvisionedComponentDevice.cpp
+++ b/KM300/JavacardRemotelyProvisionedComponentDevice.cpp
@@ -29,7 +29,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
**
- ** Copyright 2023 NXP
+ ** Copyright 2023,2024 NXP
**
*********************************************************************************/
#define LOG_TAG "javacard.keymint.device.rkp.strongbox-impl"
@@ -125,6 +125,7 @@
LOG(INFO) << "Returning defaultHwInfo in getHardwareInfo.";
return defaultHwInfo(info);
}
+ card_->sendPendingEvents();
info->rpcAuthorName = std::move(optRpcAuthorName.value());
info->versionNumber = static_cast<int32_t>(std::move(optVersionNumber.value()));
info->supportedEekCurve = static_cast<int32_t>(std::move(optSupportedEekCurve.value()));
@@ -138,6 +139,7 @@
if (testMode) {
return km_utils::kmError2ScopedAStatus(static_cast<keymaster_error_t>(STATUS_REMOVED));
}
+ card_->sendPendingEvents();
auto [item, err] = card_->sendRequest(Instruction::INS_GENERATE_RKP_KEY_CMD);
if (err != KM_ERROR_OK) {
LOG(ERROR) << "Error in sending generateEcdsaP256KeyPair.";
diff --git a/KM300/JavacardSecureElement.cpp b/KM300/JavacardSecureElement.cpp
index b20915f..0937e2b 100644
--- a/KM300/JavacardSecureElement.cpp
+++ b/KM300/JavacardSecureElement.cpp
@@ -44,6 +44,10 @@
#include <string>
#include <vector>
+#ifdef INIT_USING_SEHAL_TRANSPORT
+#include <HalToHalTransport.h>
+#endif
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <keymaster/android_keymaster_messages.h>
@@ -51,21 +55,22 @@
#include "keymint_utils.h"
namespace keymint::javacard {
+using ::aidl::android::hardware::security::keymint::ErrorCode;
+const std::vector<uint8_t> gStrongBoxAppletAID = {0xA0, 0x00, 0x00, 0x00, 0x62};
+
+namespace {
+keymaster_error_t aidlEnumErrorCode2km(ErrorCode err) {
+ return static_cast<keymaster_error_t>(err);
+}
+} // namespace
keymaster_error_t JavacardSecureElement::initializeJavacard() {
- keymaster_error_t ret = KM_ERROR_OK;
- if (!isCardInitialized) {
- Array request;
- request.add(Uint(getOsVersion()));
- request.add(Uint(getOsPatchlevel()));
- request.add(Uint(getVendorPatchlevel()));
- auto [item, err] = sendRequest(Instruction::INS_INIT_STRONGBOX_CMD, request);
- if (err == KM_ERROR_OK) {
- isCardInitialized = true;
- }
- ret = err;
- }
- return ret;
+ Array request;
+ request.add(Uint(getOsVersion()));
+ request.add(Uint(getOsPatchlevel()));
+ request.add(Uint(getVendorPatchlevel()));
+ auto [item, err] = sendRequest(Instruction::INS_INIT_STRONGBOX_CMD, request);
+ return err;
}
void JavacardSecureElement::setDeleteAllKeysPending() {
@@ -75,26 +80,34 @@
isEarlyBootEndedPending = true;
}
void JavacardSecureElement::sendPendingEvents() {
+ if (isCardInitPending) {
+ if (KM_ERROR_OK == initializeJavacard()) {
+ isCardInitPending = false;
+ } else {
+ LOG(ERROR) << "Error in sending system properties(OS_VERSION, OS_PATCH, VENDOR_PATCH).";
+ }
+ }
+
if (isDeleteAllKeysPending) {
- auto [_, err] = sendRequest(Instruction::INS_DELETE_ALL_KEYS_CMD);
- if (err == KM_ERROR_OK) {
- isDeleteAllKeysPending = false;
- } else {
- LOG(ERROR) << "Error in sending deleteAllKeys.";
- }
+ auto [_, err] = sendRequest(Instruction::INS_DELETE_ALL_KEYS_CMD);
+ if (err == KM_ERROR_OK) {
+ isDeleteAllKeysPending = false;
+ } else {
+ LOG(ERROR) << "Error in sending deleteAllKeys.";
+ }
}
if (isEarlyBootEndedPending) {
- auto [_, err] = sendRequest(Instruction::INS_EARLY_BOOT_ENDED_CMD);
- if (err == KM_ERROR_OK) {
- isEarlyBootEndedPending = false;
- } else {
- LOG(ERROR) << "Error in sending earlyBootEnded.";
- }
+ auto [_, err] = sendRequest(Instruction::INS_EARLY_BOOT_ENDED_CMD);
+ if (err == KM_ERROR_OK) {
+ isEarlyBootEndedPending = false;
+ } else {
+ LOG(ERROR) << "Error in sending earlyBootEnded.";
+ }
}
}
keymaster_error_t JavacardSecureElement::constructApduMessage(Instruction& ins,
- std::vector<uint8_t>& inputData,
+ const std::vector<uint8_t>& inputData,
std::vector<uint8_t>& apduOut) {
apduOut.push_back(static_cast<uint8_t>(APDU_CLS)); // CLS
apduOut.push_back(static_cast<uint8_t>(ins)); // INS
@@ -124,7 +137,9 @@
return (KM_ERROR_OK); // success
}
-keymaster_error_t JavacardSecureElement::sendData(Instruction ins, std::vector<uint8_t>& inData,
+keymaster_error_t JavacardSecureElement::sendData(const std::shared_ptr<ITransport>& transport,
+ Instruction ins,
+ const std::vector<uint8_t>& inData,
std::vector<uint8_t>& response) {
keymaster_error_t ret = KM_ERROR_UNKNOWN_ERROR;
std::vector<uint8_t> apdu;
@@ -135,7 +150,7 @@
return ret;
}
- if (!transport_->sendData(apdu, response) && (response.size() < 2)) {
+ if (!transport->sendData(apdu, response) && (response.size() < 2)) {
LOG(ERROR) << "Error in sending C-APDU";
return (KM_ERROR_SECURE_HW_COMMUNICATION_FAILED);
}
@@ -152,35 +167,78 @@
return (KM_ERROR_OK); // success
}
-std::tuple<std::unique_ptr<Item>, keymaster_error_t>
-JavacardSecureElement::sendRequest(Instruction ins, Array& request) {
- vector<uint8_t> response;
- // encode request
- std::vector<uint8_t> command = request.encode();
- auto sendError = sendData(ins, command, response);
- if (sendError != KM_ERROR_OK) {
- return {unique_ptr<Item>(nullptr), sendError};
- }
- // decode the response and send that back
- return cbor_.decodeData(response);
+keymaster_error_t JavacardSecureElement::sendData(Instruction ins,
+ const std::vector<uint8_t>& inData,
+ std::vector<uint8_t>& response) {
+ return sendData(transport_, ins, inData, response);
}
-std::tuple<std::unique_ptr<Item>, keymaster_error_t>
-JavacardSecureElement::sendRequest(Instruction ins, std::vector<uint8_t>& command) {
- vector<uint8_t> response;
- auto sendError = sendData(ins, command, response);
- if (sendError != KM_ERROR_OK) {
- return {unique_ptr<Item>(nullptr), sendError};
- }
- // decode the response and send that back
- return cbor_.decodeData(response);
+std::tuple<std::unique_ptr<Item>, keymaster_error_t> JavacardSecureElement::sendRequest(
+ Instruction ins, const Array& request) {
+ return sendRequest(transport_, ins, request.encode());
}
-std::tuple<std::unique_ptr<Item>, keymaster_error_t>
-JavacardSecureElement::sendRequest(Instruction ins) {
+std::tuple<std::unique_ptr<Item>, keymaster_error_t> JavacardSecureElement::sendRequest(
+ Instruction ins, const std::vector<uint8_t>& command) {
+ return sendRequest(transport_, ins, command);
+}
+
+std::tuple<std::unique_ptr<Item>, keymaster_error_t> JavacardSecureElement::sendRequest(
+ Instruction ins) {
+ return sendRequest(transport_, ins, std::vector<uint8_t>());
+}
+#ifdef INIT_USING_SEHAL_TRANSPORT
+bool JavacardSecureElement::initSEHal() {
+ if (seHalTransport == nullptr) {
+ seHalTransport = std::make_shared<HalToHalTransport>(gStrongBoxAppletAID);
+ }
+ return seHalTransport->openConnection();
+}
+
+bool JavacardSecureElement::closeSEHal() {
+ bool ret = true;
+ if (seHalTransport != nullptr) {
+ ret = seHalTransport->closeConnection();
+ if (!ret) {
+ LOG(INFO) << "Failed to close SE Hal.";
+ }
+ seHalTransport = nullptr;
+ }
+ return ret;
+}
+#endif
+std::tuple<std::unique_ptr<Item>, keymaster_error_t> JavacardSecureElement::sendRequestSeHal(
+ Instruction ins, const std::vector<uint8_t>& command) {
+ if (seHalTransport != nullptr) {
+ return sendRequest(seHalTransport, ins, command);
+ } else {
+ auto [item, err] = sendRequest(ins, command);
+ if (err != KM_ERROR_OK) {
+#ifdef INIT_USING_SEHAL_TRANSPORT
+ if (err == aidlEnumErrorCode2km(ErrorCode::SECURE_HW_COMMUNICATION_FAILED)) {
+ LOG(DEBUG) << "OMAPI is not yet available. Send INS: " << static_cast<int>(ins)
+ << " via SE Hal.";
+ if (initSEHal()) {
+ return sendRequest(seHalTransport, ins, command);
+ }
+ LOG(ERROR) << "Failed to initialize SE HAL";
+ }
+#endif
+ }
+ return {std::move(item), std::move(err)};
+ }
+}
+
+std::tuple<std::unique_ptr<Item>, keymaster_error_t> JavacardSecureElement::sendRequestSeHal(
+ Instruction ins) {
+ return sendRequestSeHal(ins, std::vector<uint8_t>());
+}
+
+std::tuple<std::unique_ptr<Item>, keymaster_error_t> JavacardSecureElement::sendRequest(
+ const std::shared_ptr<ITransport>& transport, Instruction ins,
+ const std::vector<uint8_t>& command) {
vector<uint8_t> response;
- vector<uint8_t> emptyRequest;
- auto sendError = sendData(ins, emptyRequest, response);
+ auto sendError = sendData(transport, ins, command, response);
if (sendError != KM_ERROR_OK) {
return {unique_ptr<Item>(nullptr), sendError};
}
diff --git a/KM300/JavacardSecureElement.h b/KM300/JavacardSecureElement.h
index 5ccbbc3..63975a1 100644
--- a/KM300/JavacardSecureElement.h
+++ b/KM300/JavacardSecureElement.h
@@ -78,7 +78,7 @@
INS_UPDATE_AAD_OPERATION_CMD = KEYMINT_CMD_APDU_START + 23,
INS_BEGIN_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 24,
INS_FINISH_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 25,
- //INS_INIT_STRONGBOX_CMD = KEYMINT_CMD_APDU_START + 26,
+ // INS_INIT_STRONGBOX_CMD = KEYMINT_CMD_APDU_START + 26,
INS_INIT_STRONGBOX_CMD = KEYMINT_VENDOR_CMD_APDU_START + 9,
// RKP Commands
INS_GET_RKP_HARDWARE_INFO = KEYMINT_CMD_APDU_START + 27,
@@ -103,22 +103,29 @@
class JavacardSecureElement {
public:
explicit JavacardSecureElement(shared_ptr<ITransport> transport)
- : transport_(std::move(transport)), isEarlyBootEndedPending(false),
- isDeleteAllKeysPending(false), isCardInitialized(false) {
- transport_->openConnection();
+ : transport_(std::move(transport)),
+ isEarlyBootEndedPending(false),
+ isDeleteAllKeysPending(false),
+ isCardInitPending(true) {
+ transport_->openConnection();
}
virtual ~JavacardSecureElement() { transport_->closeConnection(); }
std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins,
- Array& request);
+ const Array& request);
std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins);
- std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins,
- std::vector<uint8_t>& command);
+ std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(
+ Instruction ins, const std::vector<uint8_t>& command);
- keymaster_error_t sendData(Instruction ins, std::vector<uint8_t>& inData,
+ std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequestSeHal(
+ Instruction ins, const std::vector<uint8_t>& command);
+ std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequestSeHal(Instruction ins);
+
+ bool closeSEHal();
+
+ keymaster_error_t sendData(Instruction ins, const std::vector<uint8_t>& inData,
std::vector<uint8_t>& response);
-
- keymaster_error_t constructApduMessage(Instruction& ins, std::vector<uint8_t>& inputData,
+ keymaster_error_t constructApduMessage(Instruction& ins, const std::vector<uint8_t>& inputData,
std::vector<uint8_t>& apduOut);
keymaster_error_t initializeJavacard();
void sendPendingEvents();
@@ -135,10 +142,17 @@
}
private:
+ bool initSEHal();
+ keymaster_error_t sendData(const std::shared_ptr<ITransport>& transport, Instruction ins,
+ const std::vector<uint8_t>& inData, std::vector<uint8_t>& response);
+ std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(
+ const std::shared_ptr<ITransport>& transport, Instruction ins,
+ const std::vector<uint8_t>& command);
shared_ptr<ITransport> transport_;
+ shared_ptr<ITransport> seHalTransport;
bool isEarlyBootEndedPending;
bool isDeleteAllKeysPending;
- bool isCardInitialized;
+ bool isCardInitPending;
CborConverter cbor_;
};
} // namespace keymint::javacard
diff --git a/KM300/JavacardSharedSecret.cpp b/KM300/JavacardSharedSecret.cpp
index aa03673..4473d2a 100644
--- a/KM300/JavacardSharedSecret.cpp
+++ b/KM300/JavacardSharedSecret.cpp
@@ -36,11 +36,11 @@
static uint8_t getSharedSecretRetryCount = 0x00;
ScopedAStatus JavacardSharedSecret::getSharedSecretParameters(SharedSecretParameters* params) {
- auto error = card_->initializeJavacard();
- if (error != KM_ERROR_OK) {
- LOG(ERROR) << "Error in initializing javacard.";
- }
+#ifdef INIT_USING_SEHAL_TRANSPORT
+ auto [item, err] = card_->sendRequestSeHal(Instruction::INS_GET_SHARED_SECRET_PARAM_CMD);
+#else
auto [item, err] = card_->sendRequest(Instruction::INS_GET_SHARED_SECRET_PARAM_CMD);
+#endif
#ifdef NXP_EXTNS
if (err == KM_ERROR_SECURE_HW_COMMUNICATION_FAILED &&
(getSharedSecretRetryCount < MAX_SHARED_SECRET_RETRY_COUNT)) {
@@ -69,17 +69,17 @@
return ScopedAStatus::ok();
}
-ScopedAStatus
-JavacardSharedSecret::computeSharedSecret(const std::vector<SharedSecretParameters>& params,
- std::vector<uint8_t>* secret) {
- card_->sendPendingEvents();
- auto error = card_->initializeJavacard();
- if (error != KM_ERROR_OK) {
- LOG(ERROR) << "Error in initializing javacard.";
- }
+ScopedAStatus JavacardSharedSecret::computeSharedSecret(
+ const std::vector<SharedSecretParameters>& params, std::vector<uint8_t>* secret) {
cppbor::Array request;
cbor_.addSharedSecretParameters(request, params);
- auto [item, err] = card_->sendRequest(Instruction::INS_COMPUTE_SHARED_SECRET_CMD, request);
+#ifdef INIT_USING_SEHAL_TRANSPORT
+ auto [item, err] =
+ card_->sendRequestSeHal(Instruction::INS_COMPUTE_SHARED_SECRET_CMD, request.encode());
+#else
+ auto [item, err] =
+ card_->sendRequest(Instruction::INS_COMPUTE_SHARED_SECRET_CMD, request.encode());
+#endif
if (err != KM_ERROR_OK) {
LOG(ERROR) << "Error in sending in computeSharedSecret.";
return keymint::km_utils::kmError2ScopedAStatus(err);
diff --git a/KM300/service.cpp b/KM300/service.cpp
index 35dff1e..f424da0 100644
--- a/KM300/service.cpp
+++ b/KM300/service.cpp
@@ -29,7 +29,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
**
- ** Copyright 2020-2023 NXP
+ ** Copyright 2020-2024 NXP
**
*********************************************************************************/
#define LOG_TAG "javacard.strongbox-service"
@@ -65,6 +65,7 @@
#if defined OMAPI_TRANSPORT
using keymint::javacard::OmapiTransport;
#elif defined HAL_TO_HAL_TRANSPORT
+using keymint::javacard::HalToHalTransport;
#else
using keymint::javacard::SocketTransport;
#endif
diff --git a/transport/Android.bp b/transport/Android.bp
index 3c779d5..58ce80a 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -50,16 +50,9 @@
export_include_dirs: [
"include"
],
- export_shared_lib_headers: [
- "android.hardware.secure_element@1.0",
- "android.hardware.secure_element@1.1",
- "android.hardware.secure_element@1.2",
- ],
shared_libs: [
- "android.hardware.secure_element@1.0",
- "android.hardware.secure_element@1.1",
- "android.hardware.secure_element@1.2",
"android.se.omapi-V1-ndk",
+ "android.hardware.secure_element-V1-ndk",
"libbase",
"liblog",
"libcutils",
diff --git a/transport/AppletConnection.cpp b/transport/AppletConnection.cpp
index 510ed71..97eee57 100644
--- a/transport/AppletConnection.cpp
+++ b/transport/AppletConnection.cpp
@@ -30,14 +30,14 @@
** See the License for the specific language governing permissions and
** limitations under the License.
**
- ** Copyright 2020-2021 NXP
+ ** Copyright 2020-2021,2024 NXP
**
*********************************************************************************/
-#define LOG_TAG "OmapiTransport"
+#define LOG_TAG "AppletConnection"
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
-#include <log/log.h>
+#include <android/binder_manager.h>
#include <signal.h>
#include <iomanip>
#include <mutex>
@@ -48,100 +48,117 @@
#include <EseTransportUtils.h>
#include <SignalHandler.h>
-using ::android::hardware::secure_element::V1_0::SecureElementStatus;
-using ::android::hardware::secure_element::V1_0::LogicalChannelResponse;
+using aidl::android::hardware::secure_element::BnSecureElementCallback;
+using aidl::android::hardware::secure_element::ISecureElement;
+using aidl::android::hardware::secure_element::LogicalChannelResponse;
using android::base::StringPrintf;
+using ndk::ScopedAStatus;
+using ndk::SharedRefBase;
+using ndk::SpAIBinder;
namespace keymint::javacard {
static bool isStrongBox = false; // true when linked with StrongBox HAL process
const std::vector<uint8_t> kStrongBoxAppletAID = {0xA0, 0x00, 0x00, 0x00, 0x62};
+constexpr const char eseHalServiceName[] = "android.hardware.secure_element.ISecureElement/eSE1";
-class SecureElementCallback : public ISecureElementHalCallback {
- public:
- Return<void> onStateChange(bool state) override {
- mSEClientState = state;
- return Void();
+class SecureElementCallback : public BnSecureElementCallback {
+ public:
+ ScopedAStatus onStateChange(bool state, const std::string& in_debugReason) override {
+ LOGD_OMAPI("connected =" << (state ? "true " : "false ") << "reason: " << in_debugReason);
+ mConnState = state;
+ return ScopedAStatus::ok();
};
- Return<void> onStateChange_1_1(bool state, const hidl_string& reason) override {
- LOGD_OMAPI("connected =" << (state?"true " : "false " ) << "reason: " << reason);
- mSEClientState = state;
- return Void();
- };
- bool isClientConnected() {
- return mSEClientState;
- }
- private:
- bool mSEClientState = false;
+ bool isClientConnected() { return mConnState; }
+
+ private:
+ bool mConnState = false;
};
-sp<SecureElementCallback> mCallback = nullptr;
+void AppletConnection::BinderDiedCallback(void* cookie) {
+ LOG(ERROR) << "Received binder death ntf. SE HAL Service died";
+ auto thiz = static_cast<AppletConnection*>(cookie);
+ thiz->mSecureElementCallback->onStateChange(false, "SE HAL died");
+ thiz->mSecureElement = nullptr;
+}
-class SEDeathRecipient : public android::hardware::hidl_death_recipient {
- virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
- LOG(ERROR) << "Secure Element Service died disconnecting SE HAL .....";
- if(mCallback != nullptr) {
- LOG(INFO) << "Changing state to disconnect ...";
- mCallback->onStateChange(false);// Change state to disconnect
- }
- }
-};
-
-sp<SEDeathRecipient> mSEDeathRecipient = nullptr;
-
-AppletConnection::AppletConnection(const std::vector<uint8_t>& aid) : kAppletAID(aid) {
+AppletConnection::AppletConnection(const std::vector<uint8_t>& aid)
+ : kAppletAID(aid), mSBAccessController(SBAccessController::getInstance()) {
if (kAppletAID == kStrongBoxAppletAID) {
isStrongBox = true;
}
+ mDeathRecipient =
+ ::ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback));
}
bool AppletConnection::connectToSEService() {
if (!SignalHandler::getInstance()->isHandlerRegistered()) {
- LOG(INFO) << "register signal handler";
+ LOG(DEBUG) << "register signal handler";
SignalHandler::getInstance()->installHandler(this);
}
- if (mSEClient != nullptr && mCallback->isClientConnected()) {
+ if (mSecureElement != nullptr && mSecureElementCallback->isClientConnected()) {
LOG(INFO) <<"Already connected";
return true;
}
-
- uint8_t retry = 0;
- bool status = false;
- while (( mSEClient == nullptr ) && retry++ < MAX_GET_SERVICE_RETRY ){ // How long should we try before giving up !
- mSEClient = ISecureElement::tryGetService("eSE1");
-
- if(mSEClient == nullptr){
- LOG(ERROR) << "failed to get eSE HAL service : retry after 1 sec , retry cnt = " << android::hardware::toString(retry) ;
- }else {
- LOG(INFO) << " !!! SuccessFully got Handle to eSE HAL service" ;
- if (mCallback == nullptr) {
- mCallback = new SecureElementCallback();
+ bool connected = false;
+ SpAIBinder binder = SpAIBinder(AServiceManager_waitForService(eseHalServiceName));
+ mSecureElement = ISecureElement::fromBinder(binder);
+ if (mSecureElement == nullptr) {
+ LOG(ERROR) << "Failed to connect to Secure element service";
+ } else {
+ mSecureElementCallback = SharedRefBase::make<SecureElementCallback>();
+ auto status = mSecureElement->init(mSecureElementCallback);
+ connected = status.isOk() && mSecureElementCallback->isClientConnected();
+ if (!connected) {
+ LOG(ERROR) << "Failed to initialize SE HAL service";
}
- mSEDeathRecipient = new SEDeathRecipient();
- mSEClient->init_1_1(mCallback);
- mSEClient->linkToDeath(mSEDeathRecipient, 0/*cookie*/);
- status = mCallback->isClientConnected();
- break;
- }
- usleep(ONE_SEC);
}
- return status;
+ return connected;
}
+// AIDL Hal returns empty response for failure case
+// so prepare response based on service specific errorcode
+void prepareServiceSpecificErrorRepsponse(std::vector<uint8_t>& resp, int32_t errorCode) {
+ resp.clear();
+ switch (errorCode) {
+ case ISecureElement::NO_SUCH_ELEMENT_ERROR:
+ resp.push_back(0x6A);
+ resp.push_back(0x82);
+ break;
+ case ISecureElement::CHANNEL_NOT_AVAILABLE:
+ resp.push_back(0x6A);
+ resp.push_back(0x81);
+ break;
+ case ISecureElement::UNSUPPORTED_OPERATION:
+ resp.push_back(0x6A);
+ resp.push_back(0x86);
+ break;
+ case ISecureElement::IOERROR:
+ resp.push_back(0x64);
+ resp.push_back(0xFF);
+ break;
+ default:
+ resp.push_back(0xFF);
+ resp.push_back(0xFF);
+ }
+}
bool AppletConnection::selectApplet(std::vector<uint8_t>& resp, uint8_t p2) {
bool stat = false;
- mSEClient->openLogicalChannel(
- kAppletAID, p2, [&](LogicalChannelResponse selectResponse, SecureElementStatus status) {
- if (status == SecureElementStatus::SUCCESS) {
- resp = selectResponse.selectResponse;
- mOpenChannel = selectResponse.channelNumber;
- stat = true;
- mSBAccessController.parseResponse(resp);
- LOG(INFO) << "openLogicalChannel:" << toString(status) << " channelNumber ="
- << ::android::hardware::toString(selectResponse.channelNumber) << " "
- << selectResponse.selectResponse;
- }
- });
+ resp.clear();
+ LogicalChannelResponse logical_channel_response;
+ auto status = mSecureElement->openLogicalChannel(kAppletAID, p2, &logical_channel_response);
+ if (status.isOk()) {
+ mOpenChannel = logical_channel_response.channelNumber;
+ resp = logical_channel_response.selectResponse;
+ stat = true;
+ } else {
+ mOpenChannel = -1;
+ resp = logical_channel_response.selectResponse;
+ LOG(ERROR) << "openLogicalChannel: Failed ";
+ // AIDL Hal returns empty response for failure case
+ // so prepare response based on service specific errorcode
+ prepareServiceSpecificErrorRepsponse(resp, status.getServiceSpecificError());
+ }
return stat;
}
void prepareErrorRepsponse(std::vector<uint8_t>& resp){
@@ -152,14 +169,6 @@
bool AppletConnection::openChannelToApplet(std::vector<uint8_t>& resp) {
bool ret = false;
uint8_t retry = 0;
- if (mCallback == nullptr || !mCallback->isClientConnected()) {
- mSEClient = nullptr;
- mOpenChannel = -1;
- if (!connectToSEService()) {
- LOG(ERROR) << "Not connected to eSE Service";
- return ret;
- }
- }
if (isChannelOpen()) {
LOG(INFO) << "channel Already opened";
return true;
@@ -180,16 +189,15 @@
} else {
ret = selectApplet(resp, 0x0);
}
-
return ret;
}
bool AppletConnection::transmit(std::vector<uint8_t>& CommandApdu , std::vector<uint8_t>& output){
- hidl_vec<uint8_t> cmd = CommandApdu;
+ std::vector<uint8_t> cmd = CommandApdu;
cmd[0] |= mOpenChannel ;
- LOGD_OMAPI("Channel number " << ::android::hardware::toString(mOpenChannel));
+ LOGD_OMAPI("Channel number: " << static_cast<int>(mOpenChannel));
- if (mSEClient == nullptr) return false;
+ if (mSecureElement == nullptr) return false;
if (isStrongBox) {
if (!mSBAccessController.isOperationAllowed(CommandApdu[APDU_INS_OFFSET])) {
std::vector<uint8_t> ins;
@@ -201,12 +209,9 @@
}
// block any fatal signal delivery
SignalHandler::getInstance()->blockSignals();
-
- mSEClient->transmit(cmd, [&](hidl_vec<uint8_t> result) {
- output = result;
- LOG(INFO) << "received response size = " << ::android::hardware::toString(result.size()) << " data = " << result;
- });
-
+ std::vector<uint8_t> response;
+ mSecureElement->transmit(cmd, &response);
+ output = response;
// un-block signal delivery
SignalHandler::getInstance()->unblockSignals();
return true;
@@ -218,16 +223,16 @@
bool AppletConnection::close() {
std::lock_guard<std::mutex> lock(channel_mutex_);
- if (mSEClient == nullptr) {
- LOG(ERROR) << "Channel couldn't be closed mSEClient handle is null";
- return false;
+ if (mSecureElement == nullptr) {
+ LOG(ERROR) << "Channel couldn't be closed mSEClient handle is null";
+ return false;
}
if(mOpenChannel < 0){
LOG(INFO) << "Channel is already closed";
return true;
}
- SecureElementStatus status = mSEClient->closeChannel(mOpenChannel);
- if (status != SecureElementStatus::SUCCESS) {
+ auto status = mSecureElement->closeChannel(mOpenChannel);
+ if (!status.isOk()) {
/*
* reason could be SE reset or HAL deinit triggered from other client
* which anyway closes all the opened channels
@@ -241,12 +246,16 @@
return true;
}
-bool AppletConnection::isChannelOpen() {
+bool AppletConnection::isServiceConnected() {
std::lock_guard<std::mutex> lock(channel_mutex_);
- if(mCallback == nullptr || !mCallback->isClientConnected()) {
- return false;
+ if (mSecureElement == nullptr || !mSecureElementCallback->isClientConnected()) {
+ return false;
}
- return mOpenChannel >= 0;
+ return true;
}
+bool AppletConnection::isChannelOpen() {
+ std::lock_guard<std::mutex> lock(channel_mutex_);
+ return mOpenChannel >= 0;
+}
} // namespace keymint::javacard
diff --git a/transport/HalToHalTransport.cpp b/transport/HalToHalTransport.cpp
index 0d0ebd4..33f1c39 100644
--- a/transport/HalToHalTransport.cpp
+++ b/transport/HalToHalTransport.cpp
@@ -30,7 +30,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
**
- ** Copyright 2020-2021, 2023 NXP
+ ** Copyright 2020-2021, 2023-2024 NXP
**
*********************************************************************************/
#define LOG_TAG "HalToHalTransport"
@@ -57,27 +57,30 @@
}
bool HalToHalTransport::sendData(const vector<uint8_t>& inData, vector<uint8_t>& output) {
- bool status = false;
std::vector<uint8_t> cApdu(inData);
#ifdef INTERVAL_TIMER
LOGD_OMAPI("stop the timer");
mTimer.kill();
#endif
if (!isConnected()) {
- std::vector<uint8_t> selectResponse;
- status = mAppletConnection.openChannelToApplet(selectResponse);
- if (!status) {
- LOG(ERROR) << " Failed to open Logical Channel ,response " << selectResponse;
- output = std::move(selectResponse);
- return status;
+ if (!openConnection()) {
+ return false;
}
}
+ std::vector<uint8_t> selectResponse;
+ bool status = mAppletConnection.openChannelToApplet(selectResponse);
+ if (!status) {
+ LOG(ERROR) << " Failed to open Logical Channel ,response " << selectResponse;
+ output = std::move(selectResponse);
+ return false;
+ }
status = mAppletConnection.transmit(cApdu, output);
if (output.size() < 2 ||
(output.size() >= 2 && (output.at(output.size() - 2) == LOGICAL_CH_NOT_SUPPORTED_SW1 &&
output.at(output.size() - 1) == LOGICAL_CH_NOT_SUPPORTED_SW2))) {
LOGD_OMAPI("transmit failed ,close the channel");
- return mAppletConnection.close();
+ mAppletConnection.close();
+ return false;
}
#ifdef INTERVAL_TIMER
int timeout = mAppletConnection.getSessionTimeout();
@@ -88,7 +91,7 @@
mTimer.set(mAppletConnection.getSessionTimeout(), this, SessionTimerFunc);
}
#endif
- return status;
+ return true;
}
bool HalToHalTransport::closeConnection() {
@@ -96,6 +99,6 @@
}
bool HalToHalTransport::isConnected() {
- return mAppletConnection.isChannelOpen();
+ return mAppletConnection.isServiceConnected();
}
} // namespace keymint::javacard
diff --git a/transport/OmapiTransport.cpp b/transport/OmapiTransport.cpp
index 3dc4b31..530cfc2 100644
--- a/transport/OmapiTransport.cpp
+++ b/transport/OmapiTransport.cpp
@@ -287,9 +287,9 @@
#endif
if (!isConnected()) {
// Try to initialize connection to eSE
- LOG(INFO) << "Failed to send data, try to initialize connection SE connection";
+ LOG(INFO) << "Not connected, try to initialize connection to OMAPI";
if (!initialize()) {
- LOG(ERROR) << "Failed to send data, initialization not completed";
+ LOG(ERROR) << "Failed to connect to OMAPI";
closeConnection();
return false;
}
@@ -420,6 +420,7 @@
}
if (channel == nullptr) {
LOG(ERROR) << "Could not open channel null";
+ prepareErrorRepsponse(transmitResponse);
return false;
}
@@ -440,14 +441,12 @@
}
}
- status = false;
if (!isSBAppletAID ||
mSBAccessController.isOperationAllowed(apdu[APDU_INS_OFFSET])) {
#ifdef ENABLE_DEBUG_LOG
LOGD_OMAPI("constructed apdu: " << apdu);
#endif
res = channel->transmit(apdu, &transmitResponse);
- status = true;
} else {
LOG(ERROR) << "command Ins:" << apdu[APDU_INS_OFFSET] << " not allowed";
prepareErrorRepsponse(transmitResponse);
@@ -483,7 +482,7 @@
LOG(ERROR) << "transmit error: " << res.getMessage();
return false;
}
- return status;
+ return true;
}
void OmapiTransport::prepareErrorRepsponse(std::vector<uint8_t>& resp){
diff --git a/transport/SBAccessController.cpp b/transport/SBAccessController.cpp
index 7a3cc6d..7ccefe8 100644
--- a/transport/SBAccessController.cpp
+++ b/transport/SBAccessController.cpp
@@ -35,9 +35,9 @@
// These should be in sync with JavacardKeymasterDevice41.cpp
// Allow listed cmds
-std::map<uint8_t, uint8_t> allowedCmdIns = {{0xD9 /*INS_SET_VERSION_PATCHLEVEL*/, 0},
+std::map<uint8_t, uint8_t> allowedCmdIns = {{0x2D /*INS_GET_HMAC_SHARING_PARAM*/, 0},
{0x2A /*INS_COMPUTE_SHARED_HMAC*/, 0},
- {0x2D /*INS_GET_HMAC_SHARING_PARAM*/, 0}};
+ {0x4D /*INS_GET_ROT_CHALLENGE_CMD*/, 0}};
static void CryptoOpTimerFunc(union sigval arg) {
(void)arg; // unused
@@ -50,7 +50,10 @@
LOG(DEBUG) << "Applet access-block timer expired";
g_AccessAllowed = true;
}
-
+SBAccessController& SBAccessController::getInstance() {
+ static SBAccessController sb_access_cntrl;
+ return sb_access_cntrl;
+}
void SBAccessController::startTimer(bool isStart, IntervalTimer& t, int timeout,
void (*timerFunc)(union sigval)) {
t.kill();
@@ -145,8 +148,8 @@
break;
}
}
- if (cmdIns == EARLY_BOOT_ENDED_CMD) {
- // allowed as this is sent by VOLD only during early boot
+ if (cmdIns == EARLY_BOOT_ENDED_CMD || cmdIns == INS_SEND_ROT_DATA_CMD) {
+ // allowed as these may be received during early boot
op_allowed = true;
}
return op_allowed;
diff --git a/transport/include/AppletConnection.h b/transport/include/AppletConnection.h
index c224c18..ef79c99 100644
--- a/transport/include/AppletConnection.h
+++ b/transport/include/AppletConnection.h
@@ -30,32 +30,21 @@
** See the License for the specific language governing permissions and
** limitations under the License.
**
- ** Copyright 2020-2021 NXP
+ ** Copyright 2020-2021,2024 NXP
**
*********************************************************************************/
#ifndef __APPLETCONNECTION_H__
#define __APPLETCONNECTION_H__
-#include <android/hardware/secure_element/1.0/types.h>
-#include <android/hardware/secure_element/1.1/ISecureElementHalCallback.h>
-#include <android/hardware/secure_element/1.2/ISecureElement.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
+#include <aidl/android/hardware/secure_element/BnSecureElementCallback.h>
+#include <aidl/android/hardware/secure_element/ISecureElement.h>
#include <vector>
#include <SBAccessController.h>
namespace keymint::javacard {
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-using ::android::hardware::secure_element::V1_2::ISecureElement;
-using ::android::hardware::secure_element::V1_1::ISecureElementHalCallback;
+class SecureElementCallback;
+using aidl::android::hardware::secure_element::ISecureElement;
struct AppletConnection {
public:
@@ -87,6 +76,11 @@
* Checks if a channel to the applet is open.
*/
bool isChannelOpen();
+
+ /**
+ * Checks if service is connected to eSE HAL.
+ */
+ bool isServiceConnected();
/**
* Get session timeout value based on select response normal/update session
*/
@@ -99,10 +93,14 @@
bool selectApplet(std::vector<uint8_t>& resp, uint8_t p2);
std::mutex channel_mutex_; // exclusive access to isChannelopen()/close()
- sp<ISecureElement> mSEClient;
+
+ std::shared_ptr<ISecureElement> mSecureElement;
+ std::shared_ptr<SecureElementCallback> mSecureElementCallback;
+ ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+ static void BinderDiedCallback(void* cookie);
std::vector<uint8_t> kAppletAID;
int8_t mOpenChannel = -1;
- SBAccessController mSBAccessController;
+ SBAccessController& mSBAccessController;
};
} // namespace keymint::javacard
diff --git a/transport/include/OmapiTransport.h b/transport/include/OmapiTransport.h
index d10463a..c8615c4 100644
--- a/transport/include/OmapiTransport.h
+++ b/transport/include/OmapiTransport.h
@@ -47,11 +47,10 @@
#include <map>
-#include "ITransport.h"
-#include <AppletConnection.h>
#include <IntervalTimer.h>
#include <memory>
#include <vector>
+#include "ITransport.h"
#include <SBAccessController.h>
@@ -121,7 +120,7 @@
private:
//AppletConnection mAppletConnection;
- SBAccessController mSBAccessController;
+ SBAccessController& mSBAccessController;
IntervalTimer mTimer;
int mTimeout;
std::vector<uint8_t> mSelectableAid;
@@ -135,10 +134,16 @@
/* Applet ID Weaver */
const std::vector<uint8_t> kWeaverAID = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x10, 0x10};
#endif
- OmapiTransport(const std::vector<uint8_t> &mAppletAID)
- : ITransport(mAppletAID), mTimeout(0), mSelectableAid(mAppletAID),
- omapiSeService(nullptr), eSEReader(nullptr), session(nullptr),
- channel(nullptr), mVSReaders({}) {
+ OmapiTransport(const std::vector<uint8_t>& mAppletAID)
+ : ITransport(mAppletAID),
+ mSBAccessController(SBAccessController::getInstance()),
+ mTimeout(0),
+ mSelectableAid(mAppletAID),
+ omapiSeService(nullptr),
+ eSEReader(nullptr),
+ session(nullptr),
+ channel(nullptr),
+ mVSReaders({}) {
#ifdef NXP_EXTNS
mDeathRecipient = ::ndk::ScopedAIBinder_DeathRecipient(
AIBinder_DeathRecipient_new(BinderDiedCallback));
diff --git a/transport/include/SBAccessController.h b/transport/include/SBAccessController.h
index 901b3d7..9067c7b 100644
--- a/transport/include/SBAccessController.h
+++ b/transport/include/SBAccessController.h
@@ -22,6 +22,7 @@
#include <vector>
#define EARLY_BOOT_ENDED_CMD (0x35) // INS Received from VOLD when earlyboot state ends
+#define INS_SEND_ROT_DATA_CMD (0x4F) // Google defined RoT cmd
#define BEGIN_OPERATION_CMD (0x30) // begin()
#define FINISH_OPERATION_CMD (0x32) // finish()
#define ABORT_OPERATION_CMD (0x33) // abort()
@@ -50,11 +51,6 @@
class SBAccessController {
public:
/**
- * Constructor
- */
- SBAccessController() : mIsUpdateInProgress(false), mBootState(SB_EARLY_BOOT) {}
-
- /**
* Controls Applet selection
* 1) Not allowed when actual upgrade is in progress for 40 secs
* 2) Only allowed for allow listed cmds during early boot in upgrade teared case
@@ -103,7 +99,17 @@
*/
void updateBootState();
+ /**
+ * Helper function to get singleton instance
+ * Params: void
+ * Returns: Instance of SBAccessController
+ */
+ static SBAccessController& getInstance();
+ SBAccessController(const SBAccessController&) = delete;
+
private:
+ // mark constructor private
+ SBAccessController() : mIsUpdateInProgress(false), mBootState(SB_EARLY_BOOT) {}
bool mIsUpdateInProgress; // stores Applet upgrade state
BOOTSTATE mBootState;