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