1 /*
2 * Copyright (C) 2022-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 "adaptor_algorithm.h"
17 #include <openssl/evp.h>
18 #include <openssl/hmac.h>
19 #include <openssl/rand.h>
20 #include <openssl/kdf.h>
21 #include <openssl/sha.h>
22 #include "securec.h"
23 #include "adaptor_log.h"
24 #include "adaptor_memory.h"
25 #include "buffer.h"
26 #include "defines.h"
27
28 #define OPENSSL_SUCCESS 1
29
30 #define ED25519_FIX_PRIKEY_BUFFER_SIZE 32
31
32 #define SHA512_DIGEST_SIZE 64
33 #define NO_PADDING 0
34
CreateEd25519KeyPair(void)35 static KeyPair *CreateEd25519KeyPair(void)
36 {
37 KeyPair *keyPair = Malloc(sizeof(KeyPair));
38 if (keyPair == NULL) {
39 LOG_ERROR("no memory for key pair");
40 return NULL;
41 }
42 keyPair->pubKey = CreateBufferBySize(ED25519_FIX_PUBKEY_BUFFER_SIZE);
43 if (keyPair->pubKey == NULL) {
44 LOG_ERROR("no memory for pub key");
45 Free(keyPair);
46 return NULL;
47 }
48 keyPair->priKey = CreateBufferBySize(ED25519_FIX_PRIKEY_BUFFER_SIZE);
49 if (keyPair->priKey == NULL) {
50 LOG_ERROR("no memory for pri key");
51 DestroyBuffer(keyPair->pubKey);
52 Free(keyPair);
53 return NULL;
54 }
55 return keyPair;
56 }
57
DestroyKeyPair(KeyPair * keyPair)58 void DestroyKeyPair(KeyPair *keyPair)
59 {
60 if (keyPair == NULL) {
61 return;
62 }
63 if (keyPair->pubKey != NULL) {
64 DestroyBuffer(keyPair->pubKey);
65 }
66 if (keyPair->priKey != NULL) {
67 DestroyBuffer(keyPair->priKey);
68 }
69 Free(keyPair);
70 }
71
IsEd25519KeyPairValid(const KeyPair * keyPair)72 bool IsEd25519KeyPairValid(const KeyPair *keyPair)
73 {
74 if (keyPair == NULL) {
75 LOG_ERROR("invalid key pair");
76 return false;
77 }
78 if (!CheckBufferWithSize(keyPair->pubKey, ED25519_FIX_PUBKEY_BUFFER_SIZE)) {
79 LOG_ERROR("invalid pub key");
80 return false;
81 }
82 if (!CheckBufferWithSize(keyPair->priKey, ED25519_FIX_PRIKEY_BUFFER_SIZE)) {
83 LOG_ERROR("invalid pri key");
84 return false;
85 }
86 return true;
87 }
88
GenerateEd25519KeyPair(void)89 KeyPair *GenerateEd25519KeyPair(void)
90 {
91 KeyPair *keyPair = CreateEd25519KeyPair();
92 if (keyPair == NULL) {
93 LOG_ERROR("create key pair fail");
94 return NULL;
95 }
96 EVP_PKEY *key = NULL;
97 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
98 if (ctx == NULL) {
99 LOG_ERROR("new ctx fail");
100 goto ERROR;
101 }
102 if (EVP_PKEY_keygen_init(ctx) != OPENSSL_SUCCESS) {
103 LOG_ERROR("init ctx fail");
104 goto ERROR;
105 }
106 if (EVP_PKEY_keygen(ctx, &key) != OPENSSL_SUCCESS) {
107 LOG_ERROR("generate key fail");
108 goto ERROR;
109 }
110 size_t pubKeySize = keyPair->pubKey->maxSize;
111 if (EVP_PKEY_get_raw_public_key(key, keyPair->pubKey->buf, &pubKeySize) != OPENSSL_SUCCESS) {
112 LOG_ERROR("get pub key fail");
113 goto ERROR;
114 }
115 keyPair->pubKey->contentSize = pubKeySize;
116 size_t priKeySize = keyPair->priKey->maxSize;
117 if (EVP_PKEY_get_raw_private_key(key, keyPair->priKey->buf, &priKeySize) != OPENSSL_SUCCESS) {
118 LOG_ERROR("get pri key fail");
119 goto ERROR;
120 }
121 keyPair->priKey->contentSize = priKeySize;
122 goto EXIT;
123
124 ERROR:
125 DestroyKeyPair(keyPair);
126 keyPair = NULL;
127 EXIT:
128 if (key != NULL) {
129 EVP_PKEY_free(key);
130 }
131 if (ctx != NULL) {
132 EVP_PKEY_CTX_free(ctx);
133 }
134 return keyPair;
135 }
136
Ed25519Sign(const KeyPair * keyPair,const Buffer * data,Buffer ** sign)137 int32_t Ed25519Sign(const KeyPair *keyPair, const Buffer *data, Buffer **sign)
138 {
139 if (!IsEd25519KeyPairValid(keyPair) || !IsBufferValid(data) || sign == NULL) {
140 LOG_ERROR("bad param");
141 return RESULT_BAD_PARAM;
142 }
143 int32_t ret = RESULT_GENERAL_ERROR;
144 EVP_PKEY *key = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL,
145 keyPair->priKey->buf, keyPair->priKey->contentSize);
146 if (key == NULL) {
147 LOG_ERROR("get pri key fail");
148 return ret;
149 }
150 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
151 if (ctx == NULL) {
152 LOG_ERROR("get ctx fail");
153 EVP_PKEY_free(key);
154 return ret;
155 }
156 if (EVP_DigestSignInit(ctx, NULL, NULL, NULL, key) != OPENSSL_SUCCESS) {
157 LOG_ERROR("init sign fail");
158 goto EXIT;
159 }
160 *sign = CreateBufferBySize(ED25519_FIX_SIGN_BUFFER_SIZE);
161 if (!IsBufferValid(*sign)) {
162 LOG_ERROR("create buffer fail");
163 goto EXIT;
164 }
165 size_t signSize = (*sign)->maxSize;
166 if (EVP_DigestSign(ctx, (*sign)->buf, &signSize, data->buf, data->contentSize) != OPENSSL_SUCCESS) {
167 LOG_ERROR("sign fail");
168 DestroyBuffer(*sign);
169 *sign = NULL;
170 goto EXIT;
171 }
172 (*sign)->contentSize = signSize;
173 ret = RESULT_SUCCESS;
174
175 EXIT:
176 EVP_PKEY_free(key);
177 EVP_MD_CTX_free(ctx);
178 return ret;
179 }
180
Ed25519Verify(const Buffer * pubKey,const Buffer * data,const Buffer * sign)181 int32_t Ed25519Verify(const Buffer *pubKey, const Buffer *data, const Buffer *sign)
182 {
183 if (!CheckBufferWithSize(pubKey, ED25519_FIX_PUBKEY_BUFFER_SIZE) || !IsBufferValid(data) ||
184 !CheckBufferWithSize(sign, ED25519_FIX_SIGN_BUFFER_SIZE)) {
185 LOG_ERROR("bad param");
186 return RESULT_BAD_PARAM;
187 }
188 int32_t ret = RESULT_GENERAL_ERROR;
189 EVP_PKEY *key = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, pubKey->buf, pubKey->contentSize);
190 if (key == NULL) {
191 LOG_ERROR("get pub key fail");
192 return ret;
193 }
194 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
195 if (ctx == NULL) {
196 LOG_ERROR("get ctx fail");
197 EVP_PKEY_free(key);
198 return ret;
199 }
200 if (EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, key) != OPENSSL_SUCCESS) {
201 LOG_ERROR("init verify fail");
202 goto EXIT;
203 }
204 if (EVP_DigestVerify(ctx, sign->buf, sign->contentSize, data->buf, data->contentSize) != OPENSSL_SUCCESS) {
205 LOG_ERROR("verify fail");
206 goto EXIT;
207 }
208 ret = RESULT_SUCCESS;
209
210 EXIT:
211 EVP_PKEY_free(key);
212 EVP_MD_CTX_free(ctx);
213 return ret;
214 }
215
IamHmac(const EVP_MD * alg,const Buffer * hmacKey,const Buffer * data,Buffer * hmac)216 static int32_t IamHmac(const EVP_MD *alg,
217 const Buffer *hmacKey, const Buffer *data, Buffer *hmac)
218 {
219 if (!IsBufferValid(hmacKey) || hmacKey->contentSize > INT_MAX ||
220 !IsBufferValid(data) || !IsBufferValid(hmac) || hmac->maxSize > UINT_MAX) {
221 LOG_ERROR("bad param");
222 return RESULT_BAD_PARAM;
223 }
224 unsigned int hmacSize = hmac->maxSize;
225 uint8_t *hmacData = HMAC(alg, hmacKey->buf, (int)hmacKey->contentSize, data->buf, data->contentSize,
226 hmac->buf, &hmacSize);
227 if (hmacData == NULL) {
228 LOG_ERROR("hmac fail");
229 return RESULT_GENERAL_ERROR;
230 }
231 hmac->contentSize = hmacSize;
232 return RESULT_SUCCESS;
233 }
234
HmacSha256(const Buffer * hmacKey,const Buffer * data,Buffer ** hmac)235 int32_t HmacSha256(const Buffer *hmacKey, const Buffer *data, Buffer **hmac)
236 {
237 const EVP_MD *alg = EVP_sha256();
238 if (alg == NULL) {
239 LOG_ERROR("no algo");
240 return RESULT_GENERAL_ERROR;
241 }
242 *hmac = CreateBufferBySize(SHA256_DIGEST_SIZE);
243 if (*hmac == NULL) {
244 LOG_ERROR("create buffer fail");
245 return RESULT_NO_MEMORY;
246 }
247 if (IamHmac(alg, hmacKey, data, *hmac) != RESULT_SUCCESS) {
248 DestroyBuffer(*hmac);
249 *hmac = NULL;
250 LOG_ERROR("hmac fail");
251 return RESULT_GENERAL_ERROR;
252 }
253 return RESULT_SUCCESS;
254 }
255
HmacSha512(const Buffer * hmacKey,const Buffer * data,Buffer ** hmac)256 int32_t HmacSha512(const Buffer *hmacKey, const Buffer *data, Buffer **hmac)
257 {
258 const EVP_MD *alg = EVP_sha512();
259 if (alg == NULL) {
260 LOG_ERROR("no algo");
261 return RESULT_GENERAL_ERROR;
262 }
263 *hmac = CreateBufferBySize(SHA512_DIGEST_SIZE);
264 if (*hmac == NULL) {
265 LOG_ERROR("create buffer fail");
266 return RESULT_NO_MEMORY;
267 }
268 if (IamHmac(alg, hmacKey, data, *hmac) != RESULT_SUCCESS) {
269 DestroyBuffer(*hmac);
270 *hmac = NULL;
271 LOG_ERROR("hmac fail");
272 return RESULT_GENERAL_ERROR;
273 }
274 return RESULT_SUCCESS;
275 }
276
SecureRandom(uint8_t * buffer,uint32_t size)277 int32_t SecureRandom(uint8_t *buffer, uint32_t size)
278 {
279 if (buffer == NULL || size > INT_MAX) {
280 LOG_ERROR("bad param");
281 return RESULT_BAD_PARAM;
282 }
283 if (RAND_bytes(buffer, (int)size) != OPENSSL_SUCCESS) {
284 LOG_ERROR("rand fail");
285 return RESULT_GENERAL_ERROR;
286 }
287 return RESULT_SUCCESS;
288 }
289
290 // Here is the piling code. The real implementation needs to call the security interface.
DeriveDeviceKey(const Buffer * pinData,const Buffer * secret)291 Buffer *DeriveDeviceKey(const Buffer *pinData, const Buffer *secret)
292 {
293 if (!IsBufferValid(secret) || secret->contentSize != SECRET_SIZE || !IsBufferValid(pinData)) {
294 LOG_ERROR("bad param");
295 return NULL;
296 }
297 return CopyBuffer(secret);
298 }
299
Hkdf(const Buffer * salt,const Buffer * rootKey)300 Buffer *Hkdf(const Buffer *salt, const Buffer *rootKey)
301 {
302 if (!IsBufferValid(salt) || salt->contentSize != HKDF_SALT_SIZE ||
303 !IsBufferValid(rootKey) || rootKey->contentSize != HKDF_KEY_SIZE) {
304 LOG_ERROR("bad param");
305 return NULL;
306 }
307 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
308 if (ctx == NULL) {
309 LOG_ERROR("pctx is null");
310 return NULL;
311 }
312 Buffer *key = CreateBufferBySize(SHA256_DIGEST_SIZE);
313 if (!IsBufferValid(key)) {
314 LOG_ERROR("failed to create buffer");
315 EVP_PKEY_CTX_free(ctx);
316 return NULL;
317 }
318 size_t outLen = SHA256_DIGEST_SIZE;
319 if (EVP_PKEY_derive_init(ctx) != OPENSSL_SUCCESS ||
320 EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_sha256()) != OPENSSL_SUCCESS ||
321 EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt->buf, salt->contentSize) != OPENSSL_SUCCESS ||
322 EVP_PKEY_CTX_set1_hkdf_key(ctx, rootKey->buf, rootKey->contentSize) != OPENSSL_SUCCESS ||
323 EVP_PKEY_derive(ctx, key->buf, &outLen) != OPENSSL_SUCCESS ||
324 outLen > key->maxSize) {
325 LOG_ERROR("failed to call algorithm interface");
326 DestroyBuffer(key);
327 EVP_PKEY_CTX_free(ctx);
328 return NULL;
329 }
330 key->contentSize = outLen;
331 EVP_PKEY_CTX_free(ctx);
332 return key;
333 }
334
Sha256Adaptor(const Buffer * data)335 Buffer *Sha256Adaptor(const Buffer *data)
336 {
337 if (!IsBufferValid(data)) {
338 LOG_ERROR("bad param");
339 return NULL;
340 }
341 Buffer *result = CreateBufferBySize(SHA256_DIGEST_SIZE);
342 if (!IsBufferValid(result)) {
343 LOG_ERROR("failed to create buffer");
344 return NULL;
345 }
346 if (SHA256(data->buf, data->contentSize, result->buf) != result->buf) {
347 LOG_ERROR("failed to do sha256");
348 DestroyBuffer(result);
349 return NULL;
350 }
351 result->contentSize = SHA256_DIGEST_SIZE;
352 return result;
353 }
354
355 #define REMOTE_PIN_DISTRIBUTE_DEVICE_KEY "REMOTE_PIN_DISTRIBUTE_DEVICE_KEY"
356 #define REMOTE_PIN_DISTRIBUTE_DEVICE_KEY_SIZE 32
357
358 /* This is for example only, distribute key should be distributed in trusted environment between devices. */
GetDistributeKey(const Buffer * peerUdid,const Buffer * salt,Buffer ** key)359 int32_t GetDistributeKey(const Buffer *peerUdid, const Buffer *salt, Buffer **key)
360 {
361 if (!IsBufferValid(peerUdid) || !IsBufferValid(salt) || (key == NULL)) {
362 LOG_ERROR("bad param");
363 return RESULT_BAD_PARAM;
364 }
365 Buffer *keyData = CreateBufferBySize(salt->contentSize + REMOTE_PIN_DISTRIBUTE_DEVICE_KEY_SIZE);
366 if (keyData == NULL) {
367 LOG_ERROR("CreateBufferBySize keyData fail");
368 return RESULT_NO_MEMORY;
369 }
370 if (memcpy_s(keyData->buf, keyData->maxSize,
371 REMOTE_PIN_DISTRIBUTE_DEVICE_KEY, REMOTE_PIN_DISTRIBUTE_DEVICE_KEY_SIZE) != EOK) {
372 LOG_ERROR("copy fix tag fail");
373 DestroyBuffer(keyData);
374 return RESULT_NO_MEMORY;
375 }
376 keyData->contentSize += REMOTE_PIN_DISTRIBUTE_DEVICE_KEY_SIZE;
377 if (memcpy_s(keyData->buf + keyData->contentSize,
378 keyData->maxSize - keyData->contentSize, salt->buf, salt->contentSize) != EOK) {
379 LOG_ERROR("copy salt fail");
380 DestroyBuffer(keyData);
381 return RESULT_NO_MEMORY;
382 }
383 keyData->contentSize += salt->contentSize;
384 *key = Sha256Adaptor(keyData);
385 DestroyBuffer(keyData);
386 if (*key == NULL) {
387 LOG_ERROR("calculate key fail");
388 return RESULT_NO_MEMORY;
389 }
390 return RESULT_SUCCESS;
391 }
392
CheckAes256GcmParams(const AesGcmParam * param)393 static bool CheckAes256GcmParams(const AesGcmParam *param)
394 {
395 if (param == NULL) {
396 LOG_ERROR("get null AesGcmParam");
397 return false;
398 }
399 if (!CheckBufferWithSize(param->key, AES_GCM_256_KEY_SIZE)) {
400 LOG_ERROR("invalid key");
401 return false;
402 }
403 if (!CheckBufferWithSize(param->iv, AES_GCM_256_IV_SIZE)) {
404 LOG_ERROR("invalid iv");
405 return false;
406 }
407 if (param->aad == NULL) {
408 LOG_INFO("get null aad");
409 return true;
410 }
411 if (!IsBufferValid(param->aad)) {
412 LOG_ERROR("invalid aad");
413 return false;
414 }
415 if ((param->aad->contentSize == 0) || (param->aad->contentSize > AES_GCM_256_AAD_MAX_SIZE)) {
416 LOG_ERROR("invalid aad size");
417 return false;
418 }
419 return true;
420 }
421
SetAesEncryptParam(EVP_CIPHER_CTX * ctx,const AesGcmParam * param)422 static bool SetAesEncryptParam(EVP_CIPHER_CTX *ctx, const AesGcmParam *param)
423 {
424 if (EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, param->key->buf, NULL) != OPENSSL_SUCCESS) {
425 LOG_ERROR("EVP_EncryptInit_ex fail");
426 return false;
427 }
428 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, param->iv->contentSize, NULL) != OPENSSL_SUCCESS) {
429 LOG_ERROR("failed to set iv len");
430 return false;
431 }
432 if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, param->iv->buf) != OPENSSL_SUCCESS) {
433 LOG_ERROR("failed to init iv");
434 return false;
435 }
436 if (EVP_CIPHER_CTX_set_padding(ctx, NO_PADDING) != OPENSSL_SUCCESS) {
437 LOG_ERROR("set padding fail");
438 return false;
439 }
440 int outLen = 0;
441 if ((param->aad != NULL) &&
442 (EVP_EncryptUpdate(ctx, NULL, &outLen, param->aad->buf, param->aad->contentSize) != OPENSSL_SUCCESS)) {
443 LOG_ERROR("set aad fail");
444 return false;
445 }
446 return true;
447 }
448
DoAesEncrypt(EVP_CIPHER_CTX * ctx,const Buffer * plaintext,Buffer ** ciphertext,Buffer ** tag)449 static bool DoAesEncrypt(EVP_CIPHER_CTX *ctx, const Buffer *plaintext, Buffer **ciphertext, Buffer **tag)
450 {
451 *ciphertext = CreateBufferBySize(plaintext->contentSize);
452 *tag = CreateBufferBySize(AES_GCM_256_TAG_SIZE);
453 if ((*ciphertext == NULL) || (*tag == NULL)) {
454 LOG_ERROR("create cipher fail");
455 goto ERROR;
456 }
457
458 int outLen = 0;
459 if (EVP_EncryptUpdate(ctx, (*ciphertext)->buf, &outLen,
460 plaintext->buf, plaintext->contentSize) != OPENSSL_SUCCESS) {
461 LOG_ERROR("failed to update");
462 goto ERROR;
463 }
464 if ((outLen < 0) || ((uint32_t)outLen > (*ciphertext)->maxSize)) {
465 LOG_ERROR("outLen out of range");
466 goto ERROR;
467 }
468 (*ciphertext)->contentSize = (uint32_t)outLen;
469 if (EVP_EncryptFinal_ex(ctx, (*ciphertext)->buf + (*ciphertext)->contentSize, &outLen) != OPENSSL_SUCCESS) {
470 LOG_ERROR("failed to finish");
471 goto ERROR;
472 }
473 if ((outLen < 0) || ((uint32_t)outLen > ((*ciphertext)->maxSize) - (*ciphertext)->contentSize)) {
474 LOG_ERROR("final outLen out of range");
475 goto ERROR;
476 }
477 (*ciphertext)->contentSize += (uint32_t)outLen;
478 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AES_GCM_256_TAG_SIZE, (*tag)->buf) != OPENSSL_SUCCESS) {
479 LOG_ERROR("failed to get tag");
480 goto ERROR;
481 }
482 (*tag)->contentSize = AES_GCM_256_TAG_SIZE;
483 return true;
484
485 ERROR:
486 DestroyBuffer(*ciphertext);
487 *ciphertext = NULL;
488 DestroyBuffer(*tag);
489 *tag = NULL;
490 return false;
491 }
492
AesGcm256Encrypt(const Buffer * plaintext,const AesGcmParam * param,Buffer ** ciphertext,Buffer ** tag)493 int32_t AesGcm256Encrypt(const Buffer *plaintext, const AesGcmParam *param, Buffer **ciphertext, Buffer **tag)
494 {
495 if (!IsBufferValid(plaintext) ||
496 (plaintext->contentSize == 0) ||(plaintext->contentSize > CIPHER_INFO_MAX_SIZE) ||
497 !CheckAes256GcmParams(param) || (ciphertext == NULL) || (tag == NULL)) {
498 LOG_ERROR("bad param");
499 return RESULT_BAD_PARAM;
500 }
501
502 int result = RESULT_GENERAL_ERROR;
503 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
504 if (ctx == NULL) {
505 LOG_ERROR("get ctx fail");
506 return result;
507 }
508 if (!SetAesEncryptParam(ctx, param)) {
509 LOG_ERROR("SetAesEncryptParam fail");
510 goto EXIT;
511 }
512 if (!DoAesEncrypt(ctx, plaintext, ciphertext, tag)) {
513 LOG_ERROR("DoAesEncrypt fail");
514 goto EXIT;
515 }
516 result = RESULT_SUCCESS;
517
518 EXIT:
519 EVP_CIPHER_CTX_free(ctx);
520 return result;
521 }
522
SetAesDecryptParam(EVP_CIPHER_CTX * ctx,const AesGcmParam * param)523 static bool SetAesDecryptParam(EVP_CIPHER_CTX *ctx, const AesGcmParam *param)
524 {
525 if (EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, param->key->buf, NULL) != OPENSSL_SUCCESS) {
526 LOG_ERROR("EVP_DecryptInit_ex fail");
527 return false;
528 }
529 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, param->iv->contentSize, NULL) != OPENSSL_SUCCESS) {
530 LOG_ERROR("failed to set iv len");
531 return false;
532 }
533 if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, param->iv->buf) != OPENSSL_SUCCESS) {
534 LOG_ERROR("failed to init iv");
535 return false;
536 }
537 if (EVP_CIPHER_CTX_set_padding(ctx, NO_PADDING) != OPENSSL_SUCCESS) {
538 LOG_ERROR("failed to set padding");
539 return false;
540 }
541 int outLen = 0;
542 if ((param->aad != NULL) &&
543 (EVP_DecryptUpdate(ctx, NULL, &outLen, param->aad->buf, param->aad->contentSize) != OPENSSL_SUCCESS)) {
544 LOG_ERROR("set aad fail");
545 return false;
546 }
547 return true;
548 }
549
DoAesDecrypt(EVP_CIPHER_CTX * ctx,const Buffer * ciphertext,const Buffer * tag,Buffer ** plaintext)550 static bool DoAesDecrypt(EVP_CIPHER_CTX *ctx, const Buffer *ciphertext, const Buffer *tag, Buffer **plaintext)
551 {
552 *plaintext = CreateBufferBySize(ciphertext->contentSize);
553 if (*plaintext == NULL) {
554 LOG_ERROR("create plain fail");
555 goto ERROR;
556 }
557
558 int outLen = 0;
559 if (EVP_DecryptUpdate(ctx, (*plaintext)->buf, &outLen,
560 ciphertext->buf, ciphertext->contentSize) != OPENSSL_SUCCESS) {
561 LOG_ERROR("failed to update");
562 goto ERROR;
563 }
564 if ((outLen < 0) || ((uint32_t)outLen > (*plaintext)->maxSize)) {
565 LOG_ERROR("outLen out of range");
566 goto ERROR;
567 }
568 (*plaintext)->contentSize = (uint32_t)outLen;
569 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag->contentSize, tag->buf) != OPENSSL_SUCCESS) {
570 LOG_ERROR("failed to set tag");
571 goto ERROR;
572 }
573 if (EVP_DecryptFinal_ex(ctx, (*plaintext)->buf + (*plaintext)->contentSize, &outLen) != OPENSSL_SUCCESS) {
574 LOG_ERROR("failed to finish");
575 goto ERROR;
576 }
577 if ((outLen < 0) || ((uint32_t)outLen > ((*plaintext)->maxSize) - (*plaintext)->contentSize)) {
578 LOG_ERROR("final outLen out of range");
579 goto ERROR;
580 }
581 (*plaintext)->contentSize += (uint32_t)outLen;
582 return true;
583
584 ERROR:
585 DestroyBuffer(*plaintext);
586 *plaintext = NULL;
587 return false;
588 }
589
AesGcm256Decrypt(const Buffer * ciphertext,const AesGcmParam * param,const Buffer * tag,Buffer ** plaintext)590 int32_t AesGcm256Decrypt(const Buffer *ciphertext, const AesGcmParam *param, const Buffer *tag, Buffer **plaintext)
591 {
592 if (!IsBufferValid(ciphertext) ||
593 (ciphertext->contentSize == 0) ||(ciphertext->contentSize > CIPHER_INFO_MAX_SIZE) ||
594 !CheckAes256GcmParams(param) || !CheckBufferWithSize(tag, AES_GCM_256_TAG_SIZE) || (plaintext == NULL)) {
595 LOG_ERROR("bad param");
596 return RESULT_BAD_PARAM;
597 }
598
599 int result = RESULT_GENERAL_ERROR;
600 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
601 if (ctx == NULL) {
602 LOG_ERROR("get ctx fail");
603 return result;
604 }
605 if (!SetAesDecryptParam(ctx, param)) {
606 LOG_ERROR("SetAesEncryptParam fail");
607 goto EXIT;
608 }
609 if (!DoAesDecrypt(ctx, ciphertext, tag, plaintext)) {
610 LOG_ERROR("DoAesEncrypt fail");
611 goto EXIT;
612 }
613 result = RESULT_SUCCESS;
614
615 EXIT:
616 EVP_CIPHER_CTX_free(ctx);
617 return result;
618 }