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