/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /****************************************************************************** ** ** The original Work has been changed by NXP. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. ** ** Copyright 2022-2023 NXP ** *********************************************************************************/ #define LOG_TAG "AuthSecret-Hal" #include "AuthSecret.h" #include "AuthSecretHelper.h" using keymint::javacard::OmapiTransport; const std::vector gAuthSecretAppletAID = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x54, 0x53, 0x00, 0x00, 0x00, 0x01, 0x00, 0x52}; static std::shared_ptr gTransport = OmapiTransport::make(gAuthSecretAppletAID); static AuthSecretHelper *gAuthSecretImplInstance = AuthSecretHelper::getInstance(); namespace aidl { namespace android { namespace hardware { namespace authsecret { static void authSecretTimerExpiryFunc(union sigval arg) { LOG(INFO) << StringPrintf( "%s: Enter. Clearing AuthSecret Approved Status !!!", __func__); AuthSecret *obj = (AuthSecret *)arg.sival_ptr; if (obj != nullptr) obj->clearAuthApprovedStatus(); } void AuthSecret::clearAuthApprovedStatus() { LOG(INFO) << StringPrintf("%s: Enter", __func__); std::vector cmd; std::vector timeout; std::vector input; bool status = gAuthSecretImplInstance->constructApdu( Instruction::INS_CLEAR_APPROVED_STATUS, input, cmd, std::move(timeout)); if (!status) { LOG(ERROR) << StringPrintf("%s: constructApdu failed", __func__); return; } std::vector resp; uint8_t retry = 0; do { if (!gTransport->sendData(cmd, resp)) { LOG(ERROR) << StringPrintf("%s: Error in sending data in sendData.", __func__); } else { if ((resp.size() < 2) || (getApduStatus(resp) != APDU_RESP_STATUS_OK)) { LOG(ERROR) << StringPrintf("%s: failed", __func__); } else { break; } } usleep(1 * ONE_SEC); } while (++retry < MAX_RETRY_COUNT); LOG(INFO) << StringPrintf("%s: Exit", __func__); } // Methods from ::android::hardware::authsecret::IAuthSecret follow. ::ndk::ScopedAStatus AuthSecret::setPrimaryUserCredential(const std::vector &in_secret) { LOG(INFO) << StringPrintf("%s: Enter", __func__); std::vector cmd; std::vector timeout; bool status = gAuthSecretImplInstance->constructApdu( Instruction::INS_VERIFY_PIN, in_secret, cmd, std::move(timeout)); if (!status) { LOG(ERROR) << StringPrintf("%s: constructApdu failed", __func__); return ::ndk::ScopedAStatus::ok(); } mAuthClearTimer.kill(); clearAuthApprovedStatus(); std::vector resp; uint8_t retry = 0; do { if (!gTransport->sendData(cmd, resp)) { LOG(ERROR) << StringPrintf("%s: Error in sending data in sendData.", __func__); } else { break; } } while (++retry < MAX_RETRY_COUNT); if ((resp.size() < 2) || (getApduStatus(resp) != APDU_RESP_STATUS_OK) || !gAuthSecretImplInstance->checkVerifyStatus(resp)) { clearAuthApprovedStatus(); return ::ndk::ScopedAStatus::ok(); } uint64_t clearAuthTimeout = gAuthSecretImplInstance->extractTimeoutValue(std::move(resp)); LOG(INFO) << StringPrintf("%s: AuthSecret Clear status Timeout = %ld secs", __func__, (long)clearAuthTimeout); if (clearAuthTimeout) { if (!mAuthClearTimer.set(clearAuthTimeout * 1000, this, authSecretTimerExpiryFunc)) { LOG(ERROR) << StringPrintf("%s: Set Timer Failed !!!", __func__); clearAuthApprovedStatus(); } } gTransport->closeConnection(); LOG(INFO) << StringPrintf("%s: Exit", __func__); return ::ndk::ScopedAStatus::ok(); } } // namespace authsecret } // namespace hardware } // namespace android } // aidl