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 "pin_func.h"
17 #include "adaptor_algorithm.h"
18 #include "buffer.h"
19 #include "securec.h"
20
21 static KeyPair *g_keyPair = NULL;
22
DoEnrollPin(PinEnrollParam * pinEnrollParam,Buffer * retTlv)23 ResultCode DoEnrollPin(PinEnrollParam *pinEnrollParam, Buffer *retTlv)
24 {
25 if (pinEnrollParam == NULL || !IsBufferValid(retTlv)) {
26 LOG_ERROR("get invalid params.");
27 return RESULT_BAD_PARAM;
28 }
29 uint64_t templateId = INVALID_TEMPLATE_ID;
30 Buffer *rootSecret = CreateBufferBySize(ROOT_SECRET_LEN);
31 if (!IsBufferValid(rootSecret)) {
32 LOG_ERROR("no memory.");
33 return RESULT_BAD_PARAM;
34 }
35 ResultCode ret = AddPin(pinEnrollParam, &templateId, rootSecret);
36 if (ret != RESULT_SUCCESS) {
37 LOG_ERROR("AddPin fail.");
38 DestoryBuffer(rootSecret);
39 return ret;
40 }
41
42 ret = GenerateRetTlv(RESULT_SUCCESS, pinEnrollParam->scheduleId, templateId, retTlv, rootSecret);
43 if (ret != RESULT_SUCCESS) {
44 LOG_ERROR("GenerateRetTlv DoEnrollPin fail.");
45 }
46
47 DestoryBuffer(rootSecret);
48 return ret;
49 }
50
GetSubTypeAndFreezeTime(uint64_t * subType,uint64_t templateId,uint32_t * freezeTime,uint32_t * conut)51 static ResultCode GetSubTypeAndFreezeTime(uint64_t *subType, uint64_t templateId, uint32_t *freezeTime, uint32_t *conut)
52 {
53 ResultCode ret = GetSubType(templateId, subType);
54 if (ret != RESULT_SUCCESS) {
55 LOG_ERROR("GetSubType fail.");
56 return ret;
57 }
58 uint64_t startFreezeTime = INIT_START_FREEZE_TIMES;
59 ret = GetAntiBruteInfo(templateId, conut, &startFreezeTime);
60 if (ret != RESULT_SUCCESS) {
61 LOG_ERROR("GetAntiBruteInfo fail.");
62 return ret;
63 }
64
65 ret = ComputeFreezeTime(templateId, freezeTime, *conut, startFreezeTime);
66 if (ret != RESULT_SUCCESS) {
67 LOG_ERROR("ComputeFreezeTime fail.");
68 return ret;
69 }
70 return RESULT_SUCCESS;
71 }
72
DoAuthPin(PinAuthParam * pinAuthParam,Buffer * retTlv,ResultCode * compareRet)73 ResultCode DoAuthPin(PinAuthParam *pinAuthParam, Buffer *retTlv, ResultCode *compareRet)
74 {
75 if (!IsBufferValid(retTlv) || pinAuthParam == NULL || compareRet == NULL) {
76 LOG_ERROR("check param fail!");
77 return RESULT_BAD_PARAM;
78 }
79 *compareRet = RESULT_COMPARE_FAIL;
80
81 uint64_t subType = 0;
82 uint32_t freezeTime = 0;
83 uint32_t authErrorCount = INIT_AUTH_ERROR_COUNT;
84 ResultCode ret = GetSubTypeAndFreezeTime(&subType, pinAuthParam->templateId, &freezeTime, &authErrorCount);
85 if (ret != RESULT_SUCCESS) {
86 LOG_ERROR("GetSubTypeAndFreezeTime fail.");
87 return ret;
88 }
89
90 Buffer *rootSecret = CreateBufferBySize(ROOT_SECRET_LEN);
91 if (!IsBufferValid(rootSecret)) {
92 LOG_ERROR("no memory.");
93 return RESULT_BAD_PARAM;
94 }
95 if (freezeTime == 0) {
96 ret = AuthPinById(pinAuthParam->pinData, CONST_PIN_DATA_LEN, pinAuthParam->templateId, rootSecret, compareRet);
97 if (ret != RESULT_SUCCESS) {
98 LOG_ERROR("AuthPinById fail.");
99 goto EXIT;
100 }
101 } else {
102 LOG_ERROR("Pin is freezing.");
103 *compareRet = RESULT_PIN_FREEZE;
104 }
105
106 ret = GenerateRetTlv(*compareRet, pinAuthParam->scheduleId, pinAuthParam->templateId, retTlv, rootSecret);
107 if (ret != RESULT_SUCCESS) {
108 LOG_ERROR("GenerateRetTlv DoAuthPin fail.");
109 }
110
111 EXIT:
112 DestoryBuffer(rootSecret);
113 return ret;
114 }
115
DoQueryPinInfo(uint64_t templateId,PinCredentialInfos * pinCredentialInfo)116 ResultCode DoQueryPinInfo(uint64_t templateId, PinCredentialInfos *pinCredentialInfo)
117 {
118 if (pinCredentialInfo == NULL || templateId == INVALID_TEMPLATE_ID) {
119 LOG_ERROR("check DoQueryPin param fail!");
120 return RESULT_BAD_PARAM;
121 }
122 uint32_t authErrorCount = INIT_AUTH_ERROR_COUNT;
123 ResultCode ret = GetSubTypeAndFreezeTime(&(pinCredentialInfo->subType), templateId,
124 &(pinCredentialInfo->freezeTime), &authErrorCount);
125 if (ret != RESULT_SUCCESS) {
126 LOG_ERROR("GetSubTypeAndFreezeTime fail.");
127 return ret;
128 }
129 if (pinCredentialInfo->freezeTime > 0) {
130 pinCredentialInfo->remainTimes = 0;
131 } else {
132 ret = GetRemainTimes(templateId, &(pinCredentialInfo->remainTimes), authErrorCount);
133 if (ret != RESULT_SUCCESS) {
134 LOG_ERROR("GetRemainTimes fail.");
135 return ret;
136 }
137 }
138 return ret;
139 }
140
DoDeleteTemplate(uint64_t templateId)141 ResultCode DoDeleteTemplate(uint64_t templateId)
142 {
143 ResultCode ret = DelPinById(templateId);
144 if (ret != RESULT_SUCCESS) {
145 LOG_ERROR("delete pin fail.");
146 return RESULT_BAD_DEL;
147 }
148 return RESULT_SUCCESS;
149 }
150
151 /* This is for example only, Should be implemented in trusted environment. */
GenerateKeyPair(void)152 ResultCode GenerateKeyPair(void)
153 {
154 DestoryKeyPair(g_keyPair);
155 g_keyPair = GenerateEd25519KeyPair();
156 if (g_keyPair == NULL) {
157 LOG_ERROR("GenerateEd25519Keypair fail!");
158 return RESULT_GENERAL_ERROR;
159 }
160 LOG_INFO("GenerateKeyPair success");
161 return RESULT_SUCCESS;
162 }
163
DestoryGlobalKeyPair(void)164 void DestoryGlobalKeyPair(void)
165 {
166 DestoryKeyPair(g_keyPair);
167 g_keyPair = NULL;
168 LOG_INFO("DestoryKeyPair success");
169 }
170
171 /* This is for example only, Should be implemented in trusted environment. */
DoGetExecutorInfo(PinExecutorInfo * pinExecutorInfo)172 ResultCode DoGetExecutorInfo(PinExecutorInfo *pinExecutorInfo)
173 {
174 if (pinExecutorInfo == NULL) {
175 LOG_ERROR("check param fail!");
176 return RESULT_BAD_PARAM;
177 }
178 if (!IsEd25519KeyPairValid(g_keyPair)) {
179 LOG_ERROR("key pair not init!");
180 return RESULT_NEED_INIT;
181 }
182 uint32_t pubKeyLen = CONST_PUB_KEY_LEN;
183 if (GetBufferData(g_keyPair->pubKey, pinExecutorInfo->pubKey, &pubKeyLen) != RESULT_SUCCESS) {
184 LOG_ERROR("GetBufferData fail!");
185 return RESULT_UNKNOWN;
186 }
187 pinExecutorInfo->esl = PIN_EXECUTOR_SECURITY_LEVEL;
188 return RESULT_SUCCESS;
189 }
190
WriteTlvHead(const AuthAttributeType type,const uint32_t length,Buffer * buf)191 static ResultCode WriteTlvHead(const AuthAttributeType type, const uint32_t length, Buffer *buf)
192 {
193 int32_t tempType = type;
194 if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, &tempType, sizeof(tempType)) != EOK) {
195 LOG_ERROR("copy type fail.");
196 return RESULT_BAD_COPY;
197 }
198 buf->contentSize += sizeof(tempType);
199 if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, &length, sizeof(length)) != EOK) {
200 LOG_ERROR("copy length fail.");
201 return RESULT_BAD_COPY;
202 }
203 buf->contentSize += sizeof(length);
204 return RESULT_SUCCESS;
205 }
206
WriteTlv(const AuthAttributeType type,const uint32_t length,const uint8_t * value,Buffer * buf)207 static ResultCode WriteTlv(const AuthAttributeType type, const uint32_t length, const uint8_t *value, Buffer *buf)
208 {
209 if (WriteTlvHead(type, length, buf) != RESULT_SUCCESS) {
210 LOG_ERROR("copy head fail.");
211 return RESULT_BAD_COPY;
212 }
213 if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, value, length) != EOK) {
214 LOG_ERROR("copy value fail.");
215 return RESULT_BAD_COPY;
216 }
217 buf->contentSize += length;
218 return RESULT_SUCCESS;
219 }
220
GetDataTlvContent(uint32_t result,uint64_t scheduleId,uint64_t templateId,const Buffer * rootSecret)221 static Buffer *GetDataTlvContent(uint32_t result, uint64_t scheduleId, uint64_t templateId, const Buffer *rootSecret)
222 {
223 Buffer *ret = CreateBufferBySize(RESULT_TLV_LEN);
224 if (!IsBufferValid(ret)) {
225 LOG_ERROR("no memory.");
226 return NULL;
227 }
228 PinCredentialInfos pinCredentialInfo;
229 if (DoQueryPinInfo(templateId, &pinCredentialInfo) != RESULT_SUCCESS) {
230 LOG_ERROR("DoQueryPinInfo fail.");
231 DestoryBuffer(ret);
232 return NULL;
233 }
234 uint32_t acl = PIN_CAPABILITY_LEVEL;
235 if (WriteTlv(AUTH_RESULT_CODE, sizeof(result), (const uint8_t *)&result, ret) != RESULT_SUCCESS ||
236 WriteTlv(AUTH_TEMPLATE_ID, sizeof(templateId), (const uint8_t *)&templateId, ret) != RESULT_SUCCESS ||
237 WriteTlv(AUTH_SCHEDULE_ID, sizeof(scheduleId), (const uint8_t *)&scheduleId, ret) != RESULT_SUCCESS ||
238 WriteTlv(AUTH_SUBTYPE,
239 sizeof(pinCredentialInfo.subType), (const uint8_t *)&pinCredentialInfo.subType, ret) != RESULT_SUCCESS ||
240 WriteTlv(AUTH_REMAIN_COUNT, sizeof(pinCredentialInfo.remainTimes),
241 (const uint8_t *)&pinCredentialInfo.remainTimes, ret) != RESULT_SUCCESS ||
242 WriteTlv(AUTH_REMAIN_TIME, sizeof(pinCredentialInfo.freezeTime),
243 (const uint8_t *)&pinCredentialInfo.freezeTime, ret) != RESULT_SUCCESS ||
244 WriteTlv(AUTH_CAPABILITY_LEVEL, sizeof(acl), (const uint8_t *)&acl, ret) != RESULT_SUCCESS ||
245 WriteTlv(AUTH_ROOT_SECRET, rootSecret->contentSize,
246 (const uint8_t *)(rootSecret->buf), ret) != RESULT_SUCCESS) {
247 LOG_ERROR("write tlv fail.");
248 DestoryBuffer(ret);
249 return NULL;
250 }
251 return ret;
252 }
253
GenerateRetTlv(uint32_t result,uint64_t scheduleId,uint64_t templatedId,Buffer * retTlv,Buffer * rootSecret)254 ResultCode GenerateRetTlv(uint32_t result, uint64_t scheduleId, uint64_t templatedId, Buffer *retTlv,
255 Buffer *rootSecret)
256 {
257 if (!IsBufferValid(retTlv) || !IsEd25519KeyPairValid(g_keyPair)) {
258 LOG_ERROR("param is invalid.");
259 return RESULT_BAD_PARAM;
260 }
261 Buffer *dataContent = GetDataTlvContent(result, scheduleId, templatedId, rootSecret);
262 if (!IsBufferValid(dataContent)) {
263 LOG_ERROR("get data content fail.");
264 return RESULT_BAD_COPY;
265 }
266 Buffer *signContent = NULL;
267 if (Ed25519Sign(g_keyPair, dataContent, &signContent) != RESULT_SUCCESS) {
268 LOG_ERROR("sign data fail.");
269 DestoryBuffer(dataContent);
270 return RESULT_GENERAL_ERROR;
271 }
272 uint32_t rootLen = TAG_AND_LEN_BYTE + dataContent->contentSize + TAG_AND_LEN_BYTE + ED25519_FIX_SIGN_BUFFER_SIZE;
273 if (WriteTlvHead(AUTH_ROOT, rootLen, retTlv) != RESULT_SUCCESS ||
274 WriteTlv(AUTH_DATA, dataContent->contentSize, dataContent->buf, retTlv) != RESULT_SUCCESS ||
275 WriteTlv(AUTH_SIGNATURE, signContent->contentSize, signContent->buf, retTlv) != RESULT_SUCCESS) {
276 LOG_ERROR("write tlv fail.");
277 DestoryBuffer(dataContent);
278 DestoryBuffer(signContent);
279 return RESULT_BAD_COPY;
280 }
281 DestoryBuffer(dataContent);
282 DestoryBuffer(signContent);
283 return RESULT_SUCCESS;
284 }
285
DoVerifyTemplateData(const uint64_t * templateIdList,uint32_t templateIdListLen)286 ResultCode DoVerifyTemplateData(const uint64_t *templateIdList, uint32_t templateIdListLen)
287 {
288 if (templateIdListLen != 0 && templateIdList == NULL) {
289 LOG_ERROR("templateIdList should be not null, when templateIdListLen is not zero");
290 return RESULT_BAD_PARAM;
291 }
292 ResultCode ret = VerifyTemplateDataPin(templateIdList, templateIdListLen);
293 if (ret != RESULT_SUCCESS) {
294 LOG_ERROR("Verify TemplateDataPin fail.");
295 return ret;
296 }
297 return RESULT_SUCCESS;
298 }
299
DoWriteAntiBruteInfoToFile(uint64_t templateId)300 ResultCode DoWriteAntiBruteInfoToFile(uint64_t templateId)
301 {
302 ResultCode ret = RefreshAntiBruteInfoToFile(templateId);
303 if (ret != RESULT_SUCCESS) {
304 LOG_ERROR("RefreshAntiBruteInfoToFile fail.");
305 }
306 return ret;
307 }
308