diff options
author | Ruchi Kandoi <kandoiruchi@google.com> | 2018-01-08 15:45:46 -0800 |
---|---|---|
committer | Ruchi Kandoi <kandoiruchi@google.com> | 2018-01-31 11:51:48 -0800 |
commit | 22a4d0e07e86fd174492665e01f4a7bc33349e3c (patch) | |
tree | d28e88c915115ad0ea574b15dc8d4164ce84b959 /secure_element/1.0/vts/functional | |
parent | de542acbbf46812cfb53d231ecb50048baf8780e (diff) | |
download | android_hardware_interfaces-22a4d0e07e86fd174492665e01f4a7bc33349e3c.tar.gz android_hardware_interfaces-22a4d0e07e86fd174492665e01f4a7bc33349e3c.tar.bz2 android_hardware_interfaces-22a4d0e07e86fd174492665e01f4a7bc33349e3c.zip |
Add VTS Test for Secure Element HAL
Test: Run VTS test
Bug: 64881253
Change-Id: If77d87c88bd073409dce3d18aba8f15a1267a80e
Diffstat (limited to 'secure_element/1.0/vts/functional')
-rw-r--r-- | secure_element/1.0/vts/functional/Android.bp | 24 | ||||
-rw-r--r-- | secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp | 248 |
2 files changed, 272 insertions, 0 deletions
diff --git a/secure_element/1.0/vts/functional/Android.bp b/secure_element/1.0/vts/functional/Android.bp new file mode 100644 index 000000000..752df9e9b --- /dev/null +++ b/secure_element/1.0/vts/functional/Android.bp @@ -0,0 +1,24 @@ +// +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_test { + name: "VtsHalSecureElementV1_0TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalSecureElementV1_0TargetTest.cpp"], + static_libs: [ + "android.hardware.secure_element@1.0", + ], +} diff --git a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp new file mode 100644 index 000000000..2045e445d --- /dev/null +++ b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "secure_element_hidl_hal_test" +#include <android-base/logging.h> + +#include <android/hardware/secure_element/1.0/ISecureElement.h> +#include <android/hardware/secure_element/1.0/ISecureElementHalCallback.h> +#include <android/hardware/secure_element/1.0/types.h> + +#include <VtsHalHidlTargetCallbackBase.h> +#include <VtsHalHidlTargetTestBase.h> +#include <VtsHalHidlTargetTestEnvBase.h> + +using ::android::hardware::secure_element::V1_0::ISecureElement; +using ::android::hardware::secure_element::V1_0::ISecureElementHalCallback; +using ::android::hardware::secure_element::V1_0::SecureElementStatus; +using ::android::hardware::secure_element::V1_0::LogicalChannelResponse; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; +using ::testing::VtsHalHidlTargetTestEnvBase; + +#define SELECT_ISD \ + { 0x00, 0xA4, 0x04, 0x00, 0x00 } +#define SEQUENCE_COUNTER \ + { 0x80, 0xCA, 0x00, 0xC1, 0x00 } +#define MANAGE_SELECT \ + { 0x00, 0xA4, 0x04, 0x00, 0x00 } +#define CRS_AID \ + { 0xA0, 0x00, 0x00, 0x01, 0x51, 0x43, 0x52, 0x53, 0x00 } + +constexpr char kCallbackNameOnStateChange[] = "onStateChange"; + +class SecureElementCallbackArgs { + public: + bool state_; +}; + +class SecureElementHalCallback + : public ::testing::VtsHalHidlTargetCallbackBase<SecureElementCallbackArgs>, + public ISecureElementHalCallback { + public: + virtual ~SecureElementHalCallback() = default; + + Return<void> onStateChange(bool state) override { + SecureElementCallbackArgs args; + args.state_ = state; + NotifyFromCallback(kCallbackNameOnStateChange, args); + return Void(); + }; +}; + +class SecureElementHidlEnvironment : public VtsHalHidlTargetTestEnvBase { + public: + // get the test environment singleton + static SecureElementHidlEnvironment* Instance() { + static SecureElementHidlEnvironment* instance = new SecureElementHidlEnvironment; + return instance; + } + + virtual void registerTestServices() override { registerTestService<ISecureElement>(); } + + private: + SecureElementHidlEnvironment() {} + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SecureElementHidlEnvironment); +}; + +class SecureElementHidlTest : public ::testing::VtsHalHidlTargetTestBase { + public: + virtual void SetUp() override { + std::string serviceName = + SecureElementHidlEnvironment::Instance()->getServiceName<ISecureElement>("eSE1"); + LOG(INFO) << "get service with name:" << serviceName; + ASSERT_FALSE(serviceName.empty()); + se_ = ::testing::VtsHalHidlTargetTestBase::getService<ISecureElement>(serviceName); + ASSERT_NE(se_, nullptr); + + se_cb_ = new SecureElementHalCallback(); + ASSERT_NE(se_cb_, nullptr); + } + + sp<ISecureElement> se_; + sp<SecureElementHalCallback> se_cb_; +}; + +/* + * isCardPresent: + * Expects the card to be present + */ +TEST_F(SecureElementHidlTest, isCardPresent) { + EXPECT_TRUE(se_->isCardPresent()); +} + +/* + * transmit: + * Check status word in the response + */ +TEST_F(SecureElementHidlTest, transmit) { + std::vector<uint8_t> aid = CRS_AID; + SecureElementStatus statusReturned; + LogicalChannelResponse response; + se_->openLogicalChannel( + aid, 0x00, + [&statusReturned, &response](LogicalChannelResponse channelResponse, + SecureElementStatus status) { + statusReturned = status; + if (status == SecureElementStatus::SUCCESS) { + response.channelNumber = channelResponse.channelNumber; + response.selectResponse.resize(channelResponse.selectResponse.size()); + for (size_t i = 0; i < channelResponse.selectResponse.size(); i++) { + response.selectResponse[i] = channelResponse.selectResponse[i]; + } + } + }); + EXPECT_EQ(SecureElementStatus::SUCCESS, statusReturned); + EXPECT_LE((unsigned int)3, response.selectResponse.size()); + EXPECT_LE(1, response.channelNumber); + std::vector<uint8_t> command = SELECT_ISD; + std::vector<uint8_t> transmitResponse; + se_->transmit(command, [&transmitResponse](std::vector<uint8_t> res) { + transmitResponse.resize(res.size()); + for (size_t i = 0; i < res.size(); i++) { + transmitResponse[i] = res[i]; + } + }); + EXPECT_LE((unsigned int)3, transmitResponse.size()); + EXPECT_EQ(0x90, transmitResponse[transmitResponse.size() - 2]); + EXPECT_EQ(0x00, transmitResponse[transmitResponse.size() - 1]); + command = SEQUENCE_COUNTER; + se_->transmit(command, [&transmitResponse](std::vector<uint8_t> res) { + transmitResponse.resize(res.size()); + for (size_t i = 0; i < res.size(); i++) { + transmitResponse[i] = res[i]; + } + }); + EXPECT_LE((unsigned int)3, transmitResponse.size()); + EXPECT_EQ(0x90, transmitResponse[transmitResponse.size() - 2]); + EXPECT_EQ(0x00, transmitResponse[transmitResponse.size() - 1]); + EXPECT_EQ(SecureElementStatus::SUCCESS, se_->closeChannel(response.channelNumber)); +} + +/* + * OpenCloseBasicChannel: + * If the secure element allows opening of basic channel: + * open channel, check the length of selectResponse and close the channel + */ +TEST_F(SecureElementHidlTest, openBasicChannel) { + std::vector<uint8_t> aid = CRS_AID; + SecureElementStatus statusReturned; + std::vector<uint8_t> response; + se_->openBasicChannel(aid, 0x00, + [&statusReturned, &response](std::vector<uint8_t> selectResponse, + SecureElementStatus status) { + statusReturned = status; + if (status == SecureElementStatus::SUCCESS) { + response.resize(selectResponse.size()); + for (size_t i = 0; i < selectResponse.size(); i++) { + response[i] = selectResponse[i]; + } + } + }); + if (statusReturned == SecureElementStatus::SUCCESS) { + EXPECT_LE((unsigned int)3, response.size()); + std::vector<uint8_t> command = SELECT_ISD; + std::vector<uint8_t> transmitResponse; + se_->transmit(command, [&transmitResponse](std::vector<uint8_t> res) { + transmitResponse.resize(res.size()); + for (size_t i = 0; i < res.size(); i++) { + transmitResponse[i] = res[i]; + } + }); + EXPECT_LE((unsigned int)3, transmitResponse.size()); + EXPECT_EQ(0x90, transmitResponse[transmitResponse.size() - 2]); + EXPECT_EQ(0x00, transmitResponse[transmitResponse.size() - 1]); + return; + } + EXPECT_EQ(SecureElementStatus::UNSUPPORTED_OPERATION, statusReturned); +} + +/* + * GetATR + */ +TEST_F(SecureElementHidlTest, getAtr) { + std::vector<uint8_t> atr; + se_->getAtr([&atr](std::vector<uint8_t> atrReturned) { + atr.resize(atrReturned.size()); + for (size_t i = 0; i < atrReturned.size(); i++) { + atr[i] = atrReturned[i]; + } + }); + if (atr.size() == 0) { + return; + } + EXPECT_GE((unsigned int)32, atr.size()); + EXPECT_LE((unsigned int)1, atr.size()); +} + +/* + * OpenCloseLogicalChannel: + * Open Channel + * Check status + * Close Channel + */ +TEST_F(SecureElementHidlTest, openCloseLogicalChannel) { + std::vector<uint8_t> aid = CRS_AID; + SecureElementStatus statusReturned; + LogicalChannelResponse response; + se_->openLogicalChannel( + aid, 0x00, + [&statusReturned, &response](LogicalChannelResponse channelResponse, + SecureElementStatus status) { + statusReturned = status; + if (status == SecureElementStatus::SUCCESS) { + response.channelNumber = channelResponse.channelNumber; + response.selectResponse.resize(channelResponse.selectResponse.size()); + for (size_t i = 0; i < channelResponse.selectResponse.size(); i++) { + response.selectResponse[i] = channelResponse.selectResponse[i]; + } + } + }); + EXPECT_EQ(SecureElementStatus::SUCCESS, statusReturned); + EXPECT_LE((unsigned int)3, response.selectResponse.size()); + EXPECT_LE(1, response.channelNumber); + EXPECT_EQ(SecureElementStatus::SUCCESS, se_->closeChannel(response.channelNumber)); +} + +int main(int argc, char** argv) { + ::testing::AddGlobalTestEnvironment(SecureElementHidlEnvironment::Instance()); + ::testing::InitGoogleTest(&argc, argv); + SecureElementHidlEnvironment::Instance()->init(&argc, argv); + int status = RUN_ALL_TESTS(); + return status; +} |