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