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 "dlp_common_func.h"
17
18 #include "account_adapt.h"
19 #include "alg_common_type.h"
20 #include "alg_manager.h"
21 #include "alg_utils.h"
22 #include "dlp_permission.h"
23 #include "dlp_permission_log.h"
24
25 namespace OHOS {
26 namespace Security {
27 namespace DlpPermission {
28 namespace {
29 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpCommonFunc" };
30 }
31
GetHMACValue(const HMACSrcParams * hmacSrcParams,uint8_t ** hmacValue,uint32_t * hmacValueSize,const BlobData * aliasBlob)32 int32_t GetHMACValue(const HMACSrcParams *hmacSrcParams,
33 uint8_t **hmacValue, uint32_t *hmacValueSize, const BlobData *aliasBlob)
34 {
35 if (hmacValue == nullptr || hmacValueSize == nullptr || aliasBlob == nullptr) {
36 DLP_LOG_ERROR(LABEL, "GetHMACValue params error!");
37 return DLP_SERVICE_ERROR_VALUE_INVALID;
38 }
39 BlobData outDataBlob = { .dataSize = 0, .value = nullptr };
40
41 HuksKeyInfo keyInfo = { .protectionLevel = hmacSrcParams->protectionLevel,
42 .osAccountId = hmacSrcParams->osAccountId, .keyAlias = *aliasBlob };
43 if (!AlgIsKeyExist(&keyInfo)) {
44 if (AlgGenerateMacKey(&keyInfo) != DLP_OK) {
45 DLP_LOG_ERROR(LABEL, "Generate HMAC key failed!");
46 return DLP_SERVICE_ERROR_VALUE_INVALID;
47 }
48 }
49 int32_t ret = AlgHmac(&keyInfo, hmacSrcParams->SrcDataBlob, &outDataBlob);
50 if (ret != DLP_OK) {
51 DLP_LOG_ERROR(LABEL, "Do HMAC failed, errCode: %{public}d", ret);
52 return ret;
53 }
54
55 *hmacValue = outDataBlob.value;
56 *hmacValueSize = outDataBlob.dataSize;
57 return ret;
58 }
59
WriteHMACAndBufToFile(const HMACSrcParams * hmacSrcParams,const char * keyAlias,const char * filePath)60 int32_t WriteHMACAndBufToFile(const HMACSrcParams *hmacSrcParams, const char *keyAlias, const char *filePath)
61 {
62 if (hmacSrcParams == nullptr || !IsBlobDataValid(hmacSrcParams->SrcDataBlob) ||
63 keyAlias == nullptr || filePath == nullptr) {
64 DLP_LOG_ERROR(LABEL, "Input params is invalid.");
65 return DLP_SERVICE_ERROR_VALUE_INVALID;
66 }
67 uint8_t *hmacValue = nullptr;
68 uint32_t hmacValueSize = 0;
69 uint32_t keyAliasLen = HcStrlen(keyAlias);
70 if (keyAliasLen == 0) {
71 DLP_LOG_ERROR(LABEL, "KeyAlias length is invalid.");
72 return DLP_SERVICE_ERROR_VALUE_INVALID;
73 }
74 BlobData keyAliasBlob = { keyAliasLen, (uint8_t *)keyAlias };
75 int32_t res = GetHMACValue(hmacSrcParams, &hmacValue, &hmacValueSize, &keyAliasBlob);
76 if (res != DLP_OK) {
77 return res;
78 }
79 HcParcel parcel = CreateParcel(0, 0);
80 if (ParcelWrite(&parcel, &hmacValueSize, sizeof(hmacValueSize)) != HC_TRUE ||
81 ParcelWrite(&parcel, hmacValue, hmacValueSize) != HC_TRUE ||
82 ParcelWrite(&parcel, hmacSrcParams->SrcDataBlob->value, hmacSrcParams->SrcDataBlob->dataSize) != HC_TRUE) {
83 DLP_LOG_ERROR(LABEL, "parcel write hmac and buffer failed!");
84 DeleteParcel(&parcel);
85 DLP_FREE_PTR(hmacValue);
86 return DLP_SERVICE_ERROR_VALUE_INVALID;
87 }
88 DLP_FREE_PTR(hmacValue);
89 uint32_t fileLen = GetParcelDataSize(&parcel);
90 const char *fileBuffer = GetParcelData(&parcel);
91 if (fileBuffer == nullptr) {
92 DLP_LOG_ERROR(LABEL, "GetParcelData failed!");
93 DeleteParcel(&parcel);
94 return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
95 }
96 FileHandle file = { 0 };
97 res = HcFileOpen(filePath, MODE_FILE_WRITE, &file, USER_R_W_FILE_PERMISSION);
98 if (res != 0) {
99 DeleteParcel(&parcel);
100 return DLP_SERVICE_ERROR_VALUE_INVALID;
101 }
102 res = HcFileWrite(file, fileBuffer, fileLen);
103 HcFileClose(file);
104 DeleteParcel(&parcel);
105 if (res < 0 || (uint32_t)res != fileLen) {
106 DLP_LOG_ERROR(LABEL, "HcFileWrite buffer failed!");
107 return DLP_SERVICE_ERROR_VALUE_INVALID;
108 }
109 return DLP_OK;
110 }
111
ReadBufFromFile(uint8_t ** fileBuffer,uint32_t * fileSize,const char * filePath)112 int32_t ReadBufFromFile(uint8_t **fileBuffer, uint32_t *fileSize, const char *filePath)
113 {
114 if (fileBuffer == nullptr || fileSize == nullptr || filePath == nullptr) {
115 DLP_LOG_ERROR(LABEL, "Input params is invalid.");
116 return DLP_SERVICE_ERROR_VALUE_INVALID;
117 }
118
119 FileHandle file = { 0 };
120 if (HcFileOpen(filePath, MODE_FILE_READ, &file, USER_R_W_FILE_PERMISSION) != 0) {
121 DLP_LOG_ERROR(LABEL, "Open file failed (maybe file not exist)");
122 return DLP_SERVICE_ERROR_VALUE_INVALID;
123 }
124 int32_t len = HcFileSize(file);
125 if (len <= 0 || len > MAX_POLICY_DATA_LEN) {
126 DLP_LOG_ERROR(LABEL, "Invalid server file size: %{public}d", len);
127 HcFileClose(file);
128 return DLP_SERVICE_ERROR_VALUE_INVALID;
129 }
130 *fileBuffer = (uint8_t *)HcMalloc(len, 0);
131 if (*fileBuffer == nullptr) {
132 DLP_LOG_ERROR(LABEL, "Allocate file buffer failed!");
133 HcFileClose(file);
134 return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
135 }
136 int32_t readSize = HcFileRead(file, *fileBuffer, len);
137 HcFileClose(file);
138 if (readSize != len) {
139 DLP_LOG_ERROR(LABEL, "Read file path failed");
140 DLP_FREE_PTR(*fileBuffer);
141 return DLP_SERVICE_ERROR_VALUE_INVALID;
142 }
143 *fileSize = (uint32_t)len;
144 return DLP_OK;
145 }
146
AllocHMACValue(HcParcel * parcel,uint8_t ** hmacValue1,uint32_t * hmacLen1)147 static int32_t AllocHMACValue(HcParcel *parcel, uint8_t **hmacValue1, uint32_t *hmacLen1)
148 {
149 if (ParcelRead(parcel, hmacLen1, sizeof(uint32_t)) != HC_TRUE) {
150 return DLP_SERVICE_ERROR_VALUE_INVALID;
151 }
152 if (*hmacLen1 == 0 || *hmacLen1 > MAX_POLICY_DATA_LEN) {
153 return DLP_SERVICE_ERROR_VALUE_INVALID;
154 }
155 *hmacValue1 = (uint8_t *)HcMalloc(*hmacLen1, 0);
156 if (*hmacValue1 == nullptr) {
157 DLP_LOG_ERROR(LABEL, "Allocate hmacValue1 failed!");
158 return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
159 }
160 if (ParcelRead(parcel, *hmacValue1, *hmacLen1) != HC_TRUE) {
161 return DLP_SERVICE_ERROR_VALUE_INVALID;
162 }
163
164 return DLP_OK;
165 }
166
CompareHMACValue(const HMACSrcParams * hmacSrcParams,uint8_t ** buffer,uint32_t * bufLen,const char * keyAlias)167 int32_t CompareHMACValue(const HMACSrcParams *hmacSrcParams, uint8_t **buffer, uint32_t *bufLen, const char *keyAlias)
168 {
169 if (hmacSrcParams == nullptr || !IsBlobDataValid(hmacSrcParams->SrcDataBlob) ||
170 buffer == nullptr || bufLen == 0 || keyAlias == nullptr) {
171 DLP_LOG_ERROR(LABEL, "Input params is invalid.");
172 return DLP_SERVICE_ERROR_VALUE_INVALID;
173 }
174
175 HcParcel parcel = CreateParcel(0, 0);
176 uint8_t *hmacValue1 = nullptr;
177 uint8_t *hmacValue2 = nullptr;
178 int32_t ret = DLP_SERVICE_ERROR_VALUE_INVALID;
179 do {
180 if (ParcelWrite(&parcel, hmacSrcParams->SrcDataBlob->value, hmacSrcParams->SrcDataBlob->dataSize) != HC_TRUE) {
181 break;
182 }
183 uint32_t hmacLen1 = 0;
184 if (AllocHMACValue(&parcel, &hmacValue1, &hmacLen1) != DLP_OK) {
185 break;
186 }
187 uint32_t bufSize = GetParcelDataSize(&parcel);
188 *buffer = (uint8_t *)HcMalloc(bufSize, 0);
189 if (*buffer == nullptr) {
190 break;
191 }
192 if (ParcelRead(&parcel, *buffer, bufSize) != HC_TRUE) {
193 DLP_FREE_PTR(*buffer);
194 break;
195 }
196 uint32_t hmacLen2 = 0;
197 uint32_t keyAliasLen = HcStrlen(keyAlias);
198 BlobData keyAliasBlob = { keyAliasLen, (uint8_t *)keyAlias };
199 BlobData bufferBlob = { bufSize, (uint8_t *)(*buffer) };
200 HMACSrcParams hmacBuffParams = { .osAccountId = hmacSrcParams->osAccountId,
201 .protectionLevel = hmacSrcParams->protectionLevel, .SrcDataBlob = &bufferBlob };
202 if (GetHMACValue(&hmacBuffParams, &hmacValue2, &hmacLen2, &keyAliasBlob) != DLP_OK) {
203 DLP_FREE_PTR(*buffer);
204 break;
205 }
206 if (hmacLen1 == hmacLen2 && memcmp(hmacValue1, hmacValue2, hmacLen1) == 0) {
207 ret = DLP_OK;
208 *bufLen = bufSize;
209 } else {
210 DLP_FREE_PTR(*buffer);
211 ret = DLP_SERVICE_ERROR_VALUE_INVALID;
212 }
213 } while (0);
214 DeleteParcel(&parcel);
215 DLP_FREE_PTR(hmacValue1);
216 DLP_FREE_PTR(hmacValue2);
217 return ret;
218 }
219
220 } // namespace DlpPermission
221 } // namespace Security
222 } // namespace OHOS