• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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