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;