1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "signature_operation.h"
17 
18 #include "securec.h"
19 
20 #include "buffer.h"
21 #include "adaptor_algorithm.h"
22 #include "iam_logger.h"
23 #include "iam_para2str.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "USER_AUTH_HDI"
27 
28 namespace OHOS {
29 namespace HDI {
30 namespace UserAuth {
31 namespace {
32     KeyPair *g_keyPair = nullptr;
33     constexpr uint32_t TAG_AND_LEN_BYTE = 8;
34     constexpr uint32_t FACE_AUTH_CAPABILITY_LEVEL = 3;
35     constexpr uint32_t RESULT_TLV_LEN = 500;
36 } // namespace
37 
38 enum AuthAttributeType : uint32_t {
39     /* Root tag */
40     ATTR_ROOT = 100000,
41     /* Result code */
42     ATTR_RESULT_CODE = 100001,
43     /* Tag of signature data in TLV */
44     ATTR_SIGNATURE = 100004,
45     /* Identify mode */
46     ATTR_IDENTIFY_MODE = 100005,
47     /* Tag of templateId data in TLV */
48     ATTR_TEMPLATE_ID = 100006,
49     /* Tag of templateId list data in TLV */
50     ATTR_TEMPLATE_ID_LIST = 100007,
51     /* Expected attribute, tag of remain count in TLV */
52     ATTR_REMAIN_ATTEMPTS = 100009,
53     /* Remain time */
54     ATTR_LOCKOUT_DURATION = 100010,
55     /* Session id, required when decode in C */
56     ATTR_SCHEDULE_ID = 100014,
57     /* Package name */
58     ATTR_CALLER_NAME = 100015,
59     /* Schedule version */
60     AUTH_SCHEDULE_VERSION = 100016,
61     /* Tag of lock out template in TLV */
62     AUTH_LOCK_OUT_TEMPLATE = 100018,
63     /* Tag of data */
64     ATTR_DATA = 100020,
65     /* Tag of auth subType */
66     ATTR_PIN_SUB_TYPE = 100021,
67     /* Tag of auth schedule mode */
68     ATTR_SCHEDULE_MODE = 100022,
69     /* Tag of property */
70     ATTR_PROPERTY_MODE = 100023,
71     /* Tag of auth type */
72     ATTR_TYPE = 100024,
73     /* Tag of cred id */
74     ATTR_CREDENTIAL_ID = 100025,
75     /* Controller */
76     ATTR_CONTROLLER = 100026,
77     /* calleruid */
78     ATTR_CALLER_UID = 100027,
79     /* result */
80     ATTR_RESULT = 100028,
81     /* capability level */
82     ATTR_CAPABILITY_LEVEL = 100029,
83     /* algorithm setinfo */
84     ATTR_ALGORITHM_INFO = 100030,
85     /* time stamp */
86     ATTR_TIME_STAMP = 100031,
87     /* root secret */
88     ATTR_ROOT_SECRET = 100032,
89     /* attrs */
90     ATTR_ATTRS = 100033,
91     /* executor index */
92     ATTR_EXECUTOR_INDEX = 100034,
93     /* public key */
94     ATTR_PUBLIC_KEY = 100035,
95     /* executor matcher */
96     ATTR_EXECUTOR_MATCHER = 100036,
97     /* local udid */
98     ATTR_LOCAL_UDID = 100037,
99     /* peer udid */
100     ATTR_PEER_UDID = 100038,
101     /* user id */
102     ATTR_USER_ID = 100041,
103     /* token */
104     ATTR_TOKEN = 100042,
105     /* executor role */
106     ATTR_EXECUTOR_ROLE = 100043,
107     /* esl */
108     ATTR_ESL = 100044,
109     /* VERIFIER udid */
110     ATTR_VERIFIER_UDID = 100045,
111     /* COLLECTOR udid */
112     ATTR_COLLECTOR_UDID = 100046,
113     /* Challenge */
114     ATTR_CHALLENGE = 100066,
115 };
116 
GenerateExecutorKeyPair()117 ResultCode GenerateExecutorKeyPair()
118 {
119     g_keyPair = GenerateEd25519KeyPair();
120     if (g_keyPair == nullptr) {
121         IAM_LOGE("GenerateEd25519Keypair fail");
122         return RESULT_GENERAL_ERROR;
123     }
124     IAM_LOGI("GenerateExecutorKeyPair success");
125     return RESULT_SUCCESS;
126 }
127 
WriteTlvHead(const AuthAttributeType type,const uint32_t length,Buffer * buf)128 static ResultCode WriteTlvHead(const AuthAttributeType type, const uint32_t length, Buffer *buf)
129 {
130     int32_t tempType = type;
131     if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, &tempType, sizeof(tempType)) != EOK) {
132         IAM_LOGE("copy type fail");
133         return RESULT_GENERAL_ERROR;
134     }
135     buf->contentSize += sizeof(tempType);
136     if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, &length, sizeof(length)) != EOK) {
137         IAM_LOGE("copy length fail");
138         return RESULT_GENERAL_ERROR;
139     }
140     buf->contentSize += sizeof(length);
141     return RESULT_SUCCESS;
142 }
143 
WriteTlv(const AuthAttributeType type,const uint32_t length,const uint8_t * value,Buffer * buf)144 static ResultCode WriteTlv(const AuthAttributeType type, const uint32_t length, const uint8_t *value, Buffer *buf)
145 {
146     if (WriteTlvHead(type, length, buf) != RESULT_SUCCESS) {
147         IAM_LOGE("write tlv head fail");
148         return RESULT_GENERAL_ERROR;
149     }
150 
151     if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, value, length) != EOK) {
152         IAM_LOGE("copy buffer content fail %{public}d  %{public}d",  buf->maxSize - buf->contentSize, length);
153         return RESULT_GENERAL_ERROR;
154     }
155     buf->contentSize += length;
156     return RESULT_SUCCESS;
157 }
158 
GetDataTlvContent(uint32_t result,uint64_t scheduleId,uint64_t subType,uint64_t templatedId,uint32_t remainAttempts)159 static Buffer *GetDataTlvContent(uint32_t result, uint64_t scheduleId, uint64_t subType, uint64_t templatedId,
160     uint32_t remainAttempts)
161 {
162     Buffer *ret = CreateBufferBySize(500);
163     if (!IsBufferValid(ret)) {
164         IAM_LOGE("create buffer fail");
165         return nullptr;
166     }
167 
168     constexpr int32_t zero = 0;
169     constexpr uint32_t secretLen = 32;
170     constexpr uint32_t secretValueLen = 100;
171     constexpr uint8_t secretValue = 8;
172     std::vector<uint8_t> rootSecret(secretValueLen, secretValue);
173     uint32_t acl = FACE_AUTH_CAPABILITY_LEVEL;
174     if (WriteTlv(ATTR_RESULT_CODE, sizeof(result), (const uint8_t *)&result, ret) != RESULT_SUCCESS ||
175         WriteTlv(ATTR_TEMPLATE_ID, sizeof(templatedId), (const uint8_t *)&templatedId, ret) != RESULT_SUCCESS ||
176         WriteTlv(ATTR_SCHEDULE_ID, sizeof(scheduleId), (const uint8_t *)&scheduleId, ret) != RESULT_SUCCESS ||
177         WriteTlv(ATTR_PIN_SUB_TYPE, sizeof(subType), (const uint8_t *)&subType, ret) != RESULT_SUCCESS ||
178         WriteTlv(ATTR_CAPABILITY_LEVEL, sizeof(acl), (const uint8_t *)&acl, ret) != RESULT_SUCCESS ||
179         WriteTlv(ATTR_LOCKOUT_DURATION, sizeof(int32_t), (const uint8_t *)&zero, ret) != RESULT_SUCCESS ||
180         WriteTlv(ATTR_REMAIN_ATTEMPTS, sizeof(int32_t), (const uint8_t *)&remainAttempts, ret) != RESULT_SUCCESS ||
181         WriteTlv(ATTR_ROOT_SECRET, secretLen, &rootSecret[0], ret) != RESULT_SUCCESS) {
182         IAM_LOGE("write tlv fail");
183         DestoryBuffer(ret);
184         return nullptr;
185     }
186     return ret;
187 }
188 
GenerateRetTlv(const TlvRequiredPara & para,Buffer * retTlv)189 static ResultCode GenerateRetTlv(const TlvRequiredPara &para, Buffer *retTlv)
190 {
191     if (!IsBufferValid(retTlv)) {
192         IAM_LOGE("param(retTlv) is invalid");
193         return RESULT_GENERAL_ERROR;
194     }
195     if (!IsEd25519KeyPairValid(g_keyPair)) {
196         IAM_LOGE("param(g_keyPair) is invalid");
197         return RESULT_GENERAL_ERROR;
198     }
199 
200     IAM_LOGI("scheduleId %{public}s", GET_MASKED_STRING(para.scheduleId).c_str());
201     Buffer *dataContent = GetDataTlvContent(para.result, para.scheduleId, para.subType, para.templateId,
202         para.remainAttempts);
203     if (!IsBufferValid(dataContent)) {
204         IAM_LOGE("get data content fail");
205         return RESULT_GENERAL_ERROR;
206     }
207 
208     Buffer *signContent = nullptr;
209     if (Ed25519Sign(g_keyPair, dataContent, &signContent) != RESULT_SUCCESS) {
210         IAM_LOGE("sign data fail");
211         DestoryBuffer(dataContent);
212         return RESULT_GENERAL_ERROR;
213     }
214 
215     uint32_t rootLen = TAG_AND_LEN_BYTE + dataContent->contentSize + TAG_AND_LEN_BYTE + ED25519_FIX_SIGN_BUFFER_SIZE;
216     if (WriteTlvHead(ATTR_ROOT, rootLen, retTlv) != RESULT_SUCCESS ||
217         WriteTlv(ATTR_DATA, dataContent->contentSize, dataContent->buf, retTlv) != RESULT_SUCCESS ||
218         WriteTlv(ATTR_SIGNATURE, signContent->contentSize, signContent->buf, retTlv) != RESULT_SUCCESS) {
219         IAM_LOGE("write tlv fail");
220         DestoryBuffer(dataContent);
221         DestoryBuffer(signContent);
222         return RESULT_GENERAL_ERROR;
223     }
224     DestoryBuffer(dataContent);
225     DestoryBuffer(signContent);
226     return RESULT_SUCCESS;
227 }
228 
GetExecutorResultTlv(const TlvRequiredPara & para,std::vector<uint8_t> & resultTlv)229 ResultCode GetExecutorResultTlv(const TlvRequiredPara &para, std::vector<uint8_t> &resultTlv)
230 {
231     Buffer *retTlv = CreateBufferBySize(RESULT_TLV_LEN);
232     if (retTlv == nullptr) {
233         IAM_LOGE("CreateBufferBySize failed");
234         return RESULT_GENERAL_ERROR;
235     }
236 
237     ResultCode ret = GenerateRetTlv(para, retTlv);
238     if (ret != RESULT_SUCCESS) {
239         IAM_LOGE("GenerateRetTlv fail");
240         return RESULT_GENERAL_ERROR;
241     }
242 
243     resultTlv.resize(retTlv->contentSize);
244     if (memcpy_s(&resultTlv[0], retTlv->contentSize, retTlv->buf, retTlv->contentSize) != EOK) {
245         IAM_LOGE("copy retTlv to resultTlv fail");
246         return RESULT_GENERAL_ERROR;
247     }
248     IAM_LOGI("get result tlv success");
249     return RESULT_SUCCESS;
250 }
251 
GetExecutorPublicKey(std::vector<uint8_t> & vPubKey)252 ResultCode GetExecutorPublicKey(std::vector<uint8_t> &vPubKey)
253 {
254     if (!IsEd25519KeyPairValid(g_keyPair)) {
255         GenerateExecutorKeyPair();
256     }
257     if (g_keyPair == nullptr) {
258         IAM_LOGE("key pair is invalid");
259         return RESULT_GENERAL_ERROR;
260     }
261     Buffer *pubKey = g_keyPair->pubKey;
262     vPubKey.resize(pubKey->contentSize);
263     if (memcpy_s(&vPubKey[0], pubKey->contentSize, pubKey->buf, pubKey->contentSize) != EOK) {
264         IAM_LOGE("copy public key fail");
265         return RESULT_GENERAL_ERROR;
266     }
267     return RESULT_SUCCESS;
268 }
269 } // namespace UserAuth
270 } // namespace HDI
271 } // namespace OHOS
272