1 /*
2 * Copyright (C) 2021 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/android/se/omapi/BnSecureElementListener.h>
18 #include <aidl/android/se/omapi/ISecureElementChannel.h>
19 #include <aidl/android/se/omapi/ISecureElementListener.h>
20 #include <aidl/android/se/omapi/ISecureElementReader.h>
21 #include <aidl/android/se/omapi/ISecureElementService.h>
22 #include <aidl/android/se/omapi/ISecureElementSession.h>
23
24 #include <VtsCoreUtil.h>
25 #include <aidl/Gtest.h>
26 #include <aidl/Vintf.h>
27 #include <android-base/logging.h>
28 #include <android/binder_manager.h>
29 #include <binder/IServiceManager.h>
30 #include <cutils/properties.h>
31 #include <gtest/gtest.h>
32 #include <hidl/GtestPrinter.h>
33 #include <hidl/ServiceManagement.h>
34 #include <utils/String16.h>
35
36 using namespace std;
37 using namespace ::testing;
38 using namespace android;
39
main(int argc,char ** argv)40 int main(int argc, char** argv) {
41 InitGoogleTest(&argc, argv);
42 int status = RUN_ALL_TESTS();
43 return status;
44 }
45
46 namespace {
47
48 class OMAPISEAccessControlTest : public TestWithParam<std::string> {
49 protected:
50
51 class SEListener : public ::aidl::android::se::omapi::BnSecureElementListener {};
52
53 /**
54 * Verifies TLV data
55 *
56 * @return true if the data is tlv formatted, false otherwise
57 */
verifyBerTlvData(std::vector<uint8_t> tlv)58 bool verifyBerTlvData(std::vector<uint8_t> tlv) {
59 if (tlv.size() == 0) {
60 LOG(ERROR) << "Invalid tlv, null";
61 return false;
62 }
63 int i = 0;
64 if ((tlv[i++] & 0x1F) == 0x1F) {
65 // extra byte for TAG field
66 i++;
67 }
68
69 int len = tlv[i++] & 0xFF;
70 if (len > 127) {
71 // more than 1 byte for length
72 int bytesLength = len - 128;
73 len = 0;
74 for (int j = bytesLength; j > 0; j--) {
75 len += (len << 8) + (tlv[i++] & 0xFF);
76 }
77 }
78 // Additional 2 bytes for the SW
79 return (tlv.size() == (i + len + 2));
80 }
81
testSelectableAid(std::vector<std::vector<uint8_t>> authorizedAids)82 void testSelectableAid(
83 std::vector<std::vector<uint8_t>> authorizedAids) {
84 for (auto aid : authorizedAids) {
85 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
86 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
87 auto seListener = ndk::SharedRefBase::make<SEListener>();
88
89 if (mVSReaders.size() > 0) {
90 for (const auto& [name, reader] : mVSReaders) {
91 std::vector<uint8_t> selectResponse = {};
92 ASSERT_NE(reader, nullptr) << "reader is null";
93
94 bool status = false;
95 auto res = reader->isSecureElementPresent(&status);
96 ASSERT_TRUE(res.isOk()) << res.getMessage();
97 ASSERT_TRUE(status);
98
99 res = reader->openSession(&session);
100 ASSERT_TRUE(res.isOk()) << res.getMessage();
101 ASSERT_NE(session, nullptr) << "Could not open session";
102
103 res = session->openLogicalChannel(aid, 0x00, seListener, &channel);
104 ASSERT_TRUE(res.isOk()) << res.getMessage();
105 ASSERT_NE(channel, nullptr) << "Could not open channel";
106
107 res = channel->getSelectResponse(&selectResponse);
108 ASSERT_TRUE(res.isOk()) << "failed to get Select Response";
109 ASSERT_GE(selectResponse.size(), 2);
110
111 if (channel != nullptr) channel->close();
112 if (session != nullptr) session->close();
113
114 ASSERT_EQ((selectResponse[selectResponse.size() - 1] & 0xFF), (0x00));
115 ASSERT_EQ((selectResponse[selectResponse.size() - 2] & 0xFF), (0x90));
116 ASSERT_TRUE(
117 verifyBerTlvData(selectResponse)) << "Select Response is not complete";
118 }
119 }
120 }
121 }
122
testUnauthorisedAid(std::vector<std::vector<uint8_t>> unAuthorizedAids)123 void testUnauthorisedAid(
124 std::vector<std::vector<uint8_t>> unAuthorizedAids) {
125 for (auto aid : unAuthorizedAids) {
126 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
127 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
128 auto seListener = ndk::SharedRefBase::make<SEListener>();
129
130 if (mVSReaders.size() > 0) {
131 for (const auto& [name, reader] : mVSReaders) {
132 ASSERT_NE(reader, nullptr) << "reader is null";
133
134 bool status = false;
135 auto res = reader->isSecureElementPresent(&status);
136 ASSERT_TRUE(res.isOk()) << res.getMessage();
137 ASSERT_TRUE(status);
138
139 res = reader->openSession(&session);
140 ASSERT_TRUE(res.isOk()) << res.getMessage();
141 ASSERT_NE(session, nullptr) << "Could not open session";
142
143 res = session->openLogicalChannel(aid, 0x00, seListener, &channel);
144
145 if (channel != nullptr) channel->close();
146 if (session != nullptr) session->close();
147
148 if (!res.isOk()) {
149 ASSERT_EQ(res.getExceptionCode(), EX_SECURITY);
150 ASSERT_FALSE(res.isOk()) << "expected failed status for this test";
151 }
152 }
153 }
154 }
155 }
156
testTransmitAPDU(std::vector<uint8_t> aid,std::vector<std::vector<uint8_t>> apdus)157 void testTransmitAPDU(
158 std::vector<uint8_t> aid,
159 std::vector<std::vector<uint8_t>> apdus) {
160 for (auto apdu : apdus) {
161 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
162 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
163 auto seListener = ndk::SharedRefBase::make<SEListener>();
164
165 if (mVSReaders.size() > 0) {
166 for (const auto& [name, reader] : mVSReaders) {
167 ASSERT_NE(reader, nullptr) << "reader is null";
168 bool status = false;
169 std::vector<uint8_t> selectResponse = {};
170 std::vector<uint8_t> transmitResponse = {};
171 auto res = reader->isSecureElementPresent(&status);
172 ASSERT_TRUE(res.isOk()) << res.getMessage();
173 ASSERT_TRUE(status);
174
175 res = reader->openSession(&session);
176 ASSERT_TRUE(res.isOk()) << res.getMessage();
177 ASSERT_NE(session, nullptr) << "Could not open session";
178
179 res = session->openLogicalChannel(aid, 0x00, seListener, &channel);
180 ASSERT_TRUE(res.isOk()) << res.getMessage();
181 ASSERT_NE(channel, nullptr) << "Could not open channel";
182
183 res = channel->getSelectResponse(&selectResponse);
184 ASSERT_TRUE(res.isOk()) << "failed to get Select Response";
185 ASSERT_GE(selectResponse.size(), 2);
186 ASSERT_EQ((selectResponse[selectResponse.size() - 1] & 0xFF), (0x00));
187 ASSERT_EQ((selectResponse[selectResponse.size() - 2] & 0xFF), (0x90));
188 ASSERT_TRUE(
189 verifyBerTlvData(selectResponse)) << "Select Response is not complete";
190
191 res = channel->transmit(apdu, &transmitResponse);
192 LOG(INFO) << "STATUS OF TRNSMIT: " << res.getExceptionCode()
193 << " Message: " << res.getMessage();
194 if (channel != nullptr) channel->close();
195 if (session != nullptr) session->close();
196 ASSERT_TRUE(res.isOk()) << "failed to transmit";
197 }
198 }
199 }
200 }
201
testUnauthorisedAPDU(std::vector<uint8_t> aid,std::vector<std::vector<uint8_t>> apdus)202 void testUnauthorisedAPDU(
203 std::vector<uint8_t> aid,
204 std::vector<std::vector<uint8_t>> apdus) {
205 for (auto apdu : apdus) {
206 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
207 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
208 auto seListener = ndk::SharedRefBase::make<SEListener>();
209
210 if (mVSReaders.size() > 0) {
211 for (const auto& [name, reader] : mVSReaders) {
212 ASSERT_NE(reader, nullptr) << "reader is null";
213 bool status = false;
214 std::vector<uint8_t> selectResponse = {};
215 std::vector<uint8_t> transmitResponse = {};
216 auto res = reader->isSecureElementPresent(&status);
217 ASSERT_TRUE(res.isOk()) << res.getMessage();
218 ASSERT_TRUE(status);
219
220 res = reader->openSession(&session);
221 ASSERT_TRUE(res.isOk()) << res.getMessage();
222 ASSERT_NE(session, nullptr) << "Could not open session";
223
224 res = session->openLogicalChannel(aid, 0x00, seListener, &channel);
225 ASSERT_TRUE(res.isOk()) << res.getMessage();
226 ASSERT_NE(channel, nullptr) << "Could not open channel";
227
228 res = channel->getSelectResponse(&selectResponse);
229 ASSERT_TRUE(res.isOk()) << "failed to get Select Response";
230 ASSERT_GE(selectResponse.size(), 2);
231 ASSERT_EQ((selectResponse[selectResponse.size() - 1] & 0xFF), (0x00));
232 ASSERT_EQ((selectResponse[selectResponse.size() - 2] & 0xFF), (0x90));
233 ASSERT_TRUE(
234 verifyBerTlvData(selectResponse)) << "Select Response is not complete";
235
236 res = channel->transmit(apdu, &transmitResponse);
237 LOG(INFO) << "STATUS OF TRNSMIT: " << res.getExceptionCode()
238 << " Message: " << res.getMessage();
239
240 if (channel != nullptr) channel->close();
241 if (session != nullptr) session->close();
242 if (!res.isOk()) {
243 ASSERT_EQ(res.getExceptionCode(), EX_SECURITY);
244 ASSERT_FALSE(res.isOk()) << "expected failed status for this test";
245 }
246 }
247 }
248 }
249 }
250
supportOMAPIReaders()251 bool supportOMAPIReaders() {
252 return (deviceSupportsFeature(FEATURE_SE_OMAPI_ESE.c_str()));
253 }
254
getFirstApiLevel(int32_t * outApiLevel)255 void getFirstApiLevel(int32_t* outApiLevel) {
256 int32_t firstApiLevel = property_get_int32(FEATURE_SE_API_LEVEL.c_str(), -1);
257 if (firstApiLevel < 0) {
258 firstApiLevel = property_get_int32(FEATURE_SE_SDK_VERSION.c_str(), -1);
259 }
260 ASSERT_GT(firstApiLevel, 0); // first_api_level must exist
261 *outApiLevel = firstApiLevel;
262 return;
263 }
264
supportsHardware()265 bool supportsHardware() {
266 bool lowRamDevice = property_get_bool(FEATURE_SE_LOW_RAM.c_str(), true);
267 return !lowRamDevice || deviceSupportsFeature(FEATURE_SE_HARDWARE_WATCH.c_str()) ||
268 deviceSupportsFeature(FEATURE_SE_OMAPI_SERVICE.c_str()); // android.se.omapi
269 }
270
SetUp()271 void SetUp() override {
272 ASSERT_TRUE(supportsHardware());
273 int32_t apiLevel;
274 getFirstApiLevel(&apiLevel);
275 ASSERT_TRUE(apiLevel > 27);
276 ASSERT_TRUE(supportOMAPIReaders());
277 LOG(INFO) << "get OMAPI service with name:" << GetParam();
278 ::ndk::SpAIBinder ks2Binder(AServiceManager_getService(GetParam().c_str()));
279 mOmapiSeService = aidl::android::se::omapi::ISecureElementService::fromBinder(ks2Binder);
280 ASSERT_TRUE(mOmapiSeService);
281
282 std::vector<std::string> readers = {};
283
284 if (mOmapiSeService != NULL) {
285 auto status = mOmapiSeService->getReaders(&readers);
286 ASSERT_TRUE(status.isOk()) << status.getMessage();
287
288 for (auto readerName : readers) {
289 // Filter eSE readers only
290 if (readerName.find(ESE_READER_PREFIX, 0) != std::string::npos) {
291 std::shared_ptr<::aidl::android::se::omapi::ISecureElementReader> reader;
292 status = mOmapiSeService->getReader(readerName, &reader);
293 ASSERT_TRUE(status.isOk()) << status.getMessage();
294
295 mVSReaders[readerName] = reader;
296 }
297 }
298 }
299 }
300
TearDown()301 void TearDown() override {
302 if (mOmapiSeService != nullptr) {
303 if (mVSReaders.size() > 0) {
304 for (const auto& [name, reader] : mVSReaders) {
305 reader->closeSessions();
306 }
307 }
308 }
309 }
310
311 static inline std::string const ESE_READER_PREFIX = "eSE";
312 static inline std::string const FEATURE_SE_OMAPI_ESE = "android.hardware.se.omapi.ese";
313 static inline std::string const FEATURE_SE_LOW_RAM = "ro.config.low_ram";
314 static inline std::string const FEATURE_SE_HARDWARE_WATCH = "android.hardware.type.watch";
315 static inline std::string const FEATURE_SE_OMAPI_SERVICE = "com.android.se";
316 static inline std::string const FEATURE_SE_SDK_VERSION = "ro.build.version.sdk";
317 static inline std::string const FEATURE_SE_API_LEVEL = "ro.product.first_api_level";
318
319 std::vector<uint8_t> AID_40 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
320 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x40};
321 std::vector<uint8_t> AID_41 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
322 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x41};
323 std::vector<uint8_t> AID_42 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
324 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x42};
325 std::vector<uint8_t> AID_43 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
326 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x43};
327 std::vector<uint8_t> AID_44 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
328 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x44};
329 std::vector<uint8_t> AID_45 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
330 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x45};
331 std::vector<uint8_t> AID_46 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
332 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x46};
333 std::vector<uint8_t> AID_47 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
334 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x47};
335 std::vector<uint8_t> AID_48 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
336 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x48};
337 std::vector<uint8_t> AID_49 = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
338 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x49};
339 std::vector<uint8_t> AID_4A = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
340 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x4A};
341 std::vector<uint8_t> AID_4B = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
342 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x4B};
343 std::vector<uint8_t> AID_4C = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
344 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x4C};
345 std::vector<uint8_t> AID_4D = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
346 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x4D};
347 std::vector<uint8_t> AID_4E = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
348 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x4E};
349 std::vector<uint8_t> AID_4F = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
350 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x4F};
351
352 std::vector<std::vector<uint8_t>> AUTHORIZED_AID = {AID_40, AID_41, AID_42, AID_44, AID_45,
353 AID_47, AID_48, AID_49, AID_4A, AID_4B,
354 AID_4C, AID_4D, AID_4E, AID_4F};
355 std::vector<std::vector<uint8_t>> UNAUTHORIZED_AID = {AID_43, AID_46};
356
357 /* Authorized APDU for AID_40 */
358 std::vector<std::vector<uint8_t>> AUTHORIZED_APDU_AID_40 = {
359 {0x00, 0x06, 0x00, 0x00},
360 {0xA0, 0x06, 0x00, 0x00},
361 };
362 /* Unauthorized APDU for AID_40 */
363 std::vector<std::vector<uint8_t>> UNAUTHORIZED_APDU_AID_40 = {
364 {0x00, 0x08, 0x00, 0x00, 0x00},
365 {0x80, 0x06, 0x00, 0x00},
366 {0xA0, 0x08, 0x00, 0x00, 0x00},
367 {0x94, 0x06, 0x00, 0x00, 0x00},
368 };
369
370 /* Authorized APDU for AID_41 */
371 std::vector<std::vector<uint8_t>> AUTHORIZED_APDU_AID_41 = {
372 {0x94, 0x06, 0x00, 0x00},
373 {0x94, 0x08, 0x00, 0x00, 0x00},
374 {0x94, 0x0C, 0x00, 0x00, 0x01, 0xAA, 0x00},
375 {0x94, 0x0A, 0x00, 0x00, 0x01, 0xAA}};
376 /* Unauthorized APDU for AID_41 */
377 std::vector<std::vector<uint8_t>> UNAUTHORIZED_APDU_AID_41 = {
378 {0x00, 0x06, 0x00, 0x00},
379 {0x80, 0x06, 0x00, 0x00},
380 {0xA0, 0x06, 0x00, 0x00},
381 {0x00, 0x08, 0x00, 0x00, 0x00},
382 {0x00, 0x0A, 0x00, 0x00, 0x01, 0xAA},
383 {0x80, 0x0A, 0x00, 0x00, 0x01, 0xAA},
384 {0xA0, 0x0A, 0x00, 0x00, 0x01, 0xAA},
385 {0x80, 0x08, 0x00, 0x00, 0x00},
386 {0xA0, 0x08, 0x00, 0x00, 0x00},
387 {0x00, 0x0C, 0x00, 0x00, 0x01, 0xAA, 0x00},
388 {0x80, 0x0C, 0x00, 0x00, 0x01, 0xAA, 0x00},
389 {0xA0, 0x0C, 0x00, 0x00, 0x01, 0xAA, 0x00},
390 };
391
392 std::shared_ptr<aidl::android::se::omapi::ISecureElementService> mOmapiSeService;
393
394 std::map<std::string, std::shared_ptr<aidl::android::se::omapi::ISecureElementReader>>
395 mVSReaders = {};
396 };
397
TEST_P(OMAPISEAccessControlTest,TestAuthorizedAID)398 TEST_P(OMAPISEAccessControlTest, TestAuthorizedAID) {
399 testSelectableAid(AUTHORIZED_AID);
400 }
401
TEST_P(OMAPISEAccessControlTest,TestUnauthorizedAID)402 TEST_P(OMAPISEAccessControlTest, TestUnauthorizedAID) {
403 testUnauthorisedAid(UNAUTHORIZED_AID);
404 }
405
TEST_P(OMAPISEAccessControlTest,TestAuthorizedAPDUAID40)406 TEST_P(OMAPISEAccessControlTest, TestAuthorizedAPDUAID40) {
407 testTransmitAPDU(AID_40, AUTHORIZED_APDU_AID_40);
408 }
409
TEST_P(OMAPISEAccessControlTest,TestUnauthorisedAPDUAID40)410 TEST_P(OMAPISEAccessControlTest, TestUnauthorisedAPDUAID40) {
411 testUnauthorisedAPDU(AID_40, UNAUTHORIZED_APDU_AID_40);
412 }
413
TEST_P(OMAPISEAccessControlTest,TestAuthorizedAPDUAID41)414 TEST_P(OMAPISEAccessControlTest, TestAuthorizedAPDUAID41) {
415 testTransmitAPDU(AID_41, AUTHORIZED_APDU_AID_41);
416 }
417
TEST_P(OMAPISEAccessControlTest,TestUnauthorisedAPDUAID41)418 TEST_P(OMAPISEAccessControlTest, TestUnauthorisedAPDUAID41) {
419 testUnauthorisedAPDU(AID_41, UNAUTHORIZED_APDU_AID_41);
420 }
421
422 INSTANTIATE_TEST_SUITE_P(PerInstance, OMAPISEAccessControlTest,
423 testing::ValuesIn(::android::getAidlHalInstanceNames(
424 aidl::android::se::omapi::ISecureElementService::descriptor)),
425 android::hardware::PrintInstanceNameToString);
426 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OMAPISEAccessControlTest);
427
428 } // namespace
429