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 }