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 #define LOG_LABEL OHOS::UserIam::Common::LABEL_USER_AUTH_HDI
26
27 namespace OHOS {
28 namespace HDI {
29 namespace UserAuth {
30 namespace {
31 KeyPair *g_keyPair = nullptr;
32 const uint32_t TAG_AND_LEN_BYTE = 8;
33 const uint32_t FACE_AUTH_CAPABILITY_LEVEL = 3;
34 const uint32_t RESULT_TLV_LEN = 500;
35 } // namespace
36
37 enum AuthAttributeType : uint32_t {
38 /* Root tag */
39 AUTH_ROOT = 100000,
40 /* Result code */
41 AUTH_RESULT_CODE = 100001,
42 /* Tag of signature data in TLV */
43 AUTH_SIGNATURE = 100004,
44 /* Identify mode */
45 AUTH_IDENTIFY_MODE = 100005,
46 /* Tag of templateId data in TLV */
47 AUTH_TEMPLATE_ID = 100006,
48 /* Tag of templateId list data in TLV */
49 AUTH_TEMPLATE_ID_LIST = 100007,
50 /* Expected attribute, tag of remain count in TLV */
51 AUTH_REMAIN_COUNT = 100009,
52 /* Remain time */
53 AUTH_REMAIN_TIME = 100010,
54 /* Session id, required when decode in C */
55 AUTH_SCHEDULE_ID = 100014,
56 /* Package name */
57 AUTH_CALLER_NAME = 100015,
58 /* Schedule version */
59 AUTH_SCHEDULE_VERSION = 100016,
60 /* Tag of lock out template in TLV */
61 AUTH_LOCK_OUT_TEMPLATE = 100018,
62 /* Tag of unlock template in TLV */
63 AUTH_UNLOCK_TEMPLATE = 100019,
64 /* Tag of data */
65 AUTH_DATA = 100020,
66 /* Tag of auth subType */
67 AUTH_SUBTYPE = 100021,
68 /* Tag of auth schedule mode */
69 AUTH_SCHEDULE_MODE = 100022,
70 /* Tag of property */
71 AUTH_PROPERTY_MODE = 100023,
72 /* Tag of auth type */
73 AUTH_TYPE = 100024,
74 /* Tag of cred id */
75 AUTH_CREDENTIAL_ID = 100025,
76 /* Controller */
77 AUTH_CONTROLLER = 100026,
78 /* calleruid */
79 AUTH_CALLER_UID = 100027,
80 /* result */
81 AUTH_RESULT = 100028,
82 /* capability level */
83 AUTH_CAPABILITY_LEVEL = 100029,
84 /* algorithm setinfo */
85 ALGORITHM_INFO = 100030,
86 /* time stamp */
87 AUTH_TIME_STAMP = 100031,
88 /* root secret */
89 AUTH_ROOT_SECRET = 100032,
90 };
91
GenerateExecutorKeyPair()92 ResultCode GenerateExecutorKeyPair()
93 {
94 g_keyPair = GenerateEd25519KeyPair();
95 if (g_keyPair == nullptr) {
96 IAM_LOGE("GenerateEd25519Keypair fail");
97 return RESULT_GENERAL_ERROR;
98 }
99 IAM_LOGI("GenerateExecutorKeyPair success");
100 return RESULT_SUCCESS;
101 }
102
WriteTlvHead(const AuthAttributeType type,const uint32_t length,Buffer * buf)103 static ResultCode WriteTlvHead(const AuthAttributeType type, const uint32_t length, Buffer *buf)
104 {
105 int32_t tempType = type;
106 if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, &tempType, sizeof(tempType)) != EOK) {
107 IAM_LOGE("copy type fail");
108 return RESULT_GENERAL_ERROR;
109 }
110 buf->contentSize += sizeof(tempType);
111 if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, &length, sizeof(length)) != EOK) {
112 IAM_LOGE("copy length fail");
113 return RESULT_GENERAL_ERROR;
114 }
115 buf->contentSize += sizeof(length);
116 return RESULT_SUCCESS;
117 }
118
WriteTlv(const AuthAttributeType type,const uint32_t length,const uint8_t * value,Buffer * buf)119 static ResultCode WriteTlv(const AuthAttributeType type, const uint32_t length, const uint8_t *value, Buffer *buf)
120 {
121 if (WriteTlvHead(type, length, buf) != RESULT_SUCCESS) {
122 IAM_LOGE("write tlv head fail");
123 return RESULT_GENERAL_ERROR;
124 }
125
126 if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, value, length) != EOK) {
127 IAM_LOGE("copy buffer content fail %{public}d %{public}d", buf->maxSize - buf->contentSize, length);
128 return RESULT_GENERAL_ERROR;
129 }
130 buf->contentSize += length;
131 return RESULT_SUCCESS;
132 }
133
GetDataTlvContent(uint32_t result,uint64_t scheduleId,uint64_t subType,uint64_t templatedId,uint32_t remainAttempts)134 static Buffer *GetDataTlvContent(uint32_t result, uint64_t scheduleId, uint64_t subType, uint64_t templatedId,
135 uint32_t remainAttempts)
136 {
137 Buffer *ret = CreateBufferBySize(500);
138 if (!IsBufferValid(ret)) {
139 IAM_LOGE("create buffer fail");
140 return nullptr;
141 }
142
143 const int32_t ZERO = 0;
144 const uint32_t secretLen = 32;
145 const uint32_t secretValueLen = 100;
146 std::vector<uint8_t> rootSecret(secretValueLen, 8);
147 uint32_t acl = FACE_AUTH_CAPABILITY_LEVEL;
148 if (WriteTlv(AUTH_RESULT_CODE, sizeof(result), (const uint8_t *)&result, ret) != RESULT_SUCCESS ||
149 WriteTlv(AUTH_TEMPLATE_ID, sizeof(templatedId), (const uint8_t *)&templatedId, ret) != RESULT_SUCCESS ||
150 WriteTlv(AUTH_SCHEDULE_ID, sizeof(scheduleId), (const uint8_t *)&scheduleId, ret) != RESULT_SUCCESS ||
151 WriteTlv(AUTH_SUBTYPE, sizeof(subType), (const uint8_t *)&subType, ret) != RESULT_SUCCESS ||
152 WriteTlv(AUTH_CAPABILITY_LEVEL, sizeof(acl), (const uint8_t *)&acl, ret) != RESULT_SUCCESS ||
153 WriteTlv(AUTH_REMAIN_TIME, sizeof(int32_t), (const uint8_t *)&ZERO, ret) != RESULT_SUCCESS ||
154 WriteTlv(AUTH_REMAIN_COUNT, sizeof(int32_t), (const uint8_t *)&remainAttempts, ret) != RESULT_SUCCESS ||
155 WriteTlv(AUTH_ROOT_SECRET, secretLen, &rootSecret[0], ret) != RESULT_SUCCESS) {
156 IAM_LOGE("write tlv fail");
157 DestoryBuffer(ret);
158 return nullptr;
159 }
160 return ret;
161 }
162
GenerateRetTlv(const TlvRequiredPara & para,Buffer * retTlv)163 static ResultCode GenerateRetTlv(const TlvRequiredPara ¶, Buffer *retTlv)
164 {
165 if (!IsBufferValid(retTlv)) {
166 IAM_LOGE("param(retTlv) is invalid");
167 return RESULT_GENERAL_ERROR;
168 }
169 if (!IsEd25519KeyPairValid(g_keyPair)) {
170 IAM_LOGE("param(g_keyPair) is invalid");
171 return RESULT_GENERAL_ERROR;
172 }
173
174 IAM_LOGI("scheduleId %{public}s", GET_MASKED_STRING(para.scheduleId).c_str());
175 Buffer *dataContent = GetDataTlvContent(para.result, para.scheduleId, para.subType, para.templateId,
176 para.remainAttempts);
177 if (!IsBufferValid(dataContent)) {
178 IAM_LOGE("get data content fail");
179 return RESULT_GENERAL_ERROR;
180 }
181
182 Buffer *signContent = nullptr;
183 if (Ed25519Sign(g_keyPair, dataContent, &signContent) != RESULT_SUCCESS) {
184 IAM_LOGE("sign data fail");
185 DestoryBuffer(dataContent);
186 return RESULT_GENERAL_ERROR;
187 }
188
189 uint32_t rootLen = TAG_AND_LEN_BYTE + dataContent->contentSize + TAG_AND_LEN_BYTE + ED25519_FIX_SIGN_BUFFER_SIZE;
190 if (WriteTlvHead(AUTH_ROOT, rootLen, retTlv) != RESULT_SUCCESS ||
191 WriteTlv(AUTH_DATA, dataContent->contentSize, dataContent->buf, retTlv) != RESULT_SUCCESS ||
192 WriteTlv(AUTH_SIGNATURE, signContent->contentSize, signContent->buf, retTlv) != RESULT_SUCCESS) {
193 IAM_LOGE("write tlv fail");
194 DestoryBuffer(dataContent);
195 DestoryBuffer(signContent);
196 return RESULT_GENERAL_ERROR;
197 }
198 DestoryBuffer(dataContent);
199 DestoryBuffer(signContent);
200 return RESULT_SUCCESS;
201 }
202
GetExecutorResultTlv(const TlvRequiredPara & para,std::vector<uint8_t> & resultTlv)203 ResultCode GetExecutorResultTlv(const TlvRequiredPara ¶, std::vector<uint8_t> &resultTlv)
204 {
205 Buffer *retTlv = CreateBufferBySize(RESULT_TLV_LEN);
206 if (retTlv == nullptr) {
207 IAM_LOGE("CreateBufferBySize failed");
208 return RESULT_GENERAL_ERROR;
209 }
210
211 ResultCode ret = GenerateRetTlv(para, retTlv);
212 if (ret != RESULT_SUCCESS) {
213 IAM_LOGE("GenerateRetTlv fail");
214 return RESULT_GENERAL_ERROR;
215 }
216
217 resultTlv.resize(retTlv->contentSize);
218 if (memcpy_s(&resultTlv[0], retTlv->contentSize, retTlv->buf, retTlv->contentSize) != EOK) {
219 IAM_LOGE("copy retTlv to resultTlv fail");
220 return RESULT_GENERAL_ERROR;
221 }
222 IAM_LOGI("get result tlv success");
223 return RESULT_SUCCESS;
224 }
225
GetExecutorPublicKey(std::vector<uint8_t> & vPubKey)226 ResultCode GetExecutorPublicKey(std::vector<uint8_t> &vPubKey)
227 {
228 if (!IsEd25519KeyPairValid(g_keyPair)) {
229 GenerateExecutorKeyPair();
230 }
231 if (g_keyPair == nullptr) {
232 IAM_LOGE("key pair is invalid");
233 return RESULT_GENERAL_ERROR;
234 }
235 Buffer *pubKey = g_keyPair->pubKey;
236 vPubKey.resize(pubKey->contentSize);
237 if (memcpy_s(&vPubKey[0], pubKey->contentSize, pubKey->buf, pubKey->contentSize) != EOK) {
238 IAM_LOGE("copy public key fail");
239 return RESULT_GENERAL_ERROR;
240 }
241 return RESULT_SUCCESS;
242 }
243 } // namespace UserAuth
244 } // namespace HDI
245 } // namespace OHOS
246