1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker
17*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/secure_element/BnSecureElement.h>
18*4d7e907cSAndroid Build Coastguard Worker #include <android-base/hex.h>
19*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
20*4d7e907cSAndroid Build Coastguard Worker #include <android/binder_manager.h>
21*4d7e907cSAndroid Build Coastguard Worker #include <android/binder_process.h>
22*4d7e907cSAndroid Build Coastguard Worker
23*4d7e907cSAndroid Build Coastguard Worker #include <algorithm>
24*4d7e907cSAndroid Build Coastguard Worker
25*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::secure_element::BnSecureElement;
26*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::secure_element::ISecureElementCallback;
27*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::secure_element::LogicalChannelResponse;
28*4d7e907cSAndroid Build Coastguard Worker using android::base::HexString;
29*4d7e907cSAndroid Build Coastguard Worker using ndk::ScopedAStatus;
30*4d7e907cSAndroid Build Coastguard Worker
31*4d7e907cSAndroid Build Coastguard Worker static const std::vector<uint8_t> kIssuerSecurityDomainSelectResponse = {0x00, 0x00, 0x90, 0x00};
32*4d7e907cSAndroid Build Coastguard Worker
33*4d7e907cSAndroid Build Coastguard Worker namespace se {
34*4d7e907cSAndroid Build Coastguard Worker // Application identifier.
35*4d7e907cSAndroid Build Coastguard Worker using Aid = std::vector<uint8_t>;
36*4d7e907cSAndroid Build Coastguard Worker
37*4d7e907cSAndroid Build Coastguard Worker // ISO7816 APDU status codes.
38*4d7e907cSAndroid Build Coastguard Worker enum Status : uint16_t {
39*4d7e907cSAndroid Build Coastguard Worker SW_WRONG_DATA = 0x6A80,
40*4d7e907cSAndroid Build Coastguard Worker SW_LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881,
41*4d7e907cSAndroid Build Coastguard Worker SW_CONDITIONS_NOT_SATISFIED = 0x6985,
42*4d7e907cSAndroid Build Coastguard Worker SW_INCORRECT_P1P2 = 0x6A86,
43*4d7e907cSAndroid Build Coastguard Worker SW_BYTES_REMAINING_00 = 0x6100,
44*4d7e907cSAndroid Build Coastguard Worker SW_WRONG_LENGTH = 0x6700,
45*4d7e907cSAndroid Build Coastguard Worker SW_CORRECT_LENGTH_00 = 0x6C00,
46*4d7e907cSAndroid Build Coastguard Worker SW_INS_NOT_SUPPORTED = 0x6D00,
47*4d7e907cSAndroid Build Coastguard Worker SW_NO_ERROR = 0x9000,
48*4d7e907cSAndroid Build Coastguard Worker };
49*4d7e907cSAndroid Build Coastguard Worker
50*4d7e907cSAndroid Build Coastguard Worker // Type for raw APDUs.
51*4d7e907cSAndroid Build Coastguard Worker using RawApdu = std::vector<uint8_t>;
52*4d7e907cSAndroid Build Coastguard Worker
53*4d7e907cSAndroid Build Coastguard Worker // Wrap a command APDU (Application Processing Data Unit) to provide
54*4d7e907cSAndroid Build Coastguard Worker // accessors for header fields.
55*4d7e907cSAndroid Build Coastguard Worker struct Apdu {
56*4d7e907cSAndroid Build Coastguard Worker public:
57*4d7e907cSAndroid Build Coastguard Worker // Construct a command Apdu.
Apduse::Apdu58*4d7e907cSAndroid Build Coastguard Worker Apdu(std::vector<uint8_t> packet) : bytes_(std::move(packet)) {
59*4d7e907cSAndroid Build Coastguard Worker CHECK(bytes_.size() >= kHeaderSize) << "command APDU created with invalid length";
60*4d7e907cSAndroid Build Coastguard Worker size_t payload_len = bytes_.size() - kHeaderSize;
61*4d7e907cSAndroid Build Coastguard Worker
62*4d7e907cSAndroid Build Coastguard Worker // TODO(b/123254068) - add support for extended command APDUs.
63*4d7e907cSAndroid Build Coastguard Worker // Pre compute Lc and Le.
64*4d7e907cSAndroid Build Coastguard Worker
65*4d7e907cSAndroid Build Coastguard Worker // Case 1: CLA | INS | P1 | P2
66*4d7e907cSAndroid Build Coastguard Worker if (payload_len == 0) {
67*4d7e907cSAndroid Build Coastguard Worker lc_ = 0;
68*4d7e907cSAndroid Build Coastguard Worker le_ = 0;
69*4d7e907cSAndroid Build Coastguard Worker return;
70*4d7e907cSAndroid Build Coastguard Worker }
71*4d7e907cSAndroid Build Coastguard Worker
72*4d7e907cSAndroid Build Coastguard Worker // Case 2: CLA | INS | P1 | P2 | Le
73*4d7e907cSAndroid Build Coastguard Worker // Le has a value of 1 to 255.
74*4d7e907cSAndroid Build Coastguard Worker if (payload_len == 1) {
75*4d7e907cSAndroid Build Coastguard Worker le_ = bytes_[kHeaderSize];
76*4d7e907cSAndroid Build Coastguard Worker le_ = le_ == 0 ? 256 : le_;
77*4d7e907cSAndroid Build Coastguard Worker lc_ = 0;
78*4d7e907cSAndroid Build Coastguard Worker return;
79*4d7e907cSAndroid Build Coastguard Worker }
80*4d7e907cSAndroid Build Coastguard Worker
81*4d7e907cSAndroid Build Coastguard Worker // Case 3: CLA | INS | P1 | P2 | Lc | Data
82*4d7e907cSAndroid Build Coastguard Worker // Lc is less than 256 bytes
83*4d7e907cSAndroid Build Coastguard Worker // of data, and Le is zero.
84*4d7e907cSAndroid Build Coastguard Worker lc_ = bytes_[kHeaderSize];
85*4d7e907cSAndroid Build Coastguard Worker if (payload_len <= (1 + lc_)) {
86*4d7e907cSAndroid Build Coastguard Worker le_ = 0;
87*4d7e907cSAndroid Build Coastguard Worker }
88*4d7e907cSAndroid Build Coastguard Worker
89*4d7e907cSAndroid Build Coastguard Worker // Case 4: CLA | INS | P1 | P2 | Lc | Data | Le
90*4d7e907cSAndroid Build Coastguard Worker // The legacy Case 4. Lc and Le
91*4d7e907cSAndroid Build Coastguard Worker // are less than 256 bytes of data.
92*4d7e907cSAndroid Build Coastguard Worker else {
93*4d7e907cSAndroid Build Coastguard Worker le_ = bytes_[bytes_.size() - 1];
94*4d7e907cSAndroid Build Coastguard Worker le_ = le_ == 0 ? 256 : le_;
95*4d7e907cSAndroid Build Coastguard Worker }
96*4d7e907cSAndroid Build Coastguard Worker }
97*4d7e907cSAndroid Build Coastguard Worker
98*4d7e907cSAndroid Build Coastguard Worker // Construct a response Apdu with data.
CreateResponsese::Apdu99*4d7e907cSAndroid Build Coastguard Worker static RawApdu CreateResponse(std::vector<uint8_t> data, Status status) {
100*4d7e907cSAndroid Build Coastguard Worker // Append status word.
101*4d7e907cSAndroid Build Coastguard Worker data.push_back(status >> 8);
102*4d7e907cSAndroid Build Coastguard Worker data.push_back(status);
103*4d7e907cSAndroid Build Coastguard Worker return data;
104*4d7e907cSAndroid Build Coastguard Worker }
105*4d7e907cSAndroid Build Coastguard Worker
106*4d7e907cSAndroid Build Coastguard Worker // Construct a response Apdu with no data.
CreateResponsese::Apdu107*4d7e907cSAndroid Build Coastguard Worker static RawApdu CreateResponse(Status status) {
108*4d7e907cSAndroid Build Coastguard Worker // Append status word.
109*4d7e907cSAndroid Build Coastguard Worker return std::vector<uint8_t>{static_cast<uint8_t>(status >> 8),
110*4d7e907cSAndroid Build Coastguard Worker static_cast<uint8_t>(status)};
111*4d7e907cSAndroid Build Coastguard Worker }
112*4d7e907cSAndroid Build Coastguard Worker
113*4d7e907cSAndroid Build Coastguard Worker // Return if command APDU is extended.
114*4d7e907cSAndroid Build Coastguard Worker // The ISO/IEC 7816-4:2013 specification defines an extended APDU as any APDU
115*4d7e907cSAndroid Build Coastguard Worker // whose payload data, response data or expected data length exceeds the 256
116*4d7e907cSAndroid Build Coastguard Worker // byte limit.
IsExtendedse::Apdu117*4d7e907cSAndroid Build Coastguard Worker bool IsExtended() const { return (bytes_.size() - kHeaderSize) > 256; }
118*4d7e907cSAndroid Build Coastguard Worker
119*4d7e907cSAndroid Build Coastguard Worker // Return if command APDU has payload bytes.
HasPayloadse::Apdu120*4d7e907cSAndroid Build Coastguard Worker bool HasPayload() const { return bytes_.size() > kHeaderSize; }
121*4d7e907cSAndroid Build Coastguard Worker
get_clase::Apdu122*4d7e907cSAndroid Build Coastguard Worker uint8_t get_cla() const { return bytes_[0]; }
get_insse::Apdu123*4d7e907cSAndroid Build Coastguard Worker uint8_t get_ins() const { return bytes_[1]; }
get_p1se::Apdu124*4d7e907cSAndroid Build Coastguard Worker uint8_t get_p1() const { return bytes_[2]; }
get_p2se::Apdu125*4d7e907cSAndroid Build Coastguard Worker uint8_t get_p2() const { return bytes_[3]; }
126*4d7e907cSAndroid Build Coastguard Worker
127*4d7e907cSAndroid Build Coastguard Worker // Return the channel number encoded in the CLA field.
get_channel_numberse::Apdu128*4d7e907cSAndroid Build Coastguard Worker uint8_t get_channel_number() const {
129*4d7e907cSAndroid Build Coastguard Worker // Type 4 commands — Encode legacy ISO/IEC 7816-4 logical channel
130*4d7e907cSAndroid Build Coastguard Worker // information. Type 16 commands — Defined by the ISO/IEC 7816-4:2013
131*4d7e907cSAndroid Build Coastguard Worker // specification to
132*4d7e907cSAndroid Build Coastguard Worker // encode information for additional 16 logical channels in the card.
133*4d7e907cSAndroid Build Coastguard Worker uint8_t cla = get_cla();
134*4d7e907cSAndroid Build Coastguard Worker return (cla & 0x40) == 0 ? cla & 0x3 : 4 + (cla & 0xf);
135*4d7e907cSAndroid Build Coastguard Worker }
136*4d7e907cSAndroid Build Coastguard Worker
137*4d7e907cSAndroid Build Coastguard Worker // Return the length of the command data field.
get_lcse::Apdu138*4d7e907cSAndroid Build Coastguard Worker uint16_t get_lc() const { return lc_; }
139*4d7e907cSAndroid Build Coastguard Worker
140*4d7e907cSAndroid Build Coastguard Worker // Return the expected length of the response data field.
141*4d7e907cSAndroid Build Coastguard Worker // Le should be have the same format as Lc.
get_lese::Apdu142*4d7e907cSAndroid Build Coastguard Worker uint16_t get_le() const { return le_; }
143*4d7e907cSAndroid Build Coastguard Worker
144*4d7e907cSAndroid Build Coastguard Worker // Get the pointer to the APDU raw data.
get_datase::Apdu145*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> const& get_data() const { return bytes_; }
146*4d7e907cSAndroid Build Coastguard Worker
147*4d7e907cSAndroid Build Coastguard Worker private:
148*4d7e907cSAndroid Build Coastguard Worker // Size of command header, including CLA, INS, P1, P2 fields.
149*4d7e907cSAndroid Build Coastguard Worker const size_t kHeaderSize = 4;
150*4d7e907cSAndroid Build Coastguard Worker
151*4d7e907cSAndroid Build Coastguard Worker // Command or response buffer.
152*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> bytes_{};
153*4d7e907cSAndroid Build Coastguard Worker
154*4d7e907cSAndroid Build Coastguard Worker // Lengths of command data field and expected response data field.
155*4d7e907cSAndroid Build Coastguard Worker uint16_t lc_{0};
156*4d7e907cSAndroid Build Coastguard Worker uint16_t le_{0};
157*4d7e907cSAndroid Build Coastguard Worker };
158*4d7e907cSAndroid Build Coastguard Worker
159*4d7e907cSAndroid Build Coastguard Worker // Type of SE applets.
160*4d7e907cSAndroid Build Coastguard Worker class Applet {
161*4d7e907cSAndroid Build Coastguard Worker public:
~Applet()162*4d7e907cSAndroid Build Coastguard Worker virtual ~Applet() {}
163*4d7e907cSAndroid Build Coastguard Worker
164*4d7e907cSAndroid Build Coastguard Worker // Called to inform this applet that it has been selected.
165*4d7e907cSAndroid Build Coastguard Worker virtual RawApdu Select(Aid const& aid, uint8_t p2) = 0;
166*4d7e907cSAndroid Build Coastguard Worker
167*4d7e907cSAndroid Build Coastguard Worker // Called by the Java Card runtime environment to process an
168*4d7e907cSAndroid Build Coastguard Worker // incoming APDU command. SELECT commands are processed by \ref select
169*4d7e907cSAndroid Build Coastguard Worker // instead.
170*4d7e907cSAndroid Build Coastguard Worker virtual RawApdu Process(Apdu const& apdu) = 0;
171*4d7e907cSAndroid Build Coastguard Worker };
172*4d7e907cSAndroid Build Coastguard Worker }; // namespace se
173*4d7e907cSAndroid Build Coastguard Worker
174*4d7e907cSAndroid Build Coastguard Worker // Implement the Google-eSE-test.cap test applet for passing OMAPI CTS tests
175*4d7e907cSAndroid Build Coastguard Worker // on Cuttlefish. The reference can be found here:
176*4d7e907cSAndroid Build Coastguard Worker // cts/tests/tests/secure_element/sample_applet/src/com/android/cts/omapi/test/CtsAndroidOmapiTestApplet.java
177*4d7e907cSAndroid Build Coastguard Worker class CtsAndroidOmapiTestApplet : public se::Applet {
178*4d7e907cSAndroid Build Coastguard Worker public:
CtsAndroidOmapiTestApplet()179*4d7e907cSAndroid Build Coastguard Worker CtsAndroidOmapiTestApplet() {}
~CtsAndroidOmapiTestApplet()180*4d7e907cSAndroid Build Coastguard Worker virtual ~CtsAndroidOmapiTestApplet() {}
181*4d7e907cSAndroid Build Coastguard Worker
Select(se::Aid const & aid,uint8_t)182*4d7e907cSAndroid Build Coastguard Worker se::RawApdu Select(se::Aid const& aid, uint8_t /*p2*/) override {
183*4d7e907cSAndroid Build Coastguard Worker if (aid[aid.size() - 1] == 0x31) {
184*4d7e907cSAndroid Build Coastguard Worker // AID: A000000476416E64726F696443545331
185*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(se::Status::SW_NO_ERROR);
186*4d7e907cSAndroid Build Coastguard Worker } else {
187*4d7e907cSAndroid Build Coastguard Worker // AID: A000000476416E64726F696443545332
188*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(GenerateBerTLVBytes(SELECT_RESPONSE_DATA_LENGTH),
189*4d7e907cSAndroid Build Coastguard Worker se::Status::SW_NO_ERROR);
190*4d7e907cSAndroid Build Coastguard Worker }
191*4d7e907cSAndroid Build Coastguard Worker }
192*4d7e907cSAndroid Build Coastguard Worker
ReadNextResponseChunk(uint16_t max_output_len)193*4d7e907cSAndroid Build Coastguard Worker se::RawApdu ReadNextResponseChunk(uint16_t max_output_len) {
194*4d7e907cSAndroid Build Coastguard Worker uint16_t output_len = static_cast<uint16_t>(response_.size() - response_offset_);
195*4d7e907cSAndroid Build Coastguard Worker output_len = std::min<uint16_t>(max_output_len, output_len);
196*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> output{
197*4d7e907cSAndroid Build Coastguard Worker &response_[response_offset_],
198*4d7e907cSAndroid Build Coastguard Worker &response_[response_offset_ + output_len],
199*4d7e907cSAndroid Build Coastguard Worker };
200*4d7e907cSAndroid Build Coastguard Worker response_offset_ += output_len;
201*4d7e907cSAndroid Build Coastguard Worker uint16_t remaining_len = response_.size() - response_offset_;
202*4d7e907cSAndroid Build Coastguard Worker se::Status status = se::Status::SW_NO_ERROR;
203*4d7e907cSAndroid Build Coastguard Worker if (remaining_len > 0) {
204*4d7e907cSAndroid Build Coastguard Worker if (remaining_len > 256) {
205*4d7e907cSAndroid Build Coastguard Worker remaining_len = 0x00;
206*4d7e907cSAndroid Build Coastguard Worker }
207*4d7e907cSAndroid Build Coastguard Worker status = se::Status(se::Status::SW_BYTES_REMAINING_00 | remaining_len);
208*4d7e907cSAndroid Build Coastguard Worker } else {
209*4d7e907cSAndroid Build Coastguard Worker response_.clear();
210*4d7e907cSAndroid Build Coastguard Worker response_offset_ = 0;
211*4d7e907cSAndroid Build Coastguard Worker }
212*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(output, status);
213*4d7e907cSAndroid Build Coastguard Worker }
214*4d7e907cSAndroid Build Coastguard Worker
Process(se::Apdu const & apdu)215*4d7e907cSAndroid Build Coastguard Worker se::RawApdu Process(se::Apdu const& apdu) override {
216*4d7e907cSAndroid Build Coastguard Worker uint16_t lc;
217*4d7e907cSAndroid Build Coastguard Worker uint16_t le = apdu.get_le();
218*4d7e907cSAndroid Build Coastguard Worker uint8_t p1 = apdu.get_p1();
219*4d7e907cSAndroid Build Coastguard Worker uint8_t p2 = apdu.get_p2();
220*4d7e907cSAndroid Build Coastguard Worker
221*4d7e907cSAndroid Build Coastguard Worker switch (apdu.get_ins()) {
222*4d7e907cSAndroid Build Coastguard Worker case NO_DATA_INS_1:
223*4d7e907cSAndroid Build Coastguard Worker case NO_DATA_INS_2:
224*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": NO_DATA_INS_1|2";
225*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(se::Status::SW_NO_ERROR);
226*4d7e907cSAndroid Build Coastguard Worker
227*4d7e907cSAndroid Build Coastguard Worker case DATA_INS_1:
228*4d7e907cSAndroid Build Coastguard Worker case DATA_INS_2:
229*4d7e907cSAndroid Build Coastguard Worker // Return 256 bytes of data.
230*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": DATA_INS_1|2";
231*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(GeneratesBytes(256), se::Status::SW_NO_ERROR);
232*4d7e907cSAndroid Build Coastguard Worker
233*4d7e907cSAndroid Build Coastguard Worker case GET_RESPONSE_INS:
234*4d7e907cSAndroid Build Coastguard Worker // ISO GET_RESPONSE command.
235*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": GET_RESPONSE_INS";
236*4d7e907cSAndroid Build Coastguard Worker if (response_.empty()) {
237*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(se::Status::SW_CONDITIONS_NOT_SATISFIED);
238*4d7e907cSAndroid Build Coastguard Worker }
239*4d7e907cSAndroid Build Coastguard Worker return ReadNextResponseChunk(apdu.get_le());
240*4d7e907cSAndroid Build Coastguard Worker
241*4d7e907cSAndroid Build Coastguard Worker case SW_62xx_APDU_INS:
242*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": SW_62xx_APDU_INS";
243*4d7e907cSAndroid Build Coastguard Worker if (p1 < 1 || p1 > 16) {
244*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(se::Status::SW_INCORRECT_P1P2);
245*4d7e907cSAndroid Build Coastguard Worker }
246*4d7e907cSAndroid Build Coastguard Worker if (p2 == SW_62xx_DATA_APDU_P2) {
247*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(GeneratesBytes(3),
248*4d7e907cSAndroid Build Coastguard Worker se::Status(SW_62xx_resp[p1 - 1]));
249*4d7e907cSAndroid Build Coastguard Worker }
250*4d7e907cSAndroid Build Coastguard Worker if (p2 == SW_62xx_VALIDATE_DATA_P2) {
251*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> output{SW_62xx_VALIDATE_DATA_RESP.begin(),
252*4d7e907cSAndroid Build Coastguard Worker SW_62xx_VALIDATE_DATA_RESP.end()};
253*4d7e907cSAndroid Build Coastguard Worker output[2] = p1;
254*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(std::move(output),
255*4d7e907cSAndroid Build Coastguard Worker se::Status(SW_62xx_resp[p1 - 1]));
256*4d7e907cSAndroid Build Coastguard Worker }
257*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(se::Status(SW_62xx_resp[p1 - 1]));
258*4d7e907cSAndroid Build Coastguard Worker
259*4d7e907cSAndroid Build Coastguard Worker case SEGMENTED_RESP_INS_1:
260*4d7e907cSAndroid Build Coastguard Worker case SEGMENTED_RESP_INS_2:
261*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_1|2";
262*4d7e907cSAndroid Build Coastguard Worker response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
263*4d7e907cSAndroid Build Coastguard Worker response_offset_ = 0;
264*4d7e907cSAndroid Build Coastguard Worker return ReadNextResponseChunk(std::min<uint16_t>(apdu.get_le(), 256));
265*4d7e907cSAndroid Build Coastguard Worker
266*4d7e907cSAndroid Build Coastguard Worker case SEGMENTED_RESP_INS_3:
267*4d7e907cSAndroid Build Coastguard Worker case SEGMENTED_RESP_INS_4:
268*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_3|4";
269*4d7e907cSAndroid Build Coastguard Worker response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
270*4d7e907cSAndroid Build Coastguard Worker response_offset_ = 0;
271*4d7e907cSAndroid Build Coastguard Worker return ReadNextResponseChunk(apdu.get_le());
272*4d7e907cSAndroid Build Coastguard Worker
273*4d7e907cSAndroid Build Coastguard Worker case SEGMENTED_RESP_INS_5:
274*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_5";
275*4d7e907cSAndroid Build Coastguard Worker if (le == 0xff) {
276*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(
277*4d7e907cSAndroid Build Coastguard Worker se::Status(se::Status::SW_CORRECT_LENGTH_00 | 0xff));
278*4d7e907cSAndroid Build Coastguard Worker }
279*4d7e907cSAndroid Build Coastguard Worker response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
280*4d7e907cSAndroid Build Coastguard Worker response_offset_ = 0;
281*4d7e907cSAndroid Build Coastguard Worker return ReadNextResponseChunk(apdu.get_le());
282*4d7e907cSAndroid Build Coastguard Worker
283*4d7e907cSAndroid Build Coastguard Worker case CHECK_SELECT_P2_APDU:
284*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": CHECK_SELECT_P2_APDU";
285*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(std::vector<uint8_t>{apdu.get_p2()},
286*4d7e907cSAndroid Build Coastguard Worker se::Status::SW_NO_ERROR);
287*4d7e907cSAndroid Build Coastguard Worker
288*4d7e907cSAndroid Build Coastguard Worker default:
289*4d7e907cSAndroid Build Coastguard Worker // Case is not known.
290*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << ": UNKNOWN_INS";
291*4d7e907cSAndroid Build Coastguard Worker return se::Apdu::CreateResponse(se::Status::SW_INS_NOT_SUPPORTED);
292*4d7e907cSAndroid Build Coastguard Worker }
293*4d7e907cSAndroid Build Coastguard Worker }
294*4d7e907cSAndroid Build Coastguard Worker
295*4d7e907cSAndroid Build Coastguard Worker private:
296*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> response_{};
297*4d7e907cSAndroid Build Coastguard Worker uint16_t response_offset_{0};
298*4d7e907cSAndroid Build Coastguard Worker
299*4d7e907cSAndroid Build Coastguard Worker static const uint8_t NO_DATA_INS_1 = 0x06;
300*4d7e907cSAndroid Build Coastguard Worker static const uint8_t NO_DATA_INS_2 = 0x0A;
301*4d7e907cSAndroid Build Coastguard Worker static const uint8_t DATA_INS_1 = 0x08;
302*4d7e907cSAndroid Build Coastguard Worker static const uint8_t DATA_INS_2 = 0x0C;
303*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SW_62xx_APDU_INS = 0xF3;
304*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SW_62xx_DATA_APDU_P2 = 0x08;
305*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SW_62xx_VALIDATE_DATA_P2 = 0x0C;
306*4d7e907cSAndroid Build Coastguard Worker
307*4d7e907cSAndroid Build Coastguard Worker static constexpr std::array<uint8_t, 7> SW_62xx_VALIDATE_DATA_RESP = {0x01, 0xF3, 0x00, 0x0C,
308*4d7e907cSAndroid Build Coastguard Worker 0x01, 0xAA, 0x00};
309*4d7e907cSAndroid Build Coastguard Worker static constexpr uint16_t SW_62xx_resp[] = {
310*4d7e907cSAndroid Build Coastguard Worker 0x6200, 0x6281, 0x6282, 0x6283, 0x6285, 0x62F1, 0x62F2, 0x63F1,
311*4d7e907cSAndroid Build Coastguard Worker 0x63F2, 0x63C2, 0x6202, 0x6280, 0x6284, 0x6286, 0x6300, 0x6381,
312*4d7e907cSAndroid Build Coastguard Worker };
313*4d7e907cSAndroid Build Coastguard Worker
314*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SEGMENTED_RESP_INS_1 = 0xC2;
315*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SEGMENTED_RESP_INS_2 = 0xC4;
316*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SEGMENTED_RESP_INS_3 = 0xC6;
317*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SEGMENTED_RESP_INS_4 = 0xC8;
318*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SEGMENTED_RESP_INS_5 = 0xCF;
319*4d7e907cSAndroid Build Coastguard Worker static const uint8_t CHECK_SELECT_P2_APDU = 0xF4;
320*4d7e907cSAndroid Build Coastguard Worker static const uint8_t GET_RESPONSE_INS = 0xC0;
321*4d7e907cSAndroid Build Coastguard Worker static const uint8_t BER_TLV_TYPE = 0x1F;
322*4d7e907cSAndroid Build Coastguard Worker static const uint16_t SELECT_RESPONSE_DATA_LENGTH = 252;
323*4d7e907cSAndroid Build Coastguard Worker
324*4d7e907cSAndroid Build Coastguard Worker static const uint16_t LENGTH_256 = 0x0100;
325*4d7e907cSAndroid Build Coastguard Worker static constexpr std::array<uint8_t, 256> resp_bytes256{
326*4d7e907cSAndroid Build Coastguard Worker 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
327*4d7e907cSAndroid Build Coastguard Worker 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
328*4d7e907cSAndroid Build Coastguard Worker 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
329*4d7e907cSAndroid Build Coastguard Worker 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
330*4d7e907cSAndroid Build Coastguard Worker 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
331*4d7e907cSAndroid Build Coastguard Worker 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
332*4d7e907cSAndroid Build Coastguard Worker 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61,
333*4d7e907cSAndroid Build Coastguard Worker 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
334*4d7e907cSAndroid Build Coastguard Worker 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D,
335*4d7e907cSAndroid Build Coastguard Worker 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B,
336*4d7e907cSAndroid Build Coastguard Worker 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
337*4d7e907cSAndroid Build Coastguard Worker 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
338*4d7e907cSAndroid Build Coastguard Worker 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
339*4d7e907cSAndroid Build Coastguard Worker 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3,
340*4d7e907cSAndroid Build Coastguard Worker 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1,
341*4d7e907cSAndroid Build Coastguard Worker 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
342*4d7e907cSAndroid Build Coastguard Worker 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED,
343*4d7e907cSAndroid Build Coastguard Worker 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB,
344*4d7e907cSAndroid Build Coastguard Worker 0xFC, 0xFD, 0xFE, 0xFF};
345*4d7e907cSAndroid Build Coastguard Worker
346*4d7e907cSAndroid Build Coastguard Worker // Generate a response buffer of the selected length containing valid
347*4d7e907cSAndroid Build Coastguard Worker // BER TLV bytes.
GenerateBerTLVBytes(uint16_t le)348*4d7e907cSAndroid Build Coastguard Worker static std::vector<uint8_t> GenerateBerTLVBytes(uint16_t le) {
349*4d7e907cSAndroid Build Coastguard Worker // Support length from 0x00 - 0x7FFF.
350*4d7e907cSAndroid Build Coastguard Worker uint16_t le_len = 1;
351*4d7e907cSAndroid Build Coastguard Worker if (le < (uint16_t)0x80) {
352*4d7e907cSAndroid Build Coastguard Worker le_len = 1;
353*4d7e907cSAndroid Build Coastguard Worker } else if (le < (uint16_t)0x100) {
354*4d7e907cSAndroid Build Coastguard Worker le_len = 2;
355*4d7e907cSAndroid Build Coastguard Worker } else {
356*4d7e907cSAndroid Build Coastguard Worker le_len = 3;
357*4d7e907cSAndroid Build Coastguard Worker }
358*4d7e907cSAndroid Build Coastguard Worker
359*4d7e907cSAndroid Build Coastguard Worker uint16_t total_len = (uint16_t)(le + 2 + le_len);
360*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> output(total_len);
361*4d7e907cSAndroid Build Coastguard Worker uint16_t i = 0;
362*4d7e907cSAndroid Build Coastguard Worker
363*4d7e907cSAndroid Build Coastguard Worker output[i++] = BER_TLV_TYPE;
364*4d7e907cSAndroid Build Coastguard Worker output[i++] = 0x00; // second byte of Type
365*4d7e907cSAndroid Build Coastguard Worker if (le < 0x80) {
366*4d7e907cSAndroid Build Coastguard Worker output[i++] = le;
367*4d7e907cSAndroid Build Coastguard Worker } else if (le < 0x100) {
368*4d7e907cSAndroid Build Coastguard Worker output[i++] = 0x81;
369*4d7e907cSAndroid Build Coastguard Worker output[i++] = le;
370*4d7e907cSAndroid Build Coastguard Worker } else {
371*4d7e907cSAndroid Build Coastguard Worker output[i++] = 0x82;
372*4d7e907cSAndroid Build Coastguard Worker output[i++] = (le >> 8);
373*4d7e907cSAndroid Build Coastguard Worker output[i++] = (le & 0xFF);
374*4d7e907cSAndroid Build Coastguard Worker }
375*4d7e907cSAndroid Build Coastguard Worker while (i < total_len) {
376*4d7e907cSAndroid Build Coastguard Worker output[i++] = ((i - 2 - le_len) & 0xFF);
377*4d7e907cSAndroid Build Coastguard Worker }
378*4d7e907cSAndroid Build Coastguard Worker
379*4d7e907cSAndroid Build Coastguard Worker // Set the last byte to 0xFF for CTS validation.
380*4d7e907cSAndroid Build Coastguard Worker output[total_len - 1] = 0xFF;
381*4d7e907cSAndroid Build Coastguard Worker return output;
382*4d7e907cSAndroid Build Coastguard Worker }
383*4d7e907cSAndroid Build Coastguard Worker
384*4d7e907cSAndroid Build Coastguard Worker // Generate a response buffer of the selected length using the
385*4d7e907cSAndroid Build Coastguard Worker // array resp_bytes256 as input.
GeneratesBytes(uint16_t total_len)386*4d7e907cSAndroid Build Coastguard Worker static std::vector<uint8_t> GeneratesBytes(uint16_t total_len) {
387*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> output(total_len);
388*4d7e907cSAndroid Build Coastguard Worker uint16_t i = 0;
389*4d7e907cSAndroid Build Coastguard Worker
390*4d7e907cSAndroid Build Coastguard Worker while (i < total_len) {
391*4d7e907cSAndroid Build Coastguard Worker if ((total_len - i) >= resp_bytes256.size()) {
392*4d7e907cSAndroid Build Coastguard Worker std::memcpy(&output[i], resp_bytes256.data(), resp_bytes256.size());
393*4d7e907cSAndroid Build Coastguard Worker i += resp_bytes256.size();
394*4d7e907cSAndroid Build Coastguard Worker } else {
395*4d7e907cSAndroid Build Coastguard Worker output[i] = i & 0xFF;
396*4d7e907cSAndroid Build Coastguard Worker i += 1;
397*4d7e907cSAndroid Build Coastguard Worker }
398*4d7e907cSAndroid Build Coastguard Worker }
399*4d7e907cSAndroid Build Coastguard Worker
400*4d7e907cSAndroid Build Coastguard Worker // Set the last byte to 0xFF for CTS validation.
401*4d7e907cSAndroid Build Coastguard Worker output[total_len - 1] = 0xFF;
402*4d7e907cSAndroid Build Coastguard Worker return output;
403*4d7e907cSAndroid Build Coastguard Worker }
404*4d7e907cSAndroid Build Coastguard Worker };
405*4d7e907cSAndroid Build Coastguard Worker
406*4d7e907cSAndroid Build Coastguard Worker class EmulatedSecureElement : public BnSecureElement {
407*4d7e907cSAndroid Build Coastguard Worker public:
EmulatedSecureElement()408*4d7e907cSAndroid Build Coastguard Worker EmulatedSecureElement() {
409*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<CtsAndroidOmapiTestApplet> test_applet =
410*4d7e907cSAndroid Build Coastguard Worker std::make_shared<CtsAndroidOmapiTestApplet>();
411*4d7e907cSAndroid Build Coastguard Worker
412*4d7e907cSAndroid Build Coastguard Worker applets_.push_back(std::pair{se::Aid{0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, 0x72,
413*4d7e907cSAndroid Build Coastguard Worker 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x31},
414*4d7e907cSAndroid Build Coastguard Worker test_applet});
415*4d7e907cSAndroid Build Coastguard Worker
416*4d7e907cSAndroid Build Coastguard Worker applets_.push_back(std::pair{se::Aid{0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, 0x72,
417*4d7e907cSAndroid Build Coastguard Worker 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x32},
418*4d7e907cSAndroid Build Coastguard Worker test_applet});
419*4d7e907cSAndroid Build Coastguard Worker }
420*4d7e907cSAndroid Build Coastguard Worker
init(const std::shared_ptr<ISecureElementCallback> & client_callback)421*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus init(const std::shared_ptr<ISecureElementCallback>& client_callback) override {
422*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " callback: " << client_callback.get();
423*4d7e907cSAndroid Build Coastguard Worker if (client_callback == nullptr) {
424*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
425*4d7e907cSAndroid Build Coastguard Worker }
426*4d7e907cSAndroid Build Coastguard Worker for (auto& channel : channels_) {
427*4d7e907cSAndroid Build Coastguard Worker channel = Channel();
428*4d7e907cSAndroid Build Coastguard Worker }
429*4d7e907cSAndroid Build Coastguard Worker client_callback_ = client_callback;
430*4d7e907cSAndroid Build Coastguard Worker client_callback_->onStateChange(true, "init");
431*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
432*4d7e907cSAndroid Build Coastguard Worker }
433*4d7e907cSAndroid Build Coastguard Worker
getAtr(std::vector<uint8_t> * aidl_return)434*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus getAtr(std::vector<uint8_t>* aidl_return) override {
435*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__;
436*4d7e907cSAndroid Build Coastguard Worker if (client_callback_ == nullptr) {
437*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
438*4d7e907cSAndroid Build Coastguard Worker }
439*4d7e907cSAndroid Build Coastguard Worker *aidl_return = atr_;
440*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
441*4d7e907cSAndroid Build Coastguard Worker }
442*4d7e907cSAndroid Build Coastguard Worker
reset()443*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus reset() override {
444*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__;
445*4d7e907cSAndroid Build Coastguard Worker if (client_callback_ == nullptr) {
446*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
447*4d7e907cSAndroid Build Coastguard Worker }
448*4d7e907cSAndroid Build Coastguard Worker client_callback_->onStateChange(false, "reset");
449*4d7e907cSAndroid Build Coastguard Worker client_callback_->onStateChange(true, "reset");
450*4d7e907cSAndroid Build Coastguard Worker // All channels are closed after reset.
451*4d7e907cSAndroid Build Coastguard Worker for (auto& channel : channels_) {
452*4d7e907cSAndroid Build Coastguard Worker channel = Channel();
453*4d7e907cSAndroid Build Coastguard Worker }
454*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
455*4d7e907cSAndroid Build Coastguard Worker }
456*4d7e907cSAndroid Build Coastguard Worker
isCardPresent(bool * aidl_return)457*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus isCardPresent(bool* aidl_return) override {
458*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__;
459*4d7e907cSAndroid Build Coastguard Worker if (client_callback_ == nullptr) {
460*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
461*4d7e907cSAndroid Build Coastguard Worker }
462*4d7e907cSAndroid Build Coastguard Worker *aidl_return = true;
463*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
464*4d7e907cSAndroid Build Coastguard Worker }
465*4d7e907cSAndroid Build Coastguard Worker
openBasicChannel(const std::vector<uint8_t> & aid,int8_t p2,std::vector<uint8_t> * aidl_return)466*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus openBasicChannel(const std::vector<uint8_t>& aid, int8_t p2,
467*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t>* aidl_return) override {
468*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
469*4d7e907cSAndroid Build Coastguard Worker << ") p2 " << p2;
470*4d7e907cSAndroid Build Coastguard Worker if (client_callback_ == nullptr) {
471*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
472*4d7e907cSAndroid Build Coastguard Worker }
473*4d7e907cSAndroid Build Coastguard Worker
474*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> select_response;
475*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<se::Applet> applet = nullptr;
476*4d7e907cSAndroid Build Coastguard Worker
477*4d7e907cSAndroid Build Coastguard Worker // The basic channel can only be opened once, and stays opened
478*4d7e907cSAndroid Build Coastguard Worker // and locked until the channel is closed.
479*4d7e907cSAndroid Build Coastguard Worker if (channels_[0].opened) {
480*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " basic channel already opened";
481*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromServiceSpecificError(CHANNEL_NOT_AVAILABLE);
482*4d7e907cSAndroid Build Coastguard Worker }
483*4d7e907cSAndroid Build Coastguard Worker
484*4d7e907cSAndroid Build Coastguard Worker // If the AID is defined (the AID is not Null and the length of the
485*4d7e907cSAndroid Build Coastguard Worker // AID is not 0) and the channel is not locked then the corresponding
486*4d7e907cSAndroid Build Coastguard Worker // applet shall be selected.
487*4d7e907cSAndroid Build Coastguard Worker if (aid.size() > 0) {
488*4d7e907cSAndroid Build Coastguard Worker applet = SelectApplet(aid);
489*4d7e907cSAndroid Build Coastguard Worker if (applet == nullptr) {
490*4d7e907cSAndroid Build Coastguard Worker // No applet registered with matching AID.
491*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " basic channel AID not found";
492*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
493*4d7e907cSAndroid Build Coastguard Worker }
494*4d7e907cSAndroid Build Coastguard Worker select_response = applet->Select(aid, p2);
495*4d7e907cSAndroid Build Coastguard Worker }
496*4d7e907cSAndroid Build Coastguard Worker
497*4d7e907cSAndroid Build Coastguard Worker // If the AID is a 0 length AID and the channel is not locked, the
498*4d7e907cSAndroid Build Coastguard Worker // method will select the Issuer Security Domain of the SE by sending a
499*4d7e907cSAndroid Build Coastguard Worker // SELECT command with a 0 length AID as defined in
500*4d7e907cSAndroid Build Coastguard Worker // [GP Card specification].
501*4d7e907cSAndroid Build Coastguard Worker if (aid.size() == 0) {
502*4d7e907cSAndroid Build Coastguard Worker select_response = kIssuerSecurityDomainSelectResponse;
503*4d7e907cSAndroid Build Coastguard Worker }
504*4d7e907cSAndroid Build Coastguard Worker
505*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " sending response: "
506*4d7e907cSAndroid Build Coastguard Worker << HexString(select_response.data(), select_response.size());
507*4d7e907cSAndroid Build Coastguard Worker
508*4d7e907cSAndroid Build Coastguard Worker // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
509*4d7e907cSAndroid Build Coastguard Worker // or APDU. The functionality here is enough to exercise the framework,
510*4d7e907cSAndroid Build Coastguard Worker // but actual calls to the secure element will fail. This implementation
511*4d7e907cSAndroid Build Coastguard Worker // does not model channel isolation or any other aspects important to
512*4d7e907cSAndroid Build Coastguard Worker // implementing secure element.
513*4d7e907cSAndroid Build Coastguard Worker channels_[0] = Channel(aid, p2, applet);
514*4d7e907cSAndroid Build Coastguard Worker *aidl_return = select_response;
515*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
516*4d7e907cSAndroid Build Coastguard Worker }
517*4d7e907cSAndroid Build Coastguard Worker
openLogicalChannel(const std::vector<uint8_t> & aid,int8_t p2,::aidl::android::hardware::secure_element::LogicalChannelResponse * aidl_return)518*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus openLogicalChannel(
519*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t>& aid, int8_t p2,
520*4d7e907cSAndroid Build Coastguard Worker ::aidl::android::hardware::secure_element::LogicalChannelResponse* aidl_return)
521*4d7e907cSAndroid Build Coastguard Worker override {
522*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
523*4d7e907cSAndroid Build Coastguard Worker << ") p2 " << p2;
524*4d7e907cSAndroid Build Coastguard Worker
525*4d7e907cSAndroid Build Coastguard Worker if (client_callback_ == nullptr) {
526*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
527*4d7e907cSAndroid Build Coastguard Worker }
528*4d7e907cSAndroid Build Coastguard Worker
529*4d7e907cSAndroid Build Coastguard Worker size_t channel_number = 1;
530*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> select_response;
531*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<se::Applet> applet = nullptr;
532*4d7e907cSAndroid Build Coastguard Worker
533*4d7e907cSAndroid Build Coastguard Worker // Look for an available channel number.
534*4d7e907cSAndroid Build Coastguard Worker for (; channel_number < channels_.size(); channel_number++) {
535*4d7e907cSAndroid Build Coastguard Worker if (channels_[channel_number].opened == false) {
536*4d7e907cSAndroid Build Coastguard Worker break;
537*4d7e907cSAndroid Build Coastguard Worker }
538*4d7e907cSAndroid Build Coastguard Worker }
539*4d7e907cSAndroid Build Coastguard Worker
540*4d7e907cSAndroid Build Coastguard Worker // All channels are currently allocated.
541*4d7e907cSAndroid Build Coastguard Worker if (channel_number >= channels_.size()) {
542*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " all logical channels already opened";
543*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromServiceSpecificError(CHANNEL_NOT_AVAILABLE);
544*4d7e907cSAndroid Build Coastguard Worker }
545*4d7e907cSAndroid Build Coastguard Worker
546*4d7e907cSAndroid Build Coastguard Worker // If the AID is defined (the AID is not Null and the length of the
547*4d7e907cSAndroid Build Coastguard Worker // AID is not 0) then the corresponding applet shall be selected.
548*4d7e907cSAndroid Build Coastguard Worker if (aid.size() > 0) {
549*4d7e907cSAndroid Build Coastguard Worker applet = SelectApplet(aid);
550*4d7e907cSAndroid Build Coastguard Worker if (applet == nullptr) {
551*4d7e907cSAndroid Build Coastguard Worker // No applet registered with matching AID.
552*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " logical channel AID not found";
553*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
554*4d7e907cSAndroid Build Coastguard Worker }
555*4d7e907cSAndroid Build Coastguard Worker select_response = applet->Select(aid, p2);
556*4d7e907cSAndroid Build Coastguard Worker }
557*4d7e907cSAndroid Build Coastguard Worker
558*4d7e907cSAndroid Build Coastguard Worker // If the length of the AID is 0, the method will select the
559*4d7e907cSAndroid Build Coastguard Worker // Issuer Security Domain of the SE by sending a SELECT command
560*4d7e907cSAndroid Build Coastguard Worker // with 0 length AID as defined in [GPCS].
561*4d7e907cSAndroid Build Coastguard Worker if (aid.size() == 0) {
562*4d7e907cSAndroid Build Coastguard Worker select_response = kIssuerSecurityDomainSelectResponse;
563*4d7e907cSAndroid Build Coastguard Worker }
564*4d7e907cSAndroid Build Coastguard Worker
565*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " sending response: "
566*4d7e907cSAndroid Build Coastguard Worker << HexString(select_response.data(), select_response.size());
567*4d7e907cSAndroid Build Coastguard Worker
568*4d7e907cSAndroid Build Coastguard Worker // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
569*4d7e907cSAndroid Build Coastguard Worker // or APDU. The functionality here is enough to exercise the framework,
570*4d7e907cSAndroid Build Coastguard Worker // but actual calls to the secure element will fail. This implementation
571*4d7e907cSAndroid Build Coastguard Worker // does not model channel isolation or any other aspects important to
572*4d7e907cSAndroid Build Coastguard Worker // implementing secure element.
573*4d7e907cSAndroid Build Coastguard Worker channels_[channel_number] = Channel(aid, p2, applet);
574*4d7e907cSAndroid Build Coastguard Worker *aidl_return = LogicalChannelResponse{
575*4d7e907cSAndroid Build Coastguard Worker .channelNumber = static_cast<int8_t>(channel_number),
576*4d7e907cSAndroid Build Coastguard Worker .selectResponse = select_response,
577*4d7e907cSAndroid Build Coastguard Worker };
578*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
579*4d7e907cSAndroid Build Coastguard Worker }
580*4d7e907cSAndroid Build Coastguard Worker
closeChannel(int8_t channel_number)581*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus closeChannel(int8_t channel_number) override {
582*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " channel number: " << static_cast<int>(channel_number);
583*4d7e907cSAndroid Build Coastguard Worker if (client_callback_ == nullptr) {
584*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
585*4d7e907cSAndroid Build Coastguard Worker }
586*4d7e907cSAndroid Build Coastguard Worker
587*4d7e907cSAndroid Build Coastguard Worker // The selected basic or logical channel is not opened.
588*4d7e907cSAndroid Build Coastguard Worker if (channel_number >= channels_.size() || !channels_[channel_number].opened) {
589*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromServiceSpecificError(FAILED);
590*4d7e907cSAndroid Build Coastguard Worker }
591*4d7e907cSAndroid Build Coastguard Worker
592*4d7e907cSAndroid Build Coastguard Worker // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
593*4d7e907cSAndroid Build Coastguard Worker // or APDU. The functionality here is enough to exercise the framework,
594*4d7e907cSAndroid Build Coastguard Worker // but actual calls to the secure element will fail. This implementation
595*4d7e907cSAndroid Build Coastguard Worker // does not model channel isolation or any other aspects important to
596*4d7e907cSAndroid Build Coastguard Worker // implementing secure element.
597*4d7e907cSAndroid Build Coastguard Worker channels_[channel_number].opened = false;
598*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
599*4d7e907cSAndroid Build Coastguard Worker }
600*4d7e907cSAndroid Build Coastguard Worker
transmit(const std::vector<uint8_t> & data,std::vector<uint8_t> * aidl_return)601*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus transmit(const std::vector<uint8_t>& data,
602*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t>* aidl_return) override {
603*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " data: " << HexString(data.data(), data.size()) << " ("
604*4d7e907cSAndroid Build Coastguard Worker << data.size() << ")";
605*4d7e907cSAndroid Build Coastguard Worker if (client_callback_ == nullptr) {
606*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
607*4d7e907cSAndroid Build Coastguard Worker }
608*4d7e907cSAndroid Build Coastguard Worker
609*4d7e907cSAndroid Build Coastguard Worker se::Apdu apdu(data);
610*4d7e907cSAndroid Build Coastguard Worker uint8_t channel_number = apdu.get_channel_number();
611*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> response_apdu;
612*4d7e907cSAndroid Build Coastguard Worker
613*4d7e907cSAndroid Build Coastguard Worker switch (apdu.get_ins()) {
614*4d7e907cSAndroid Build Coastguard Worker // TODO(b/123254068) - Implement support channel management APDUs.
615*4d7e907cSAndroid Build Coastguard Worker case MANAGE_CHANNEL_INS:
616*4d7e907cSAndroid Build Coastguard Worker // P1 = '00' to open
617*4d7e907cSAndroid Build Coastguard Worker // P1 = '80' to close
618*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " MANAGE_CHANNEL apdu";
619*4d7e907cSAndroid Build Coastguard Worker response_apdu =
620*4d7e907cSAndroid Build Coastguard Worker se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
621*4d7e907cSAndroid Build Coastguard Worker break;
622*4d7e907cSAndroid Build Coastguard Worker
623*4d7e907cSAndroid Build Coastguard Worker // TODO(b/123254068) - Implement support channel management APDUs.
624*4d7e907cSAndroid Build Coastguard Worker case SELECT_INS:
625*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " SELECT apdu";
626*4d7e907cSAndroid Build Coastguard Worker response_apdu =
627*4d7e907cSAndroid Build Coastguard Worker se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
628*4d7e907cSAndroid Build Coastguard Worker break;
629*4d7e907cSAndroid Build Coastguard Worker
630*4d7e907cSAndroid Build Coastguard Worker default:
631*4d7e907cSAndroid Build Coastguard Worker CHECK(channel_number < channels_.size()) << " invalid channel number";
632*4d7e907cSAndroid Build Coastguard Worker if (!channels_[channel_number].opened) {
633*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__ << " the channel " << static_cast<int>(channel_number)
634*4d7e907cSAndroid Build Coastguard Worker << " is not opened";
635*4d7e907cSAndroid Build Coastguard Worker response_apdu =
636*4d7e907cSAndroid Build Coastguard Worker se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
637*4d7e907cSAndroid Build Coastguard Worker break;
638*4d7e907cSAndroid Build Coastguard Worker }
639*4d7e907cSAndroid Build Coastguard Worker // Send the APDU to the applet for processing.
640*4d7e907cSAndroid Build Coastguard Worker // Applet implementation is optional, default to sending
641*4d7e907cSAndroid Build Coastguard Worker // SW_INS_NOT_SUPPORTED.
642*4d7e907cSAndroid Build Coastguard Worker if (channels_[channel_number].applet == nullptr) {
643*4d7e907cSAndroid Build Coastguard Worker response_apdu = se::Apdu::CreateResponse(se::Status::SW_INS_NOT_SUPPORTED);
644*4d7e907cSAndroid Build Coastguard Worker } else {
645*4d7e907cSAndroid Build Coastguard Worker response_apdu = channels_[channel_number].applet->Process(apdu);
646*4d7e907cSAndroid Build Coastguard Worker }
647*4d7e907cSAndroid Build Coastguard Worker break;
648*4d7e907cSAndroid Build Coastguard Worker }
649*4d7e907cSAndroid Build Coastguard Worker
650*4d7e907cSAndroid Build Coastguard Worker aidl_return->assign(response_apdu.begin(), response_apdu.end());
651*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__
652*4d7e907cSAndroid Build Coastguard Worker << " response: " << HexString(aidl_return->data(), aidl_return->size()) << " ("
653*4d7e907cSAndroid Build Coastguard Worker << aidl_return->size() << ")";
654*4d7e907cSAndroid Build Coastguard Worker return ScopedAStatus::ok();
655*4d7e907cSAndroid Build Coastguard Worker }
656*4d7e907cSAndroid Build Coastguard Worker
657*4d7e907cSAndroid Build Coastguard Worker private:
658*4d7e907cSAndroid Build Coastguard Worker struct Channel {
659*4d7e907cSAndroid Build Coastguard Worker public:
660*4d7e907cSAndroid Build Coastguard Worker Channel() = default;
661*4d7e907cSAndroid Build Coastguard Worker Channel(Channel const&) = default;
ChannelEmulatedSecureElement::Channel662*4d7e907cSAndroid Build Coastguard Worker Channel(se::Aid const& aid, uint8_t p2, std::shared_ptr<se::Applet> applet)
663*4d7e907cSAndroid Build Coastguard Worker : opened(true), aid(aid), p2(p2), applet(std::move(applet)) {}
664*4d7e907cSAndroid Build Coastguard Worker Channel& operator=(Channel const&) = default;
665*4d7e907cSAndroid Build Coastguard Worker
666*4d7e907cSAndroid Build Coastguard Worker bool opened{false};
667*4d7e907cSAndroid Build Coastguard Worker se::Aid aid{};
668*4d7e907cSAndroid Build Coastguard Worker uint8_t p2{0};
669*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<se::Applet> applet{nullptr};
670*4d7e907cSAndroid Build Coastguard Worker };
671*4d7e907cSAndroid Build Coastguard Worker
672*4d7e907cSAndroid Build Coastguard Worker // OMAPI abstraction.
673*4d7e907cSAndroid Build Coastguard Worker
674*4d7e907cSAndroid Build Coastguard Worker // Channel 0 is the basic channel, channels 1-19 are the logical channels.
675*4d7e907cSAndroid Build Coastguard Worker std::array<Channel, 20> channels_{};
676*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<ISecureElementCallback> client_callback_{nullptr};
677*4d7e907cSAndroid Build Coastguard Worker
678*4d7e907cSAndroid Build Coastguard Worker // Secure element abstraction.
679*4d7e907cSAndroid Build Coastguard Worker
680*4d7e907cSAndroid Build Coastguard Worker static const uint8_t MANAGE_CHANNEL_INS = 0x70;
681*4d7e907cSAndroid Build Coastguard Worker static const uint8_t SELECT_INS = 0xa4;
682*4d7e907cSAndroid Build Coastguard Worker
683*4d7e907cSAndroid Build Coastguard Worker // Secure element ATR (Answer-To-Reset).
684*4d7e907cSAndroid Build Coastguard Worker // The format is specified by ISO/IEC 1816-4 2020 and lists
685*4d7e907cSAndroid Build Coastguard Worker // the capabilities of the card.
686*4d7e907cSAndroid Build Coastguard Worker //
687*4d7e907cSAndroid Build Coastguard Worker // TODO(b/123254068): encode the default SE properties in the ATR:
688*4d7e907cSAndroid Build Coastguard Worker // support for extended Lc / Le fields, maximum number of logical channels.
689*4d7e907cSAndroid Build Coastguard Worker // The CTS tests are *not* checking this value.
690*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> const atr_{};
691*4d7e907cSAndroid Build Coastguard Worker
692*4d7e907cSAndroid Build Coastguard Worker // Applet registration.
693*4d7e907cSAndroid Build Coastguard Worker std::vector<std::pair<se::Aid, std::shared_ptr<se::Applet>>> applets_{};
694*4d7e907cSAndroid Build Coastguard Worker
695*4d7e907cSAndroid Build Coastguard Worker // Return the first applet that matches the selected aid.
SelectApplet(se::Aid const & aid)696*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<se::Applet> SelectApplet(se::Aid const& aid) {
697*4d7e907cSAndroid Build Coastguard Worker for (auto& [applet_aid, applet] : applets_) {
698*4d7e907cSAndroid Build Coastguard Worker if (applet_aid == aid) {
699*4d7e907cSAndroid Build Coastguard Worker return applet;
700*4d7e907cSAndroid Build Coastguard Worker }
701*4d7e907cSAndroid Build Coastguard Worker }
702*4d7e907cSAndroid Build Coastguard Worker return nullptr;
703*4d7e907cSAndroid Build Coastguard Worker }
704*4d7e907cSAndroid Build Coastguard Worker };
705*4d7e907cSAndroid Build Coastguard Worker
main()706*4d7e907cSAndroid Build Coastguard Worker int main() {
707*4d7e907cSAndroid Build Coastguard Worker ABinderProcess_setThreadPoolMaxThreadCount(0);
708*4d7e907cSAndroid Build Coastguard Worker
709*4d7e907cSAndroid Build Coastguard Worker auto se = ndk::SharedRefBase::make<EmulatedSecureElement>();
710*4d7e907cSAndroid Build Coastguard Worker const std::string name = std::string() + BnSecureElement::descriptor + "/eSE1";
711*4d7e907cSAndroid Build Coastguard Worker binder_status_t status = AServiceManager_addService(se->asBinder().get(), name.c_str());
712*4d7e907cSAndroid Build Coastguard Worker CHECK_EQ(status, STATUS_OK);
713*4d7e907cSAndroid Build Coastguard Worker
714*4d7e907cSAndroid Build Coastguard Worker ABinderProcess_joinThreadPool();
715*4d7e907cSAndroid Build Coastguard Worker return EXIT_FAILURE; // should not reach
716*4d7e907cSAndroid Build Coastguard Worker }
717