• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <openssl/err.h>
20 #include <openssl/evp.h>
21 #include <openssl/rand.h>
22 #include <securec.h>
23 #include <string>
24 #include "dlp_permission.h"
25 #include "dlp_permission_log.h"
26 
27 using namespace OHOS::Security::DlpPermission;
28 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpParse"};
29 static const uint32_t BYTE_LEN = 8;
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
DlpOpensslCheckBlob(const struct DlpBlob * blob)35 inline bool DlpOpensslCheckBlob(const struct DlpBlob* blob)
36 {
37     return (blob != nullptr) && (blob->data != nullptr);
38 }
39 
DlpOpensslCheckBlobZero(const struct DlpBlob * blob)40 inline bool DlpOpensslCheckBlobZero(const struct DlpBlob* blob)
41 {
42     if (blob == nullptr) {
43         return false;
44     }
45 
46     if (blob->data == nullptr && blob->size == 0) {
47         return true;
48     }
49 
50     if (blob->data == nullptr) {
51         return false;
52     }
53 
54     return true;
55 }
56 
AesGenKeyCheckParam(uint32_t keySize)57 static bool AesGenKeyCheckParam(uint32_t keySize)
58 {
59     return (keySize == DLP_AES_KEY_SIZE_128) || (keySize == DLP_AES_KEY_SIZE_192) || (keySize == DLP_AES_KEY_SIZE_256);
60 }
61 
DlpOpensslGenerateRandomKey(uint32_t keySize,struct DlpBlob * key)62 int32_t DlpOpensslGenerateRandomKey(uint32_t keySize, struct DlpBlob* key)
63 {
64     if (key == nullptr) {
65         DLP_LOG_ERROR(LABEL, "Generate key fail, blob is nullptr");
66         return DLP_PARSE_ERROR_VALUE_INVALID;
67     }
68     if (!AesGenKeyCheckParam(keySize)) {
69         DLP_LOG_ERROR(LABEL, "Generate key fail, key size %{public}u is invalid", keySize);
70         return DLP_PARSE_ERROR_VALUE_INVALID;
71     }
72     uint32_t keySizeByte = keySize / BIT_NUM_OF_UINT8;
73 
74     uint8_t* tmpKey = new (std::nothrow) uint8_t[keySizeByte];
75     if (tmpKey == nullptr) {
76         DLP_LOG_ERROR(LABEL, "Generate key fail, alloc %{public}u buffer fail", keySizeByte);
77         return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
78     }
79 
80     int res = RAND_bytes(tmpKey, keySizeByte);
81     if (res <= 0) {
82         DLP_LOG_ERROR(LABEL, "Generate key fail, generate rand bytes error, errno=%{public}d", res);
83         (void)memset_s(tmpKey, keySizeByte, 0, keySizeByte);
84         delete[] tmpKey;
85         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
86     } else {
87         key->data = tmpKey;
88         key->size = keySizeByte;
89     }
90     return DLP_OK;
91 }
92 
GetCtrCipherType(uint32_t keySize)93 static const EVP_CIPHER* GetCtrCipherType(uint32_t keySize)
94 {
95     switch (keySize) {
96         case DLP_KEY_BYTES(DLP_AES_KEY_SIZE_128):
97             return EVP_aes_128_ctr();
98         case DLP_KEY_BYTES(DLP_AES_KEY_SIZE_192):
99             return EVP_aes_192_ctr();
100         case DLP_KEY_BYTES(DLP_AES_KEY_SIZE_256):
101             return EVP_aes_256_ctr();
102         default:
103             return nullptr;
104     }
105 }
106 
DlpLogOpensslError(void)107 inline void DlpLogOpensslError(void)
108 {
109     char szErr[DLP_OPENSSL_ERROR_LEN] = {0};
110     unsigned long errCode = ERR_get_error();
111     ERR_error_string_n(errCode, szErr, DLP_OPENSSL_ERROR_LEN);
112     DLP_LOG_ERROR(LABEL, "Openssl engine error, errno=%{public}lu, errmsg=%{public}s", errCode, szErr);
113 }
114 
OpensslAesCipherInit(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,bool isEncrypt,EVP_CIPHER_CTX ** ctx)115 static int32_t OpensslAesCipherInit(
116     const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec, bool isEncrypt, EVP_CIPHER_CTX** ctx)
117 {
118     int32_t ret;
119     struct DlpCipherParam* cipherParam = usageSpec->algParam;
120 
121     *ctx = EVP_CIPHER_CTX_new();
122     if (*ctx == nullptr) {
123         DlpLogOpensslError();
124         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
125     }
126 
127     const EVP_CIPHER* cipher = GetCtrCipherType(key->size);
128     if (cipher == nullptr) {
129         DLP_LOG_ERROR(LABEL, "Aes cipher init fail, get cipher type error");
130         EVP_CIPHER_CTX_free(*ctx);
131         return DLP_PARSE_ERROR_VALUE_INVALID;
132     }
133 
134     if (isEncrypt) {
135         ret = EVP_EncryptInit_ex(*ctx, cipher, nullptr, nullptr, nullptr);
136     } else {
137         ret = EVP_DecryptInit_ex(*ctx, cipher, nullptr, nullptr, nullptr);
138     }
139     if (ret != DLP_OPENSSL_SUCCESS) {
140         DlpLogOpensslError();
141         EVP_CIPHER_CTX_free(*ctx);
142         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
143     }
144 
145     if (isEncrypt) {
146         ret = EVP_EncryptInit_ex(
147             *ctx, nullptr, nullptr, key->data, (cipherParam == nullptr) ? nullptr : cipherParam->iv.data);
148     } else {
149         ret = EVP_DecryptInit_ex(
150             *ctx, nullptr, nullptr, key->data, (cipherParam == nullptr) ? nullptr : cipherParam->iv.data);
151     }
152     if (ret != DLP_OPENSSL_SUCCESS) {
153         DlpLogOpensslError();
154         EVP_CIPHER_CTX_free(*ctx);
155         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
156     }
157 
158     ret = EVP_CIPHER_CTX_set_padding(*ctx, OPENSSL_CTX_PADDING_ENABLE);
159     if (ret != DLP_OPENSSL_SUCCESS) {
160         DlpLogOpensslError();
161         EVP_CIPHER_CTX_free(*ctx);
162         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
163     }
164 
165     return DLP_OK;
166 }
167 
OpensslAesCipherEncryptFinal(EVP_CIPHER_CTX * ctx,const struct DlpBlob * message,struct DlpBlob * cipherText)168 static int32_t OpensslAesCipherEncryptFinal(
169     EVP_CIPHER_CTX* ctx, const struct DlpBlob* message, struct DlpBlob* cipherText)
170 {
171     int32_t outLen = 0;
172 
173     if (EVP_EncryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
174         DlpLogOpensslError();
175         EVP_CIPHER_CTX_free(ctx);
176         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
177     }
178     cipherText->size = static_cast<uint32_t>(outLen);
179 
180     if (EVP_EncryptFinal_ex(ctx, cipherText->data + outLen, &outLen) != DLP_OPENSSL_SUCCESS) {
181         DlpLogOpensslError();
182         EVP_CIPHER_CTX_free(ctx);
183         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
184     }
185     cipherText->size += static_cast<uint32_t>(outLen);
186 
187     EVP_CIPHER_CTX_free(ctx);
188     return DLP_OK;
189 }
190 
OpensslAesCipherCryptInitParams(const struct DlpBlob * key,EVP_CIPHER_CTX * ctx,const struct DlpCipherParam * cipherParam,bool isEncrypt)191 static int32_t OpensslAesCipherCryptInitParams(const struct DlpBlob* key, EVP_CIPHER_CTX* ctx,
192     const struct DlpCipherParam* cipherParam, bool isEncrypt)
193 {
194     int32_t ret;
195     if (isEncrypt) {
196         ret = EVP_EncryptInit_ex(
197             ctx, nullptr, nullptr, key->data, (cipherParam == nullptr) ? nullptr : cipherParam->iv.data);
198     } else {
199         ret = EVP_DecryptInit_ex(
200             ctx, nullptr, nullptr, key->data, (cipherParam == nullptr) ? nullptr : cipherParam->iv.data);
201     }
202     if (ret != DLP_OPENSSL_SUCCESS) {
203         DlpLogOpensslError();
204         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
205     }
206     ret = EVP_CIPHER_CTX_set_padding(ctx, OPENSSL_CTX_PADDING_ENABLE);
207     if (ret != DLP_OPENSSL_SUCCESS) {
208         DlpLogOpensslError();
209         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
210     }
211     return DLP_OK;
212 }
213 
OpensslAesCipherCryptInit(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,bool isEncrypt,void ** cryptoCtx)214 static int32_t OpensslAesCipherCryptInit(
215     const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec, bool isEncrypt, void** cryptoCtx)
216 {
217     int32_t ret;
218     struct DlpCipherParam* cipherParam = reinterpret_cast<struct DlpCipherParam*>(usageSpec->algParam);
219 
220     EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
221     if (ctx == nullptr) {
222         DlpLogOpensslError();
223         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
224     }
225 
226     const EVP_CIPHER* cipher = GetCtrCipherType(key->size);
227     if (cipher == nullptr) {
228         DLP_LOG_ERROR(LABEL, "Aes cipher crypt init fail, get cipher type error");
229         EVP_CIPHER_CTX_free(ctx);
230         return DLP_PARSE_ERROR_VALUE_INVALID;
231     }
232 
233     if (isEncrypt) {
234         ret = EVP_EncryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr);
235     } else {
236         ret = EVP_DecryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr);
237     }
238     if (ret != DLP_OPENSSL_SUCCESS) {
239         DlpLogOpensslError();
240         EVP_CIPHER_CTX_free(ctx);
241         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
242     }
243 
244     ret = OpensslAesCipherCryptInitParams(key, ctx, cipherParam, isEncrypt);
245     if (ret != DLP_OK) {
246         EVP_CIPHER_CTX_free(ctx);
247         DLP_LOG_ERROR(LABEL, "Aes cipher crypt init fail, init cipher params error, errno=%d", ret);
248         return ret;
249     }
250 
251     struct DlpOpensslAesCtx* outCtx = static_cast<struct DlpOpensslAesCtx*>(malloc(sizeof(DlpOpensslAesCtx)));
252     if (outCtx == nullptr) {
253         DLP_LOG_ERROR(LABEL, "Aes cipher crypt init fail, alloc aes ctx fail");
254         EVP_CIPHER_CTX_free(ctx);
255         return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
256     }
257 
258     outCtx->mode = usageSpec->mode;
259     outCtx->append = static_cast<void*>(ctx);
260 
261     *cryptoCtx = static_cast<void*>(outCtx);
262 
263     return DLP_OK;
264 }
265 
OpensslAesCipherEncryptUpdate(void * cryptoCtx,const struct DlpBlob * message,struct DlpBlob * cipherText)266 static int32_t OpensslAesCipherEncryptUpdate(void* cryptoCtx, const struct DlpBlob* message, struct DlpBlob* cipherText)
267 {
268     struct DlpOpensslAesCtx* aesCtx = static_cast<struct DlpOpensslAesCtx*>(cryptoCtx);
269     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(aesCtx->append);
270     if (ctx == nullptr) {
271         return DLP_PARSE_ERROR_VALUE_INVALID;
272     }
273 
274     int32_t outLen = 0;
275     if (EVP_EncryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
276         DlpLogOpensslError();
277         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
278     }
279     cipherText->size = static_cast<uint32_t>(outLen);
280 
281     return DLP_OK;
282 }
283 
OpensslAesCipherEncryptFinalThree(void ** cryptoCtx,const struct DlpBlob * message,struct DlpBlob * cipherText)284 static int32_t OpensslAesCipherEncryptFinalThree(
285     void** cryptoCtx, const struct DlpBlob* message, struct DlpBlob* cipherText)
286 {
287     struct DlpOpensslAesCtx* aesCtx = (struct DlpOpensslAesCtx*)*cryptoCtx;
288     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(aesCtx->append);
289 
290     if (ctx == nullptr) {
291         DLP_FREE_PTR(*cryptoCtx);
292         return DLP_PARSE_ERROR_VALUE_INVALID;
293     }
294 
295     int32_t ret = DLP_OK;
296     do {
297         int32_t outLen = 0;
298         if (message->size != 0) {
299             if (EVP_EncryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size) !=
300                 DLP_OPENSSL_SUCCESS) {
301                 DlpLogOpensslError();
302                 ret = DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
303                 break;
304             }
305             cipherText->size = static_cast<uint32_t>(outLen);
306         }
307 
308         if (EVP_EncryptFinal_ex(ctx, (cipherText->data + outLen), &outLen) != DLP_OPENSSL_SUCCESS) {
309             DlpLogOpensslError();
310             ret = DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
311             break;
312         }
313         cipherText->size += static_cast<uint32_t>(outLen);
314     } while (0);
315 
316     EVP_CIPHER_CTX_free(ctx);
317     aesCtx->append = nullptr;
318     DLP_FREE_PTR(*cryptoCtx);
319 
320     return ret;
321 }
322 
OpensslAesCipherDecryptUpdate(void * cryptoCtx,const struct DlpBlob * message,struct DlpBlob * plainText)323 static int32_t OpensslAesCipherDecryptUpdate(void* cryptoCtx, const struct DlpBlob* message, struct DlpBlob* plainText)
324 {
325     struct DlpOpensslAesCtx* aesCtx = static_cast<struct DlpOpensslAesCtx*>(cryptoCtx);
326     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(aesCtx->append);
327 
328     if (ctx == nullptr) {
329         return DLP_PARSE_ERROR_VALUE_INVALID;
330     }
331 
332     int32_t outLen = 0;
333     if (EVP_DecryptUpdate(ctx, plainText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
334         DlpLogOpensslError();
335         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
336     }
337     plainText->size = static_cast<uint32_t>(outLen);
338 
339     return DLP_OK;
340 }
341 
OpensslAesCipherDecryptFinalThree(void ** cryptoCtx,const struct DlpBlob * message,struct DlpBlob * plainText)342 static int32_t OpensslAesCipherDecryptFinalThree(
343     void** cryptoCtx, const struct DlpBlob* message, struct DlpBlob* plainText)
344 {
345     struct DlpOpensslAesCtx* aesCtx = (struct DlpOpensslAesCtx*)*cryptoCtx;
346     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(aesCtx->append);
347     if (ctx == nullptr) {
348         DLP_FREE_PTR(*cryptoCtx);
349         return DLP_PARSE_ERROR_VALUE_INVALID;
350     }
351 
352     int32_t ret = DLP_OK;
353     do {
354         int32_t outLen = 0;
355         if (message->size != 0) {
356             if (EVP_DecryptUpdate(ctx, plainText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
357                 DlpLogOpensslError();
358                 ret = DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
359                 break;
360             }
361             plainText->size = static_cast<uint32_t>(outLen);
362         }
363 
364         if (EVP_DecryptFinal_ex(ctx, plainText->data + outLen, &outLen) != DLP_OPENSSL_SUCCESS) {
365             DlpLogOpensslError();
366             ret = DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
367             break;
368         }
369         plainText->size += static_cast<uint32_t>(outLen);
370     } while (0);
371 
372     EVP_CIPHER_CTX_free(ctx);
373     aesCtx->append = nullptr;
374     DLP_FREE_PTR(*cryptoCtx);
375     return ret;
376 }
377 
OpensslAesCipherDecryptFinal(EVP_CIPHER_CTX * ctx,const struct DlpBlob * message,struct DlpBlob * plainText)378 static int32_t OpensslAesCipherDecryptFinal(
379     EVP_CIPHER_CTX* ctx, const struct DlpBlob* message, struct DlpBlob* plainText)
380 {
381     int32_t outLen = 0;
382 
383     if (EVP_DecryptUpdate(ctx, plainText->data, &outLen, message->data, message->size) != DLP_OPENSSL_SUCCESS) {
384         DlpLogOpensslError();
385         EVP_CIPHER_CTX_free(ctx);
386         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
387     }
388     plainText->size = static_cast<uint32_t>(outLen);
389 
390     if (EVP_DecryptFinal_ex(ctx, plainText->data + outLen, &outLen) != DLP_OPENSSL_SUCCESS) {
391         DlpLogOpensslError();
392         EVP_CIPHER_CTX_free(ctx);
393         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
394     }
395     plainText->size += static_cast<uint32_t>(outLen);
396 
397     EVP_CIPHER_CTX_free(ctx);
398     return DLP_OK;
399 }
400 
DlpOpensslAesEncryptInit(void ** cryptoCtx,const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec)401 int32_t DlpOpensslAesEncryptInit(void** cryptoCtx, const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec)
402 {
403     if (cryptoCtx == nullptr) {
404         DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, ctx is null");
405         return DLP_PARSE_ERROR_VALUE_INVALID;
406     }
407     if (usageSpec == nullptr) {
408         DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, usage spec is null");
409         return DLP_PARSE_ERROR_VALUE_INVALID;
410     }
411     if (!DlpOpensslCheckBlob(key)) {
412         DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, key is invalid");
413         return DLP_PARSE_ERROR_VALUE_INVALID;
414     }
415 
416     int32_t ret;
417     switch (usageSpec->mode) {
418         case DLP_MODE_CTR:
419             ret = OpensslAesCipherCryptInit(key, usageSpec, true, cryptoCtx);
420             if (ret != DLP_OK) {
421                 DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, errno=%{public}d", ret);
422                 return ret;
423             }
424             break;
425 
426         default:
427             DLP_LOG_ERROR(LABEL, "Aes encrypt init fail, aes mode 0x%{public}x unsupport", usageSpec->mode);
428             return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
429     }
430 
431     return DLP_OK;
432 }
433 
DlpOpensslAesEncryptUpdate(void * cryptoCtx,const struct DlpBlob * message,struct DlpBlob * cipherText)434 int32_t DlpOpensslAesEncryptUpdate(void* cryptoCtx, const struct DlpBlob* message, struct DlpBlob* cipherText)
435 {
436     if (cryptoCtx == nullptr) {
437         DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, ctx is null");
438         return DLP_PARSE_ERROR_VALUE_INVALID;
439     }
440     if (!DlpOpensslCheckBlobZero(message)) {
441         DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, msg is invalid");
442         return DLP_PARSE_ERROR_VALUE_INVALID;
443     }
444     if (!DlpOpensslCheckBlob(cipherText)) {
445         DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, cipher text is invalid");
446         return DLP_PARSE_ERROR_VALUE_INVALID;
447     }
448 
449     struct DlpOpensslAesCtx* contex = static_cast<struct DlpOpensslAesCtx*>(cryptoCtx);
450     uint32_t mode = contex->mode;
451 
452     int32_t ret;
453     switch (mode) {
454         case DLP_MODE_CTR:
455             ret = OpensslAesCipherEncryptUpdate(cryptoCtx, message, cipherText);
456             if (ret != DLP_OK) {
457                 DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, errno=%{public}d", ret);
458                 return ret;
459             }
460             break;
461         default:
462             DLP_LOG_ERROR(LABEL, "Aes encrypt update fail, aes mode 0x%{public}x unsupport", mode);
463             return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
464     }
465 
466     return DLP_OK;
467 }
468 
DlpOpensslAesEncryptFinal(void ** cryptoCtx,const struct DlpBlob * message,struct DlpBlob * cipherText)469 int32_t DlpOpensslAesEncryptFinal(void** cryptoCtx, const struct DlpBlob* message, struct DlpBlob* cipherText)
470 {
471     if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
472         DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, ctx is null");
473         return DLP_PARSE_ERROR_VALUE_INVALID;
474     }
475     if (!DlpOpensslCheckBlobZero(message)) {
476         DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, msg is invalid");
477         return DLP_PARSE_ERROR_VALUE_INVALID;
478     }
479     if (!DlpOpensslCheckBlob(cipherText)) {
480         DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, cipher text is invalid");
481         return DLP_PARSE_ERROR_VALUE_INVALID;
482     }
483 
484     struct DlpOpensslAesCtx* contex = (struct DlpOpensslAesCtx*)*cryptoCtx;
485     uint32_t mode = contex->mode;
486 
487     int32_t ret;
488     switch (mode) {
489         case DLP_MODE_CTR:
490             ret = OpensslAesCipherEncryptFinalThree(cryptoCtx, message, cipherText);
491             if (ret != DLP_OK) {
492                 DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, errno=%{public}d", ret);
493                 return ret;
494             }
495             break;
496         default:
497             DLP_LOG_ERROR(LABEL, "Aes encrypt final fail, aes mode 0x%{public}x unsupport", mode);
498             return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
499     }
500 
501     return DLP_OK;
502 }
503 
DlpOpensslAesDecryptInit(void ** cryptoCtx,const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec)504 int32_t DlpOpensslAesDecryptInit(void** cryptoCtx, const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec)
505 {
506     if (cryptoCtx == nullptr) {
507         DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, ctx is null");
508         return DLP_PARSE_ERROR_VALUE_INVALID;
509     }
510     if (usageSpec == nullptr) {
511         DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, usage spec is null");
512         return DLP_PARSE_ERROR_VALUE_INVALID;
513     }
514     if (!DlpOpensslCheckBlob(key)) {
515         DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, key is invalid");
516         return DLP_PARSE_ERROR_VALUE_INVALID;
517     }
518 
519     int32_t ret;
520     switch (usageSpec->mode) {
521         case DLP_MODE_CTR:
522             ret = OpensslAesCipherCryptInit(key, usageSpec, false, cryptoCtx);
523             if (ret != DLP_OK) {
524                 DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, errno=%{public}d", ret);
525                 return ret;
526             }
527             break;
528         default:
529             DLP_LOG_ERROR(LABEL, "Aes decrypt init fail, aes mode 0x%{public}x unsupport", usageSpec->mode);
530             return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
531     }
532 
533     return ret;
534 }
535 
DlpOpensslAesDecryptUpdate(void * cryptoCtx,const struct DlpBlob * message,struct DlpBlob * plainText)536 int32_t DlpOpensslAesDecryptUpdate(void* cryptoCtx, const struct DlpBlob* message, struct DlpBlob* plainText)
537 {
538     if (cryptoCtx == nullptr) {
539         DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, ctx is null");
540         return DLP_PARSE_ERROR_VALUE_INVALID;
541     }
542     if (!DlpOpensslCheckBlobZero(message)) {
543         DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, msg is invalid");
544         return DLP_PARSE_ERROR_VALUE_INVALID;
545     }
546     if (!DlpOpensslCheckBlob(plainText)) {
547         DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, plain text is invalid");
548         return DLP_PARSE_ERROR_VALUE_INVALID;
549     }
550 
551     struct DlpOpensslAesCtx* contex = static_cast<struct DlpOpensslAesCtx*>(cryptoCtx);
552     uint32_t mode = contex->mode;
553 
554     int32_t ret;
555     switch (mode) {
556         case DLP_MODE_CTR:
557             ret = OpensslAesCipherDecryptUpdate(cryptoCtx, message, plainText);
558             if (ret != DLP_OK) {
559                 DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, errno=%{public}d", ret);
560                 return ret;
561             }
562             break;
563         default:
564             DLP_LOG_ERROR(LABEL, "Aes decrypt update fail, aes mode 0x%{public}x unsupport", mode);
565             return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
566     }
567 
568     return ret;
569 }
570 
DlpOpensslAesDecryptFinal(void ** cryptoCtx,const struct DlpBlob * message,struct DlpBlob * plainText)571 int32_t DlpOpensslAesDecryptFinal(void** cryptoCtx, const struct DlpBlob* message, struct DlpBlob* plainText)
572 {
573     if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
574         DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, ctx is null");
575         return DLP_PARSE_ERROR_VALUE_INVALID;
576     }
577     if (!DlpOpensslCheckBlobZero(message)) {
578         DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, msg is invalid");
579         return DLP_PARSE_ERROR_VALUE_INVALID;
580     }
581     if (!DlpOpensslCheckBlob(plainText)) {
582         DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, plain text is invalid");
583         return DLP_PARSE_ERROR_VALUE_INVALID;
584     }
585 
586     struct DlpOpensslAesCtx* contex = (struct DlpOpensslAesCtx*)*cryptoCtx;
587     uint32_t mode = contex->mode;
588 
589     int32_t ret;
590     switch (mode) {
591         case DLP_MODE_CTR:
592             ret = OpensslAesCipherDecryptFinalThree(cryptoCtx, message, plainText);
593             if (ret != DLP_OK) {
594                 DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, errno=%{public}d", ret);
595                 return ret;
596             }
597             break;
598         default:
599             DLP_LOG_ERROR(LABEL, "Aes decrypt final fail, aes mode 0x%{public}x unsupport", mode);
600             return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
601     }
602 
603     return DLP_OK;
604 }
605 
DlpOpensslAesHalFreeCtx(void ** cryptoCtx)606 void DlpOpensslAesHalFreeCtx(void** cryptoCtx)
607 {
608     if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
609         DLP_LOG_ERROR(LABEL, "Aes free ctx fail, cxt is null");
610         return;
611     }
612 
613     struct DlpOpensslAesCtx* opensslAesCtx = (struct DlpOpensslAesCtx*)*cryptoCtx;
614     switch (opensslAesCtx->mode) {
615         case DLP_MODE_CTR:
616             if (reinterpret_cast<EVP_CIPHER_CTX*>(opensslAesCtx->append) != nullptr) {
617                 EVP_CIPHER_CTX_free(reinterpret_cast<EVP_CIPHER_CTX*>(opensslAesCtx->append));
618                 opensslAesCtx->append = nullptr;
619             }
620             break;
621 
622         default:
623             DLP_LOG_ERROR(LABEL, "Aes free ctx fail, aes mode 0x%{public}x unsupport", opensslAesCtx->mode);
624             break;
625     }
626 
627     DLP_FREE_PTR(*cryptoCtx);
628 }
629 
AesParamCheck(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const struct DlpBlob * message,struct DlpBlob * cipherText)630 static bool AesParamCheck(const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec,
631     const struct DlpBlob* message, struct DlpBlob* cipherText)
632 {
633     if (usageSpec == nullptr) {
634         DLP_LOG_ERROR(LABEL, "Check aes params fail, usage spec is null");
635         return false;
636     }
637 
638     if (!DlpOpensslCheckBlob(key)) {
639         DLP_LOG_ERROR(LABEL, "Check aes params fail, key is invalid");
640         return false;
641     }
642 
643     if (!DlpOpensslCheckBlob(message)) {
644         DLP_LOG_ERROR(LABEL, "Check aes params fail, msg in invalid");
645         return false;
646     }
647 
648     if (!DlpOpensslCheckBlob(cipherText)) {
649         DLP_LOG_ERROR(LABEL, "Check aes params fail, cipher text is invalid");
650         return false;
651     }
652 
653     return true;
654 }
655 
DlpOpensslAesEncrypt(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const struct DlpBlob * message,struct DlpBlob * cipherText)656 int32_t DlpOpensslAesEncrypt(const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec,
657     const struct DlpBlob* message, struct DlpBlob* cipherText)
658 {
659     if (!AesParamCheck(key, usageSpec, message, cipherText)) {
660         DLP_LOG_ERROR(LABEL, "Aes encrypt fail, check aes params error");
661         return DLP_PARSE_ERROR_VALUE_INVALID;
662     }
663 
664     EVP_CIPHER_CTX* ctx = nullptr;
665     struct DlpBlob tmpCipherText = *cipherText;
666 
667     int32_t ret;
668     switch (usageSpec->mode) {
669         case DLP_MODE_CTR:
670             ret = OpensslAesCipherInit(key, usageSpec, true, &ctx);
671             if (ret != DLP_OK) {
672                 DLP_LOG_ERROR(LABEL, "Aes encrypt fail, encrypt init error, errno=%{public}d", ret);
673                 return ret;
674             }
675 
676             ret = OpensslAesCipherEncryptFinal(ctx, message, &tmpCipherText);
677             if (ret != DLP_OK) {
678                 DLP_LOG_ERROR(LABEL, "Aes encrypt fail, encrypt final error, errno=%{public}d", ret);
679                 return ret;
680             }
681             break;
682 
683         default:
684             DLP_LOG_ERROR(LABEL, "Aes encrypt fail, aes mode 0x%{public}x unsupport", usageSpec->mode);
685             return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
686     }
687 
688     cipherText->size = tmpCipherText.size;
689     return DLP_OK;
690 }
691 
DlpOpensslAesDecrypt(const struct DlpBlob * key,const struct DlpUsageSpec * usageSpec,const struct DlpBlob * message,struct DlpBlob * plainText)692 int32_t DlpOpensslAesDecrypt(const struct DlpBlob* key, const struct DlpUsageSpec* usageSpec,
693     const struct DlpBlob* message, struct DlpBlob* plainText)
694 {
695     if (!AesParamCheck(key, usageSpec, message, plainText)) {
696         DLP_LOG_ERROR(LABEL, "Aes decrypt fail, check aes params error");
697         return DLP_PARSE_ERROR_VALUE_INVALID;
698     }
699     EVP_CIPHER_CTX* ctx = nullptr;
700     struct DlpBlob tmpPlainText = *plainText;
701 
702     int32_t ret;
703     switch (usageSpec->mode) {
704         case DLP_MODE_CTR:
705             ret = OpensslAesCipherInit(key, usageSpec, false, &ctx);
706             if (ret != DLP_OK) {
707                 DLP_LOG_ERROR(LABEL, "Aes decrypt fail, decrypt init error, errno=%{public}d", ret);
708                 return ret;
709             }
710 
711             ret = OpensslAesCipherDecryptFinal(ctx, message, &tmpPlainText);
712             if (ret != DLP_OK) {
713                 DLP_LOG_ERROR(LABEL, "Aes decrypt fail, decrypt final error, errno=%{public}d", ret);
714                 return ret;
715             }
716             break;
717         default:
718             DLP_LOG_ERROR(LABEL, "Aes decrypt fail, aes mode 0x%{public}x unsupport", usageSpec->mode);
719             return DLP_PARSE_ERROR_OPERATION_UNSUPPORTED;
720     }
721 
722     plainText->size = tmpPlainText.size;
723     return ret;
724 }
725 
CheckDigestAlg(uint32_t alg)726 static bool CheckDigestAlg(uint32_t alg)
727 {
728     switch (alg) {
729         case DLP_DIGEST_SHA256:
730         case DLP_DIGEST_SHA384:
731         case DLP_DIGEST_SHA512:
732             return true;
733         default:
734             return false;
735     }
736 }
737 
GetOpensslAlg(uint32_t alg)738 const EVP_MD* GetOpensslAlg(uint32_t alg)
739 {
740     switch (alg) {
741         case DLP_DIGEST_SHA256:
742             return EVP_sha256();
743         case DLP_DIGEST_SHA384:
744             return EVP_sha384();
745         case DLP_DIGEST_SHA512:
746             return EVP_sha512();
747         default:
748             return nullptr;
749     }
750 }
751 
GetHashLen(uint32_t alg)752 static uint32_t GetHashLen(uint32_t alg)
753 {
754     if (alg == DLP_DIGEST_SHA256) {
755         return SHA256_LEN;
756     } else if (alg == DLP_DIGEST_SHA384) {
757         return SHA384_LEN;
758     } else {
759         return SHA512_LEN;
760     }
761 }
762 
HashCheckParam(uint32_t alg,const struct DlpBlob * msg,struct DlpBlob * hash)763 static bool HashCheckParam(uint32_t alg, const struct DlpBlob* msg, struct DlpBlob* hash)
764 {
765     if (!CheckDigestAlg(alg)) {
766         DLP_LOG_ERROR(LABEL, "Check hash param fail, alg type is unsupported");
767         return false;
768     }
769 
770     if (!DlpOpensslCheckBlob(hash)) {
771         DLP_LOG_ERROR(LABEL, "Check hash param fail, hash is invalid");
772         return false;
773     }
774 
775     uint32_t hashLen = GetHashLen(alg);
776     if (hash->size < hashLen) {
777         DLP_LOG_ERROR(LABEL, "Check hash param fail, hash buff too short");
778         return false;
779     }
780 
781     if (!DlpOpensslCheckBlob(msg)) {
782         DLP_LOG_ERROR(LABEL, "Check hash param fail, msg is invalid");
783         return false;
784     }
785 
786     return true;
787 }
788 
DlpOpensslHash(uint32_t alg,const struct DlpBlob * msg,struct DlpBlob * hash)789 int32_t DlpOpensslHash(uint32_t alg, const struct DlpBlob* msg, struct DlpBlob* hash)
790 {
791     if (!HashCheckParam(alg, msg, hash)) {
792         DLP_LOG_ERROR(LABEL, "Openssl hash fail, param is invalid");
793         return DLP_PARSE_ERROR_VALUE_INVALID;
794     }
795 
796     const EVP_MD* opensslAlg = GetOpensslAlg(alg);
797     if (opensslAlg == nullptr) {
798         DLP_LOG_ERROR(LABEL, "Openssl hash fail, get alg fail");
799         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
800     }
801 
802     int32_t ret = EVP_Digest(msg->data, msg->size, hash->data, &hash->size, opensslAlg, nullptr);
803     if (ret != DLP_OPENSSL_SUCCESS) {
804         DlpLogOpensslError();
805         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
806     }
807     return DLP_OK;
808 }
809 
DlpOpensslHashInit(void ** cryptoCtx,uint32_t alg)810 int32_t DlpOpensslHashInit(void** cryptoCtx, uint32_t alg)
811 {
812     if (cryptoCtx == nullptr) {
813         DLP_LOG_ERROR(LABEL, "Openssl hash init fail, ctx is null");
814         return DLP_PARSE_ERROR_DIGEST_INVALID;
815     }
816     if (!CheckDigestAlg(alg)) {
817         DLP_LOG_ERROR(LABEL, "Openssl hash init fail, alg is invalid");
818         return DLP_PARSE_ERROR_DIGEST_INVALID;
819     }
820     const EVP_MD* opensslAlg = GetOpensslAlg(alg);
821     if (opensslAlg == nullptr) {
822         DLP_LOG_ERROR(LABEL, "Openssl hash init fail, get alg fail");
823         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
824     }
825     EVP_MD_CTX* tmpctx = EVP_MD_CTX_new();
826     if (tmpctx == nullptr) {
827         DLP_LOG_ERROR(LABEL, "Openssl hash init fail, alloc ctx fail");
828         return DLP_PARSE_ERROR_VALUE_INVALID;
829     }
830 
831     EVP_MD_CTX_set_flags(tmpctx, EVP_MD_CTX_FLAG_ONESHOT);
832     int32_t ret = EVP_DigestInit_ex(tmpctx, opensslAlg, nullptr);
833     if (ret != DLP_OPENSSL_SUCCESS) {
834         DlpLogOpensslError();
835         EVP_MD_CTX_free(tmpctx);
836         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
837     }
838     *cryptoCtx = static_cast<void*>(tmpctx);
839     return DLP_OK;
840 }
841 
DlpOpensslHashUpdate(void * cryptoCtx,const struct DlpBlob * msg)842 int32_t DlpOpensslHashUpdate(void* cryptoCtx, const struct DlpBlob* msg)
843 {
844     if (cryptoCtx == nullptr) {
845         DLP_LOG_ERROR(LABEL, "Openssl hash update fail, ctx is null");
846         return DLP_PARSE_ERROR_VALUE_INVALID;
847     }
848     if (!DlpOpensslCheckBlob(msg)) {
849         DLP_LOG_ERROR(LABEL, "Openssl hash update fail, msg is invalid");
850         return DLP_PARSE_ERROR_VALUE_INVALID;
851     }
852 
853     int32_t ret = EVP_DigestUpdate(
854         reinterpret_cast<EVP_MD_CTX*>(cryptoCtx), reinterpret_cast<void*>(msg->data), msg->size);
855     if (ret != DLP_OPENSSL_SUCCESS) {
856         DlpLogOpensslError();
857         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
858     }
859     return DLP_OK;
860 }
861 
DlpOpensslHashFinal(void ** cryptoCtx,const struct DlpBlob * msg,struct DlpBlob * hash)862 int32_t DlpOpensslHashFinal(void** cryptoCtx, const struct DlpBlob* msg, struct DlpBlob* hash)
863 {
864     if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
865         DLP_LOG_ERROR(LABEL, "Openssl hash final fail, ctx is null");
866         return DLP_PARSE_ERROR_VALUE_INVALID;
867     }
868     if (!DlpOpensslCheckBlobZero(msg)) {
869         DLP_LOG_ERROR(LABEL, "Openssl hash final fail, msg is invalid");
870         return DLP_PARSE_ERROR_VALUE_INVALID;
871     }
872     if (!DlpOpensslCheckBlob(hash)) {
873         DLP_LOG_ERROR(LABEL, "Openssl hash final fail, hash is invalid");
874         return DLP_PARSE_ERROR_VALUE_INVALID;
875     }
876 
877     int32_t ret;
878     if (msg->size != 0) {
879         ret = EVP_DigestUpdate((EVP_MD_CTX*)*cryptoCtx, msg->data, msg->size);
880         if (ret != DLP_OPENSSL_SUCCESS) {
881             DlpLogOpensslError();
882             EVP_MD_CTX_free((EVP_MD_CTX*)*cryptoCtx);
883             *cryptoCtx = nullptr;
884             return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
885         }
886     }
887 
888     ret = EVP_DigestFinal_ex((EVP_MD_CTX*)*cryptoCtx, hash->data, &hash->size);
889     if (ret != DLP_OPENSSL_SUCCESS) {
890         DlpLogOpensslError();
891         EVP_MD_CTX_free((EVP_MD_CTX*)*cryptoCtx);
892         *cryptoCtx = nullptr;
893         return DLP_PARSE_ERROR_CRYPTO_ENGINE_ERROR;
894     }
895 
896     EVP_MD_CTX_free((EVP_MD_CTX*)*cryptoCtx);
897     *cryptoCtx = nullptr;
898     return DLP_OK;
899 }
900 
DlpOpensslHashFreeCtx(void ** cryptoCtx)901 int32_t DlpOpensslHashFreeCtx(void** cryptoCtx)
902 {
903     if (cryptoCtx == nullptr || *cryptoCtx == nullptr) {
904         DLP_LOG_ERROR(LABEL, "Openssl hash free ctx fail, param is invalid");
905         return DLP_PARSE_ERROR_VALUE_INVALID;
906     }
907     EVP_MD_CTX_free((EVP_MD_CTX*)*cryptoCtx);
908     *cryptoCtx = nullptr;
909     return DLP_OK;
910 }
911 
IncIvCounterLitteEndian(struct DlpBlob & iv,uint32_t count)912 static void IncIvCounterLitteEndian(struct DlpBlob& iv, uint32_t count)
913 {
914     uint8_t* data = iv.data;
915     int size = static_cast<int>(iv.size - 1);
916     for (int i = size; i >= 0; i--) {
917         count += data[i];
918         data[i] = static_cast<uint8_t>(count);
919         count >>= BYTE_LEN;
920         if (count == 0) {
921             break;
922         }
923     }
924 }
925 
DlpCtrModeIncreaeIvCounter(struct DlpBlob & iv,uint32_t count)926 int32_t DlpCtrModeIncreaeIvCounter(struct DlpBlob& iv, uint32_t count)
927 {
928     if (iv.data == nullptr || iv.size == 0) {
929         DLP_LOG_ERROR(LABEL, "param error");
930         return DLP_PARSE_ERROR_VALUE_INVALID;
931     }
932 
933     IncIvCounterLitteEndian(iv, count);
934     return DLP_OK;
935 }
936 #ifdef __cplusplus
937 }
938 #endif
939