• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "huks_adapt_manager.h"
17 
18 #include "hks_api.h"
19 #include "hks_param.h"
20 #include "securec.h"
21 
22 #include "alg_utils.h"
23 #include "dlp_permission.h"
24 #include "dlp_permission_log.h"
25 
26 namespace OHOS {
27 namespace Security {
28 namespace DlpPermission {
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "HuksAdaptManager" };
31 }
32 static const uint32_t HMAC_KEY_SIZE_256 = 256;
33 
CheckHMACParams(const HuksKeyInfo * keyInfo,const BlobData * data,const BlobData * outData)34 static bool CheckHMACParams(const HuksKeyInfo *keyInfo, const BlobData *data, const BlobData *outData)
35 {
36     if (keyInfo == nullptr || !IsBlobDataValid(&(keyInfo->keyAlias))) {
37         DLP_LOG_ERROR(LABEL, "Mac keyInfo is invalid!");
38         return false;
39     }
40     if (!IsBlobDataValid(data) || data->dataSize > MAX_DATABASE_FILE_SIZE) {
41         DLP_LOG_ERROR(LABEL, "Mac data is invalid!");
42         return false;
43     }
44     if (outData == nullptr) {
45         DLP_LOG_ERROR(LABEL, "Mac outData is invalid!");
46         return false;
47     }
48     return true;
49 }
50 
ConstructParamSet(struct HksParamSet ** outParamSet,struct HksParam * params,uint32_t paramcount)51 static int32_t ConstructParamSet(struct HksParamSet **outParamSet, struct HksParam *params,
52     uint32_t paramcount)
53 {
54     int32_t res = HksInitParamSet(outParamSet);
55     if (res != HKS_SUCCESS) {
56         DLP_LOG_ERROR(LABEL, "HksInitParamSet failed, error code: %{public}d.", res);
57         return DLP_SERVICE_ERROR_VALUE_INVALID;
58     }
59 
60     res = HksAddParams(*outParamSet, params, paramcount);
61     if (res != HKS_SUCCESS) {
62         DLP_LOG_ERROR(LABEL, "HksAddParams failed, error code: %{public}d.", res);
63         HksFreeParamSet(outParamSet);
64         return DLP_SERVICE_ERROR_VALUE_INVALID;
65     }
66 
67     res = HksBuildParamSet(outParamSet);
68     if (res != HKS_SUCCESS) {
69         DLP_LOG_ERROR(LABEL, "HksBuildParamSet failed, error code: %{public}d.", res);
70         HksFreeParamSet(outParamSet);
71         return DLP_SERVICE_ERROR_VALUE_INVALID;
72     }
73     return DLP_OK;
74 }
75 
MallocAndCheckBlobData(struct HksBlob * blob,uint32_t blobSize)76 static int32_t MallocAndCheckBlobData(struct HksBlob *blob, uint32_t blobSize)
77 {
78     blob->data = (uint8_t *)HcMalloc(blobSize, 0);
79     if (blob->data == nullptr) {
80         DLP_LOG_ERROR(LABEL, "Allocate blob data memory failed!");
81         return HKS_FAILURE;
82     }
83     return HKS_SUCCESS;
84 }
85 
LessThanMaxSeg(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData)86 static int32_t LessThanMaxSeg(const struct HksBlob *handle, const struct HksParamSet *paramSet,
87     const struct HksBlob *inData, struct HksBlob *outData)
88 {
89     struct HksBlob tmpOutData = { MAX_OUTDATA_SIZE, nullptr };
90     if (MallocAndCheckBlobData(&tmpOutData, tmpOutData.size) != HKS_SUCCESS) {
91         return HKS_FAILURE;
92     }
93     int32_t ret = HksUpdate(handle, paramSet, inData, &tmpOutData);
94     HcFree(tmpOutData.data);
95     if (ret != HKS_SUCCESS) {
96         DLP_LOG_ERROR(LABEL, "HksUpdate Failed.");
97         return HKS_FAILURE;
98     }
99     struct HksBlob tmpInData = { 0, nullptr };
100     if (MallocAndCheckBlobData(&tmpInData, MAX_UPDATE_SIZE) != HKS_SUCCESS) {
101         return HKS_FAILURE;
102     }
103 
104     ret = HksFinish(handle, paramSet, &tmpInData, outData);
105     HcFree(tmpInData.data);
106     if (ret != HKS_SUCCESS) {
107         DLP_LOG_ERROR(LABEL, "HksFinish Failed.");
108         return HKS_FAILURE;
109     }
110     return HKS_SUCCESS;
111 }
112 
HksShardingUpdateAndFinish(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData)113 static int32_t HksShardingUpdateAndFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet,
114     const struct HksBlob *inData, struct HksBlob *outData)
115 {
116     struct HksBlob inDataSeg = *inData;
117     inDataSeg.size = MAX_UPDATE_SIZE;
118     uint8_t *lastPtr = inData->data + inData->size - 1;
119     struct HksBlob outDataSeg = { MAX_OUTDATA_SIZE, nullptr };
120 
121     if (inData->size <= MAX_UPDATE_SIZE) {
122         return LessThanMaxSeg(handle, paramSet, inData, outData);
123     }
124 
125     while (inDataSeg.data <= lastPtr) {
126         if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
127             outDataSeg.size = MAX_OUTDATA_SIZE;
128             if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size) != HKS_SUCCESS) {
129                 return HKS_FAILURE;
130             }
131         } else {
132             inDataSeg.size = lastPtr - inDataSeg.data + 1;
133             break;
134         }
135         if (HksUpdate(handle, paramSet, &inDataSeg, &outDataSeg) != HKS_SUCCESS) {
136             DLP_LOG_ERROR(LABEL, "HksUpdate Failed.");
137             DLP_FREE_PTR(outDataSeg.data);
138             return HKS_FAILURE;
139         }
140         DLP_FREE_PTR(outDataSeg.data);
141         if (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr) {
142             return HKS_FAILURE;
143         }
144         inDataSeg.data += MAX_UPDATE_SIZE;
145     }
146     if (HksFinish(handle, paramSet, &inDataSeg, outData) != HKS_SUCCESS) {
147         DLP_LOG_ERROR(LABEL, "Finish stage failed.");
148         return HKS_FAILURE;
149     }
150     return HKS_SUCCESS;
151 }
152 
HksHMACThreeStages(const BlobData * keyAlias,struct HksParamSet * hmacParamSet,const BlobData * data,BlobData * outData)153 static int32_t HksHMACThreeStages(const BlobData *keyAlias, struct HksParamSet *hmacParamSet,
154     const BlobData *data, BlobData *outData)
155 {
156     uint8_t handle[SIZE_OF_UINT64] = { 0 };
157     struct HksBlob handleHMAC = { SIZE_OF_UINT64, handle };
158     int32_t ret = HksInit((struct HksBlob *)keyAlias, hmacParamSet, &handleHMAC, nullptr);
159     if (ret != HKS_SUCCESS) {
160         return ret;
161     }
162 
163     ret = HksShardingUpdateAndFinish(&handleHMAC, hmacParamSet, (struct HksBlob *)data, (struct HksBlob *)outData);
164     if (ret != HKS_SUCCESS) {
165         DLP_LOG_ERROR(LABEL, "Update and finish stage failed, error code: %{public}d", ret);
166         HksAbort(&handleHMAC, hmacParamSet);
167         return DLP_SERVICE_ERROR_VALUE_INVALID;
168     }
169     return DLP_OK;
170 }
171 
IsHuksMgrKeyExist(const HuksKeyInfo * keyInfo)172 bool IsHuksMgrKeyExist(const HuksKeyInfo *keyInfo)
173 {
174     if (keyInfo == nullptr || !IsBlobDataValid(&(keyInfo->keyAlias))) {
175         DLP_LOG_ERROR(LABEL, "keyInfo is invalid!");
176         return false;
177     }
178     struct HksParamSet *paramSet = nullptr;
179     struct HksParam deHmacParams[] = {
180         { .tag = HKS_TAG_SPECIFIC_USER_ID, .uint32Param = keyInfo->osAccountId },
181         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
182     };
183     int32_t res = ConstructParamSet(&paramSet, deHmacParams, sizeof(deHmacParams) / sizeof(deHmacParams[0]));
184     if (res != DLP_OK) {
185         DLP_LOG_ERROR(LABEL, "construct param set failed!");
186         return false;
187     }
188     res = HksKeyExist((struct HksBlob *)(&(keyInfo->keyAlias)), paramSet);
189     HksFreeParamSet(&paramSet);
190     if (res != HKS_SUCCESS) {
191         DLP_LOG_ERROR(LABEL, "Key is not exist, error code: %{public}d.", res);
192         return false;
193     }
194     return true;
195 }
196 
HuksGenerateMacKey(const HuksKeyInfo * keyInfo)197 int32_t HuksGenerateMacKey(const HuksKeyInfo *keyInfo)
198 {
199     if (keyInfo == nullptr || !IsBlobDataValid(&(keyInfo->keyAlias))) {
200         DLP_LOG_ERROR(LABEL, "keyInfo is invalid!");
201         return DLP_SERVICE_ERROR_VALUE_INVALID;
202     }
203 
204     struct HksParamSet *paramSet = nullptr;
205     struct HksParam deGenParams[] = {
206         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_HMAC },
207         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_MAC },
208         { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 },
209         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HMAC_KEY_SIZE_256 },
210         { .tag = HKS_TAG_SPECIFIC_USER_ID, .uint32Param = keyInfo->osAccountId },
211         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
212     };
213     int32_t ret = ConstructParamSet(&paramSet, deGenParams, sizeof(deGenParams) / sizeof(deGenParams[0]));
214     if (ret != DLP_OK) {
215         DLP_LOG_ERROR(LABEL, "Construct MacKey ParamSet failed!");
216         return DLP_SERVICE_ERROR_VALUE_INVALID;
217     }
218     ret = HksGenerateKey((struct HksBlob *)(&(keyInfo->keyAlias)), paramSet, nullptr);
219     HksFreeParamSet(&paramSet);
220     if (ret != HKS_SUCCESS) {
221         DLP_LOG_ERROR(LABEL, "HksGenerateKey for mac key failed, error code: %{public}d.", ret);
222         return DLP_SERVICE_ERROR_VALUE_INVALID;
223     }
224     return DLP_OK;
225 }
226 
HuksGenerateHmac(const HuksKeyInfo * keyInfo,const BlobData * data,BlobData * outData)227 int32_t HuksGenerateHmac(const HuksKeyInfo *keyInfo, const BlobData *data, BlobData *outData)
228 {
229     if (!CheckHMACParams(keyInfo, data, outData)) {
230         return DLP_SERVICE_ERROR_VALUE_INVALID;
231     }
232     outData->value = (uint8_t *)HcMalloc(HASH_SIZE_SHA_256, 0);
233     if (outData->value == nullptr) {
234         DLP_LOG_ERROR(LABEL, "Allocate outData memory failed");
235         return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
236     }
237     outData->dataSize = HASH_SIZE_SHA_256;
238 
239     struct HksParamSet *hmacParamSet = nullptr;
240     struct HksParam deHmacParams[] = {
241         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_HMAC },
242         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_MAC },
243         { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 },
244         { .tag = HKS_TAG_SPECIFIC_USER_ID, .uint32Param = keyInfo->osAccountId },
245         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
246     };
247     int32_t res = ConstructParamSet(&hmacParamSet, deHmacParams, sizeof(deHmacParams) / sizeof(deHmacParams[0]));
248     if (res != DLP_OK) {
249         DLP_LOG_ERROR(LABEL, "construct hmac param set failed!");
250         FreeBlobData(outData);
251         return DLP_SERVICE_ERROR_VALUE_INVALID;
252     }
253     res = HksHMACThreeStages(&(keyInfo->keyAlias), hmacParamSet, data, outData);
254     HksFreeParamSet(&hmacParamSet);
255     if (res != DLP_OK) {
256         FreeBlobData(outData);
257         res = DLP_SERVICE_ERROR_VALUE_INVALID;
258     }
259     return res;
260 }
261 }  // namespace DlpPermission
262 }  // namespace Security
263 }  // namespace OHOS