blob: a85a8bcad8928fdaf2ebda10516dc5fd29bef83e [file] [log] [blame]
Steven Moreland6fe69542022-11-03 17:42:32 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <aidl/Gtest.h>
18#include <aidl/Vintf.h>
19#include <aidl/android/hardware/secure_element/BnSecureElementCallback.h>
20#include <aidl/android/hardware/secure_element/ISecureElement.h>
21#include <android/binder_manager.h>
22#include <android/binder_process.h>
23#include <gmock/gmock.h>
24#include <gtest/gtest.h>
25
26#include <chrono>
27#include <condition_variable>
28#include <mutex>
29
30using namespace std::chrono_literals;
31
32using aidl::android::hardware::secure_element::BnSecureElementCallback;
33using aidl::android::hardware::secure_element::ISecureElement;
34using aidl::android::hardware::secure_element::LogicalChannelResponse;
35using ndk::ScopedAStatus;
36using ndk::SharedRefBase;
37using ndk::SpAIBinder;
38using testing::ElementsAre;
39using testing::ElementsAreArray;
40
41#define EXPECT_OK(status) \
42 do { \
43 auto status_impl = (status); \
44 EXPECT_TRUE(status_impl.isOk()) << status_impl.getDescription(); \
45 } while (false)
46
47static const std::vector<uint8_t> kDataApdu = {0x00, 0x08, 0x00, 0x00, 0x00};
48static const std::vector<uint8_t> kAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
49 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
50 0x43, 0x54, 0x53, 0x31};
51
52class MySecureElementCallback : public BnSecureElementCallback {
53 public:
54 ScopedAStatus onStateChange(bool state, const std::string& debugReason) override {
55 {
56 std::unique_lock<std::mutex> l(m);
57 (void)debugReason;
58 history.push_back(state);
59 }
60 cv.notify_one();
61 return ScopedAStatus::ok();
62 };
63
64 void expectCallbackHistory(std::vector<bool>&& want) {
65 std::unique_lock<std::mutex> l(m);
66 cv.wait_for(l, 2s, [&]() { return history.size() >= want.size(); });
67 EXPECT_THAT(history, ElementsAreArray(want));
68 }
69
70 private:
71 std::mutex m; // guards history
72 std::condition_variable cv;
73 std::vector<bool> history;
74};
75
76class SecureElementAidl : public ::testing::TestWithParam<std::string> {
77 public:
78 virtual void SetUp() override {
79 SpAIBinder binder = SpAIBinder(AServiceManager_waitForService(GetParam().c_str()));
80 se = ISecureElement::fromBinder(binder);
81 ASSERT_NE(se, nullptr);
82
83 cb = SharedRefBase::make<MySecureElementCallback>();
84 EXPECT_OK(se->init(cb));
85
86 cb->expectCallbackHistory({true});
87 }
88
89 std::shared_ptr<ISecureElement> se;
90 std::shared_ptr<MySecureElementCallback> cb;
91};
92
93TEST_P(SecureElementAidl, isCardPresent) {
94 bool res = false;
95 EXPECT_OK(se->isCardPresent(&res));
96 EXPECT_TRUE(res);
97}
98
99TEST_P(SecureElementAidl, transmit) {
100 LogicalChannelResponse response;
101 EXPECT_OK(se->openLogicalChannel(kAndroidTestAid, 0x00, &response));
102
103 EXPECT_GE(response.selectResponse.size(), 2u);
104 EXPECT_GE(response.channelNumber, 1);
105
106 std::vector<uint8_t> command = kDataApdu;
107 command[0] |= response.channelNumber;
108
109 std::vector<uint8_t> transmitResponse;
110 EXPECT_OK(se->transmit(command, &transmitResponse));
111
112 EXPECT_LE(transmitResponse.size(), 3);
113 EXPECT_GE(transmitResponse.size(), 2);
114 EXPECT_EQ(transmitResponse[transmitResponse.size() - 1], 0x00);
115 EXPECT_EQ(transmitResponse[transmitResponse.size() - 2], 0x90);
116
117 EXPECT_OK(se->closeChannel(response.channelNumber));
118}
119
120TEST_P(SecureElementAidl, openBasicChannel) {
121 std::vector<uint8_t> response;
122 auto status = se->openBasicChannel(kAndroidTestAid, 0x00, &response);
123
124 if (!status.isOk()) {
125 EXPECT_EQ(status.getServiceSpecificError(), ISecureElement::CHANNEL_NOT_AVAILABLE)
126 << status.getDescription();
127 return;
128 }
129
130 EXPECT_GE(response.size(), 2u);
131 EXPECT_OK(se->closeChannel(0));
132}
133
134TEST_P(SecureElementAidl, getAtr) {
135 std::vector<uint8_t> atr;
136 EXPECT_OK(se->getAtr(&atr));
137 if (atr.size() == 0) {
138 return;
139 }
140 EXPECT_LE(atr.size(), 32u);
141 EXPECT_GE(atr.size(), 1u);
142}
143
144TEST_P(SecureElementAidl, openCloseLogicalChannel) {
145 LogicalChannelResponse response;
146 EXPECT_OK(se->openLogicalChannel(kAndroidTestAid, 0x00, &response));
147 EXPECT_GE(response.selectResponse.size(), 2u);
148 EXPECT_GE(response.channelNumber, 1);
149 EXPECT_OK(se->closeChannel(response.channelNumber));
150}
151
152TEST_P(SecureElementAidl, openInvalidAid) {
153 LogicalChannelResponse response;
154 auto status = se->openLogicalChannel({0x42}, 0x00, &response);
155 EXPECT_EQ(status.getServiceSpecificError(), ISecureElement::NO_SUCH_ELEMENT_ERROR)
156 << status.getDescription();
157}
158
159TEST_P(SecureElementAidl, Reset) {
160 cb->expectCallbackHistory({true});
161 EXPECT_OK(se->reset());
162 cb->expectCallbackHistory({true, false, true});
163}
164
165GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SecureElementAidl);
166INSTANTIATE_TEST_SUITE_P(
167 SecureElement, SecureElementAidl,
168 testing::ValuesIn(android::getAidlHalInstanceNames(ISecureElement::descriptor)),
169 android::PrintInstanceNameToString);
170
171int main(int argc, char** argv) {
172 ::testing::InitGoogleTest(&argc, argv);
173 ABinderProcess_setThreadPoolMaxThreadCount(1);
174 ABinderProcess_startThreadPool();
175 return RUN_ALL_TESTS();
176}