1 /*
2 * Copyright (c) 2022 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 "softbus_adapter_crypto.h"
17
18 #include <securec.h>
19
20 #include <openssl/evp.h>
21 #include <openssl/hmac.h>
22 #include <openssl/kdf.h>
23 #include <openssl/rand.h>
24
25 #include "comm_log.h"
26 #include "softbus_adapter_file.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_error_code.h"
29
30 static SoftBusMutex g_randomLock;
31
32 #define OPENSSL_EVP_PADDING_FUNC_OPEN (1)
33 #define OPENSSL_EVP_PADDING_FUNC_CLOSE (0)
34
35 #define EVP_AES_128_KEYLEN 16
36 #define EVP_AES_256_KEYLEN 32
37
GetGcmAlgorithmByKeyLen(uint32_t keyLen)38 static EVP_CIPHER *GetGcmAlgorithmByKeyLen(uint32_t keyLen)
39 {
40 switch (keyLen) {
41 case EVP_AES_128_KEYLEN:
42 return (EVP_CIPHER *)EVP_aes_128_gcm();
43 case EVP_AES_256_KEYLEN:
44 return (EVP_CIPHER *)EVP_aes_256_gcm();
45 default:
46 return NULL;
47 }
48 return NULL;
49 }
50
GetCtrAlgorithmByKeyLen(uint32_t keyLen)51 static EVP_CIPHER *GetCtrAlgorithmByKeyLen(uint32_t keyLen)
52 {
53 switch (keyLen) {
54 case EVP_AES_128_KEYLEN:
55 return (EVP_CIPHER *)EVP_aes_128_ctr();
56 case EVP_AES_256_KEYLEN:
57 return (EVP_CIPHER *)EVP_aes_256_ctr();
58 default:
59 return NULL;
60 }
61 return NULL;
62 }
63
OpensslEvpInit(EVP_CIPHER_CTX ** ctx,uint32_t keyLen,bool mode)64 static int32_t OpensslEvpInit(EVP_CIPHER_CTX **ctx, uint32_t keyLen, bool mode)
65 {
66 EVP_CIPHER *cipher = GetGcmAlgorithmByKeyLen(keyLen);
67 if (cipher == NULL) {
68 COMM_LOGE(COMM_ADAPTER, "get cipher fail.");
69 return SOFTBUS_DECRYPT_ERR;
70 }
71 int32_t ret;
72 *ctx = EVP_CIPHER_CTX_new();
73 if (*ctx == NULL) {
74 return SOFTBUS_DECRYPT_ERR;
75 }
76 EVP_CIPHER_CTX_set_padding(*ctx, OPENSSL_EVP_PADDING_FUNC_OPEN);
77 if (mode == true) {
78 ret = EVP_EncryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
79 if (ret != 1) {
80 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
81 EVP_CIPHER_CTX_free(*ctx);
82 return SOFTBUS_DECRYPT_ERR;
83 }
84 } else {
85 ret = EVP_DecryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
86 if (ret != 1) {
87 COMM_LOGE(COMM_ADAPTER, "EVP_DecryptInit_ex fail.");
88 EVP_CIPHER_CTX_free(*ctx);
89 return SOFTBUS_DECRYPT_ERR;
90 }
91 }
92 ret = EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_IVLEN, GCM_IV_LEN, NULL);
93 if (ret != 1) {
94 COMM_LOGE(COMM_ADAPTER, "Set iv len fail.");
95 EVP_CIPHER_CTX_free(*ctx);
96 return SOFTBUS_DECRYPT_ERR;
97 }
98 return SOFTBUS_OK;
99 }
100
PackIvAndTag(EVP_CIPHER_CTX * ctx,const AesGcmCipherKey * cipherkey,uint32_t dataLen,unsigned char * cipherText,uint32_t cipherTextLen)101 static int32_t PackIvAndTag(EVP_CIPHER_CTX *ctx, const AesGcmCipherKey *cipherkey, uint32_t dataLen,
102 unsigned char *cipherText, uint32_t cipherTextLen)
103 {
104 if ((dataLen + OVERHEAD_LEN) > cipherTextLen) {
105 COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
106 return SOFTBUS_ENCRYPT_ERR;
107 }
108 if (memcpy_s(cipherText, cipherTextLen - dataLen, cipherkey->iv, GCM_IV_LEN) != EOK) {
109 COMM_LOGE(COMM_ADAPTER, "EVP memcpy iv fail.");
110 return SOFTBUS_ENCRYPT_ERR;
111 }
112 char tagbuf[TAG_LEN];
113 int ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_LEN, (void *)tagbuf);
114 if (ret != 1) {
115 COMM_LOGE(COMM_ADAPTER, "EVP_CIPHER_CTX_ctrl fail.");
116 return SOFTBUS_DECRYPT_ERR;
117 }
118 if (memcpy_s(cipherText + dataLen + GCM_IV_LEN, cipherTextLen - dataLen - GCM_IV_LEN, tagbuf, TAG_LEN) != EOK) {
119 COMM_LOGE(COMM_ADAPTER, "EVP memcpy tag fail.");
120 return SOFTBUS_ENCRYPT_ERR;
121 }
122 return SOFTBUS_OK;
123 }
124
SslAesGcmEncrypt(const AesGcmCipherKey * cipherkey,const unsigned char * plainText,uint32_t plainTextSize,unsigned char * cipherText,uint32_t cipherTextLen)125 static int32_t SslAesGcmEncrypt(const AesGcmCipherKey *cipherkey, const unsigned char *plainText,
126 uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
127 {
128 if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
129 (cipherTextLen < plainTextSize + OVERHEAD_LEN)) {
130 COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
131 return SOFTBUS_INVALID_PARAM;
132 }
133
134 int32_t outlen = 0;
135 int32_t outbufLen;
136 EVP_CIPHER_CTX *ctx = NULL;
137 int32_t ret = OpensslEvpInit(&ctx, cipherkey->keyLen, true);
138 if (ret != SOFTBUS_OK) {
139 COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
140 return SOFTBUS_DECRYPT_ERR;
141 }
142 ret = EVP_EncryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
143 if (ret != 1) {
144 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
145 EVP_CIPHER_CTX_free(ctx);
146 return SOFTBUS_DECRYPT_ERR;
147 }
148 ret = EVP_EncryptUpdate(ctx, cipherText + GCM_IV_LEN, (int32_t *)&outbufLen, plainText, plainTextSize);
149 if (ret != 1) {
150 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptUpdate fail.");
151 EVP_CIPHER_CTX_free(ctx);
152 return SOFTBUS_DECRYPT_ERR;
153 }
154 outlen += outbufLen;
155 ret = EVP_EncryptFinal_ex(ctx, cipherText + GCM_IV_LEN + outbufLen, (int32_t *)&outbufLen);
156 if (ret != 1) {
157 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptFinal_ex fail.");
158 EVP_CIPHER_CTX_free(ctx);
159 return SOFTBUS_DECRYPT_ERR;
160 }
161 outlen += outbufLen;
162 ret = PackIvAndTag(ctx, cipherkey, outlen, cipherText, cipherTextLen);
163 if (ret != SOFTBUS_OK) {
164 COMM_LOGE(COMM_ADAPTER, "pack iv and tag fail.");
165 EVP_CIPHER_CTX_free(ctx);
166 return SOFTBUS_DECRYPT_ERR;
167 }
168 EVP_CIPHER_CTX_free(ctx);
169 return (outlen + OVERHEAD_LEN);
170 }
171
SslAesGcmDecrypt(const AesGcmCipherKey * cipherkey,const unsigned char * cipherText,uint32_t cipherTextSize,unsigned char * plain,uint32_t plainLen)172 static int32_t SslAesGcmDecrypt(const AesGcmCipherKey *cipherkey, const unsigned char *cipherText,
173 uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
174 {
175 if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL ||
176 (plainLen < cipherTextSize - OVERHEAD_LEN)) {
177 COMM_LOGE(COMM_ADAPTER, "Decrypt invalid para.");
178 return SOFTBUS_INVALID_PARAM;
179 }
180
181 int32_t outLen = 0;
182 EVP_CIPHER_CTX *ctx = NULL;
183 int32_t ret = OpensslEvpInit(&ctx, cipherkey->keyLen, false);
184 if (ret != SOFTBUS_OK) {
185 COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
186 return SOFTBUS_DECRYPT_ERR;
187 }
188 ret = EVP_DecryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
189 if (ret != 1) {
190 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
191 goto EXIT;
192 }
193 ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, TAG_LEN, (void *)(cipherText + (cipherTextSize - TAG_LEN)));
194 if (ret != 1) {
195 COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
196 goto EXIT;
197 }
198 ret = EVP_DecryptUpdate(ctx, plain, (int32_t *)&plainLen, cipherText + GCM_IV_LEN, cipherTextSize - OVERHEAD_LEN);
199 if (ret != 1) {
200 COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
201 goto EXIT;
202 }
203 if (plainLen > INT32_MAX) {
204 COMM_LOGE(COMM_ADAPTER, "PlainLen convert overflow.");
205 goto EXIT;
206 }
207 outLen += (int32_t)plainLen;
208 ret = EVP_DecryptFinal_ex(ctx, plain + plainLen, (int32_t *)&plainLen);
209 if (ret != 1) {
210 COMM_LOGE(COMM_ADAPTER, "EVP_DecryptFinal_ex fail.");
211 goto EXIT;
212 }
213 if ((int32_t)plainLen > INT32_MAX - outLen) {
214 COMM_LOGE(COMM_ADAPTER, "outLen convert overflow.");
215 goto EXIT;
216 }
217 outLen += (int32_t)plainLen;
218 EVP_CIPHER_CTX_free(ctx);
219 return outLen;
220 EXIT:
221 EVP_CIPHER_CTX_free(ctx);
222 return SOFTBUS_DECRYPT_ERR;
223 }
224
HandleError(EVP_CIPHER_CTX * ctx,const char * buf)225 static int32_t HandleError(EVP_CIPHER_CTX *ctx, const char *buf)
226 {
227 if (buf != NULL) {
228 COMM_LOGE(COMM_ADAPTER, "buf=%{public}s", buf);
229 }
230 if (ctx != NULL) {
231 EVP_CIPHER_CTX_free(ctx);
232 }
233 return SOFTBUS_DECRYPT_ERR;
234 }
235
SoftBusBase64Encode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)236 int32_t SoftBusBase64Encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
237 {
238 if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
239 return SOFTBUS_INVALID_PARAM;
240 }
241 *olen = 0;
242 int32_t outlen;
243 EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
244 if (ctx == NULL) {
245 return SOFTBUS_DECRYPT_ERR;
246 }
247 unsigned char *dstTmp = SoftBusCalloc(EVP_ENCODE_LENGTH(slen));
248 if (dstTmp == NULL) {
249 COMM_LOGE(COMM_ADAPTER, "[TRANS] SoftBusCalloc fail.");
250 EVP_ENCODE_CTX_free(ctx);
251 return SOFTBUS_MEM_ERR;
252 }
253 EVP_EncodeInit(ctx);
254 int32_t ret = EVP_EncodeUpdate(ctx, dstTmp, &outlen, src, slen);
255 if (ret != 1) {
256 COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_EncodeUpdate fail.");
257 EVP_ENCODE_CTX_free(ctx);
258 SoftBusFree(dstTmp);
259 return SOFTBUS_DECRYPT_ERR;
260 }
261 *olen += outlen;
262 EVP_EncodeFinal(ctx, dstTmp + outlen, &outlen);
263 *olen += outlen;
264
265 if (*olen > dlen) {
266 COMM_LOGE(COMM_ADAPTER, "[TRANS] invalid dlen=%{public}zu, olen=%{public}zu.", dlen, *olen);
267 EVP_ENCODE_CTX_free(ctx);
268 SoftBusFree(dstTmp);
269 return SOFTBUS_INVALID_PARAM;
270 }
271
272 ret = memcpy_s(dst, dlen, dstTmp, *olen);
273 if (ret != EOK) {
274 COMM_LOGE(COMM_ADAPTER, "[TRANS] memcpy_s failed.");
275 EVP_ENCODE_CTX_free(ctx);
276 SoftBusFree(dstTmp);
277 return SOFTBUS_MEM_ERR;
278 }
279 if ((*olen > 0) && (dst[*olen - 1] == '\n')) {
280 (*olen)--;
281 dst[*olen] = 0;
282 }
283
284 EVP_ENCODE_CTX_free(ctx);
285 SoftBusFree(dstTmp);
286 return SOFTBUS_OK;
287 }
288
SoftBusBase64Decode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)289 int32_t SoftBusBase64Decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
290 {
291 if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
292 return SOFTBUS_INVALID_PARAM;
293 }
294 *olen = 0;
295 int32_t outlen;
296 EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
297 if (ctx == NULL) {
298 return SOFTBUS_DECRYPT_ERR;
299 }
300 unsigned char *dstTmp = SoftBusCalloc(EVP_DECODE_LENGTH(slen));
301 if (dstTmp == NULL) {
302 COMM_LOGE(COMM_ADAPTER, "[TRANS] SoftBusCalloc fail.");
303 EVP_ENCODE_CTX_free(ctx);
304 return SOFTBUS_MEM_ERR;
305 }
306 EVP_DecodeInit(ctx);
307 int32_t ret = EVP_DecodeUpdate(ctx, dstTmp, &outlen, src, slen);
308 if (ret == -1) {
309 COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_DecodeUpdate fail.");
310 ret = SOFTBUS_DECRYPT_ERR;
311 goto FINISHED;
312 }
313 *olen += outlen;
314 ret = EVP_DecodeFinal(ctx, dstTmp + outlen, &outlen);
315 if (ret != 1) {
316 COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_DecodeFinal fail.");
317 ret = SOFTBUS_DECRYPT_ERR;
318 goto FINISHED;
319 }
320 *olen += outlen;
321 if (*olen > dlen) {
322 COMM_LOGE(COMM_ADAPTER, "[TRANS] invalid dlen=%{public}zu, olen=%{public}zu.", dlen, *olen);
323 ret = SOFTBUS_INVALID_PARAM;
324 goto FINISHED;
325 }
326
327 ret = memcpy_s(dst, dlen, dstTmp, *olen);
328 if (ret != EOK) {
329 COMM_LOGE(COMM_ADAPTER, "[TRANS] memcpy_s failed.");
330 ret = SOFTBUS_MEM_ERR;
331 goto FINISHED;
332 }
333 ret = SOFTBUS_OK;
334 FINISHED:
335 EVP_ENCODE_CTX_free(ctx);
336 SoftBusFree(dstTmp);
337 return ret;
338 }
339
SoftBusGenerateStrHash(const unsigned char * str,uint32_t len,unsigned char * hash)340 int32_t SoftBusGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash)
341 {
342 if (str == NULL || hash == NULL || len == 0) {
343 return SOFTBUS_INVALID_PARAM;
344 }
345 uint32_t olen;
346 int32_t ret = EVP_Digest(str, len, hash, &olen, EVP_sha256(), NULL);
347 if (ret != 1) {
348 COMM_LOGE(COMM_ADAPTER, "[TRANS] Get Openssl Hash fail.");
349 return SOFTBUS_DECRYPT_ERR;
350 }
351 return SOFTBUS_OK;
352 }
353
SoftBusGenerateRandomArray(unsigned char * randStr,uint32_t len)354 int32_t SoftBusGenerateRandomArray(unsigned char *randStr, uint32_t len)
355 {
356 if (randStr == NULL || len == 0) {
357 return SOFTBUS_INVALID_PARAM;
358 }
359
360 static bool initFlag = false;
361 int32_t ret;
362
363 if (SoftBusMutexInit(&g_randomLock, NULL) != SOFTBUS_OK) {
364 COMM_LOGE(COMM_ADAPTER, "init mutex failed.");
365 return SOFTBUS_ERR;
366 }
367
368 if (SoftBusMutexLock(&g_randomLock) != SOFTBUS_OK) {
369 COMM_LOGE(COMM_ADAPTER, "lock mutex failed");
370 return SOFTBUS_ERR;
371 }
372 if (initFlag == false) {
373 RAND_seed(randStr, (int32_t)len);
374 initFlag = true;
375 }
376
377 ret = RAND_bytes(randStr, (int32_t)len);
378 SoftBusMutexUnlock(&g_randomLock);
379 if (ret != 1) {
380 COMM_LOGE(COMM_ADAPTER, "gen random error, ret=%{public}d", ret);
381 return SOFTBUS_ERR;
382 }
383 return SOFTBUS_OK;
384 }
385
SoftBusGenerateSessionKey(char * key,uint32_t len)386 int32_t SoftBusGenerateSessionKey(char *key, uint32_t len)
387 {
388 if (SoftBusGenerateRandomArray((unsigned char *)key, len) != SOFTBUS_OK) {
389 COMM_LOGE(COMM_ADAPTER, "generate sessionKey error.");
390 return SOFTBUS_ENCRYPT_ERR;
391 }
392 return SOFTBUS_OK;
393 }
394
SoftBusEncryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)395 int32_t SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
396 unsigned char *encryptData, uint32_t *encryptLen)
397 {
398 if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
399 return SOFTBUS_INVALID_PARAM;
400 }
401
402 if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
403 COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
404 return SOFTBUS_ENCRYPT_ERR;
405 }
406 uint32_t outLen = inLen + OVERHEAD_LEN;
407 int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
408 if (result <= 0) {
409 return SOFTBUS_ENCRYPT_ERR;
410 }
411 *encryptLen = result;
412 return SOFTBUS_OK;
413 }
414
SoftBusEncryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen,int32_t seqNum)415 int32_t SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
416 unsigned char *encryptData, uint32_t *encryptLen, int32_t seqNum)
417 {
418 if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
419 return SOFTBUS_INVALID_PARAM;
420 }
421 if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
422 COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
423 return SOFTBUS_ENCRYPT_ERR;
424 }
425 if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) {
426 return SOFTBUS_ENCRYPT_ERR;
427 }
428 uint32_t outLen = inLen + OVERHEAD_LEN;
429 int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
430 if (result <= 0) {
431 return SOFTBUS_ENCRYPT_ERR;
432 }
433 *encryptLen = result;
434 return SOFTBUS_OK;
435 }
436
SoftBusDecryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)437 int32_t SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
438 unsigned char *decryptData, uint32_t *decryptLen)
439 {
440 if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) {
441 return SOFTBUS_INVALID_PARAM;
442 }
443
444 if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) {
445 COMM_LOGE(COMM_ADAPTER, "copy iv failed.");
446 return SOFTBUS_MEM_ERR;
447 }
448 uint32_t outLen = inLen - OVERHEAD_LEN;
449 int32_t result = SslAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen);
450 if (result <= 0) {
451 return SOFTBUS_DECRYPT_ERR;
452 }
453 *decryptLen = (uint32_t)result;
454 return SOFTBUS_OK;
455 }
456
SoftBusDecryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen,int32_t seqNum)457 int32_t SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
458 unsigned char *decryptData, uint32_t *decryptLen, int32_t seqNum)
459 {
460 (void)seqNum;
461 return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen);
462 }
463
SoftBusCryptoRand(void)464 uint32_t SoftBusCryptoRand(void)
465 {
466 int32_t fd = SoftBusOpenFile("/dev/urandom", SOFTBUS_O_RDONLY);
467 if (fd < 0) {
468 COMM_LOGE(COMM_ADAPTER, "CryptoRand open file fail");
469 return 0;
470 }
471 uint32_t value = 0;
472 int32_t len = SoftBusReadFile(fd, &value, sizeof(uint32_t));
473 if (len < 0) {
474 COMM_LOGE(COMM_ADAPTER, "CryptoRand read file fail");
475 SoftBusCloseFile(fd);
476 return 0;
477 }
478 SoftBusCloseFile(fd);
479 return value;
480 }
481
SoftBusEncryptDataByCtr(AesCtrCipherKey * key,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)482 int32_t SoftBusEncryptDataByCtr(
483 AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, unsigned char *encryptData, uint32_t *encryptLen)
484 {
485 if (key == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
486 return SOFTBUS_INVALID_PARAM;
487 }
488 EVP_CIPHER_CTX *ctx = NULL;
489 int32_t len = 0;
490 *encryptLen = 0;
491 EVP_CIPHER *cipher = NULL;
492 if (!(cipher = GetCtrAlgorithmByKeyLen(key->keyLen))) {
493 return HandleError(ctx, "get cipher failed");
494 }
495 if (!(ctx = EVP_CIPHER_CTX_new())) {
496 return HandleError(ctx, "EVP_CIPHER_CTX_new ctr failed");
497 }
498 if (EVP_EncryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
499 return HandleError(ctx, "EVP_EncryptInit_ex ctr failed");
500 }
501 if (EVP_EncryptUpdate(ctx, encryptData, &len, input, inLen) != 1) {
502 return HandleError(ctx, "EVP_EncryptUpdate ctr failed");
503 }
504 *encryptLen += len;
505 if (EVP_EncryptFinal_ex(ctx, encryptData + len, &len) != 1) {
506 return HandleError(ctx, "EVP_EncryptFinal_ex ctr failed");
507 }
508 *encryptLen += len;
509 EVP_CIPHER_CTX_free(ctx);
510 return SOFTBUS_OK;
511 }
512
SoftBusDecryptDataByCtr(AesCtrCipherKey * key,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)513 int32_t SoftBusDecryptDataByCtr(
514 AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, unsigned char *decryptData, uint32_t *decryptLen)
515 {
516 if (key == NULL || input == NULL || inLen == 0 || decryptData == NULL || decryptLen == NULL) {
517 return SOFTBUS_INVALID_PARAM;
518 }
519 EVP_CIPHER_CTX *ctx = NULL;
520 int32_t len = 0;
521 *decryptLen = 0;
522 EVP_CIPHER *cipher = NULL;
523 if (!(cipher = GetCtrAlgorithmByKeyLen(key->keyLen))) {
524 return HandleError(ctx, "get cipher failed");
525 }
526 if (!(ctx = EVP_CIPHER_CTX_new())) {
527 return HandleError(ctx, "EVP_CIPHER_CTX_new ctr failed");
528 }
529 if (EVP_DecryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
530 return HandleError(ctx, "EVP_DecryptInit_ex ctr failed");
531 }
532 if (EVP_DecryptUpdate(ctx, decryptData, &len, input, inLen) != 1) {
533 return HandleError(ctx, "EVP_DecryptUpdate ctr failed");
534 }
535 *decryptLen += len;
536 if (EVP_DecryptFinal_ex(ctx, decryptData + len, &len) != 1) {
537 return HandleError(ctx, "EVP_DecryptFinal_ex ctr failed");
538 }
539 *decryptLen += len;
540 EVP_CIPHER_CTX_free(ctx);
541 return SOFTBUS_OK;
542 }
543
PackTag(EVP_CIPHER_CTX * ctx,uint32_t dataLen,unsigned char * cipherText,uint32_t cipherTextLen)544 static int32_t PackTag(EVP_CIPHER_CTX *ctx, uint32_t dataLen, unsigned char *cipherText, uint32_t cipherTextLen)
545 {
546 if ((dataLen + SHORT_TAG_LEN) > cipherTextLen) {
547 COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
548 return SOFTBUS_ENCRYPT_ERR;
549 }
550
551 char tagbuf[SHORT_TAG_LEN];
552 int ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, SHORT_TAG_LEN, (void *)tagbuf);
553 if (ret != 1) {
554 COMM_LOGE(COMM_ADAPTER, "EVP_CIPHER_CTX_ctrl fail.");
555 return SOFTBUS_ENCRYPT_ERR;
556 }
557 if (memcpy_s(cipherText + dataLen, cipherTextLen - dataLen, tagbuf, SHORT_TAG_LEN) != EOK) {
558 COMM_LOGE(COMM_ADAPTER, "EVP memcpy tag fail.");
559 return SOFTBUS_ENCRYPT_ERR;
560 }
561 return SOFTBUS_OK;
562 }
563
SslAesGcm128Encrypt(const AesGcm128CipherKey * cipherkey,const unsigned char * plainText,uint32_t plainTextSize,unsigned char * cipherText,uint32_t cipherTextLen)564 static int32_t SslAesGcm128Encrypt(const AesGcm128CipherKey *cipherkey, const unsigned char *plainText,
565 uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
566 {
567 if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
568 (cipherTextLen < plainTextSize + SHORT_TAG_LEN)) {
569 COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
570 return SOFTBUS_INVALID_PARAM;
571 }
572
573 int32_t outlen = 0;
574 int32_t outbufLen;
575 EVP_CIPHER_CTX *ctx = NULL;
576 int32_t ret = OpensslEvpInit(&ctx, cipherkey->keyLen, true);
577 if (ret != SOFTBUS_OK) {
578 COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
579 return SOFTBUS_ENCRYPT_ERR;
580 }
581 ret = EVP_EncryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
582 if (ret != 1) {
583 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
584 EVP_CIPHER_CTX_free(ctx);
585 return SOFTBUS_ENCRYPT_ERR;
586 }
587 ret = EVP_EncryptUpdate(ctx, cipherText, (int32_t *)&outbufLen, plainText, plainTextSize);
588 if (ret != 1) {
589 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptUpdate fail.");
590 EVP_CIPHER_CTX_free(ctx);
591 return SOFTBUS_ENCRYPT_ERR;
592 }
593 outlen += outbufLen;
594 ret = EVP_EncryptFinal_ex(ctx, cipherText + outbufLen, (int32_t *)&outbufLen);
595 if (ret != 1) {
596 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptFinal_ex fail.");
597 EVP_CIPHER_CTX_free(ctx);
598 return SOFTBUS_ENCRYPT_ERR;
599 }
600 outlen += outbufLen;
601 ret = PackTag(ctx, outlen, cipherText, cipherTextLen);
602 if (ret != SOFTBUS_OK) {
603 COMM_LOGE(COMM_ADAPTER, "pack iv and tag fail.");
604 EVP_CIPHER_CTX_free(ctx);
605 return SOFTBUS_ENCRYPT_ERR;
606 }
607 EVP_CIPHER_CTX_free(ctx);
608 return (outlen + SHORT_TAG_LEN);
609 }
610
SoftBusEncryptDataByGcm128(AesGcm128CipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)611 int32_t SoftBusEncryptDataByGcm128(AesGcm128CipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
612 unsigned char *encryptData, uint32_t *encryptLen)
613 {
614 if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
615 COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
616 return SOFTBUS_INVALID_PARAM;
617 }
618 uint32_t outLen = inLen + SHORT_TAG_LEN;
619 int32_t result = SslAesGcm128Encrypt(cipherKey, input, inLen, encryptData, outLen);
620 if (result <= 0) {
621 COMM_LOGE(COMM_ADAPTER, "SslAesGcmEncrypt error.");
622 return SOFTBUS_ENCRYPT_ERR;
623 }
624 *encryptLen = result;
625 return SOFTBUS_OK;
626 }
627
SslAesGcm128Decryp(const AesGcm128CipherKey * cipherkey,const unsigned char * cipherText,uint32_t cipherTextSize,unsigned char * plain,uint32_t plainLen)628 static int32_t SslAesGcm128Decryp(const AesGcm128CipherKey *cipherkey, const unsigned char *cipherText,
629 uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
630 {
631 if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= SHORT_TAG_LEN) || plain == NULL ||
632 (plainLen < cipherTextSize - SHORT_TAG_LEN)) {
633 COMM_LOGE(COMM_ADAPTER, "Decrypt invalid para.");
634 return SOFTBUS_INVALID_PARAM;
635 }
636
637 int32_t outLen = 0;
638 EVP_CIPHER_CTX *ctx = NULL;
639 int32_t ret = OpensslEvpInit(&ctx, cipherkey->keyLen, false);
640 if (ret != SOFTBUS_OK) {
641 COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
642 return SOFTBUS_DECRYPT_ERR;
643 }
644 ret = EVP_DecryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
645 if (ret != 1) {
646 COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
647 goto EXIT;
648 }
649 ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, SHORT_TAG_LEN,
650 (void *)(cipherText + (cipherTextSize - SHORT_TAG_LEN)));
651 if (ret != 1) {
652 COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
653 goto EXIT;
654 }
655 ret = EVP_DecryptUpdate(ctx, plain, (int32_t *)&plainLen, cipherText, cipherTextSize - SHORT_TAG_LEN);
656 if (ret != 1) {
657 COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
658 goto EXIT;
659 }
660 if (plainLen > INT32_MAX) {
661 COMM_LOGE(COMM_ADAPTER, "PlainLen convert overflow.");
662 goto EXIT;
663 }
664 outLen += (int32_t)plainLen;
665 ret = EVP_DecryptFinal_ex(ctx, plain + plainLen, (int32_t *)&plainLen);
666 if (ret != 1) {
667 COMM_LOGE(COMM_ADAPTER, "EVP_DecryptFinal_ex fail.");
668 goto EXIT;
669 }
670 if ((int32_t)plainLen > INT32_MAX - outLen) {
671 COMM_LOGE(COMM_ADAPTER, "outLen convert overflow.");
672 goto EXIT;
673 }
674 outLen += (int32_t)plainLen;
675 EVP_CIPHER_CTX_free(ctx);
676 return outLen;
677 EXIT:
678 EVP_CIPHER_CTX_free(ctx);
679 return SOFTBUS_DECRYPT_ERR;
680 }
681
SoftBusDecryptDataByGcm128(AesGcm128CipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)682 int32_t SoftBusDecryptDataByGcm128(AesGcm128CipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
683 unsigned char *decryptData, uint32_t *decryptLen)
684 {
685 if (cipherKey == NULL || input == NULL || inLen < SHORT_TAG_LEN || decryptData == NULL || decryptLen == NULL) {
686 return SOFTBUS_INVALID_PARAM;
687 }
688
689 uint32_t outLen = inLen - SHORT_TAG_LEN;
690 int32_t result = SslAesGcm128Decryp(cipherKey, input, inLen, decryptData, outLen);
691 if (result <= 0) {
692 return SOFTBUS_DECRYPT_ERR;
693 }
694 *decryptLen = (uint32_t)result;
695 return SOFTBUS_OK;
696 }
697
SoftBusCalcHKDF(const uint8_t * inData,uint32_t inLen,uint8_t * outData,uint32_t outLen)698 int32_t SoftBusCalcHKDF(const uint8_t *inData, uint32_t inLen, uint8_t *outData, uint32_t outLen)
699 {
700 if (outLen > HKDF_BYTES_LEN || inData == NULL || outData == NULL) {
701 COMM_LOGE(COMM_ADAPTER, "calc HKDF invalid para.");
702 return SOFTBUS_INVALID_PARAM;
703 }
704 EVP_PKEY_CTX *pctx;
705 const EVP_MD *md = EVP_sha256();
706 if (md == NULL) {
707 COMM_LOGE(COMM_ADAPTER, "get EVP_sha256 fail.");
708 return SOFTBUS_CALC_HKDF_FAIL;
709 }
710 unsigned char tmp[HKDF_BYTES_LEN] = { 0 };
711 size_t tmpLen = sizeof(tmp);
712 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
713 if (pctx == NULL) {
714 COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_CTX_new_id fail.");
715 return SOFTBUS_CALC_HKDF_FAIL;
716 }
717 int32_t ret = EVP_PKEY_derive_init(pctx);
718 if (ret <= 0) {
719 COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_derive_init fail.");
720 return SOFTBUS_CALC_HKDF_FAIL;
721 }
722 ret = EVP_PKEY_CTX_set_hkdf_md(pctx, md);
723 if (ret <= 0) {
724 COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_CTX_set_hkdf_md fail.");
725 return SOFTBUS_CALC_HKDF_FAIL;
726 }
727 ret = EVP_PKEY_CTX_set1_hkdf_key(pctx, inData, inLen);
728 if (ret <= 0) {
729 COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_CTX_set1_hkdf_key fail.");
730 EVP_PKEY_CTX_free(pctx);
731 return SOFTBUS_CALC_HKDF_FAIL;
732 }
733 ret = EVP_PKEY_derive(pctx, tmp, &tmpLen);
734 if (ret <= 0) {
735 COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_derive fail.");
736 EVP_PKEY_CTX_free(pctx);
737 return SOFTBUS_CALC_HKDF_FAIL;
738 }
739 if (memcpy_s(outData, outLen, tmp, outLen) != EOK) {
740 COMM_LOGE(COMM_ADAPTER, "memcpy_s fail.");
741 EVP_PKEY_CTX_free(pctx);
742 return SOFTBUS_CALC_HKDF_FAIL;
743 }
744 EVP_PKEY_CTX_free(pctx);
745 return SOFTBUS_OK;
746 }
747
748