Merge "secure-element to AIDL"

This commit is contained in:
Steven Moreland 2022-11-29 22:30:40 +00:00 committed by Gerrit Code Review
commit 40e84d92e0
13 changed files with 722 additions and 0 deletions

View file

@ -608,6 +608,15 @@
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.secure_element</name>
<version>1</version>
<interface>
<name>ISecureElement</name>
<regex-instance>eSE[1-9][0-9]*</regex-instance>
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.security.secureclock</name>
<version>1</version>

View file

@ -0,0 +1,35 @@
aidl_interface {
name: "android.hardware.secure_element",
vendor_available: true,
host_supported: true,
srcs: ["android/hardware/secure_element/*.aidl"],
stability: "vintf",
backend: {
cpp: {
enabled: false,
},
java: {
sdk_version: "system_current",
},
},
}
cc_test {
name: "VtsHalSecureElementTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
srcs: ["vts/VtsHalSecureElementTargetTest.cpp"],
shared_libs: [
"libbinder_ndk",
],
static_libs: [
"android.hardware.secure_element-V1-ndk",
"libgmock",
],
test_suites: [
"general-tests",
"vts",
],
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) 2022 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.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.secure_element;
@VintfStability
interface ISecureElement {
void closeChannel(in byte channelNumber);
byte[] getAtr();
void init(in android.hardware.secure_element.ISecureElementCallback clientCallback);
boolean isCardPresent();
byte[] openBasicChannel(in byte[] aid, in byte p2);
android.hardware.secure_element.LogicalChannelResponse openLogicalChannel(in byte[] aid, in byte p2);
void reset();
byte[] transmit(in byte[] data);
const int FAILED = 1;
const int CHANNEL_NOT_AVAILABLE = 2;
const int NO_SUCH_ELEMENT_ERROR = 3;
const int UNSUPPORTED_OPERATION = 4;
const int IOERROR = 5;
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2022 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.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.secure_element;
@VintfStability
interface ISecureElementCallback {
void onStateChange(in boolean connected, in String debugReason);
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2022 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.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.secure_element;
@VintfStability
parcelable LogicalChannelResponse {
byte channelNumber;
byte[] selectResponse;
}

View file

@ -0,0 +1,129 @@
/*
* Copyright (C) 2022 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.
*/
package android.hardware.secure_element;
import android.hardware.secure_element.ISecureElementCallback;
import android.hardware.secure_element.LogicalChannelResponse;
@VintfStability
interface ISecureElement {
const int FAILED = 1;
const int CHANNEL_NOT_AVAILABLE = 2;
const int NO_SUCH_ELEMENT_ERROR = 3;
const int UNSUPPORTED_OPERATION = 4;
const int IOERROR = 5;
/**
* Closes the channel indicated by the channelNumber.
*
* @throws ServiceSpecificException Closing a channel must return
* FAILED on an error or if a basic channel (i.e. channel 0)
* is used.
*
* @param channelNumber to be closed
*/
void closeChannel(in byte channelNumber);
/**
* Returns Answer to Reset as per ISO/IEC 7816
*
* @return containing the response. Empty vector if Secure Element
* doesn't support ATR.
*/
byte[] getAtr();
/**
* Initializes the Secure Element. This may include updating the applet
* and/or vendor-specific initialization.
*
* HAL service must send onStateChange() with connected equal to true
* after all the initialization has been successfully completed.
* Clients must wait for a onStateChange(true) before opening channels.
*
* @param clientCallback callback used to sent status of the SE back to the
* client
*/
void init(in ISecureElementCallback clientCallback);
/**
* Returns the current state of the card.
*
* This is useful for removable Secure Elements like UICC,
* Secure Elements on SD cards etc.
*
* @return true if present, false otherwise
*/
boolean isCardPresent();
/**
* Opens a basic channel with the Secure Element, selecting the applet
* represented by the Application ID (AID). A basic channel has channel
* number 0.
*
* @throws ServiceSpecificException with codes
* - CHANNEL_NOT_AVAILABLE if secure element has reached the maximum
* limit on the number of channels it can support.
* - NO_SUCH_ELEMENT_ERROR if AID provided doesn't match any applet
* on the secure element.
* - UNSUPPORTED_OPERATION if operation provided by the P2 parameter
* is not permitted by the applet.
* - IOERROR if there was an error communicating with the Secure Element.
*
* @param aid AID to uniquely identify the applet on the Secure Element
* @param p2 P2 parameter of SELECT APDU as per ISO 7816-4
*
* @return On success, response to SELECT command.
*/
byte[] openBasicChannel(in byte[] aid, in byte p2);
/**
* Opens a logical channel with the Secure Element, selecting the applet
* represented by the Application ID (AID).
*
* @param aid AID to uniquely identify the applet on the Secure Element
* @param p2 P2 parameter of SELECT APDU as per ISO 7816-4
* @throws ServiceSpecificException on error with the following code:
* - CHANNEL_NOT_AVAILABLE if secure element has reached the maximum
* limit on the number of channels it can support.
* - NO_SUCH_ELEMENT_ERROR if AID provided doesn't match any applet
* on the secure element.
* - UNSUPPORTED_OPERATION if operation provided by the P2 parameter
* is not permitted by the applet.
* - IOERROR if there was an error communicating with the Secure Element.
*
* @return On success, response to SELECT command
*/
LogicalChannelResponse openLogicalChannel(in byte[] aid, in byte p2);
/**
* Reset the Secure Element.
*
* HAL should trigger reset to the secure element. It could hardware power cycle or
* a soft reset depends on the hardware design.
* HAL service must send onStateChange() with connected equal to true
* after resetting and all the re-initialization has been successfully completed.
*/
void reset();
/**
* Transmits an APDU command (as per ISO/IEC 7816) to the SE.
*
* @param data APDU command to be sent
* @return response to the command
*/
byte[] transmit(in byte[] data);
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2022 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.
*/
package android.hardware.secure_element;
@VintfStability
interface ISecureElementCallback {
/**
* Used to inform the client about changes in the state of the Secure
* Element.
*
* @param connected indicates the current state of the SE
* @param reason provides additional data why there was a change in state
* ex. initialization error, SE removed etc
* This is used only for debugging purpose to understand
* in-field issues.
*/
void onStateChange(in boolean connected, in String debugReason);
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (C) 2022 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.
*/
package android.hardware.secure_element;
@VintfStability
parcelable LogicalChannelResponse {
/**
* Channel number to uniquely identify the channel
*/
byte channelNumber;
/**
* Response to SELECT command as per ISO/IEC 7816
*/
byte[] selectResponse;
}

View file

@ -0,0 +1,15 @@
cc_binary {
name: "android.hardware.secure_element-service.example",
relative_install_path: "hw",
vendor: true,
init_rc: ["secure_element.rc"],
vintf_fragments: ["secure_element.xml"],
shared_libs: [
"libbase",
"libbinder_ndk",
"android.hardware.secure_element-V1-ndk",
],
srcs: [
"main.cpp",
],
}

View file

@ -0,0 +1,159 @@
/*
* Copyright (C) 2022 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 <aidl/android/hardware/secure_element/BnSecureElement.h>
#include <android-base/hex.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using aidl::android::hardware::secure_element::BnSecureElement;
using aidl::android::hardware::secure_element::ISecureElementCallback;
using aidl::android::hardware::secure_element::LogicalChannelResponse;
using android::base::HexString;
using ndk::ScopedAStatus;
static const std::vector<uint8_t> kAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
0x43, 0x54, 0x53, 0x31};
static const std::vector<uint8_t> kLongAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
0x43, 0x54, 0x53, 0x32};
class MySecureElement : public BnSecureElement {
public:
ScopedAStatus closeChannel(int8_t channelNumber) override {
LOG(INFO) << __func__ << " channel number: " << channelNumber;
return ScopedAStatus::ok();
}
ScopedAStatus getAtr(std::vector<uint8_t>* _aidl_return) override {
LOG(INFO) << __func__;
_aidl_return->clear();
return ScopedAStatus::ok();
}
ScopedAStatus init(const std::shared_ptr<ISecureElementCallback>& clientCallback) override {
LOG(INFO) << __func__ << " callback: " << clientCallback.get();
if (!clientCallback) {
return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
}
mCb = clientCallback;
mCb->onStateChange(true, "");
return ScopedAStatus::ok();
}
ScopedAStatus isCardPresent(bool* _aidl_return) override {
LOG(INFO) << __func__;
*_aidl_return = true;
return ScopedAStatus::ok();
}
ScopedAStatus openBasicChannel(const std::vector<uint8_t>& aid, int8_t p2,
std::vector<uint8_t>* _aidl_return) override {
LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
<< ") p2 " << p2;
// TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
// The functionality here is enough to exercise the framework, but actual
// calls to the secure element will fail. This implementation does not model
// channel isolation or any other aspects important to implementing secure element.
*_aidl_return = {0x90, 0x00, 0x00}; // DO NOT COPY
return ScopedAStatus::ok();
}
ScopedAStatus openLogicalChannel(
const std::vector<uint8_t>& aid, int8_t p2,
::aidl::android::hardware::secure_element::LogicalChannelResponse* _aidl_return)
override {
LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
<< ") p2 " << p2;
if (aid != kAndroidTestAid && aid != kLongAndroidTestAid) {
return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
}
*_aidl_return = LogicalChannelResponse{.channelNumber = 1, .selectResponse = {}};
// TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
// The functionality here is enough to exercise the framework, but actual
// calls to the secure element will fail. This implementation does not model
// channel isolation or any other aspects important to implementing secure element.
if (aid == kAndroidTestAid) { // DO NOT COPY
size_t size = 2050; // DO NOT COPY
_aidl_return->selectResponse.resize(size); // DO NOT COPY
_aidl_return->selectResponse[size - 1] = 0x00; // DO NOT COPY
_aidl_return->selectResponse[size - 2] = 0x90; // DO NOT COPY
} else { // DO NOT COPY
_aidl_return->selectResponse = {0x00, 0x00, 0x90, 0x00}; // DO NOT COPY
} // DO NOT COPY
LOG(INFO) << __func__ << " sending response: "
<< HexString(_aidl_return->selectResponse.data(),
_aidl_return->selectResponse.size());
return ScopedAStatus::ok();
}
ScopedAStatus reset() override {
LOG(INFO) << __func__;
mCb->onStateChange(false, "reset");
mCb->onStateChange(true, "reset");
return ScopedAStatus::ok();
}
ScopedAStatus transmit(const std::vector<uint8_t>& data,
std::vector<uint8_t>* _aidl_return) override {
LOG(INFO) << __func__ << " data: " << HexString(data.data(), data.size()) << " ("
<< data.size() << ")";
// TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
// The functionality here is enough to exercise the framework, but actual
// calls to the secure element will fail. This implementation does not model
// channel isolation or any other aspects important to implementing secure element.
std::string hex = HexString(data.data(), data.size()); // DO NOT COPY
if (hex == "01a4040210a000000476416e64726f696443545331") { // DO NOT COPY
*_aidl_return = {0x00, 0x6A, 0x00}; // DO NOT COPY
} else if (data == std::vector<uint8_t>{0x00, 0xF4, 0x00, 0x00, 0x00}) { // DO NOT COPY
// CHECK_SELECT_P2_APDU w/ channel 1 // DO NOT COPY
*_aidl_return = {0x00, 0x90, 0x00}; // DO NOT COPY
} else if (data == std::vector<uint8_t>{0x01, 0xF4, 0x00, 0x00, 0x00}) { // DO NOT COPY
// CHECK_SELECT_P2_APDU w/ channel 1 // DO NOT COPY
*_aidl_return = {0x00, 0x90, 0x00}; // DO NOT COPY
} else if (data.size() == 5 || data.size() == 8) { // DO NOT COPY
// SEGMENTED_RESP_APDU - happens to use length 5 and 8 // DO NOT COPY
size_t size = (data[2] << 8 | data[3]) + 2; // DO NOT COPY
_aidl_return->resize(size); // DO NOT COPY
(*_aidl_return)[size - 1] = 0x00; // DO NOT COPY
(*_aidl_return)[size - 2] = 0x90; // DO NOT COPY
if (size >= 3) (*_aidl_return)[size - 3] = 0xFF; // DO NOT COPY
} else { // DO NOT COPY
*_aidl_return = {0x90, 0x00, 0x00}; // DO NOT COPY
} // DO NOT COPY
return ScopedAStatus::ok();
}
private:
std::shared_ptr<ISecureElementCallback> mCb;
};
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
auto se = ndk::SharedRefBase::make<MySecureElement>();
const std::string name = std::string() + BnSecureElement::descriptor + "/eSE1";
binder_status_t status = AServiceManager_addService(se->asBinder().get(), name.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View file

@ -0,0 +1,4 @@
service vendor.secure_element /vendor/bin/hw/android.hardware.secure_element-service.example
class hal
user nobody
group nobody

View file

@ -0,0 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.secure_element</name>
<version>1</version>
<fqname>ISecureElement/eSE1</fqname>
</hal>
</manifest>

View file

@ -0,0 +1,176 @@
/*
* Copyright (C) 2022 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 <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/secure_element/BnSecureElementCallback.h>
#include <aidl/android/hardware/secure_element/ISecureElement.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
using namespace std::chrono_literals;
using aidl::android::hardware::secure_element::BnSecureElementCallback;
using aidl::android::hardware::secure_element::ISecureElement;
using aidl::android::hardware::secure_element::LogicalChannelResponse;
using ndk::ScopedAStatus;
using ndk::SharedRefBase;
using ndk::SpAIBinder;
using testing::ElementsAre;
using testing::ElementsAreArray;
#define EXPECT_OK(status) \
do { \
auto status_impl = (status); \
EXPECT_TRUE(status_impl.isOk()) << status_impl.getDescription(); \
} while (false)
static const std::vector<uint8_t> kDataApdu = {0x00, 0x08, 0x00, 0x00, 0x00};
static const std::vector<uint8_t> kAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
0x43, 0x54, 0x53, 0x31};
class MySecureElementCallback : public BnSecureElementCallback {
public:
ScopedAStatus onStateChange(bool state, const std::string& debugReason) override {
{
std::unique_lock<std::mutex> l(m);
(void)debugReason;
history.push_back(state);
}
cv.notify_one();
return ScopedAStatus::ok();
};
void expectCallbackHistory(std::vector<bool>&& want) {
std::unique_lock<std::mutex> l(m);
cv.wait_for(l, 2s, [&]() { return history.size() >= want.size(); });
EXPECT_THAT(history, ElementsAreArray(want));
}
private:
std::mutex m; // guards history
std::condition_variable cv;
std::vector<bool> history;
};
class SecureElementAidl : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
SpAIBinder binder = SpAIBinder(AServiceManager_waitForService(GetParam().c_str()));
se = ISecureElement::fromBinder(binder);
ASSERT_NE(se, nullptr);
cb = SharedRefBase::make<MySecureElementCallback>();
EXPECT_OK(se->init(cb));
cb->expectCallbackHistory({true});
}
std::shared_ptr<ISecureElement> se;
std::shared_ptr<MySecureElementCallback> cb;
};
TEST_P(SecureElementAidl, isCardPresent) {
bool res = false;
EXPECT_OK(se->isCardPresent(&res));
EXPECT_TRUE(res);
}
TEST_P(SecureElementAidl, transmit) {
LogicalChannelResponse response;
EXPECT_OK(se->openLogicalChannel(kAndroidTestAid, 0x00, &response));
EXPECT_GE(response.selectResponse.size(), 2u);
EXPECT_GE(response.channelNumber, 1);
std::vector<uint8_t> command = kDataApdu;
command[0] |= response.channelNumber;
std::vector<uint8_t> transmitResponse;
EXPECT_OK(se->transmit(command, &transmitResponse));
EXPECT_LE(transmitResponse.size(), 3);
EXPECT_GE(transmitResponse.size(), 2);
EXPECT_EQ(transmitResponse[transmitResponse.size() - 1], 0x00);
EXPECT_EQ(transmitResponse[transmitResponse.size() - 2], 0x90);
EXPECT_OK(se->closeChannel(response.channelNumber));
}
TEST_P(SecureElementAidl, openBasicChannel) {
std::vector<uint8_t> response;
auto status = se->openBasicChannel(kAndroidTestAid, 0x00, &response);
if (!status.isOk()) {
EXPECT_EQ(status.getServiceSpecificError(), ISecureElement::CHANNEL_NOT_AVAILABLE)
<< status.getDescription();
return;
}
EXPECT_GE(response.size(), 2u);
EXPECT_OK(se->closeChannel(0));
}
TEST_P(SecureElementAidl, getAtr) {
std::vector<uint8_t> atr;
EXPECT_OK(se->getAtr(&atr));
if (atr.size() == 0) {
return;
}
EXPECT_LE(atr.size(), 32u);
EXPECT_GE(atr.size(), 1u);
}
TEST_P(SecureElementAidl, openCloseLogicalChannel) {
LogicalChannelResponse response;
EXPECT_OK(se->openLogicalChannel(kAndroidTestAid, 0x00, &response));
EXPECT_GE(response.selectResponse.size(), 2u);
EXPECT_GE(response.channelNumber, 1);
EXPECT_OK(se->closeChannel(response.channelNumber));
}
TEST_P(SecureElementAidl, openInvalidAid) {
LogicalChannelResponse response;
auto status = se->openLogicalChannel({0x42}, 0x00, &response);
EXPECT_EQ(status.getServiceSpecificError(), ISecureElement::NO_SUCH_ELEMENT_ERROR)
<< status.getDescription();
}
TEST_P(SecureElementAidl, Reset) {
cb->expectCallbackHistory({true});
EXPECT_OK(se->reset());
cb->expectCallbackHistory({true, false, true});
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SecureElementAidl);
INSTANTIATE_TEST_SUITE_P(
SecureElement, SecureElementAidl,
testing::ValuesIn(android::getAidlHalInstanceNames(ISecureElement::descriptor)),
android::PrintInstanceNameToString);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
}