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 #include "utility/ValidateXml.h"
36
37 using namespace std;
38 using namespace ::testing;
39 using namespace android;
40
main(int argc,char ** argv)41 int main(int argc, char** argv) {
42 InitGoogleTest(&argc, argv);
43 int status = RUN_ALL_TESTS();
44 return status;
45 }
46
47 namespace {
48
49 class OMAPISEServiceHalTest : public TestWithParam<std::string> {
50 protected:
51 class SEListener : public ::aidl::android::se::omapi::BnSecureElementListener {};
52
testSelectableAid(std::shared_ptr<aidl::android::se::omapi::ISecureElementReader> reader,std::vector<uint8_t> aid,std::vector<uint8_t> & selectResponse)53 void testSelectableAid(
54 std::shared_ptr<aidl::android::se::omapi::ISecureElementReader> reader,
55 std::vector<uint8_t> aid, std::vector<uint8_t>& selectResponse) {
56 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
57 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
58 auto seListener = ndk::SharedRefBase::make<::OMAPISEServiceHalTest::SEListener>();
59
60 ASSERT_NE(reader, nullptr) << "reader is null";
61
62 bool status = false;
63 auto res = reader->isSecureElementPresent(&status);
64 ASSERT_TRUE(res.isOk()) << res.getMessage();
65 ASSERT_TRUE(status);
66
67 res = reader->openSession(&session);
68 ASSERT_TRUE(res.isOk()) << res.getMessage();
69 ASSERT_NE(session, nullptr) << "Could not open session";
70
71 res = session->openLogicalChannel(aid, 0x00, seListener, &channel);
72 ASSERT_TRUE(res.isOk()) << res.getMessage();
73 ASSERT_NE(channel, nullptr) << "Could not open channel";
74
75 res = channel->getSelectResponse(&selectResponse);
76 ASSERT_TRUE(res.isOk()) << "failed to get Select Response";
77 ASSERT_GE(selectResponse.size(), 2);
78
79 if (channel != nullptr) channel->close();
80 if (session != nullptr) session->close();
81
82 ASSERT_EQ((selectResponse[selectResponse.size() - 1] & 0xFF), (0x00));
83 ASSERT_EQ((selectResponse[selectResponse.size() - 2] & 0xFF), (0x90));
84 }
85
testNonSelectableAid(std::shared_ptr<aidl::android::se::omapi::ISecureElementReader> reader,std::vector<uint8_t> aid)86 void testNonSelectableAid(
87 std::shared_ptr<aidl::android::se::omapi::ISecureElementReader> reader,
88 std::vector<uint8_t> aid) {
89 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
90 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
91 auto seListener = ndk::SharedRefBase::make<::OMAPISEServiceHalTest::SEListener>();
92
93 ASSERT_NE(reader, nullptr) << "reader is null";
94
95 bool status = false;
96 auto res = reader->isSecureElementPresent(&status);
97 ASSERT_TRUE(res.isOk()) << res.getMessage();
98 ASSERT_TRUE(status);
99
100 res = reader->openSession(&session);
101 ASSERT_TRUE(res.isOk()) << res.getMessage();
102 ASSERT_NE(session, nullptr) << "Could not open session";
103
104 res = session->openLogicalChannel(aid, 0x00, seListener, &channel);
105 if (channel != nullptr) channel->close();
106 if (session != nullptr) session->close();
107
108 LOG(ERROR) << res.getMessage();
109 ASSERT_FALSE(res.isOk()) << "expected to fail to open channel for this test";
110 }
111
112 /**
113 * Verifies TLV data
114 *
115 * @return true if the data is tlv formatted, false otherwise
116 */
verifyBerTlvData(std::vector<uint8_t> tlv)117 bool verifyBerTlvData(std::vector<uint8_t> tlv) {
118 if (tlv.size() == 0) {
119 LOG(ERROR) << "Invalid tlv, null";
120 return false;
121 }
122 int i = 0;
123 if ((tlv[i++] & 0x1F) == 0x1F) {
124 // extra byte for TAG field
125 i++;
126 }
127
128 int len = tlv[i++] & 0xFF;
129 if (len > 127) {
130 // more than 1 byte for length
131 int bytesLength = len - 128;
132 len = 0;
133 for (int j = bytesLength; j > 0; j--) {
134 len += (len << 8) + (tlv[i++] & 0xFF);
135 }
136 }
137 // Additional 2 bytes for the SW
138 return (tlv.size() == (i + len + 2));
139 }
140
internalTransmitApdu(std::shared_ptr<aidl::android::se::omapi::ISecureElementReader> reader,std::vector<uint8_t> apdu,std::vector<uint8_t> & transmitResponse)141 void internalTransmitApdu(
142 std::shared_ptr<aidl::android::se::omapi::ISecureElementReader> reader,
143 std::vector<uint8_t> apdu, std::vector<uint8_t>& transmitResponse) {
144 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
145 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
146 auto seListener = ndk::SharedRefBase::make<::OMAPISEServiceHalTest::SEListener>();
147 std::vector<uint8_t> selectResponse = {};
148
149 ASSERT_NE(reader, nullptr) << "reader is null";
150
151 bool status = false;
152 auto res = reader->isSecureElementPresent(&status);
153 ASSERT_TRUE(res.isOk()) << res.getMessage();
154 ASSERT_TRUE(status);
155
156 res = reader->openSession(&session);
157 ASSERT_TRUE(res.isOk()) << res.getMessage();
158 ASSERT_NE(session, nullptr) << "Could not open session";
159
160 res = session->openLogicalChannel(SELECTABLE_AID, 0x00, seListener, &channel);
161 ASSERT_TRUE(res.isOk()) << res.getMessage();
162 ASSERT_NE(channel, nullptr) << "Could not open channel";
163
164 res = channel->getSelectResponse(&selectResponse);
165 ASSERT_TRUE(res.isOk()) << "failed to get Select Response";
166 ASSERT_GE(selectResponse.size(), 2);
167
168 res = channel->transmit(apdu, &transmitResponse);
169 if (channel != nullptr) channel->close();
170 if (session != nullptr) session->close();
171 LOG(INFO) << "STATUS OF TRNSMIT: " << res.getExceptionCode()
172 << " Message: " << res.getMessage();
173 ASSERT_TRUE(res.isOk()) << "failed to transmit";
174 }
175
supportOMAPIReaders()176 bool supportOMAPIReaders() {
177 return (deviceSupportsFeature(FEATURE_SE_OMAPI_ESE.c_str()));
178 }
179
getUuidMappingFile()180 std::optional<std::string> getUuidMappingFile() {
181 char value[PROPERTY_VALUE_MAX] = {0};
182 int len = property_get("ro.boot.product.hardware.sku", value, "config");
183 std::string uuidMappingConfigFile = UUID_MAPPING_CONFIG_PREFIX
184 + std::string(value, len)
185 + UUID_MAPPING_CONFIG_EXT;
186 std::string uuidMapConfigPath;
187 // Search in predefined folders
188 for (auto path : UUID_MAPPING_CONFIG_PATHS) {
189 uuidMapConfigPath = path + uuidMappingConfigFile;
190 auto confFile = fopen(uuidMapConfigPath.c_str(), "r");
191 if (confFile) {
192 fclose(confFile);
193 return uuidMapConfigPath;
194 }
195 }
196 return std::optional<std::string>();
197 }
198
SetUp()199 void SetUp() override {
200 LOG(INFO) << "get OMAPI service with name:" << GetParam();
201 ::ndk::SpAIBinder ks2Binder(AServiceManager_getService(GetParam().c_str()));
202 mOmapiSeService = aidl::android::se::omapi::ISecureElementService::fromBinder(ks2Binder);
203 ASSERT_TRUE(mOmapiSeService);
204
205 std::vector<std::string> readers = {};
206
207 if (omapiSecureService() != NULL) {
208 auto status = omapiSecureService()->getReaders(&readers);
209 ASSERT_TRUE(status.isOk()) << status.getMessage();
210
211 for (auto readerName : readers) {
212 // Filter eSE readers only
213 if (readerName.find(ESE_READER_PREFIX, 0) != std::string::npos) {
214 std::shared_ptr<::aidl::android::se::omapi::ISecureElementReader> reader;
215 status = omapiSecureService()->getReader(readerName, &reader);
216 ASSERT_TRUE(status.isOk()) << status.getMessage();
217
218 mVSReaders[readerName] = reader;
219 }
220 }
221 }
222 }
223
TearDown()224 void TearDown() override {
225 if (mOmapiSeService != nullptr) {
226 if (mVSReaders.size() > 0) {
227 for (const auto& [name, reader] : mVSReaders) {
228 reader->closeSessions();
229 }
230 }
231 }
232 }
233
isDebuggableBuild()234 bool isDebuggableBuild() {
235 char value[PROPERTY_VALUE_MAX] = {0};
236 property_get("ro.system.build.type", value, "");
237 if (strcmp(value, "userdebug") == 0) {
238 return true;
239 }
240 if (strcmp(value, "eng") == 0) {
241 return true;
242 }
243 return false;
244 }
245
omapiSecureService()246 std::shared_ptr<aidl::android::se::omapi::ISecureElementService> omapiSecureService() {
247 return mOmapiSeService;
248 }
249
250 static inline std::string const ESE_READER_PREFIX = "eSE";
251 static inline std::string const FEATURE_SE_OMAPI_ESE = "android.hardware.se.omapi.ese";
252
253 std::vector<uint8_t> SELECTABLE_AID = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
254 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x31};
255 std::vector<uint8_t> LONG_SELECT_RESPONSE_AID = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
256 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
257 0x43, 0x54, 0x53, 0x32};
258 std::vector<uint8_t> NON_SELECTABLE_AID = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
259 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0xFF};
260
261 std::vector<std::vector<uint8_t>> ILLEGAL_COMMANDS_TRANSMIT = {
262 {0x00, 0x70, 0x00, 0x00},
263 {0x00, 0x70, 0x80, 0x00},
264 {0x00, 0xA4, 0x04, 0x04, 0x10, 0x4A, 0x53, 0x52, 0x31, 0x37, 0x37,
265 0x54, 0x65, 0x73, 0x74, 0x65, 0x72, 0x20, 0x31, 0x2E, 0x30}};
266
267 /* OMAPI APDU Test case 1 and 3 */
268 std::vector<std::vector<uint8_t>> NO_DATA_APDU = {{0x00, 0x06, 0x00, 0x00},
269 {0x80, 0x06, 0x00, 0x00},
270 {0xA0, 0x06, 0x00, 0x00},
271 {0x94, 0x06, 0x00, 0x00},
272 {0x00, 0x0A, 0x00, 0x00, 0x01, 0xAA},
273 {0x80, 0x0A, 0x00, 0x00, 0x01, 0xAA},
274 {0xA0, 0x0A, 0x00, 0x00, 0x01, 0xAA},
275 {0x94, 0x0A, 0x00, 0x00, 0x01, 0xAA}};
276
277 /* OMAPI APDU Test case 2 and 4 */
278 std::vector<std::vector<uint8_t>> DATA_APDU = {{0x00, 0x08, 0x00, 0x00, 0x00},
279 {0x80, 0x08, 0x00, 0x00, 0x00},
280 {0xA0, 0x08, 0x00, 0x00, 0x00},
281 {0x94, 0x08, 0x00, 0x00, 0x00},
282 {0x00, 0x0C, 0x00, 0x00, 0x01, 0xAA, 0x00},
283 {0x80, 0x0C, 0x00, 0x00, 0x01, 0xAA, 0x00},
284 {0xA0, 0x0C, 0x00, 0x00, 0x01, 0xAA, 0x00},
285 {0x94, 0x0C, 0x00, 0x00, 0x01, 0xAA, 0x00}};
286
287 /* Case 2 APDU command expects the P2 received in the SELECT command as 1-byte outgoing data */
288 std::vector<uint8_t> CHECK_SELECT_P2_APDU = {0x00, 0xF4, 0x00, 0x00, 0x00};
289
290 /* OMAPI APDU Test case 1 and 3 */
291 std::vector<std::vector<uint8_t>> SW_62xx_NO_DATA_APDU = {{0x00, 0xF3, 0x00, 0x06},
292 {0x00, 0xF3, 0x00, 0x0A, 0x01, 0xAA}};
293
294 /* OMAPI APDU Test case 2 and 4 */
295 std::vector<uint8_t> SW_62xx_DATA_APDU = {0x00, 0xF3, 0x00, 0x08, 0x00};
296 std::vector<uint8_t> SW_62xx_VALIDATE_DATA_APDU = {0x00, 0xF3, 0x00, 0x0C, 0x01, 0xAA, 0x00};
297 std::vector<std::vector<uint8_t>> SW_62xx = {
298 {0x62, 0x00}, {0x62, 0x81}, {0x62, 0x82}, {0x62, 0x83}, {0x62, 0x85}, {0x62, 0xF1},
299 {0x62, 0xF2}, {0x63, 0xF1}, {0x63, 0xF2}, {0x63, 0xC2}, {0x62, 0x02}, {0x62, 0x80},
300 {0x62, 0x84}, {0x62, 0x86}, {0x63, 0x00}, {0x63, 0x81}};
301
302 std::vector<std::vector<uint8_t>> SEGMENTED_RESP_APDU = {
303 // Get response Case2 61FF+61XX with answer length (P1P2) of 0x0800, 2048 bytes
304 {0x00, 0xC2, 0x08, 0x00, 0x00},
305 // Get response Case4 61FF+61XX with answer length (P1P2) of 0x0800, 2048 bytes
306 {0x00, 0xC4, 0x08, 0x00, 0x02, 0x12, 0x34, 0x00},
307 // Get response Case2 6100+61XX with answer length (P1P2) of 0x0800, 2048 bytes
308 {0x00, 0xC6, 0x08, 0x00, 0x00},
309 // Get response Case4 6100+61XX with answer length (P1P2) of 0x0800, 2048 bytes
310 {0x00, 0xC8, 0x08, 0x00, 0x02, 0x12, 0x34, 0x00},
311 // Test device buffer capacity 7FFF data
312 {0x00, 0xC2, 0x7F, 0xFF, 0x00},
313 // Get response 6CFF+61XX with answer length (P1P2) of 0x0800, 2048 bytes
314 {0x00, 0xCF, 0x08, 0x00, 0x00},
315 // Get response with another CLA with answer length (P1P2) of 0x0800, 2048 bytes
316 {0x94, 0xC2, 0x08, 0x00, 0x00}};
317 long SERVICE_CONNECTION_TIME_OUT = 3000;
318
319 std::shared_ptr<aidl::android::se::omapi::ISecureElementService> mOmapiSeService;
320
321 std::map<std::string, std::shared_ptr<aidl::android::se::omapi::ISecureElementReader>>
322 mVSReaders = {};
323
324 std::string UUID_MAPPING_CONFIG_PREFIX = "hal_uuid_map_";
325 std::string UUID_MAPPING_CONFIG_EXT = ".xml";
326 std::string UUID_MAPPING_CONFIG_PATHS[3] = {"/odm/etc/", "/vendor/etc/", "/etc/"};
327 };
328
329 /** Tests getReaders API */
TEST_P(OMAPISEServiceHalTest,TestGetReaders)330 TEST_P(OMAPISEServiceHalTest, TestGetReaders) {
331 std::vector<std::shared_ptr<aidl::android::se::omapi::ISecureElementReader>> eseReaders =
332 {};
333
334 for (const auto& [name, reader] : mVSReaders) {
335 bool status = false;
336 LOG(INFO) << "Name of the reader: " << name;
337
338 if (reader) {
339 auto res = reader->isSecureElementPresent(&status);
340 ASSERT_TRUE(res.isOk()) << res.getMessage();
341 }
342 ASSERT_TRUE(status);
343
344 if (name.find(ESE_READER_PREFIX) == std::string::npos) {
345 LOG(ERROR) << "Incorrect Reader name";
346 FAIL();
347 }
348
349 if (name.find(ESE_READER_PREFIX, 0) != std::string::npos) {
350 eseReaders.push_back(reader);
351 } else {
352 LOG(INFO) << "Reader not supported: " << name;
353 FAIL();
354 }
355 }
356
357 if (deviceSupportsFeature(FEATURE_SE_OMAPI_ESE.c_str())) {
358 ASSERT_GE(eseReaders.size(), 1);
359 } else {
360 ASSERT_TRUE(eseReaders.size() == 0);
361 }
362 }
363
364 /** Tests OpenBasicChannel API when aid is null */
TEST_P(OMAPISEServiceHalTest,TestOpenBasicChannelNullAid)365 TEST_P(OMAPISEServiceHalTest, TestOpenBasicChannelNullAid) {
366 ASSERT_TRUE(supportOMAPIReaders() == true);
367 std::vector<uint8_t> aid = {};
368 auto seListener = ndk::SharedRefBase::make<::OMAPISEServiceHalTest::SEListener>();
369
370 if (mVSReaders.size() > 0) {
371 for (const auto& [name, reader] : mVSReaders) {
372 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
373 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
374 bool result = false;
375
376 auto status = reader->openSession(&session);
377 ASSERT_TRUE(status.isOk()) << status.getMessage();
378 if (!session) {
379 LOG(ERROR) << "Could not open session";
380 FAIL();
381 }
382
383 status = session->openBasicChannel(aid, 0x00, seListener, &channel);
384 ASSERT_TRUE(status.isOk()) << status.getMessage();
385
386 if (channel != nullptr) channel->close();
387 if (session != nullptr) session->close();
388
389 if (channel != nullptr) {
390 status = channel->isBasicChannel(&result);
391 ASSERT_TRUE(status.isOk()) << "Basic Channel cannot be opened";
392 }
393 }
394 }
395 }
396
397 /** Tests OpenBasicChannel API when aid is provided */
TEST_P(OMAPISEServiceHalTest,TestOpenBasicChannelNonNullAid)398 TEST_P(OMAPISEServiceHalTest, TestOpenBasicChannelNonNullAid) {
399 ASSERT_TRUE(supportOMAPIReaders() == true);
400 auto seListener = ndk::SharedRefBase::make<::OMAPISEServiceHalTest::SEListener>();
401
402 if (mVSReaders.size() > 0) {
403 for (const auto& [name, reader] : mVSReaders) {
404 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
405 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
406 bool result = false;
407
408 auto status = reader->openSession(&session);
409 ASSERT_TRUE(status.isOk()) << status.getMessage();
410 if (!session) {
411 LOG(ERROR) << "Could not open session";
412 FAIL();
413 }
414
415 status = session->openBasicChannel(SELECTABLE_AID, 0x00, seListener, &channel);
416 ASSERT_TRUE(status.isOk()) << status.getMessage();
417
418 if (channel != nullptr) channel->close();
419 if (session != nullptr) session->close();
420
421 if (channel != nullptr) {
422 status = channel->isBasicChannel(&result);
423 ASSERT_TRUE(status.isOk()) << "Basic Channel cannot be opened";
424 }
425 }
426 }
427 }
428
429 /** Tests Select API */
TEST_P(OMAPISEServiceHalTest,TestSelectableAid)430 TEST_P(OMAPISEServiceHalTest, TestSelectableAid) {
431 ASSERT_TRUE(supportOMAPIReaders() == true);
432 if (mVSReaders.size() > 0) {
433 for (const auto& [name, reader] : mVSReaders) {
434 std::vector<uint8_t> selectResponse = {};
435 testSelectableAid(reader, SELECTABLE_AID, selectResponse);
436 }
437 }
438 }
439
440 /** Tests Select API */
TEST_P(OMAPISEServiceHalTest,TestLongSelectResponse)441 TEST_P(OMAPISEServiceHalTest, TestLongSelectResponse) {
442 ASSERT_TRUE(supportOMAPIReaders() == true);
443 if (mVSReaders.size() > 0) {
444 for (const auto& [name, reader] : mVSReaders) {
445 std::vector<uint8_t> selectResponse = {};
446 testSelectableAid(reader, LONG_SELECT_RESPONSE_AID, selectResponse);
447 ASSERT_TRUE(verifyBerTlvData(selectResponse)) << "Select Response is not complete";
448 }
449 }
450 }
451
452 /** Test to fail open channel with wrong aid */
TEST_P(OMAPISEServiceHalTest,TestWrongAid)453 TEST_P(OMAPISEServiceHalTest, TestWrongAid) {
454 ASSERT_TRUE(supportOMAPIReaders() == true);
455 if (mVSReaders.size() > 0) {
456 for (const auto& [name, reader] : mVSReaders) {
457 testNonSelectableAid(reader, NON_SELECTABLE_AID);
458 }
459 }
460 }
461
462 /** Tests with invalid cmds in Transmit */
TEST_P(OMAPISEServiceHalTest,TestSecurityExceptionInTransmit)463 TEST_P(OMAPISEServiceHalTest, TestSecurityExceptionInTransmit) {
464 ASSERT_TRUE(supportOMAPIReaders() == true);
465 if (mVSReaders.size() > 0) {
466 for (const auto& [name, reader] : mVSReaders) {
467 std::shared_ptr<aidl::android::se::omapi::ISecureElementSession> session;
468 std::shared_ptr<aidl::android::se::omapi::ISecureElementChannel> channel;
469 auto seListener = ndk::SharedRefBase::make<::OMAPISEServiceHalTest::SEListener>();
470 std::vector<uint8_t> selectResponse = {};
471
472 ASSERT_NE(reader, nullptr) << "reader is null";
473
474 bool status = false;
475 auto res = reader->isSecureElementPresent(&status);
476 ASSERT_TRUE(res.isOk()) << res.getMessage();
477 ASSERT_TRUE(status);
478
479 res = reader->openSession(&session);
480 ASSERT_TRUE(res.isOk()) << res.getMessage();
481 ASSERT_NE(session, nullptr) << "Could not open session";
482
483 res = session->openLogicalChannel(SELECTABLE_AID, 0x00, seListener, &channel);
484 ASSERT_TRUE(res.isOk()) << res.getMessage();
485 ASSERT_NE(channel, nullptr) << "Could not open channel";
486
487 res = channel->getSelectResponse(&selectResponse);
488 ASSERT_TRUE(res.isOk()) << "failed to get Select Response";
489 ASSERT_GE(selectResponse.size(), 2);
490
491 ASSERT_EQ((selectResponse[selectResponse.size() - 1] & 0xFF), (0x00));
492 ASSERT_EQ((selectResponse[selectResponse.size() - 2] & 0xFF), (0x90));
493
494 for (auto cmd : ILLEGAL_COMMANDS_TRANSMIT) {
495 std::vector<uint8_t> response = {};
496 res = channel->transmit(cmd, &response);
497 ASSERT_EQ(res.getExceptionCode(), EX_SECURITY);
498 ASSERT_FALSE(res.isOk()) << "expected failed status for this test";
499 }
500 if (channel != nullptr) channel->close();
501 if (session != nullptr) session->close();
502 }
503 }
504 }
505
506 /**
507 * Tests Transmit API for all readers.
508 *
509 * Checks the return status and verifies the size of the
510 * response.
511 */
TEST_P(OMAPISEServiceHalTest,TestTransmitApdu)512 TEST_P(OMAPISEServiceHalTest, TestTransmitApdu) {
513 ASSERT_TRUE(supportOMAPIReaders() == true);
514 if (mVSReaders.size() > 0) {
515 for (const auto& [name, reader] : mVSReaders) {
516 for (auto apdu : NO_DATA_APDU) {
517 std::vector<uint8_t> response = {};
518 internalTransmitApdu(reader, apdu, response);
519 ASSERT_GE(response.size(), 2);
520 ASSERT_EQ((response[response.size() - 1] & 0xFF), (0x00));
521 ASSERT_EQ((response[response.size() - 2] & 0xFF), (0x90));
522 }
523
524 for (auto apdu : DATA_APDU) {
525 std::vector<uint8_t> response = {};
526 internalTransmitApdu(reader, apdu, response);
527 /* 256 byte data and 2 bytes of status word */
528 ASSERT_GE(response.size(), 258);
529 ASSERT_EQ((response[response.size() - 1] & 0xFF), (0x00));
530 ASSERT_EQ((response[response.size() - 2] & 0xFF), (0x90));
531 }
532 }
533 }
534 }
535
536 /**
537 * Tests if underlying implementations returns the correct Status Word
538 *
539 * TO verify that :
540 * - the device does not modify the APDU sent to the Secure Element
541 * - the warning code is properly received by the application layer as SW answer
542 * - the verify that the application layer can fetch the additionnal data (when present)
543 */
TEST_P(OMAPISEServiceHalTest,testStatusWordTransmit)544 TEST_P(OMAPISEServiceHalTest, testStatusWordTransmit) {
545 ASSERT_TRUE(supportOMAPIReaders() == true);
546 if (mVSReaders.size() > 0) {
547 for (const auto& [name, reader] : mVSReaders) {
548 for (auto apdu : SW_62xx_NO_DATA_APDU) {
549 for (uint8_t i = 0x00; i < SW_62xx.size(); i++) {
550 apdu[2] = i + 1;
551 std::vector<uint8_t> response = {};
552 internalTransmitApdu(reader, apdu, response);
553 std::vector<uint8_t> SW = SW_62xx[i];
554 ASSERT_GE(response.size(), 2);
555 ASSERT_EQ(response[response.size() - 1], SW[1]);
556 ASSERT_EQ(response[response.size() - 2], SW[0]);
557 }
558 }
559
560 for (uint8_t i = 0x00; i < SW_62xx.size(); i++) {
561 std::vector<uint8_t> apdu = SW_62xx_DATA_APDU;
562 apdu[2] = i + 1;
563 std::vector<uint8_t> response = {};
564 internalTransmitApdu(reader, apdu, response);
565 std::vector<uint8_t> SW = SW_62xx[i];
566 ASSERT_GE(response.size(), 3);
567 ASSERT_EQ(response[response.size() - 1], SW[1]);
568 ASSERT_EQ(response[response.size() - 2], SW[0]);
569 }
570
571 for (uint8_t i = 0x00; i < SW_62xx.size(); i++) {
572 std::vector<uint8_t> apdu = SW_62xx_VALIDATE_DATA_APDU;
573 apdu[2] = i + 1;
574 std::vector<uint8_t> response = {};
575 internalTransmitApdu(reader, apdu, response);
576 ASSERT_GE(response.size(), apdu.size() + 2);
577 std::vector<uint8_t> responseSubstring((response.begin() + 0),
578 (response.begin() + apdu.size()));
579 // We should not care about which channel number is actually assigned.
580 responseSubstring[0] = apdu[0];
581 ASSERT_TRUE((responseSubstring == apdu));
582 std::vector<uint8_t> SW = SW_62xx[i];
583 ASSERT_EQ(response[response.size() - 1], SW[1]);
584 ASSERT_EQ(response[response.size() - 2], SW[0]);
585 }
586 }
587 }
588 }
589
590 /** Test if the responses are segmented by the underlying implementation */
TEST_P(OMAPISEServiceHalTest,TestSegmentedResponseTransmit)591 TEST_P(OMAPISEServiceHalTest, TestSegmentedResponseTransmit) {
592 ASSERT_TRUE(supportOMAPIReaders() == true);
593 if (mVSReaders.size() > 0) {
594 for (const auto& [name, reader] : mVSReaders) {
595 for (auto apdu : SEGMENTED_RESP_APDU) {
596 std::vector<uint8_t> response = {};
597 internalTransmitApdu(reader, apdu, response);
598 int expectedLength = (0x00 << 24) | (0x00 << 16) | (apdu[2] << 8) | apdu[3];
599 ASSERT_EQ(response.size(), (expectedLength + 2));
600 ASSERT_EQ((response[response.size() - 1] & 0xFF), (0x00));
601 ASSERT_EQ((response[response.size() - 2] & 0xFF), (0x90));
602 ASSERT_EQ((response[response.size() - 3] & 0xFF), (0xFF));
603 }
604 }
605 }
606 }
607
608 /**
609 * Tests the P2 value of the select command.
610 *
611 * Verifies that the default P2 value (0x00) is not modified by the underlying implementation.
612 */
TEST_P(OMAPISEServiceHalTest,TestP2Value)613 TEST_P(OMAPISEServiceHalTest, TestP2Value) {
614 ASSERT_TRUE(supportOMAPIReaders() == true);
615 if (mVSReaders.size() > 0) {
616 for (const auto& [name, reader] : mVSReaders) {
617 std::vector<uint8_t> response = {};
618 internalTransmitApdu(reader, CHECK_SELECT_P2_APDU, response);
619 ASSERT_GE(response.size(), 3);
620 ASSERT_EQ((response[response.size() - 1] & 0xFF), (0x00));
621 ASSERT_EQ((response[response.size() - 2] & 0xFF), (0x90));
622 ASSERT_EQ((response[response.size() - 3] & 0xFF), (0x00));
623 }
624 }
625 }
626
TEST_P(OMAPISEServiceHalTest,TestUuidMappingConfig)627 TEST_P(OMAPISEServiceHalTest, TestUuidMappingConfig) {
628 constexpr const char* xsd = "/data/local/tmp/omapi_uuid_map_config.xsd";
629 auto uuidMappingFile = getUuidMappingFile();
630 ASSERT_TRUE(uuidMappingFile.has_value()) << "Unable to determine UUID mapping config file path";
631 LOG(INFO) << "UUID Mapping config file: " << uuidMappingFile.value();
632 EXPECT_VALID_XML(uuidMappingFile->c_str(), xsd);
633 }
634
635 INSTANTIATE_TEST_SUITE_P(PerInstance, OMAPISEServiceHalTest,
636 testing::ValuesIn(::android::getAidlHalInstanceNames(
637 aidl::android::se::omapi::ISecureElementService::descriptor)),
638 android::hardware::PrintInstanceNameToString);
639 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OMAPISEServiceHalTest);
640
641 } // namespace
642