1 /******************************************************************************
2 *
3 * Copyright 2023-2024 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 "AuthSecret-Hal"
19 #include "AuthSecretHelper.h"
20
21 AuthSecretHelper *AuthSecretHelper::sInstance = nullptr;
22
getInstance()23 AuthSecretHelper *AuthSecretHelper::getInstance() {
24 if (sInstance == nullptr) {
25 sInstance = new AuthSecretHelper;
26 }
27 return sInstance;
28 }
29
constructApdu(Instruction ins,const std::vector<uint8_t> & input,std::vector<uint8_t> & out,std::vector<uint8_t> timeout)30 bool AuthSecretHelper::constructApdu(Instruction ins,
31 const std::vector<uint8_t> &input,
32 std::vector<uint8_t> &out,
33 std::vector<uint8_t> timeout) {
34 /* Insert CLA, INS, P1, P2*/
35 out.push_back(static_cast<uint8_t>(APDU_CLS));
36 out.push_back(static_cast<uint8_t>(ins));
37 out.push_back(static_cast<uint8_t>(APDU_P1));
38 out.push_back(static_cast<uint8_t>(APDU_P2));
39
40 switch (ins) {
41 case Instruction::INS_VERIFY_PIN: {
42 cppbor::Array array;
43 if (input.size()) {
44 array.add(input);
45 }
46 if (timeout.size()) {
47 array.add(timeout);
48 }
49 std::vector<uint8_t> command = array.encode();
50 out.push_back(static_cast<uint8_t>(command.size()));
51 out.insert(out.end(), command.begin(), command.end());
52 } break;
53 case Instruction::INS_CLEAR_APPROVED_STATUS:
54 /* Nothing to do. No Payload for Clear approved status*/
55 break;
56 default:
57 LOG(ERROR) << "Unknown INS. constructApdu failed";
58 return false;
59 }
60
61 /* Insert LE */
62 out.push_back(static_cast<uint8_t>(0x00));
63 return true;
64 }
65
extractTimeoutValue(std::vector<uint8_t> data)66 uint64_t AuthSecretHelper::extractTimeoutValue(std::vector<uint8_t> data) {
67 LOG(INFO) << StringPrintf("%s: Enter", __func__);
68
69 auto [parsedData, _, errMsg] = cppbor::parse(data);
70 if (!parsedData) {
71 LOG(ERROR) << StringPrintf("parsedData is null");
72 return INVALID_DATA_STATUS_TIMER_VALUE;
73 }
74 auto dataArray = parsedData->asArray();
75 if (!dataArray) {
76 LOG(ERROR) << StringPrintf("parsedData is not proper CBOR Array");
77 return INVALID_DATA_STATUS_TIMER_VALUE;
78 }
79
80 uint64_t timeout = CLEAR_APPROVE_STATUS_TIMER_VALUE;
81 if ((dataArray->size() > 1) && (dataArray->get(INDEX_TIMER_VAL)->asBstr())) {
82 std::vector<uint8_t> timeoutVector =
83 dataArray->get(INDEX_TIMER_VAL)->asBstr()->value();
84 if (timeoutVector.size() == TIMEOUT_VECTOR_SIZE) {
85 timeout = (((timeoutVector[0] << 8) | (timeoutVector[1])) * 60 * 60) +
86 ((timeoutVector[2] << 8) | timeoutVector[3]);
87 }
88 }
89
90 LOG(INFO) << StringPrintf("%s:Exit", __func__);
91 return timeout;
92 }
93
checkVerifyStatus(std::vector<uint8_t> resp)94 bool AuthSecretHelper::checkVerifyStatus(std::vector<uint8_t> resp) {
95 bool status = false;
96
97 auto [parsedData, _, errMsg] = cppbor::parse(resp);
98 if (!parsedData) {
99 LOG(ERROR) << StringPrintf("parsedData is null");
100 return status;
101 }
102 auto dataArray = parsedData->asArray();
103 if (!dataArray) {
104 LOG(ERROR) << StringPrintf("parsedData is not proper CBOR Array");
105 return status;
106 }
107
108 /* Get Item 1 (status) in response CBOR apdu, if value is 0 (uint) status is
109 * OK. */
110 if ((dataArray->size() > 0) && (dataArray->get(INDEX_STATUS_VAL)->asUint())) {
111 uint64_t value = dataArray->get(INDEX_STATUS_VAL)->asUint()->value();
112 if (!value) {
113 status = true;
114 }
115 }
116 return status;
117 }