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