1 /*
2 * Copyright (c) 2023-2024 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_crypt.h"
17 #include <cstdio>
18 #include <cstdlib>
19 #include <dlfcn.h>
20 #include <openssl/err.h>
21 #include <openssl/evp.h>
22 #include <openssl/hmac.h>
23 #include <openssl/rand.h>
24 #include <securec.h>
25 #include <string>
26 #include <thread>
27 #include <unistd.h>
28 #include "dlp_permission.h"
29 #include "dlp_permission_log.h"
30
31 using namespace OHOS::Security::DlpPermission;
32 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpParse"};
33 static const uint32_t BYTE_LEN = 8;
34 const uint32_t HMAC_SIZE = 32;
35 const uint32_t SHA256_KEY_LEN = 32;
36 const uint32_t BUFFER_SIZE = 1048576;
37 static int32_t g_hIAECnt = 0;
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 static const std::string DLP_HIAE_SDK_PATH_32_BIT = "/system/lib/platformsdk/libdlp_credential_alg_hiae.z.so";
44 static const std::string DLP_HIAE_SDK_PATH_64_BIT = "/system/lib64/platformsdk/libdlp_credential_alg_hiae.z.so";
45 static const size_t LENGTH_FOR_64_BIT = 8;
46
47 typedef int32_t (*HIAEInitFunc)(HIAE_CipherCtx *ctx, const uint8_t *key, const uint32_t keyLen,
48 const uint8_t *iv, const uint32_t ivLen);
49 typedef int32_t (*HIAEClearFunc)(HIAE_CipherCtx *ctx);
50 typedef int32_t (*HIAEEncryptUpdateFunc)(HIAE_CipherCtx *ctx, const uint8_t *in, const uint32_t inLen,
51 uint8_t *out, uint32_t *outLen);
52 typedef int32_t (*HIAEDecryptUpdateFunc)(HIAE_CipherCtx *ctx, const uint8_t *in, const uint32_t inLen,
53 uint8_t *out, uint32_t *outLen);
54
55 typedef struct DlpHIAEMgrHandleT {
56 HIAEInitFunc hIAEInit;
57 HIAEClearFunc hIAEClear;
58 HIAEEncryptUpdateFunc hIAEEncryptUpdate;
59 HIAEDecryptUpdateFunc hIAEDecryptUpdate;
60 }DlpHIAEMgrHandle;
61
62 static DlpHIAEMgrHandle *g_dlpHIAEMgrHandle = nullptr;
63 static void *g_dlpModuleHandle = nullptr;
64 std::mutex g_lockDlpHIAESdk;
65
FillHIAEFuncHandle(void)66 static int32_t FillHIAEFuncHandle(void)
67 {
68 g_dlpHIAEMgrHandle->hIAEInit = reinterpret_cast<HIAEInitFunc>(dlsym(g_dlpModuleHandle, "HIAE_Init"));
69 if (g_dlpHIAEMgrHandle->hIAEInit == nullptr) {
70 DLP_LOG_ERROR(LABEL, "dlsym hIAEInit failed, %{public}s: ", dlerror());
71 return DLP_ERROR_DLSYM;
72 }
73 g_dlpHIAEMgrHandle->hIAEClear = reinterpret_cast<HIAEClearFunc>(dlsym(g_dlpModuleHandle, "HIAE_Clear"));
74 if (g_dlpHIAEMgrHandle->hIAEClear == nullptr) {
75 DLP_LOG_ERROR(LABEL, "dlsym hIAEClear failed, %{public}s: ", dlerror());
76 return DLP_ERROR_DLSYM;
77 }
78 g_dlpHIAEMgrHandle->hIAEEncryptUpdate =
79 reinterpret_cast<HIAEEncryptUpdateFunc>(dlsym(g_dlpModuleHandle, "HIAE_EncryptUpdate"));
80 if (g_dlpHIAEMgrHandle->hIAEEncryptUpdate == nullptr) {
81 DLP_LOG_ERROR(LABEL, "dlsym hIAEEncryptUpdate failed, %{public}s: ", dlerror());
82 return DLP_ERROR_DLSYM;
83 }
84 g_dlpHIAEMgrHandle->hIAEDecryptUpdate =
85 reinterpret_cast<HIAEDecryptUpdateFunc>(dlsym(g_dlpModuleHandle, "HIAE_DecryptUpdate"));
86 if (g_dlpHIAEMgrHandle->hIAEDecryptUpdate == nullptr) {
87 DLP_LOG_ERROR(LABEL, "dlsym hIAEDecryptUpdate failed, %{public}s: ", dlerror());
88 return DLP_ERROR_DLSYM;
89 }
90 return DLP_OK;
91 }
92
ClearDlpHIAEMgr(void)93 void ClearDlpHIAEMgr(void)
94 {
95 std::lock_guard<std::mutex> lock(g_lockDlpHIAESdk);
96 g_hIAECnt--;
97 if (g_dlpHIAEMgrHandle == nullptr || g_hIAECnt > 0) {
98 return;
99 }
100 delete g_dlpHIAEMgrHandle;
101 g_dlpHIAEMgrHandle = nullptr;
102 dlclose(g_dlpModuleHandle);
103 g_dlpModuleHandle = nullptr;
104 }
105
InitDlpHIAEMgr(void)106 int32_t InitDlpHIAEMgr(void)
107 {
108 std::lock_guard<std::mutex> lock(g_lockDlpHIAESdk);
109 DLP_LOG_INFO(LABEL, "support HIAE");
110 if (g_dlpModuleHandle != nullptr) {
111 g_hIAECnt++;
112 return DLP_OK;
113 }
114
115 if (sizeof(void *) == LENGTH_FOR_64_BIT) {
116 g_dlpModuleHandle = dlopen(DLP_HIAE_SDK_PATH_64_BIT.c_str(), RTLD_LAZY);
117 } else {
118 g_dlpModuleHandle = dlopen(DLP_HIAE_SDK_PATH_32_BIT.c_str(), RTLD_LAZY);
119 }
120 if (g_dlpModuleHandle == nullptr) {
121 DLP_LOG_ERROR(LABEL, "dlopen failed, %{public}s: ", dlerror());
122 return DLP_ERROR_DLOPEN;
123 }
124
125 g_dlpHIAEMgrHandle = new (std::nothrow) DlpHIAEMgrHandle;
126 if (g_dlpHIAEMgrHandle == nullptr) {
127 DLP_LOG_ERROR(LABEL, "new HIAE Handle failed");
128 dlclose(g_dlpModuleHandle);
129 g_dlpModuleHandle = nullptr;
130 return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
131 }
132
133 if (FillHIAEFuncHandle() != DLP_OK) {
134 delete g_dlpHIAEMgrHandle;
135 g_dlpHIAEMgrHandle = nullptr;
136 dlclose(g_dlpModuleHandle);
137 g_dlpModuleHandle = nullptr;
138 return DLP_ERROR_DLSYM;
139 }
140 g_hIAECnt++;
141 return DLP_OK;
142 }
143
AlgHIAEInit(HIAE_CipherCtx * ctx,const uint8_t * key,const uint32_t keyLen,const uint8_t * iv,const uint32_t ivLen)144 static int32_t AlgHIAEInit(HIAE_CipherCtx *ctx, const uint8_t *key, const uint32_t keyLen,
145 const uint8_t *iv, const uint32_t ivLen)
146 {
147 std::lock_guard<std::mutex> lock(g_lockDlpHIAESdk);
148 if (g_dlpHIAEMgrHandle == nullptr) {
149 DLP_LOG_ERROR(LABEL, "HIAE init Handle is null");
150 return DLP_PARSE_ERROR_VALUE_INVALID;
151 }
152 return g_dlpHIAEMgrHandle->hIAEInit(ctx, key, keyLen, iv, ivLen);
153 }
154
AlgHIAEClear(HIAE_CipherCtx * ctx)155 static int32_t AlgHIAEClear(HIAE_CipherCtx *ctx)
156 {
157 std::lock_guard<std::mutex> lock(g_lockDlpHIAESdk);
158 if (g_dlpHIAEMgrHandle == nullptr) {
159 DLP_LOG_ERROR(LABEL, "HIAE clear Handle is null");
160 return DLP_PARSE_ERROR_VALUE_INVALID;
161 }
162 return g_dlpHIAEMgrHandle->hIAEClear(ctx);
163 }
164
AlgHIAEEncryptUpdate(HIAE_CipherCtx * ctx,const uint8_t * in,const uint32_t inLen,uint8_t * out,uint32_t * outLen)165 static int32_t AlgHIAEEncryptUpdate(HIAE_CipherCtx *ctx, const uint8_t *in, const uint32_t inLen,
166 uint8_t *out, uint32_t *outLen)
167 {
168 std::lock_guard<std::mutex> lock(g_lockDlpHIAESdk);
169 if (g_dlpHIAEMgrHandle == nullptr) {
170 DLP_LOG_ERROR(LABEL, "HIAE encrypt Handle is null");
171 return DLP_PARSE_ERROR_VALUE_INVALID;
172 }
173 return g_dlpHIAEMgrHandle->hIAEEncryptUpdate(ctx, in, inLen, out, outLen);
174 }
175
AlgHIAEDecryptUpdate(HIAE_CipherCtx * ctx,const uint8_t * in,const uint32_t inLen,uint8_t * out,uint32_t * outLen)176 static int32_t AlgHIAEDecryptUpdate(HIAE_CipherCtx *ctx, const uint8_t *in, const uint32_t inLen,
177 uint8_t *out, uint32_t *outLen)
178 {
179 std::lock_guard<std::mutex> lock(g_lockDlpHIAESdk);
180 if (g_dlpHIAEMgrHandle == nullptr) {
181 DLP_LOG_ERROR(LABEL, "HIAE decrypt Handle is null");
182 return DLP_PARSE_ERROR_VALUE_INVALID;
183 }
184 return g_dlpHIAEMgrHandle->hIAEDecryptUpdate(ctx, in, inLen, out, outLen);
185 }
186
DlpHIAECheckBlob(const struct DlpBlob * blob)187 inline bool DlpHIAECheckBlob(const struct DlpBlob *blob)
188 {
189 return (blob != nullptr) && (blob->data != nullptr);
190 }
191
HIAEParamCheck(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const uint8_t * message,const uint8_t * cipherText)192 static bool HIAEParamCheck(const struct DlpBlob *key, const struct DlpUsageSpec *usageSpec,
193 const uint8_t *message, const uint8_t *cipherText)
194 {
195 if (!DlpHIAECheckBlob(key)) {
196 DLP_LOG_ERROR(LABEL, "check HIAE param fail, key is null");
197 return false;
198 }
199
200 if (usageSpec == nullptr || usageSpec->algParam == nullptr) {
201 DLP_LOG_ERROR(LABEL, "check HIAE param fail, usageSpec is null");
202 return false;
203 }
204
205 if (message == nullptr) {
206 DLP_LOG_ERROR(LABEL, "check HIAE param fail, message is null");
207 return false;
208 }
209
210 if (cipherText == nullptr) {
211 DLP_LOG_ERROR(LABEL, "check HIAE param fail, cipherText is null");
212 return false;
213 }
214 return true;
215 }
216
DlpHIAEEncrypt(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const uint32_t inLen,const uint8_t * message,uint8_t * cipherText)217 int32_t DlpHIAEEncrypt(const struct DlpBlob *key, const struct DlpUsageSpec *usageSpec, const uint32_t inLen,
218 const uint8_t *message, uint8_t *cipherText)
219 {
220 if (!HIAEParamCheck(key, usageSpec, message, cipherText)) {
221 return DLP_PARSE_ERROR_VALUE_INVALID;
222 }
223 HIAE_CipherCtx ctx = { { 0 }, 0, 0 };
224 int32_t ret = DLP_OK;
225 do {
226 ret = AlgHIAEInit(&ctx, key->data, key->size,
227 usageSpec->algParam->iv.data, usageSpec->algParam->iv.size);
228 if (ret != DLP_OK) {
229 DLP_LOG_ERROR(LABEL, "Alg HIAE init failed, ret = %{public}d", ret);
230 break;
231 }
232
233 uint32_t outLen = inLen;
234 ret = AlgHIAEEncryptUpdate(&ctx, message, inLen, cipherText, &outLen);
235 if (ret != DLP_OK) {
236 DLP_LOG_ERROR(LABEL, "Alg HIAE encrypt update failed, ret = %{public}d", ret);
237 break;
238 }
239 } while (0);
240
241 (void)AlgHIAEClear(&ctx);
242 return ret;
243 }
244
DlpHIAEDecrypt(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const uint32_t inLen,const uint8_t * message,uint8_t * plainText)245 int32_t DlpHIAEDecrypt(const struct DlpBlob *key, const struct DlpUsageSpec *usageSpec, const uint32_t inLen,
246 const uint8_t *message, uint8_t *plainText)
247 {
248 if (!HIAEParamCheck(key, usageSpec, message, plainText)) {
249 return DLP_PARSE_ERROR_VALUE_INVALID;
250 }
251 HIAE_CipherCtx ctx = { { 0 }, 0, 0 };
252 int32_t ret = DLP_OK;
253 do {
254 ret = AlgHIAEInit(&ctx, key->data, key->size,
255 usageSpec->algParam->iv.data, usageSpec->algParam->iv.size);
256 if (ret != DLP_OK) {
257 DLP_LOG_ERROR(LABEL, "Alg HIAE init failed, ret = %{public}d", ret);
258 break;
259 }
260
261 uint32_t outLen = inLen;
262 ret = AlgHIAEDecryptUpdate(&ctx, message, inLen, plainText, &outLen);
263 if (ret != DLP_OK) {
264 DLP_LOG_ERROR(LABEL, "Alg HIAE decrypt update failed, ret = %{public}d", ret);
265 break;
266 }
267 } while (0);
268
269 (void)AlgHIAEClear(&ctx);
270 return ret;
271 }
272
DlpOpensslCheckBlob(const struct DlpBlob * blob)273 inline bool DlpOpensslCheckBlob(const struct DlpBlob* blob)
274 {
275 return (blob != nullptr) && (blob->data != nullptr);
276 }
277
DlpOpensslCheckBlobZero(const struct DlpBlob * blob)278 inline bool DlpOpensslCheckBlobZero(const struct DlpBlob* blob)
279 {
280 if (blob == nullptr) {
281 return false;
282 }
283
284 if (blob->data == nullptr && blob->size == 0) {
285 return true;
286 }
287
288 if (blob->data == nullptr) {
289 return false;
290 }
291
292 return true;
293 }
294
DlpOpensslGenerateRandom(uint32_t keySize,struct DlpBlob * key)295 int32_t DlpOpensslGenerateRandom(uint32_t keySize, struct DlpBlob* key)
296 {
297 if (key == nullptr) {
298 DLP_LOG_ERROR(LABEL, "Generate key fail, blob is nullptr");
299 return DLP_PARSE_ERROR_VALUE_INVALID;
300 }
301 if ((keySize < BIT_NUM_OF_UINT8) || (keySize > DLP_RANDOM_MAX_SIZE)) {
302 DLP_LOG_ERROR(LABEL, "Generate key fail, key size %{public}u is invalid", keySize);
303 return DLP_PARSE_ERROR_VALUE_INVALID;
304 }
305 uint32_t keySizeByte = keySize / BIT_NUM_OF_UINT8;
306
307 uint8_t* tmpKey = new (std::nothrow) uint8_t[keySizeByte];
308 if (tmpKey == nullptr) {
309 DLP_LOG_ERROR(LABEL, "Generate key fail, alloc %{public}u buffer fail", keySizeByte);
310 return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
311 }
312
313 int res = RAND_bytes(tmpKey, keySizeByte);
314 if (res <= 0) {
315 DLP_LOG_ERROR(LABEL, "Generate key fail, generate rand bytes error, errno=%{public}d", res);
316 (void)memset_s(tmpKey, keySizeByte, 0, keySizeByte);
317 delete[] tmpKey;
318 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
319 } else {
320 key->data = tmpKey;
321 key->size = keySizeByte;
322 }
323 return DLP_OK;
324 }
325
AesGenKeyCheckParam(uint32_t keySize)326 static bool AesGenKeyCheckParam(uint32_t keySize)
327 {
328 return (keySize == DLP_AES_KEY_SIZE_128) || (keySize == DLP_AES_KEY_SIZE_192) || (keySize == DLP_AES_KEY_SIZE_256);
329 }
330
DlpOpensslGenerateRandomKey(uint32_t keySize,struct DlpBlob * key)331 int32_t DlpOpensslGenerateRandomKey(uint32_t keySize, struct DlpBlob* key)
332 {
333 if (key == nullptr) {
334 DLP_LOG_ERROR(LABEL, "Generate key fail, blob is nullptr");
335 return DLP_PARSE_ERROR_VALUE_INVALID;
336 }
337 if (!AesGenKeyCheckParam(keySize)) {
338 DLP_LOG_ERROR(LABEL, "Generate key fail, key size %{public}u is invalid", keySize);
339 return DLP_PARSE_ERROR_VALUE_INVALID;
340 }
341 return DlpOpensslGenerateRandom(keySize, key);
342 }
343
GetCtrCipherType(uint32_t keySize)344 static const EVP_CIPHER* GetCtrCipherType(uint32_t keySize)
345 {
346 switch (keySize) {
347 case DLP_KEY_BYTES(DLP_AES_KEY_SIZE_128):
348 return EVP_aes_128_ctr();
349 case DLP_KEY_BYTES(DLP_AES_KEY_SIZE_192):
350 return EVP_aes_192_ctr();
351 case DLP_KEY_BYTES(DLP_AES_KEY_SIZE_256):
352 return EVP_aes_256_ctr();
353 default:
354 return nullptr;
355 }
356 }
357
DlpLogOpensslError(void)358 inline void DlpLogOpensslError(void)
359 {
360 char szErr[DLP_OPENSSL_ERROR_LEN] = {0};
361 unsigned long errCode = ERR_get_error();
362 ERR_error_string_n(errCode, szErr, DLP_OPENSSL_ERROR_LEN);
363 DLP_LOG_ERROR(LABEL, "Openssl engine error, errno=%{public}lu, errmsg=%{public}s", errCode, szErr);
364 }
365
OpensslAesCipherInit(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,bool isEncrypt,EVP_CIPHER_CTX ** ctx)366 static int32_t OpensslAesCipherInit(
367 const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec, bool isEncrypt, EVP_CIPHER_CTX** ctx)
368 {
369 int32_t ret;
370 struct DlpCipherParam* cipherParam = usageSpec->algParam;
371
372 *ctx = EVP_CIPHER_CTX_new();
373 if (*ctx == nullptr) {
374 DlpLogOpensslError();
375 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
376 }
377
378 const EVP_CIPHER* cipher = GetCtrCipherType(key->size);
379 if (cipher == nullptr) {
380 DLP_LOG_ERROR(LABEL, "Aes cipher init fail, get cipher type error");
381 EVP_CIPHER_CTX_free(*ctx);
382 return DLP_PARSE_ERROR_VALUE_INVALID;
383 }
384
385 if (isEncrypt) {
386 ret = EVP_EncryptInit_ex(*ctx, cipher, nullptr, nullptr, nullptr);
387 } else {
388 ret = EVP_DecryptInit_ex(*ctx, cipher, nullptr, nullptr, nullptr);
389 }
390 if (ret != DLP_OPENSSL_SUCCESS) {
391 DlpLogOpensslError();
392 EVP_CIPHER_CTX_free(*ctx);
393 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
394 }
395
396 if (isEncrypt) {
397 ret = EVP_EncryptInit_ex(
398 *ctx, nullptr, nullptr, key->data, (cipherParam == nullptr) ? nullptr : cipherParam->iv.data);
399 } else {
400 ret = EVP_DecryptInit_ex(
401 *ctx, nullptr, nullptr, key->data, (cipherParam == nullptr) ? nullptr : cipherParam->iv.data);
402 }
403 if (ret != DLP_OPENSSL_SUCCESS) {
404 DlpLogOpensslError();
405 EVP_CIPHER_CTX_free(*ctx);
406 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
407 }
408
409 ret = EVP_CIPHER_CTX_set_padding(*ctx, OPENSSL_CTX_PADDING_ENABLE);
410 if (ret != DLP_OPENSSL_SUCCESS) {
411 DlpLogOpensslError();
412 EVP_CIPHER_CTX_free(*ctx);
413 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
414 }
415
416 return DLP_OK;
417 }
418
OpensslAesCipherEncryptFinal(EVP_CIPHER_CTX * ctx,const struct DlpBlob * message,struct DlpBlob * cipherText)419 static int32_t OpensslAesCipherEncryptFinal(
420 EVP_CIPHER_CTX* ctx, const struct DlpBlob* message, struct DlpBlob* cipherText)
421 {
422 int32_t outLen = 0;
423
424 if (EVP_EncryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
425 DlpLogOpensslError();
426 EVP_CIPHER_CTX_free(ctx);
427 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
428 }
429 cipherText->size = static_cast<uint32_t>(outLen);
430
431 if (EVP_EncryptFinal_ex(ctx, cipherText->data + outLen, &outLen) != DLP_OPENSSL_SUCCESS) {
432 DlpLogOpensslError();
433 EVP_CIPHER_CTX_free(ctx);
434 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
435 }
436 cipherText->size += static_cast<uint32_t>(outLen);
437
438 EVP_CIPHER_CTX_free(ctx);
439 return DLP_OK;
440 }
441
OpensslAesCipherCryptInitParams(const struct DlpBlob * key,EVP_CIPHER_CTX * ctx,const struct DlpCipherParam * cipherParam,bool isEncrypt)442 static int32_t OpensslAesCipherCryptInitParams(const struct DlpBlob* key, EVP_CIPHER_CTX* ctx,
443 const struct DlpCipherParam* cipherParam, bool isEncrypt)
444 {
445 int32_t ret;
446 if (isEncrypt) {
447 ret = EVP_EncryptInit_ex(
448 ctx, nullptr, nullptr, key->data, (cipherParam == nullptr) ? nullptr : cipherParam->iv.data);
449 } else {
450 ret = EVP_DecryptInit_ex(
451 ctx, nullptr, nullptr, key->data, (cipherParam == nullptr) ? nullptr : cipherParam->iv.data);
452 }
453 if (ret != DLP_OPENSSL_SUCCESS) {
454 DlpLogOpensslError();
455 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
456 }
457 ret = EVP_CIPHER_CTX_set_padding(ctx, OPENSSL_CTX_PADDING_ENABLE);
458 if (ret != DLP_OPENSSL_SUCCESS) {
459 DlpLogOpensslError();
460 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
461 }
462 return DLP_OK;
463 }
464
OpensslAesCipherCryptInit(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,bool isEncrypt,void ** cryptoCtx)465 static int32_t OpensslAesCipherCryptInit(
466 const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec, bool isEncrypt, void** cryptoCtx)
467 {
468 int32_t ret;
469 struct DlpCipherParam* cipherParam = reinterpret_cast<struct DlpCipherParam*>(usageSpec->algParam);
470
471 EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
472 if (ctx == nullptr) {
473 DlpLogOpensslError();
474 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
475 }
476
477 const EVP_CIPHER* cipher = GetCtrCipherType(key->size);
478 if (cipher == nullptr) {
479 DLP_LOG_ERROR(LABEL, "Aes cipher crypt init fail, get cipher type error");
480 EVP_CIPHER_CTX_free(ctx);
481 return DLP_PARSE_ERROR_VALUE_INVALID;
482 }
483
484 if (isEncrypt) {
485 ret = EVP_EncryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr);
486 } else {
487 ret = EVP_DecryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr);
488 }
489 if (ret != DLP_OPENSSL_SUCCESS) {
490 DlpLogOpensslError();
491 EVP_CIPHER_CTX_free(ctx);
492 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
493 }
494
495 ret = OpensslAesCipherCryptInitParams(key, ctx, cipherParam, isEncrypt);
496 if (ret != DLP_OK) {
497 EVP_CIPHER_CTX_free(ctx);
498 DLP_LOG_ERROR(LABEL, "Aes cipher crypt init fail, init cipher params error, errno=%d", ret);
499 return ret;
500 }
501
502 struct DlpOpensslAesCtx* outCtx = static_cast<struct DlpOpensslAesCtx*>(malloc(sizeof(DlpOpensslAesCtx)));
503 if (outCtx == nullptr) {
504 DLP_LOG_ERROR(LABEL, "Aes cipher crypt init fail, alloc aes ctx fail");
505 EVP_CIPHER_CTX_free(ctx);
506 return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
507 }
508
509 outCtx->mode = usageSpec->mode;
510 outCtx->append = static_cast<void*>(ctx);
511
512 *cryptoCtx = static_cast<void*>(outCtx);
513
514 return DLP_OK;
515 }
516
OpensslAesCipherEncryptUpdate(void * cryptoCtx,const struct DlpBlob * message,struct DlpBlob * cipherText)517 static int32_t OpensslAesCipherEncryptUpdate(void* cryptoCtx, const struct DlpBlob* message, struct DlpBlob* cipherText)
518 {
519 struct DlpOpensslAesCtx* aesCtx = static_cast<struct DlpOpensslAesCtx*>(cryptoCtx);
520 EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(aesCtx->append);
521 if (ctx == nullptr) {
522 return DLP_PARSE_ERROR_VALUE_INVALID;
523 }
524
525 int32_t outLen = 0;
526 if (EVP_EncryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
527 DlpLogOpensslError();
528 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
529 }
530 cipherText->size = static_cast<uint32_t>(outLen);
531
532 return DLP_OK;
533 }
534
OpensslAesCipherEncryptFinalThree(void ** cryptoCtx,const struct DlpBlob * message,struct DlpBlob * cipherText)535 static int32_t OpensslAesCipherEncryptFinalThree(
536 void** cryptoCtx, const struct DlpBlob* message, struct DlpBlob* cipherText)
537 {
538 struct DlpOpensslAesCtx* aesCtx = (struct DlpOpensslAesCtx*)*cryptoCtx;
539 EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(aesCtx->append);
540
541 if (ctx == nullptr) {
542 DLP_FREE_PTR(*cryptoCtx);
543 return DLP_PARSE_ERROR_VALUE_INVALID;
544 }
545
546 int32_t ret = DLP_OK;
547 do {
548 int32_t outLen = 0;
549 if (message->size != 0) {
550 if (EVP_EncryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size) !=
551 DLP_OPENSSL_SUCCESS) {
552 DlpLogOpensslError();
553 ret = DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
554 break;
555 }
556 cipherText->size = static_cast<uint32_t>(outLen);
557 }
558
559 if (EVP_EncryptFinal_ex(ctx, (cipherText->data + outLen), &outLen) != DLP_OPENSSL_SUCCESS) {
560 DlpLogOpensslError();
561 ret = DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
562 break;
563 }
564 cipherText->size += static_cast<uint32_t>(outLen);
565 } while (0);
566
567 EVP_CIPHER_CTX_free(ctx);
568 aesCtx->append = nullptr;
569 DLP_FREE_PTR(*cryptoCtx);
570
571 return ret;
572 }
573
OpensslAesCipherDecryptUpdate(void * cryptoCtx,const struct DlpBlob * message,struct DlpBlob * plainText)574 static int32_t OpensslAesCipherDecryptUpdate(void* cryptoCtx, const struct DlpBlob* message, struct DlpBlob* plainText)
575 {
576 struct DlpOpensslAesCtx* aesCtx = static_cast<struct DlpOpensslAesCtx*>(cryptoCtx);
577 EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(aesCtx->append);
578
579 if (ctx == nullptr) {
580 return DLP_PARSE_ERROR_VALUE_INVALID;
581 }
582
583 int32_t outLen = 0;
584 if (EVP_DecryptUpdate(ctx, plainText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
585 DlpLogOpensslError();
586 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
587 }
588 plainText->size = static_cast<uint32_t>(outLen);
589
590 return DLP_OK;
591 }
592
OpensslAesCipherDecryptFinalThree(void ** cryptoCtx,const struct DlpBlob * message,struct DlpBlob * plainText)593 static int32_t OpensslAesCipherDecryptFinalThree(
594 void** cryptoCtx, const struct DlpBlob* message, struct DlpBlob* plainText)
595 {
596 struct DlpOpensslAesCtx* aesCtx = (struct DlpOpensslAesCtx*)*cryptoCtx;
597 EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(aesCtx->append);
598 if (ctx == nullptr) {
599 DLP_FREE_PTR(*cryptoCtx);
600 return DLP_PARSE_ERROR_VALUE_INVALID;
601 }
602
603 int32_t ret = DLP_OK;
604 do {
605 int32_t outLen = 0;
606 if (message->size != 0) {
607 if (EVP_DecryptUpdate(ctx, plainText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
608 DlpLogOpensslError();
609 ret = DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
610 break;
611 }
612 plainText->size = static_cast<uint32_t>(outLen);
613 }
614
615 if (EVP_DecryptFinal_ex(ctx, plainText->data + outLen, &outLen) != DLP_OPENSSL_SUCCESS) {
616 DlpLogOpensslError();
617 ret = DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
618 break;
619 }
620 plainText->size += static_cast<uint32_t>(outLen);
621 } while (0);
622
623 EVP_CIPHER_CTX_free(ctx);
624 aesCtx->append = nullptr;
625 DLP_FREE_PTR(*cryptoCtx);
626 return ret;
627 }
628
OpensslAesCipherDecryptFinal(EVP_CIPHER_CTX * ctx,const struct DlpBlob * message,struct DlpBlob * plainText)629 static int32_t OpensslAesCipherDecryptFinal(
630 EVP_CIPHER_CTX* ctx, const struct DlpBlob* message, struct DlpBlob* plainText)
631 {
632 int32_t outLen = 0;
633
634 if (EVP_DecryptUpdate(ctx, plainText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
635 DlpLogOpensslError();
636 EVP_CIPHER_CTX_free(ctx);
637 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
638 }
639 plainText->size = static_cast<uint32_t>(outLen);
640
641 if (EVP_DecryptFinal_ex(ctx, plainText->data + outLen, &outLen) != DLP_OPENSSL_SUCCESS) {
642 DlpLogOpensslError();
643 EVP_CIPHER_CTX_free(ctx);
644 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
645 }
646 plainText->size += static_cast<uint32_t>(outLen);
647
648 EVP_CIPHER_CTX_free(ctx);
649 return DLP_OK;
650 }
651
DlpOpensslAesEncryptInit(void ** cryptoCtx,const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec)652 int32_t DlpOpensslAesEncryptInit(void** cryptoCtx, const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec)
653 {
654 if (cryptoCtx == nullptr) {
655 DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, ctx is null");
656 return DLP_PARSE_ERROR_VALUE_INVALID;
657 }
658 if (usageSpec == nullptr) {
659 DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, usage spec is null");
660 return DLP_PARSE_ERROR_VALUE_INVALID;
661 }
662 if (!DlpOpensslCheckBlob(key)) {
663 DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, key is invalid");
664 return DLP_PARSE_ERROR_VALUE_INVALID;
665 }
666
667 int32_t ret;
668 switch (usageSpec->mode) {
669 case DLP_MODE_CTR:
670 ret = OpensslAesCipherCryptInit(key, usageSpec, true, cryptoCtx);
671 if (ret != DLP_OK) {
672 DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, errno=%{public}d", ret);
673 return ret;
674 }
675 break;
676
677 default:
678 DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, aes mode 0x%{public}x unsupport", usageSpec->mode);
679 return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
680 }
681
682 return DLP_OK;
683 }
684
DlpOpensslAesEncryptUpdate(void * cryptoCtx,const struct DlpBlob * message,struct DlpBlob * cipherText)685 int32_t DlpOpensslAesEncryptUpdate(void* cryptoCtx, const struct DlpBlob* message, struct DlpBlob* cipherText)
686 {
687 if (cryptoCtx == nullptr) {
688 DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, ctx is null");
689 return DLP_PARSE_ERROR_VALUE_INVALID;
690 }
691 if (!DlpOpensslCheckBlobZero(message)) {
692 DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, msg is invalid");
693 return DLP_PARSE_ERROR_VALUE_INVALID;
694 }
695 if (!DlpOpensslCheckBlob(cipherText)) {
696 DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, cipher text is invalid");
697 return DLP_PARSE_ERROR_VALUE_INVALID;
698 }
699
700 struct DlpOpensslAesCtx* contex = static_cast<struct DlpOpensslAesCtx*>(cryptoCtx);
701 uint32_t mode = contex->mode;
702
703 int32_t ret;
704 switch (mode) {
705 case DLP_MODE_CTR:
706 ret = OpensslAesCipherEncryptUpdate(cryptoCtx, message, cipherText);
707 if (ret != DLP_OK) {
708 DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, errno=%{public}d", ret);
709 return ret;
710 }
711 break;
712 default:
713 DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, aes mode 0x%{public}x unsupport", mode);
714 return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
715 }
716
717 return DLP_OK;
718 }
719
DlpOpensslAesEncryptFinal(void ** cryptoCtx,const struct DlpBlob * message,struct DlpBlob * cipherText)720 int32_t DlpOpensslAesEncryptFinal(void** cryptoCtx, const struct DlpBlob* message, struct DlpBlob* cipherText)
721 {
722 if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
723 DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, ctx is null");
724 return DLP_PARSE_ERROR_VALUE_INVALID;
725 }
726 if (!DlpOpensslCheckBlobZero(message)) {
727 DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, msg is invalid");
728 return DLP_PARSE_ERROR_VALUE_INVALID;
729 }
730 if (!DlpOpensslCheckBlob(cipherText)) {
731 DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, cipher text is invalid");
732 return DLP_PARSE_ERROR_VALUE_INVALID;
733 }
734
735 struct DlpOpensslAesCtx* contex = (struct DlpOpensslAesCtx*)*cryptoCtx;
736 uint32_t mode = contex->mode;
737
738 int32_t ret;
739 switch (mode) {
740 case DLP_MODE_CTR:
741 ret = OpensslAesCipherEncryptFinalThree(cryptoCtx, message, cipherText);
742 if (ret != DLP_OK) {
743 DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, errno=%{public}d", ret);
744 return ret;
745 }
746 break;
747 default:
748 DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, aes mode 0x%{public}x unsupport", mode);
749 return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
750 }
751
752 return DLP_OK;
753 }
754
DlpOpensslAesDecryptInit(void ** cryptoCtx,const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec)755 int32_t DlpOpensslAesDecryptInit(void** cryptoCtx, const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec)
756 {
757 if (cryptoCtx == nullptr) {
758 DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, ctx is null");
759 return DLP_PARSE_ERROR_VALUE_INVALID;
760 }
761 if (usageSpec == nullptr) {
762 DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, usage spec is null");
763 return DLP_PARSE_ERROR_VALUE_INVALID;
764 }
765 if (!DlpOpensslCheckBlob(key)) {
766 DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, key is invalid");
767 return DLP_PARSE_ERROR_VALUE_INVALID;
768 }
769
770 int32_t ret;
771 switch (usageSpec->mode) {
772 case DLP_MODE_CTR:
773 ret = OpensslAesCipherCryptInit(key, usageSpec, false, cryptoCtx);
774 if (ret != DLP_OK) {
775 DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, errno=%{public}d", ret);
776 return ret;
777 }
778 break;
779 default:
780 DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, aes mode 0x%{public}x unsupport", usageSpec->mode);
781 return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
782 }
783
784 return ret;
785 }
786
DlpOpensslAesDecryptUpdate(void * cryptoCtx,const struct DlpBlob * message,struct DlpBlob * plainText)787 int32_t DlpOpensslAesDecryptUpdate(void* cryptoCtx, const struct DlpBlob* message, struct DlpBlob* plainText)
788 {
789 if (cryptoCtx == nullptr) {
790 DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, ctx is null");
791 return DLP_PARSE_ERROR_VALUE_INVALID;
792 }
793 if (!DlpOpensslCheckBlobZero(message)) {
794 DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, msg is invalid");
795 return DLP_PARSE_ERROR_VALUE_INVALID;
796 }
797 if (!DlpOpensslCheckBlob(plainText)) {
798 DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, plain text is invalid");
799 return DLP_PARSE_ERROR_VALUE_INVALID;
800 }
801
802 struct DlpOpensslAesCtx* contex = static_cast<struct DlpOpensslAesCtx*>(cryptoCtx);
803 uint32_t mode = contex->mode;
804
805 int32_t ret;
806 switch (mode) {
807 case DLP_MODE_CTR:
808 ret = OpensslAesCipherDecryptUpdate(cryptoCtx, message, plainText);
809 if (ret != DLP_OK) {
810 DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, errno=%{public}d", ret);
811 return ret;
812 }
813 break;
814 default:
815 DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, aes mode 0x%{public}x unsupport", mode);
816 return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
817 }
818
819 return ret;
820 }
821
DlpOpensslAesDecryptFinal(void ** cryptoCtx,const struct DlpBlob * message,struct DlpBlob * plainText)822 int32_t DlpOpensslAesDecryptFinal(void** cryptoCtx, const struct DlpBlob* message, struct DlpBlob* plainText)
823 {
824 if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
825 DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, ctx is null");
826 return DLP_PARSE_ERROR_VALUE_INVALID;
827 }
828 if (!DlpOpensslCheckBlobZero(message)) {
829 DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, msg is invalid");
830 return DLP_PARSE_ERROR_VALUE_INVALID;
831 }
832 if (!DlpOpensslCheckBlob(plainText)) {
833 DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, plain text is invalid");
834 return DLP_PARSE_ERROR_VALUE_INVALID;
835 }
836
837 struct DlpOpensslAesCtx* contex = (struct DlpOpensslAesCtx*)*cryptoCtx;
838 uint32_t mode = contex->mode;
839
840 int32_t ret;
841 switch (mode) {
842 case DLP_MODE_CTR:
843 ret = OpensslAesCipherDecryptFinalThree(cryptoCtx, message, plainText);
844 if (ret != DLP_OK) {
845 DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, errno=%{public}d", ret);
846 return ret;
847 }
848 break;
849 default:
850 DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, aes mode 0x%{public}x unsupport", mode);
851 return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
852 }
853
854 return DLP_OK;
855 }
856
DlpOpensslAesHalFreeCtx(void ** cryptoCtx)857 void DlpOpensslAesHalFreeCtx(void** cryptoCtx)
858 {
859 if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
860 DLP_LOG_ERROR(LABEL, "Aes free ctx fail, cxt is null");
861 return;
862 }
863
864 struct DlpOpensslAesCtx* opensslAesCtx = (struct DlpOpensslAesCtx*)*cryptoCtx;
865 switch (opensslAesCtx->mode) {
866 case DLP_MODE_CTR:
867 if (reinterpret_cast<EVP_CIPHER_CTX*>(opensslAesCtx->append) != nullptr) {
868 EVP_CIPHER_CTX_free(reinterpret_cast<EVP_CIPHER_CTX*>(opensslAesCtx->append));
869 opensslAesCtx->append = nullptr;
870 }
871 break;
872
873 default:
874 DLP_LOG_ERROR(LABEL, "Aes free ctx fail, aes mode 0x%{public}x unsupport", opensslAesCtx->mode);
875 break;
876 }
877
878 DLP_FREE_PTR(*cryptoCtx);
879 }
880
AesParamCheck(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const struct DlpBlob * message,struct DlpBlob * cipherText)881 static bool AesParamCheck(const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec,
882 const struct DlpBlob* message, struct DlpBlob* cipherText)
883 {
884 if (usageSpec == nullptr) {
885 DLP_LOG_ERROR(LABEL, "Check aes params fail, usage spec is null");
886 return false;
887 }
888
889 if (!DlpOpensslCheckBlob(key)) {
890 DLP_LOG_ERROR(LABEL, "Check aes params fail, key is invalid");
891 return false;
892 }
893
894 if (!DlpOpensslCheckBlob(message)) {
895 DLP_LOG_ERROR(LABEL, "Check aes params fail, msg in invalid");
896 return false;
897 }
898
899 if (!DlpOpensslCheckBlob(cipherText)) {
900 DLP_LOG_ERROR(LABEL, "Check aes params fail, cipher text is invalid");
901 return false;
902 }
903
904 return true;
905 }
906
DlpOpensslAesEncrypt(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const struct DlpBlob * message,struct DlpBlob * cipherText)907 int32_t DlpOpensslAesEncrypt(const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec,
908 const struct DlpBlob* message, struct DlpBlob* cipherText)
909 {
910 if (!AesParamCheck(key, usageSpec, message, cipherText)) {
911 DLP_LOG_ERROR(LABEL, "Aes encrypt fail, check aes params error");
912 return DLP_PARSE_ERROR_VALUE_INVALID;
913 }
914
915 EVP_CIPHER_CTX* ctx = nullptr;
916 struct DlpBlob tmpCipherText = *cipherText;
917
918 int32_t ret;
919 switch (usageSpec->mode) {
920 case DLP_MODE_CTR:
921 ret = OpensslAesCipherInit(key, usageSpec, true, &ctx);
922 if (ret != DLP_OK) {
923 DLP_LOG_ERROR(LABEL, "Aes encrypt fail, encrypt init error, errno=%{public}d", ret);
924 return ret;
925 }
926
927 ret = OpensslAesCipherEncryptFinal(ctx, message, &tmpCipherText);
928 if (ret != DLP_OK) {
929 DLP_LOG_ERROR(LABEL, "Aes encrypt fail, encrypt final error, errno=%{public}d", ret);
930 return ret;
931 }
932 break;
933
934 default:
935 DLP_LOG_ERROR(LABEL, "Aes encrypt fail, aes mode 0x%{public}x unsupport", usageSpec->mode);
936 return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
937 }
938
939 cipherText->size = tmpCipherText.size;
940 return DLP_OK;
941 }
942
DlpOpensslAesDecrypt(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const struct DlpBlob * message,struct DlpBlob * plainText)943 int32_t DlpOpensslAesDecrypt(const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec,
944 const struct DlpBlob* message, struct DlpBlob* plainText)
945 {
946 if (!AesParamCheck(key, usageSpec, message, plainText)) {
947 DLP_LOG_ERROR(LABEL, "Aes decrypt fail, check aes params error");
948 return DLP_PARSE_ERROR_VALUE_INVALID;
949 }
950 EVP_CIPHER_CTX* ctx = nullptr;
951 struct DlpBlob tmpPlainText = *plainText;
952
953 int32_t ret;
954 switch (usageSpec->mode) {
955 case DLP_MODE_CTR:
956 ret = OpensslAesCipherInit(key, usageSpec, false, &ctx);
957 if (ret != DLP_OK) {
958 DLP_LOG_ERROR(LABEL, "Aes decrypt fail, decrypt init error, errno=%{public}d", ret);
959 return ret;
960 }
961
962 ret = OpensslAesCipherDecryptFinal(ctx, message, &tmpPlainText);
963 if (ret != DLP_OK) {
964 DLP_LOG_ERROR(LABEL, "Aes decrypt fail, decrypt final error, errno=%{public}d", ret);
965 return ret;
966 }
967 break;
968 default:
969 DLP_LOG_ERROR(LABEL, "Aes decrypt fail, aes mode 0x%{public}x unsupport", usageSpec->mode);
970 return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
971 }
972
973 plainText->size = tmpPlainText.size;
974 return ret;
975 }
976
CheckDigestAlg(uint32_t alg)977 static bool CheckDigestAlg(uint32_t alg)
978 {
979 switch (alg) {
980 case DLP_DIGEST_SHA256:
981 case DLP_DIGEST_SHA384:
982 case DLP_DIGEST_SHA512:
983 return true;
984 default:
985 return false;
986 }
987 }
988
GetOpensslAlg(uint32_t alg)989 const EVP_MD* GetOpensslAlg(uint32_t alg)
990 {
991 switch (alg) {
992 case DLP_DIGEST_SHA256:
993 return EVP_sha256();
994 case DLP_DIGEST_SHA384:
995 return EVP_sha384();
996 case DLP_DIGEST_SHA512:
997 return EVP_sha512();
998 default:
999 return nullptr;
1000 }
1001 }
1002
GetHashLen(uint32_t alg)1003 static uint32_t GetHashLen(uint32_t alg)
1004 {
1005 if (alg == DLP_DIGEST_SHA256) {
1006 return SHA256_LEN;
1007 } else if (alg == DLP_DIGEST_SHA384) {
1008 return SHA384_LEN;
1009 } else {
1010 return SHA512_LEN;
1011 }
1012 }
1013
HashCheckParam(uint32_t alg,const struct DlpBlob * msg,struct DlpBlob * hash)1014 static bool HashCheckParam(uint32_t alg, const struct DlpBlob* msg, struct DlpBlob* hash)
1015 {
1016 if (!CheckDigestAlg(alg)) {
1017 DLP_LOG_ERROR(LABEL, "Check hash param fail, alg type is unsupported");
1018 return false;
1019 }
1020
1021 if (!DlpOpensslCheckBlob(hash)) {
1022 DLP_LOG_ERROR(LABEL, "Check hash param fail, hash is invalid");
1023 return false;
1024 }
1025
1026 uint32_t hashLen = GetHashLen(alg);
1027 if (hash->size < hashLen) {
1028 DLP_LOG_ERROR(LABEL, "Check hash param fail, hash buff too short");
1029 return false;
1030 }
1031
1032 if (!DlpOpensslCheckBlob(msg)) {
1033 DLP_LOG_ERROR(LABEL, "Check hash param fail, msg is invalid");
1034 return false;
1035 }
1036
1037 return true;
1038 }
1039
DlpOpensslHash(uint32_t alg,const struct DlpBlob * msg,struct DlpBlob * hash)1040 int32_t DlpOpensslHash(uint32_t alg, const struct DlpBlob* msg, struct DlpBlob* hash)
1041 {
1042 if (!HashCheckParam(alg, msg, hash)) {
1043 DLP_LOG_ERROR(LABEL, "Openssl hash fail, param is invalid");
1044 return DLP_PARSE_ERROR_VALUE_INVALID;
1045 }
1046
1047 const EVP_MD* opensslAlg = GetOpensslAlg(alg);
1048 if (opensslAlg == nullptr) {
1049 DLP_LOG_ERROR(LABEL, "Openssl hash fail, get alg fail");
1050 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1051 }
1052
1053 int32_t ret = EVP_Digest(msg->data, msg->size, hash->data, &hash->size, opensslAlg, nullptr);
1054 if (ret != DLP_OPENSSL_SUCCESS) {
1055 DlpLogOpensslError();
1056 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1057 }
1058 return DLP_OK;
1059 }
1060
DlpOpensslHashInit(void ** cryptoCtx,uint32_t alg)1061 int32_t DlpOpensslHashInit(void** cryptoCtx, uint32_t alg)
1062 {
1063 if (cryptoCtx == nullptr) {
1064 DLP_LOG_ERROR(LABEL, "Openssl hash init fail, ctx is null");
1065 return DLP_PARSE_ERROR_DIGEST_INVALID;
1066 }
1067 if (!CheckDigestAlg(alg)) {
1068 DLP_LOG_ERROR(LABEL, "Openssl hash init fail, alg is invalid");
1069 return DLP_PARSE_ERROR_DIGEST_INVALID;
1070 }
1071 const EVP_MD* opensslAlg = GetOpensslAlg(alg);
1072 if (opensslAlg == nullptr) {
1073 DLP_LOG_ERROR(LABEL, "Openssl hash init fail, get alg fail");
1074 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1075 }
1076 EVP_MD_CTX* tmpctx = EVP_MD_CTX_new();
1077 if (tmpctx == nullptr) {
1078 DLP_LOG_ERROR(LABEL, "Openssl hash init fail, alloc ctx fail");
1079 return DLP_PARSE_ERROR_VALUE_INVALID;
1080 }
1081
1082 EVP_MD_CTX_set_flags(tmpctx, EVP_MD_CTX_FLAG_ONESHOT);
1083 int32_t ret = EVP_DigestInit_ex(tmpctx, opensslAlg, nullptr);
1084 if (ret != DLP_OPENSSL_SUCCESS) {
1085 DlpLogOpensslError();
1086 EVP_MD_CTX_free(tmpctx);
1087 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1088 }
1089 *cryptoCtx = static_cast<void*>(tmpctx);
1090 return DLP_OK;
1091 }
1092
DlpOpensslHashUpdate(void * cryptoCtx,const struct DlpBlob * msg)1093 int32_t DlpOpensslHashUpdate(void* cryptoCtx, const struct DlpBlob* msg)
1094 {
1095 if (cryptoCtx == nullptr) {
1096 DLP_LOG_ERROR(LABEL, "Openssl hash update fail, ctx is null");
1097 return DLP_PARSE_ERROR_VALUE_INVALID;
1098 }
1099 if (!DlpOpensslCheckBlob(msg)) {
1100 DLP_LOG_ERROR(LABEL, "Openssl hash update fail, msg is invalid");
1101 return DLP_PARSE_ERROR_VALUE_INVALID;
1102 }
1103
1104 int32_t ret = EVP_DigestUpdate(
1105 reinterpret_cast<EVP_MD_CTX*>(cryptoCtx), reinterpret_cast<void*>(msg->data), msg->size);
1106 if (ret != DLP_OPENSSL_SUCCESS) {
1107 DlpLogOpensslError();
1108 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1109 }
1110 return DLP_OK;
1111 }
1112
DlpOpensslHashFinal(void ** cryptoCtx,const struct DlpBlob * msg,struct DlpBlob * hash)1113 int32_t DlpOpensslHashFinal(void** cryptoCtx, const struct DlpBlob* msg, struct DlpBlob* hash)
1114 {
1115 if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
1116 DLP_LOG_ERROR(LABEL, "Openssl hash final fail, ctx is null");
1117 return DLP_PARSE_ERROR_VALUE_INVALID;
1118 }
1119 if (!DlpOpensslCheckBlobZero(msg)) {
1120 DLP_LOG_ERROR(LABEL, "Openssl hash final fail, msg is invalid");
1121 return DLP_PARSE_ERROR_VALUE_INVALID;
1122 }
1123 if (!DlpOpensslCheckBlob(hash)) {
1124 DLP_LOG_ERROR(LABEL, "Openssl hash final fail, hash is invalid");
1125 return DLP_PARSE_ERROR_VALUE_INVALID;
1126 }
1127
1128 int32_t ret;
1129 if (msg->size != 0) {
1130 ret = EVP_DigestUpdate((EVP_MD_CTX*)*cryptoCtx, msg->data, msg->size);
1131 if (ret != DLP_OPENSSL_SUCCESS) {
1132 DlpLogOpensslError();
1133 EVP_MD_CTX_free((EVP_MD_CTX*)*cryptoCtx);
1134 *cryptoCtx = nullptr;
1135 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1136 }
1137 }
1138
1139 ret = EVP_DigestFinal_ex((EVP_MD_CTX*)*cryptoCtx, hash->data, &hash->size);
1140 if (ret != DLP_OPENSSL_SUCCESS) {
1141 DlpLogOpensslError();
1142 EVP_MD_CTX_free((EVP_MD_CTX*)*cryptoCtx);
1143 *cryptoCtx = nullptr;
1144 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1145 }
1146
1147 EVP_MD_CTX_free((EVP_MD_CTX*)*cryptoCtx);
1148 *cryptoCtx = nullptr;
1149 return DLP_OK;
1150 }
1151
DlpOpensslHashFreeCtx(void ** cryptoCtx)1152 int32_t DlpOpensslHashFreeCtx(void** cryptoCtx)
1153 {
1154 if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
1155 DLP_LOG_ERROR(LABEL, "Openssl hash free ctx fail, param is invalid");
1156 return DLP_PARSE_ERROR_VALUE_INVALID;
1157 }
1158 EVP_MD_CTX_free((EVP_MD_CTX*)*cryptoCtx);
1159 *cryptoCtx = nullptr;
1160 return DLP_OK;
1161 }
1162
IncIvCounterLitteEndian(struct DlpBlob & iv,uint32_t count)1163 static void IncIvCounterLitteEndian(struct DlpBlob& iv, uint32_t count)
1164 {
1165 uint8_t* data = iv.data;
1166 int size = static_cast<int>(iv.size - 1);
1167 for (int i = size; i >= 0; i--) {
1168 count += data[i];
1169 data[i] = static_cast<uint8_t>(count);
1170 count >>= BYTE_LEN;
1171 if (count == 0) {
1172 break;
1173 }
1174 }
1175 }
1176
DlpCtrModeIncreaeIvCounter(struct DlpBlob & iv,uint32_t count)1177 int32_t DlpCtrModeIncreaeIvCounter(struct DlpBlob& iv, uint32_t count)
1178 {
1179 if (iv.data == nullptr || iv.size == 0) {
1180 DLP_LOG_ERROR(LABEL, "param error");
1181 return DLP_PARSE_ERROR_VALUE_INVALID;
1182 }
1183
1184 IncIvCounterLitteEndian(iv, count);
1185 return DLP_OK;
1186 }
1187
DlpHmacEncodeForRaw(const DlpBlob & key,int32_t fd,uint64_t fileSize,DlpBlob & out)1188 int32_t DlpHmacEncodeForRaw(const DlpBlob& key, int32_t fd, uint64_t fileSize, DlpBlob& out)
1189 {
1190 if ((key.data == nullptr) || (key.size != SHA256_KEY_LEN)) {
1191 DLP_LOG_ERROR(LABEL, "Key blob invalid, size %{public}u", key.size);
1192 return DLP_PARSE_ERROR_DIGEST_INVALID;
1193 }
1194 if ((out.data == nullptr) || (out.size < HMAC_SIZE)) {
1195 DLP_LOG_ERROR(LABEL, "Output blob invalid, size %{public}u", out.size);
1196 return DLP_PARSE_ERROR_DIGEST_INVALID;
1197 }
1198
1199 HMAC_CTX* ctx = HMAC_CTX_new();
1200 if (ctx == nullptr) {
1201 DLP_LOG_ERROR(LABEL, "HMAC_CTX is null");
1202 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1203 }
1204 if (HMAC_Init_ex(ctx, key.data, key.size, EVP_sha256(), nullptr) != 1) {
1205 DLP_LOG_ERROR(LABEL, "HMAC_Init failed");
1206 HMAC_CTX_free(ctx);
1207 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1208 }
1209
1210 auto buf = std::make_unique<unsigned char[]>(BUFFER_SIZE);
1211 uint64_t inOffset = 0;
1212 while (inOffset < fileSize) {
1213 uint32_t readLen = ((fileSize - inOffset) < BUFFER_SIZE) ? (fileSize - inOffset) : BUFFER_SIZE;
1214 ssize_t readSize = read(fd, buf.get(), readLen);
1215 if (readSize != readLen) {
1216 DLP_LOG_ERROR(LABEL, "HMAC_Init readLen err: %{public}d", readLen);
1217 HMAC_CTX_free(ctx);
1218 return DLP_PARSE_ERROR_FILE_OPERATE_FAIL;
1219 }
1220
1221 if (HMAC_Update(ctx, buf.get(), readLen) != 1) {
1222 DLP_LOG_ERROR(LABEL, "HMAC_Update failed");
1223 HMAC_CTX_free(ctx);
1224 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1225 }
1226
1227 inOffset += readLen;
1228 }
1229
1230 if (HMAC_Final(ctx, out.data, &out.size) != 1) {
1231 DLP_LOG_ERROR(LABEL, "HMAC_Final failed");
1232 HMAC_CTX_free(ctx);
1233 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1234 }
1235
1236 HMAC_CTX_free(ctx);
1237 return DLP_OK;
1238 }
1239
DlpHmacEncode(const DlpBlob & key,int32_t fd,DlpBlob & out)1240 int32_t DlpHmacEncode(const DlpBlob& key, int32_t fd, DlpBlob& out)
1241 {
1242 if ((key.data == nullptr) || (key.size != SHA256_KEY_LEN)) {
1243 DLP_LOG_ERROR(LABEL, "Key blob invalid, size %{public}u", key.size);
1244 return DLP_PARSE_ERROR_DIGEST_INVALID;
1245 }
1246 if ((out.data == nullptr) || (out.size < HMAC_SIZE)) {
1247 DLP_LOG_ERROR(LABEL, "Output blob invalid, size %{public}u", out.size);
1248 return DLP_PARSE_ERROR_DIGEST_INVALID;
1249 }
1250
1251 HMAC_CTX* ctx = HMAC_CTX_new();
1252 if (ctx == nullptr) {
1253 DLP_LOG_ERROR(LABEL, "HMAC_CTX is null");
1254 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1255 }
1256 if (HMAC_Init_ex(ctx, key.data, key.size, EVP_sha256(), nullptr) != 1) {
1257 DLP_LOG_ERROR(LABEL, "HMAC_Init failed");
1258 HMAC_CTX_free(ctx);
1259 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1260 }
1261
1262 auto buf = std::make_unique<unsigned char[]>(BUFFER_SIZE);
1263 int32_t readSize;
1264 while ((readSize = read(fd, buf.get(), BUFFER_SIZE)) > 0) {
1265 if (HMAC_Update(ctx, buf.get(), readSize) != 1) {
1266 DLP_LOG_ERROR(LABEL, "HMAC_Update failed");
1267 HMAC_CTX_free(ctx);
1268 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1269 }
1270 }
1271 if (HMAC_Final(ctx, out.data, &out.size) != 1) {
1272 DLP_LOG_ERROR(LABEL, "HMAC_Final failed");
1273 HMAC_CTX_free(ctx);
1274 return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
1275 }
1276 HMAC_CTX_free(ctx);
1277 return DLP_OK;
1278 }
1279 #ifdef __cplusplus
1280 }
1281 #endif
1282