• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)73 ResultCode DoAuthPin(PinAuthParam *pinAuthParam, Buffer *retTlv)
74 {
75     if (!IsBufferValid(retTlv) || pinAuthParam == NULL) {
76         LOG_ERROR("check param fail!");
77         return RESULT_BAD_PARAM;
78     }
79 
80     uint64_t subType = 0;
81     uint32_t freezeTime = 0;
82     uint32_t authErrorConut = INIT_AUTH_ERROR_COUNT;
83     ResultCode ret = GetSubTypeAndFreezeTime(&subType, pinAuthParam->templateId, &freezeTime, &authErrorConut);
84     if (ret != RESULT_SUCCESS) {
85         LOG_ERROR("GetSubTypeAndFreezeTime fail.");
86         return ret;
87     }
88 
89     Buffer *rootSecret = CreateBufferBySize(ROOT_SECRET_LEN);
90     if (!IsBufferValid(rootSecret)) {
91         LOG_ERROR("no memory.");
92         return RESULT_BAD_PARAM;
93     }
94     if (freezeTime == 0) {
95         ret = AuthPinById(pinAuthParam->pinData, CONST_PIN_DATA_LEN, pinAuthParam->templateId, rootSecret);
96         if (ret != RESULT_SUCCESS) {
97             LOG_ERROR("AuthPinById fail.");
98         }
99     } else {
100         LOG_ERROR("Pin is freezing.");
101         ret = RESULT_PIN_FREEZE;
102     }
103 
104     ResultCode result = GenerateRetTlv(ret, pinAuthParam->scheduleId, pinAuthParam->templateId, retTlv, rootSecret);
105     if (result != RESULT_SUCCESS) {
106         LOG_ERROR("GenerateRetTlv DoAuthPin fail.");
107         DestoryBuffer(rootSecret);
108         return result;
109     }
110 
111     DestoryBuffer(rootSecret);
112     return ret;
113 }
114 
DoQueryPinInfo(uint64_t templateId,PinCredentialInfos * pinCredentialInfo)115 ResultCode DoQueryPinInfo(uint64_t templateId, PinCredentialInfos *pinCredentialInfo)
116 {
117     if (pinCredentialInfo == NULL || templateId == INVALID_TEMPLATE_ID) {
118         LOG_ERROR("check DoQueryPin param fail!");
119         return RESULT_BAD_PARAM;
120     }
121     uint32_t authErrorConut = INIT_AUTH_ERROR_COUNT;
122     ResultCode ret = GetSubTypeAndFreezeTime(&(pinCredentialInfo->subType), templateId,
123         &(pinCredentialInfo->freezeTime), &authErrorConut);
124     if (ret != RESULT_SUCCESS) {
125         LOG_ERROR("GetSubTypeAndFreezeTime fail.");
126         return ret;
127     }
128     if (pinCredentialInfo->freezeTime > 0) {
129         pinCredentialInfo->remainTimes = 0;
130     } else {
131         ret = GetRemainTimes(templateId, &(pinCredentialInfo->remainTimes), authErrorConut);
132         if (ret != RESULT_SUCCESS) {
133             LOG_ERROR("GetRemainTimes fail.");
134             return ret;
135         }
136     }
137     return ret;
138 }
139 
DoDeleteTemplate(uint64_t templateId)140 ResultCode DoDeleteTemplate(uint64_t templateId)
141 {
142     ResultCode ret = DelPinById(templateId);
143     if (ret != RESULT_SUCCESS) {
144         LOG_ERROR("delete pin fail.");
145         return RESULT_BAD_DEL;
146     }
147     return RESULT_SUCCESS;
148 }
149 
150 /* This is for example only, Should be implemented in trusted environment. */
GenerateKeyPair()151 ResultCode GenerateKeyPair()
152 {
153     DestoryKeyPair(g_keyPair);
154     g_keyPair = GenerateEd25519KeyPair();
155     if (g_keyPair == NULL) {
156         LOG_ERROR("GenerateEd25519Keypair fail!");
157         return RESULT_GENERAL_ERROR;
158     }
159     LOG_INFO("GenerateKeyPair success");
160     return RESULT_SUCCESS;
161 }
162 
163 /* This is for example only, Should be implemented in trusted environment. */
DoGetExecutorInfo(PinExecutorInfo * pinExecutorInfo)164 ResultCode DoGetExecutorInfo(PinExecutorInfo *pinExecutorInfo)
165 {
166     if (pinExecutorInfo == NULL) {
167         LOG_ERROR("check param fail!");
168         return RESULT_BAD_PARAM;
169     }
170     if (!IsEd25519KeyPairValid(g_keyPair)) {
171         LOG_ERROR("key pair not init!");
172         return RESULT_NEED_INIT;
173     }
174     uint32_t pubKeyLen = CONST_PUB_KEY_LEN;
175     if (GetBufferData(g_keyPair->pubKey, pinExecutorInfo->pubKey, &pubKeyLen) != RESULT_SUCCESS) {
176         LOG_ERROR("GetBufferData fail!");
177         return RESULT_UNKNOWN;
178     }
179     pinExecutorInfo->esl = PIN_EXECUTOR_SECURITY_LEVEL;
180     return RESULT_SUCCESS;
181 }
182 
WriteTlvHead(const AuthAttributeType type,const uint32_t length,Buffer * buf)183 static ResultCode WriteTlvHead(const AuthAttributeType type, const uint32_t length, Buffer *buf)
184 {
185     int32_t tempType = type;
186     if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, &tempType, sizeof(tempType)) != EOK) {
187         LOG_ERROR("copy type fail.");
188         return RESULT_BAD_COPY;
189     }
190     buf->contentSize += sizeof(tempType);
191     if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, &length, sizeof(length)) != EOK) {
192         LOG_ERROR("copy length fail.");
193         return RESULT_BAD_COPY;
194     }
195     buf->contentSize += sizeof(length);
196     return RESULT_SUCCESS;
197 }
198 
WriteTlv(const AuthAttributeType type,const uint32_t length,const uint8_t * value,Buffer * buf)199 static ResultCode WriteTlv(const AuthAttributeType type, const uint32_t length, const uint8_t *value, Buffer *buf)
200 {
201     if (WriteTlvHead(type, length, buf) != RESULT_SUCCESS) {
202         LOG_ERROR("copy head fail.");
203         return RESULT_BAD_COPY;
204     }
205     if (memcpy_s(buf->buf + buf->contentSize, buf->maxSize - buf->contentSize, value, length) != EOK) {
206         LOG_ERROR("copy value fail.");
207         return RESULT_BAD_COPY;
208     }
209     buf->contentSize += length;
210     return RESULT_SUCCESS;
211 }
212 
GetDataTlvContent(uint32_t result,uint64_t scheduleId,uint64_t templateId,const Buffer * rootSecret)213 static Buffer *GetDataTlvContent(uint32_t result, uint64_t scheduleId, uint64_t templateId, const Buffer *rootSecret)
214 {
215     Buffer *ret = CreateBufferBySize(RESULT_TLV_LEN);
216     if (!IsBufferValid(ret)) {
217         LOG_ERROR("no memory.");
218         return NULL;
219     }
220     PinCredentialInfos pinCredentialInfo;
221     if (DoQueryPinInfo(templateId, &pinCredentialInfo) != RESULT_SUCCESS) {
222         LOG_ERROR("DoQueryPinInfo fail.");
223         DestoryBuffer(ret);
224         return NULL;
225     }
226     uint32_t acl = PIN_CAPABILITY_LEVEL;
227     if (WriteTlv(AUTH_RESULT_CODE, sizeof(result), (const uint8_t *)&result, ret) != RESULT_SUCCESS ||
228         WriteTlv(AUTH_TEMPLATE_ID, sizeof(templateId), (const uint8_t *)&templateId, ret) != RESULT_SUCCESS ||
229         WriteTlv(AUTH_SCHEDULE_ID, sizeof(scheduleId), (const uint8_t *)&scheduleId, ret) != RESULT_SUCCESS ||
230         WriteTlv(AUTH_SUBTYPE,
231             sizeof(pinCredentialInfo.subType), (const uint8_t *)&pinCredentialInfo.subType, ret) != RESULT_SUCCESS ||
232         WriteTlv(AUTH_REMAIN_COUNT, sizeof(pinCredentialInfo.remainTimes),
233             (const uint8_t *)&pinCredentialInfo.remainTimes, ret) != RESULT_SUCCESS ||
234         WriteTlv(AUTH_REMAIN_TIME, sizeof(pinCredentialInfo.freezeTime),
235             (const uint8_t *)&pinCredentialInfo.freezeTime, ret) != RESULT_SUCCESS ||
236         WriteTlv(AUTH_CAPABILITY_LEVEL, sizeof(acl), (const uint8_t *)&acl, ret) != RESULT_SUCCESS ||
237         WriteTlv(AUTH_ROOT_SECRET, rootSecret->contentSize,
238             (const uint8_t *)(rootSecret->buf), ret) != RESULT_SUCCESS) {
239         LOG_ERROR("write tlv fail.");
240         DestoryBuffer(ret);
241         return NULL;
242     }
243     return ret;
244 }
245 
GenerateRetTlv(uint32_t result,uint64_t scheduleId,uint64_t templatedId,Buffer * retTlv,Buffer * rootSecret)246 ResultCode GenerateRetTlv(uint32_t result, uint64_t scheduleId, uint64_t templatedId, Buffer *retTlv,
247     Buffer *rootSecret)
248 {
249     if (!IsBufferValid(retTlv) || !IsEd25519KeyPairValid(g_keyPair)) {
250         LOG_ERROR("param is invalid.");
251         return RESULT_BAD_PARAM;
252     }
253     Buffer *dataContent = GetDataTlvContent(result, scheduleId, templatedId, rootSecret);
254     if (!IsBufferValid(dataContent)) {
255         LOG_ERROR("get data content fail.");
256         return RESULT_BAD_COPY;
257     }
258     Buffer *signContent = NULL;
259     if (Ed25519Sign(g_keyPair, dataContent, &signContent) != RESULT_SUCCESS) {
260         LOG_ERROR("sign data fail.");
261         DestoryBuffer(dataContent);
262         return RESULT_GENERAL_ERROR;
263     }
264     uint32_t rootLen = TAG_AND_LEN_BYTE + dataContent->contentSize + TAG_AND_LEN_BYTE + ED25519_FIX_SIGN_BUFFER_SIZE;
265     if (WriteTlvHead(AUTH_ROOT, rootLen, retTlv) != RESULT_SUCCESS ||
266         WriteTlv(AUTH_DATA, dataContent->contentSize, dataContent->buf, retTlv) != RESULT_SUCCESS ||
267         WriteTlv(AUTH_SIGNATURE, signContent->contentSize, signContent->buf, retTlv) != RESULT_SUCCESS) {
268         LOG_ERROR("write tlv fail.");
269         DestoryBuffer(dataContent);
270         DestoryBuffer(signContent);
271         return RESULT_BAD_COPY;
272     }
273     DestoryBuffer(dataContent);
274     DestoryBuffer(signContent);
275     return RESULT_SUCCESS;
276 }
277 
DoVerifyTemplateData(const uint64_t * templateIdList,uint32_t templateIdListLen)278 ResultCode DoVerifyTemplateData(const uint64_t *templateIdList, uint32_t templateIdListLen)
279 {
280     if (templateIdListLen != 0 && templateIdList == NULL) {
281         LOG_ERROR("templateIdList should be not null, when templateIdListLen is not zero");
282         return RESULT_BAD_PARAM;
283     }
284     ResultCode ret = VerifyTemplateDataPin(templateIdList, templateIdListLen);
285     if (ret != RESULT_SUCCESS) {
286         LOG_ERROR("Verify TemplateDataPin fail.");
287         return ret;
288     }
289     return RESULT_SUCCESS;
290 }
291