blob: 16b8236eff2cf695391003798828d5ffcc003b55 [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/android/hardware/secure_element/BnSecureElement.h>
18
19#include <android-base/hex.h>
20#include <android-base/logging.h>
21#include <android/binder_manager.h>
22#include <android/binder_process.h>
23
24using aidl::android::hardware::secure_element::BnSecureElement;
25using aidl::android::hardware::secure_element::ISecureElementCallback;
26using aidl::android::hardware::secure_element::LogicalChannelResponse;
27using android::base::HexString;
28using ndk::ScopedAStatus;
29
30static const std::vector<uint8_t> kAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
31 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
32 0x43, 0x54, 0x53, 0x31};
33static const std::vector<uint8_t> kLongAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
34 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
35 0x43, 0x54, 0x53, 0x32};
36
37class MySecureElement : public BnSecureElement {
38 public:
39 ScopedAStatus closeChannel(int8_t channelNumber) override {
40 LOG(INFO) << __func__ << " channel number: " << channelNumber;
41 return ScopedAStatus::ok();
42 }
43 ScopedAStatus getAtr(std::vector<uint8_t>* _aidl_return) override {
44 LOG(INFO) << __func__;
45 _aidl_return->clear();
46 return ScopedAStatus::ok();
47 }
48 ScopedAStatus init(const std::shared_ptr<ISecureElementCallback>& clientCallback) override {
49 LOG(INFO) << __func__ << " callback: " << clientCallback.get();
50 if (!clientCallback) {
51 return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
52 }
53 mCb = clientCallback;
54 mCb->onStateChange(true, "");
55 return ScopedAStatus::ok();
56 }
57 ScopedAStatus isCardPresent(bool* _aidl_return) override {
58 LOG(INFO) << __func__;
59 *_aidl_return = true;
60 return ScopedAStatus::ok();
61 }
62 ScopedAStatus openBasicChannel(const std::vector<uint8_t>& aid, int8_t p2,
63 std::vector<uint8_t>* _aidl_return) override {
64 LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
65 << ") p2 " << p2;
66
67 // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
68 // The functionality here is enough to exercise the framework, but actual
69 // calls to the secure element will fail. This implementation does not model
70 // channel isolation or any other aspects important to implementing secure element.
71 *_aidl_return = {0x90, 0x00, 0x00}; // DO NOT COPY
72 return ScopedAStatus::ok();
73 }
74 ScopedAStatus openLogicalChannel(
75 const std::vector<uint8_t>& aid, int8_t p2,
76 ::aidl::android::hardware::secure_element::LogicalChannelResponse* _aidl_return)
77 override {
78 LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
79 << ") p2 " << p2;
80
81 if (aid != kAndroidTestAid && aid != kLongAndroidTestAid) {
82 return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
83 }
84
85 *_aidl_return = LogicalChannelResponse{.channelNumber = 1, .selectResponse = {}};
86
87 // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
88 // The functionality here is enough to exercise the framework, but actual
89 // calls to the secure element will fail. This implementation does not model
90 // channel isolation or any other aspects important to implementing secure element.
91 if (aid == kAndroidTestAid) { // DO NOT COPY
92 size_t size = 2050; // DO NOT COPY
93 _aidl_return->selectResponse.resize(size); // DO NOT COPY
94 _aidl_return->selectResponse[size - 1] = 0x00; // DO NOT COPY
95 _aidl_return->selectResponse[size - 2] = 0x90; // DO NOT COPY
96 } else { // DO NOT COPY
97 _aidl_return->selectResponse = {0x00, 0x00, 0x90, 0x00}; // DO NOT COPY
98 } // DO NOT COPY
99
100 LOG(INFO) << __func__ << " sending response: "
101 << HexString(_aidl_return->selectResponse.data(),
102 _aidl_return->selectResponse.size());
103
104 return ScopedAStatus::ok();
105 }
106 ScopedAStatus reset() override {
107 LOG(INFO) << __func__;
108 mCb->onStateChange(false, "reset");
109 mCb->onStateChange(true, "reset");
110 return ScopedAStatus::ok();
111 }
112 ScopedAStatus transmit(const std::vector<uint8_t>& data,
113 std::vector<uint8_t>* _aidl_return) override {
114 LOG(INFO) << __func__ << " data: " << HexString(data.data(), data.size()) << " ("
115 << data.size() << ")";
116
117 // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
118 // The functionality here is enough to exercise the framework, but actual
119 // calls to the secure element will fail. This implementation does not model
120 // channel isolation or any other aspects important to implementing secure element.
121
122 std::string hex = HexString(data.data(), data.size()); // DO NOT COPY
123 if (hex == "01a4040210a000000476416e64726f696443545331") { // DO NOT COPY
124 *_aidl_return = {0x00, 0x6A, 0x00}; // DO NOT COPY
125 } else if (data == std::vector<uint8_t>{0x00, 0xF4, 0x00, 0x00, 0x00}) { // DO NOT COPY
126 // CHECK_SELECT_P2_APDU w/ channel 1 // DO NOT COPY
127 *_aidl_return = {0x00, 0x90, 0x00}; // DO NOT COPY
128 } else if (data == std::vector<uint8_t>{0x01, 0xF4, 0x00, 0x00, 0x00}) { // DO NOT COPY
129 // CHECK_SELECT_P2_APDU w/ channel 1 // DO NOT COPY
130 *_aidl_return = {0x00, 0x90, 0x00}; // DO NOT COPY
131 } else if (data.size() == 5 || data.size() == 8) { // DO NOT COPY
132 // SEGMENTED_RESP_APDU - happens to use length 5 and 8 // DO NOT COPY
133 size_t size = (data[2] << 8 | data[3]) + 2; // DO NOT COPY
134 _aidl_return->resize(size); // DO NOT COPY
135 (*_aidl_return)[size - 1] = 0x00; // DO NOT COPY
136 (*_aidl_return)[size - 2] = 0x90; // DO NOT COPY
137 if (size >= 3) (*_aidl_return)[size - 3] = 0xFF; // DO NOT COPY
138 } else { // DO NOT COPY
139 *_aidl_return = {0x90, 0x00, 0x00}; // DO NOT COPY
140 } // DO NOT COPY
141
142 return ScopedAStatus::ok();
143 }
144
145 private:
146 std::shared_ptr<ISecureElementCallback> mCb;
147};
148
149int main() {
150 ABinderProcess_setThreadPoolMaxThreadCount(0);
151
152 auto se = ndk::SharedRefBase::make<MySecureElement>();
153 const std::string name = std::string() + BnSecureElement::descriptor + "/eSE1";
154 binder_status_t status = AServiceManager_addService(se->asBinder().get(), name.c_str());
155 CHECK_EQ(status, STATUS_OK);
156
157 ABinderProcess_joinThreadPool();
158 return EXIT_FAILURE; // should not reach
159}