• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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