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