1 /*
2 * Copyright (C) 2018 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 **
18 ** The original Work has been changed by NXP.
19 **
20 ** Licensed under the Apache License, Version 2.0 (the "License");
21 ** you may not use this file except in compliance with the License.
22 ** You may obtain a copy of the License at
23 **
24 ** http://www.apache.org/licenses/LICENSE-2.0
25 **
26 ** Unless required by applicable law or agreed to in writing, software
27 ** distributed under the License is distributed on an "AS IS" BASIS,
28 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29 ** See the License for the specific language governing permissions and
30 ** limitations under the License.
31 **
32 ** Copyright 2022-2023 NXP
33 **
34 *********************************************************************************/
35
36 #define LOG_TAG "AuthSecret-Hal"
37 #include "AuthSecret.h"
38 #include "AuthSecretHelper.h"
39
40 using keymint::javacard::OmapiTransport;
41
42 const std::vector<uint8_t> gAuthSecretAppletAID = {0xA0, 0x00, 0x00, 0x03, 0x96,
43 0x54, 0x53, 0x00, 0x00, 0x00,
44 0x01, 0x00, 0x52};
45
46 static std::shared_ptr<OmapiTransport> gTransport = OmapiTransport::make(gAuthSecretAppletAID);
47 static AuthSecretHelper *gAuthSecretImplInstance = AuthSecretHelper::getInstance();
48
49 namespace aidl {
50 namespace android {
51 namespace hardware {
52 namespace authsecret {
53
authSecretTimerExpiryFunc(union sigval arg)54 static void authSecretTimerExpiryFunc(union sigval arg) {
55 LOG(INFO) << StringPrintf(
56 "%s: Enter. Clearing AuthSecret Approved Status !!!", __func__);
57 AuthSecret *obj = (AuthSecret *)arg.sival_ptr;
58 if (obj != nullptr)
59 obj->clearAuthApprovedStatus();
60 }
61
clearAuthApprovedStatus()62 void AuthSecret::clearAuthApprovedStatus() {
63 LOG(INFO) << StringPrintf("%s: Enter", __func__);
64 std::vector<uint8_t> cmd;
65 std::vector<uint8_t> timeout;
66 std::vector<uint8_t> input;
67 bool status = gAuthSecretImplInstance->constructApdu(
68 Instruction::INS_CLEAR_APPROVED_STATUS, input, cmd, std::move(timeout));
69 if (!status) {
70 LOG(ERROR) << StringPrintf("%s: constructApdu failed", __func__);
71 return;
72 }
73
74 std::vector<uint8_t> resp;
75 uint8_t retry = 0;
76 do {
77 if (!gTransport->sendData(cmd, resp)) {
78 LOG(ERROR) << StringPrintf("%s: Error in sending data in sendData.",
79 __func__);
80 } else {
81 if ((resp.size() < 2) || (getApduStatus(resp) != APDU_RESP_STATUS_OK)) {
82 LOG(ERROR) << StringPrintf("%s: failed", __func__);
83 } else { break; }
84 }
85 usleep(1 * ONE_SEC);
86 } while (++retry < MAX_RETRY_COUNT);
87
88
89 LOG(INFO) << StringPrintf("%s: Exit", __func__);
90 }
91
92 // Methods from ::android::hardware::authsecret::IAuthSecret follow.
93 ::ndk::ScopedAStatus
setPrimaryUserCredential(const std::vector<uint8_t> & in_secret)94 AuthSecret::setPrimaryUserCredential(const std::vector<uint8_t> &in_secret) {
95 LOG(INFO) << StringPrintf("%s: Enter", __func__);
96 std::vector<uint8_t> cmd;
97 std::vector<uint8_t> timeout;
98 bool status = gAuthSecretImplInstance->constructApdu(
99 Instruction::INS_VERIFY_PIN, in_secret, cmd, std::move(timeout));
100 if (!status) {
101 LOG(ERROR) << StringPrintf("%s: constructApdu failed", __func__);
102 return ::ndk::ScopedAStatus::ok();
103 }
104
105 mAuthClearTimer.kill();
106
107 clearAuthApprovedStatus();
108
109 std::vector<uint8_t> resp;
110 uint8_t retry = 0;
111 do {
112 if (!gTransport->sendData(cmd, resp)) {
113 LOG(ERROR) << StringPrintf("%s: Error in sending data in sendData.",
114 __func__);
115 } else {
116 break;
117 }
118 } while (++retry < MAX_RETRY_COUNT);
119
120 if ((resp.size() < 2) || (getApduStatus(resp) != APDU_RESP_STATUS_OK) ||
121 !gAuthSecretImplInstance->checkVerifyStatus(resp)) {
122 clearAuthApprovedStatus();
123 return ::ndk::ScopedAStatus::ok();
124 }
125
126 uint64_t clearAuthTimeout =
127 gAuthSecretImplInstance->extractTimeoutValue(std::move(resp));
128 LOG(INFO) << StringPrintf("%s: AuthSecret Clear status Timeout = %ld secs",
129 __func__, (long)clearAuthTimeout);
130 if (clearAuthTimeout) {
131 if (!mAuthClearTimer.set(clearAuthTimeout * 1000, this,
132 authSecretTimerExpiryFunc)) {
133 LOG(ERROR) << StringPrintf("%s: Set Timer Failed !!!", __func__);
134 clearAuthApprovedStatus();
135 }
136 }
137 gTransport->closeConnection();
138 LOG(INFO) << StringPrintf("%s: Exit", __func__);
139 return ::ndk::ScopedAStatus::ok();
140 }
141
142 } // namespace authsecret
143 } // namespace hardware
144 } // namespace android
145 } // aidl
146