1/****************************************************************************** 2 * 3 * Copyright 2018 NXP 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18#define LOG_TAG "NxpEseHal" 19#include <log/log.h> 20 21#include "LsClient.h" 22#include "SecureElement.h" 23#include "phNxpEse_Api.h" 24 25extern bool ese_debug_enabled; 26 27namespace android { 28namespace hardware { 29namespace secure_element { 30namespace V1_0 { 31namespace implementation { 32 33sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr; 34 35SecureElement::SecureElement() 36 : mOpenedchannelCount(0), 37 mOpenedChannels{false, false, false, false} {} 38 39Return<void> SecureElement::init( 40 const sp< 41 ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>& 42 clientCallback) { 43 ESESTATUS status = ESESTATUS_SUCCESS; 44 45 if (clientCallback == nullptr) { 46 return Void(); 47 } else { 48 mCallbackV1_0 = clientCallback; 49 if (!mCallbackV1_0->linkToDeath(this, 0 /*cookie*/)) { 50 ALOGE("%s: Failed to register death notification", __func__); 51 } 52 } 53 if (isSeInitialized()) { 54 clientCallback->onStateChange(true); 55 return Void(); 56 } 57 58 status = seHalInit(); 59 if (status != ESESTATUS_SUCCESS) { 60 clientCallback->onStateChange(false); 61 return Void(); 62 } 63 64 LSCSTATUS lsStatus = LSC_doDownload(clientCallback); 65 /* 66 * LSC_doDownload returns LSCSTATUS_FAILED in case thread creation fails. 67 * So return callback as false. 68 * Otherwise callback will be called in LSDownload module. 69 */ 70 if (lsStatus != LSCSTATUS_SUCCESS) { 71 ALOGE("%s: LSDownload thread creation failed!!!", __func__); 72 SecureElementStatus sestatus = seHalDeInit(); 73 if (sestatus != SecureElementStatus::SUCCESS) { 74 ALOGE("%s: seHalDeInit failed!!!", __func__); 75 } 76 clientCallback->onStateChange(false); 77 } 78 return Void(); 79} 80 81Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) { 82 hidl_vec<uint8_t> response; 83 _hidl_cb(response); 84 return Void(); 85} 86 87Return<bool> SecureElement::isCardPresent() { return true; } 88 89Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data, 90 transmit_cb _hidl_cb) { 91 ESESTATUS status = ESESTATUS_FAILED; 92 phNxpEse_data cmdApdu; 93 phNxpEse_data rspApdu; 94 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); 95 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); 96 97 cmdApdu.len = data.size(); 98 if (cmdApdu.len >= MIN_APDU_LENGTH) { 99 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t)); 100 memcpy(cmdApdu.p_data, data.data(), cmdApdu.len); 101 status = phNxpEse_Transceive(&cmdApdu, &rspApdu); 102 } 103 104 hidl_vec<uint8_t> result; 105 if (status != ESESTATUS_SUCCESS) { 106 ALOGE("%s: transmit failed!!!", __func__); 107 } else { 108 result.resize(rspApdu.len); 109 memcpy(&result[0], rspApdu.p_data, rspApdu.len); 110 } 111 _hidl_cb(result); 112 phNxpEse_free(cmdApdu.p_data); 113 phNxpEse_free(rspApdu.p_data); 114 return Void(); 115} 116 117Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid, 118 uint8_t p2, 119 openLogicalChannel_cb _hidl_cb) { 120 hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01}; 121 122 LogicalChannelResponse resApduBuff; 123 resApduBuff.channelNumber = 0xff; 124 memset(&resApduBuff, 0x00, sizeof(resApduBuff)); 125 126 if (!isSeInitialized()) { 127 ESESTATUS status = seHalInit(); 128 if (status != ESESTATUS_SUCCESS) { 129 ALOGE("%s: seHalInit Failed!!!", __func__); 130 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR); 131 return Void(); 132 } 133 } 134 135 SecureElementStatus sestatus = SecureElementStatus::IOERROR; 136 ESESTATUS status = ESESTATUS_FAILED; 137 phNxpEse_data cmdApdu; 138 phNxpEse_data rspApdu; 139 140 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); 141 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); 142 143 cmdApdu.len = manageChannelCommand.size(); 144 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() * 145 sizeof(uint8_t)); 146 if (cmdApdu.p_data != NULL) { 147 memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len); 148 status = phNxpEse_Transceive(&cmdApdu, &rspApdu); 149 } 150 if (status != ESESTATUS_SUCCESS) { 151 /*Transceive failed*/ 152 sestatus = SecureElementStatus::IOERROR; 153 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 && 154 rspApdu.p_data[rspApdu.len - 1] == 0x00) { 155 /*ManageChannel successful*/ 156 resApduBuff.channelNumber = rspApdu.p_data[0]; 157 mOpenedchannelCount++; 158 mOpenedChannels[resApduBuff.channelNumber] = true; 159 sestatus = SecureElementStatus::SUCCESS; 160 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A && 161 rspApdu.p_data[rspApdu.len - 1] == 0x81) { 162 sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE; 163 } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) || 164 (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) && 165 rspApdu.p_data[rspApdu.len - 1] == 0x00) { 166 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION; 167 } 168 169 /*Free the allocations*/ 170 phNxpEse_free(cmdApdu.p_data); 171 phNxpEse_free(rspApdu.p_data); 172 173 if (sestatus != SecureElementStatus::SUCCESS) { 174 /*If manageChanle is failed in any of above cases 175 send the callback and return*/ 176 _hidl_cb(resApduBuff, sestatus); 177 return Void(); 178 } 179 180 ALOGD_IF(ese_debug_enabled, "%s: Sending selectApdu", __func__); 181 /*Reset variables if manageChannel is success*/ 182 sestatus = SecureElementStatus::IOERROR; 183 status = ESESTATUS_FAILED; 184 185 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); 186 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); 187 188 cmdApdu.len = (int32_t)(5 + aid.size()); 189 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t)); 190 if (cmdApdu.p_data != NULL) { 191 uint8_t xx = 0; 192 cmdApdu.p_data[xx++] = resApduBuff.channelNumber; 193 cmdApdu.p_data[xx++] = 0xA4; // INS 194 cmdApdu.p_data[xx++] = 0x04; // P1 195 cmdApdu.p_data[xx++] = p2; // P2 196 cmdApdu.p_data[xx++] = aid.size(); // Lc 197 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size()); 198 199 status = phNxpEse_Transceive(&cmdApdu, &rspApdu); 200 } 201 202 if (status != ESESTATUS_SUCCESS) { 203 /*Transceive failed*/ 204 sestatus = SecureElementStatus::IOERROR; 205 } else { 206 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2]; 207 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1]; 208 /*Return response on success, empty vector on failure*/ 209 /*Status is success*/ 210 if (sw1 == 0x90 && sw2 == 0x00) { 211 /*Copy the response including status word*/ 212 resApduBuff.selectResponse.resize(rspApdu.len); 213 memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len); 214 sestatus = SecureElementStatus::SUCCESS; 215 } 216 /*AID provided doesn't match any applet on the secure element*/ 217 else if (sw1 == 0x6A && sw2 == 0x82) { 218 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR; 219 } 220 /*Operation provided by the P2 parameter is not permitted by the applet.*/ 221 else if (sw1 == 0x6A && sw2 == 0x86) { 222 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION; 223 } 224 } 225 226 if (sestatus != SecureElementStatus::SUCCESS) { 227 SecureElementStatus closeChannelStatus = 228 closeChannel(resApduBuff.channelNumber); 229 if (closeChannelStatus != SecureElementStatus::SUCCESS) { 230 ALOGE("%s: closeChannel Failed", __func__); 231 } else { 232 resApduBuff.channelNumber = 0xff; 233 } 234 } 235 _hidl_cb(resApduBuff, sestatus); 236 phNxpEse_free(cmdApdu.p_data); 237 phNxpEse_free(rspApdu.p_data); 238 239 return Void(); 240} 241 242Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid, 243 uint8_t p2, 244 openBasicChannel_cb _hidl_cb) { 245 hidl_vec<uint8_t> result; 246 247 if (!isSeInitialized()) { 248 ESESTATUS status = seHalInit(); 249 if (status != ESESTATUS_SUCCESS) { 250 ALOGE("%s: seHalInit Failed!!!", __func__); 251 _hidl_cb(result, SecureElementStatus::IOERROR); 252 return Void(); 253 } 254 } 255 256 SecureElementStatus sestatus = SecureElementStatus::IOERROR; 257 ESESTATUS status = ESESTATUS_FAILED; 258 phNxpEse_data cmdApdu; 259 phNxpEse_data rspApdu; 260 261 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); 262 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); 263 264 cmdApdu.len = (int32_t)(5 + aid.size()); 265 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t)); 266 if (cmdApdu.p_data != NULL) { 267 uint8_t xx = 0; 268 cmdApdu.p_data[xx++] = 0x00; // basic channel 269 cmdApdu.p_data[xx++] = 0xA4; // INS 270 cmdApdu.p_data[xx++] = 0x04; // P1 271 cmdApdu.p_data[xx++] = p2; // P2 272 cmdApdu.p_data[xx++] = aid.size(); // Lc 273 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size()); 274 275 status = phNxpEse_Transceive(&cmdApdu, &rspApdu); 276 } 277 278 if (status != ESESTATUS_SUCCESS) { 279 /* Transceive failed */ 280 sestatus = SecureElementStatus::IOERROR; 281 } else { 282 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2]; 283 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1]; 284 /*Return response on success, empty vector on failure*/ 285 /*Status is success*/ 286 if ((sw1 == 0x90) && (sw2 == 0x00)) { 287 /*Copy the response including status word*/ 288 result.resize(rspApdu.len); 289 memcpy(&result[0], rspApdu.p_data, rspApdu.len); 290 /*Set basic channel reference if it is not set */ 291 if (!mOpenedChannels[0]) { 292 mOpenedChannels[0] = true; 293 mOpenedchannelCount++; 294 } 295 sestatus = SecureElementStatus::SUCCESS; 296 } 297 /*AID provided doesn't match any applet on the secure element*/ 298 else if (sw1 == 0x6A && sw2 == 0x82) { 299 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR; 300 } 301 /*Operation provided by the P2 parameter is not permitted by the applet.*/ 302 else if (sw1 == 0x6A && sw2 == 0x86) { 303 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION; 304 } 305 } 306 307 if ((sestatus != SecureElementStatus::SUCCESS) && mOpenedChannels[0]) { 308 SecureElementStatus closeChannelStatus = 309 closeChannel(DEFAULT_BASIC_CHANNEL); 310 if (closeChannelStatus != SecureElementStatus::SUCCESS) { 311 ALOGE("%s: closeChannel Failed", __func__); 312 } 313 } 314 _hidl_cb(result, sestatus); 315 phNxpEse_free(cmdApdu.p_data); 316 phNxpEse_free(rspApdu.p_data); 317 return Void(); 318} 319 320Return<::android::hardware::secure_element::V1_0::SecureElementStatus> 321SecureElement::closeChannel(uint8_t channelNumber) { 322 ESESTATUS status = ESESTATUS_FAILED; 323 SecureElementStatus sestatus = SecureElementStatus::FAILED; 324 325 phNxpEse_data cmdApdu; 326 phNxpEse_data rspApdu; 327 328 if ((channelNumber < DEFAULT_BASIC_CHANNEL) || 329 (channelNumber >= MAX_LOGICAL_CHANNELS) || 330 (mOpenedChannels[channelNumber] == false)) { 331 ALOGE("%s: invalid channel!!!", __func__); 332 sestatus = SecureElementStatus::FAILED; 333 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) { 334 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); 335 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); 336 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t)); 337 if (cmdApdu.p_data != NULL) { 338 uint8_t xx = 0; 339 340 cmdApdu.p_data[xx++] = channelNumber; 341 cmdApdu.p_data[xx++] = 0x70; // INS 342 cmdApdu.p_data[xx++] = 0x80; // P1 343 cmdApdu.p_data[xx++] = channelNumber; // P2 344 cmdApdu.p_data[xx++] = 0x00; // Lc 345 cmdApdu.len = xx; 346 347 status = phNxpEse_Transceive(&cmdApdu, &rspApdu); 348 } 349 if (status != ESESTATUS_SUCCESS) { 350 sestatus = SecureElementStatus::FAILED; 351 } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) && 352 (rspApdu.p_data[rspApdu.len - 1] == 0x00)) { 353 sestatus = SecureElementStatus::SUCCESS; 354 } else { 355 sestatus = SecureElementStatus::FAILED; 356 } 357 phNxpEse_free(cmdApdu.p_data); 358 phNxpEse_free(rspApdu.p_data); 359 } 360 361 if ((channelNumber == DEFAULT_BASIC_CHANNEL) || 362 (sestatus == SecureElementStatus::SUCCESS)) { 363 mOpenedChannels[channelNumber] = false; 364 mOpenedchannelCount--; 365 /*If there are no channels remaining close secureElement*/ 366 if (mOpenedchannelCount == 0) { 367 sestatus = seHalDeInit(); 368 } else { 369 sestatus = SecureElementStatus::SUCCESS; 370 } 371 } 372 return sestatus; 373} 374 375void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) { 376 ALOGE("%s: SecureElement serviceDied!!!", __func__); 377 SecureElementStatus sestatus = seHalDeInit(); 378 if (sestatus != SecureElementStatus::SUCCESS) { 379 ALOGE("%s: seHalDeInit Faliled!!!", __func__); 380 } 381 if (mCallbackV1_0 != nullptr) { 382 mCallbackV1_0->unlinkToDeath(this); 383 } 384} 385 386bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); } 387 388ESESTATUS SecureElement::seHalInit() { 389 ESESTATUS status = ESESTATUS_SUCCESS; 390 phNxpEse_initParams initParams; 391 memset(&initParams, 0x00, sizeof(phNxpEse_initParams)); 392 initParams.initMode = ESE_MODE_NORMAL; 393 394 status = phNxpEse_open(initParams); 395 if (status != ESESTATUS_SUCCESS) { 396 ALOGE("%s: SecureElement open failed!!!", __func__); 397 } else { 398 status = phNxpEse_init(initParams); 399 if (status != ESESTATUS_SUCCESS) { 400 ALOGE("%s: SecureElement init failed!!!", __func__); 401 } 402 } 403 return status; 404} 405 406Return<::android::hardware::secure_element::V1_0::SecureElementStatus> 407SecureElement::seHalDeInit() { 408 ESESTATUS status = ESESTATUS_SUCCESS; 409 SecureElementStatus sestatus = SecureElementStatus::FAILED; 410 status = phNxpEse_deInit(); 411 if (status != ESESTATUS_SUCCESS) { 412 sestatus = SecureElementStatus::FAILED; 413 } else { 414 status = phNxpEse_close(); 415 if (status != ESESTATUS_SUCCESS) { 416 sestatus = SecureElementStatus::FAILED; 417 } else { 418 sestatus = SecureElementStatus::SUCCESS; 419 420 for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) { 421 mOpenedChannels[xx] = false; 422 } 423 mOpenedchannelCount = 0; 424 } 425 } 426 return sestatus; 427} 428 429} // namespace implementation 430} // namespace V1_0 431} // namespace secure_element 432} // namespace hardware 433} // namespace android 434