1/* 2 * Copyright (c) 2021 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 "comm_log.h" 21#include "mbedtls/base64.h" 22#include "mbedtls/cipher.h" 23#include "mbedtls/ctr_drbg.h" 24#include "mbedtls/entropy.h" 25#include "mbedtls/gcm.h" 26#include "mbedtls/md.h" 27#include "mbedtls/platform.h" 28#include "softbus_adapter_file.h" 29#include "softbus_errcode.h" 30 31#ifndef MBEDTLS_CTR_DRBG_C 32#define MBEDTLS_CTR_DRBG_C 33#endif 34 35#ifndef MBEDTLS_MD_C 36#define MBEDTLS_MD_C 37#endif 38 39#ifndef MBEDTLS_SHA256_C 40#define MBEDTLS_SHA256_C 41#endif 42 43#ifndef MBEDTLS_ENTROPY_C 44#define MBEDTLS_ENTROPY_C 45#endif 46 47#ifndef MBEDTLS_CIPHER_MODE_CTR 48#define MBEDTLS_CIPHER_MODE_CTR 49#endif 50 51#ifndef MBEDTLS_AES_C 52#define MBEDTLS_AES_C 53#endif 54 55#ifndef MBEDTLS_CIPHER_C 56#define MBEDTLS_CIPHER_C 57#endif 58 59#define EVP_AES_128_KEYLEN 16 60#define EVP_AES_256_KEYLEN 32 61#define BYTES_BIT_NUM 8 62 63static SoftBusMutex g_randomLock; 64 65static mbedtls_cipher_type_t GetCtrAlgorithmByKeyLen(uint32_t keyLen) 66{ 67 switch (keyLen) { 68 case EVP_AES_128_KEYLEN: 69 return MBEDTLS_CIPHER_ARIA_128_CTR; 70 case EVP_AES_256_KEYLEN: 71 return MBEDTLS_CIPHER_ARIA_256_CTR; 72 default: 73 return MBEDTLS_CIPHER_NONE; 74 } 75 return MBEDTLS_CIPHER_NONE; 76} 77 78static int32_t MbedAesGcmEncrypt(const AesGcmCipherKey *cipherKey, const unsigned char *plainText, 79 uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen) 80{ 81 if ((cipherKey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL || 82 (cipherTextLen < plainTextSize + OVERHEAD_LEN)) { 83 COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para"); 84 return SOFTBUS_INVALID_PARAM; 85 } 86 87 int32_t ret; 88 unsigned char tagBuf[TAG_LEN] = { 0 }; 89 mbedtls_gcm_context aesContext; 90 mbedtls_gcm_init(&aesContext); 91 92 ret = mbedtls_gcm_setkey(&aesContext, MBEDTLS_CIPHER_ID_AES, cipherKey->key, cipherKey->keyLen * KEY_BITS_UNIT); 93 if (ret != 0) { 94 mbedtls_gcm_free(&aesContext); 95 return SOFTBUS_ENCRYPT_ERR; 96 } 97 98 ret = mbedtls_gcm_crypt_and_tag(&aesContext, MBEDTLS_GCM_ENCRYPT, plainTextSize, cipherKey->iv, GCM_IV_LEN, NULL, 0, 99 plainText, cipherText + GCM_IV_LEN, TAG_LEN, tagBuf); 100 if (ret != 0) { 101 mbedtls_gcm_free(&aesContext); 102 return SOFTBUS_ENCRYPT_ERR; 103 } 104 105 if (memcpy_s(cipherText, cipherTextLen, cipherKey->iv, GCM_IV_LEN) != EOK) { 106 mbedtls_gcm_free(&aesContext); 107 return SOFTBUS_ENCRYPT_ERR; 108 } 109 110 if (memcpy_s(cipherText + GCM_IV_LEN + plainTextSize, cipherTextLen - GCM_IV_LEN - plainTextSize, tagBuf, 111 TAG_LEN) != 0) { 112 mbedtls_gcm_free(&aesContext); 113 return SOFTBUS_ENCRYPT_ERR; 114 } 115 116 mbedtls_gcm_free(&aesContext); 117 return (plainTextSize + OVERHEAD_LEN); 118} 119 120static int32_t MbedAesGcmDecrypt(const AesGcmCipherKey *cipherKey, const unsigned char *cipherText, 121 uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen) 122{ 123 if ((cipherKey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL || 124 (plainLen < cipherTextSize - OVERHEAD_LEN)) { 125 COMM_LOGE(COMM_ADAPTER, "Decrypt invalid para"); 126 return SOFTBUS_INVALID_PARAM; 127 } 128 129 mbedtls_gcm_context aesContext; 130 mbedtls_gcm_init(&aesContext); 131 int32_t ret = 132 mbedtls_gcm_setkey(&aesContext, MBEDTLS_CIPHER_ID_AES, cipherKey->key, cipherKey->keyLen * KEY_BITS_UNIT); 133 if (ret != 0) { 134 COMM_LOGE(COMM_ADAPTER, "Decrypt mbedtls_gcm_setkey fail."); 135 mbedtls_gcm_free(&aesContext); 136 return SOFTBUS_DECRYPT_ERR; 137 } 138 139 int32_t actualPlainLen = (int32_t)(cipherTextSize - OVERHEAD_LEN); 140 ret = mbedtls_gcm_auth_decrypt(&aesContext, cipherTextSize - OVERHEAD_LEN, cipherKey->iv, GCM_IV_LEN, NULL, 0, 141 cipherText + actualPlainLen + GCM_IV_LEN, TAG_LEN, cipherText + GCM_IV_LEN, plain); 142 if (ret != 0) { 143 COMM_LOGE(COMM_ADAPTER, "[TRANS] Decrypt mbedtls_gcm_auth_decrypt fail. ret=%{public}d", ret); 144 mbedtls_gcm_free(&aesContext); 145 return SOFTBUS_DECRYPT_ERR; 146 } 147 148 mbedtls_gcm_free(&aesContext); 149 return actualPlainLen; 150} 151 152static int32_t HandleError(mbedtls_cipher_context_t *ctx, const char *buf) 153{ 154 if (buf != NULL) { 155 COMM_LOGE(COMM_ADAPTER, "buf=%{public}s", buf); 156 } 157 if (ctx != NULL) { 158 mbedtls_cipher_free(ctx); 159 } 160 return SOFTBUS_DECRYPT_ERR; 161} 162 163int32_t SoftBusBase64Encode(unsigned char *dst, size_t dlen, 164 size_t *olen, const unsigned char *src, size_t slen) 165{ 166 if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) { 167 COMM_LOGE(COMM_ADAPTER, "base64 encode invalid para"); 168 return SOFTBUS_INVALID_PARAM; 169 } 170 return mbedtls_base64_encode(dst, dlen, olen, src, slen); 171} 172 173int32_t SoftBusBase64Decode(unsigned char *dst, size_t dlen, 174 size_t *olen, const unsigned char *src, size_t slen) 175{ 176 if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) { 177 COMM_LOGE(COMM_ADAPTER, "base64 decode invalid para"); 178 return SOFTBUS_INVALID_PARAM; 179 } 180 return mbedtls_base64_decode(dst, dlen, olen, src, slen); 181} 182 183int32_t SoftBusGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash) 184{ 185 if (str == NULL || hash == NULL || len == 0) { 186 return SOFTBUS_INVALID_PARAM; 187 } 188 189 mbedtls_md_context_t ctx; 190 const mbedtls_md_info_t *info = NULL; 191 mbedtls_md_init(&ctx); 192 193 info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); 194 if (info == NULL) { 195 mbedtls_md_free(&ctx); 196 return SOFTBUS_ENCRYPT_ERR; 197 } 198 if (mbedtls_md_setup(&ctx, info, 0) != 0) { 199 mbedtls_md_free(&ctx); 200 return SOFTBUS_ENCRYPT_ERR; 201 } 202 if (mbedtls_md_starts(&ctx) != 0) { 203 mbedtls_md_free(&ctx); 204 return SOFTBUS_ENCRYPT_ERR; 205 } 206 if (mbedtls_md_update(&ctx, str, len) != 0) { 207 mbedtls_md_free(&ctx); 208 return SOFTBUS_ENCRYPT_ERR; 209 } 210 if (mbedtls_md_finish(&ctx, hash) != 0) { 211 mbedtls_md_free(&ctx); 212 return SOFTBUS_ENCRYPT_ERR; 213 } 214 215 mbedtls_md_free(&ctx); 216 return SOFTBUS_OK; 217} 218 219int32_t SoftBusGenerateRandomArray(unsigned char *randStr, uint32_t len) 220{ 221 if (randStr == NULL || len == 0) { 222 return SOFTBUS_INVALID_PARAM; 223 } 224 225 static mbedtls_entropy_context entropy; 226 static mbedtls_ctr_drbg_context ctrDrbg; 227 static bool initFlag = false; 228 int32_t ret; 229 230 if (!initFlag) { 231 if (SoftBusMutexInit(&g_randomLock, NULL) != SOFTBUS_OK) { 232 COMM_LOGE(COMM_ADAPTER, "SoftBusGenerateRandomArray init lock fail"); 233 return SOFTBUS_LOCK_ERR; 234 } 235 mbedtls_ctr_drbg_init(&ctrDrbg); 236 mbedtls_entropy_init(&entropy); 237 ret = mbedtls_ctr_drbg_seed(&ctrDrbg, mbedtls_entropy_func, &entropy, NULL, 0); 238 if (ret != 0) { 239 SoftBusMutexUnlock(&g_randomLock); 240 COMM_LOGE(COMM_ADAPTER, "gen random seed error, ret=%{public}d", ret); 241 return SOFTBUS_ERR; 242 } 243 initFlag = true; 244 } 245 246 if (SoftBusMutexLock(&g_randomLock) != SOFTBUS_OK) { 247 COMM_LOGE(COMM_ADAPTER, "SoftBusGenerateRandomArray lock fail"); 248 return SOFTBUS_LOCK_ERR; 249 } 250 251 ret = mbedtls_ctr_drbg_random(&ctrDrbg, randStr, len); 252 SoftBusMutexUnlock(&g_randomLock); 253 if (ret != 0) { 254 COMM_LOGE(COMM_ADAPTER, "gen random error, ret=%{public}d", ret); 255 return SOFTBUS_ERR; 256 } 257 return SOFTBUS_OK; 258} 259 260int32_t SoftBusGenerateSessionKey(char *key, uint32_t len) 261{ 262 if (SoftBusGenerateRandomArray((unsigned char *)key, len) != SOFTBUS_OK) { 263 COMM_LOGE(COMM_ADAPTER, "generate sessionKey error."); 264 return SOFTBUS_ENCRYPT_ERR; 265 } 266 return SOFTBUS_OK; 267} 268 269int32_t SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen, 270 unsigned char *encryptData, uint32_t *encryptLen) 271{ 272 if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) { 273 return SOFTBUS_INVALID_PARAM; 274 } 275 276 if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) { 277 COMM_LOGE(COMM_ADAPTER, "generate random iv error."); 278 return SOFTBUS_ENCRYPT_ERR; 279 } 280 uint32_t outLen = inLen + OVERHEAD_LEN; 281 int32_t result = MbedAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen); 282 if (result <= 0) { 283 return SOFTBUS_ENCRYPT_ERR; 284 } 285 *encryptLen = result; 286 return SOFTBUS_OK; 287} 288 289int32_t SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen, 290 unsigned char *encryptData, uint32_t *encryptLen, int32_t seqNum) 291{ 292 if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) { 293 return SOFTBUS_INVALID_PARAM; 294 } 295 if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) { 296 COMM_LOGE(COMM_ADAPTER, "generate random iv error."); 297 return SOFTBUS_ENCRYPT_ERR; 298 } 299 if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) { 300 return SOFTBUS_ENCRYPT_ERR; 301 } 302 uint32_t outLen = inLen + OVERHEAD_LEN; 303 int32_t result = MbedAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen); 304 if (result <= 0) { 305 return SOFTBUS_ENCRYPT_ERR; 306 } 307 *encryptLen = result; 308 return SOFTBUS_OK; 309} 310 311int32_t SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen, 312 unsigned char *decryptData, uint32_t *decryptLen) 313{ 314 if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) { 315 return SOFTBUS_INVALID_PARAM; 316 } 317 318 if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) { 319 COMM_LOGE(COMM_ADAPTER, "copy iv failed."); 320 return SOFTBUS_ENCRYPT_ERR; 321 } 322 uint32_t outLen = inLen - OVERHEAD_LEN; 323 int32_t result = MbedAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen); 324 if (result <= 0) { 325 return SOFTBUS_ENCRYPT_ERR; 326 } 327 *decryptLen = (uint32_t)result; 328 return SOFTBUS_OK; 329} 330 331int32_t SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen, 332 unsigned char *decryptData, uint32_t *decryptLen, int32_t seqNum) 333{ 334 (void)seqNum; 335 return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen); 336} 337 338uint32_t SoftBusCryptoRand(void) 339{ 340 int32_t fd = SoftBusOpenFile("/dev/urandom", SOFTBUS_O_RDONLY); 341 if (fd < 0) { 342 COMM_LOGE(COMM_ADAPTER, "CryptoRand open file fail"); 343 return 0; 344 } 345 uint32_t value = 0; 346 int32_t len = SoftBusReadFile(fd, &value, sizeof(uint32_t)); 347 if (len < 0) { 348 COMM_LOGE(COMM_ADAPTER, "CryptoRand read file fail"); 349 SoftBusCloseFile(fd); 350 return 0; 351 } 352 SoftBusCloseFile(fd); 353 return value; 354} 355 356int32_t SoftBusEncryptDataByCtr(AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, 357 unsigned char *encryptData, uint32_t *encryptLen) 358{ 359 if (key == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) { 360 COMM_LOGE(COMM_ADAPTER, "softbus encrypt data by ctr invalid para"); 361 return SOFTBUS_INVALID_PARAM; 362 } 363 mbedtls_cipher_type_t type = GetCtrAlgorithmByKeyLen(key->keyLen); 364 if (type == MBEDTLS_CIPHER_NONE) { 365 return HandleError(NULL, "get cipher failed"); 366 } 367 size_t len = 0; 368 *encryptLen = 0; 369 mbedtls_cipher_context_t ctx; 370 const mbedtls_cipher_info_t *info = NULL; 371 mbedtls_cipher_init(&ctx); 372 if (!(info = mbedtls_cipher_info_from_type(type))) { 373 return HandleError(&ctx, "mbedtls_cipher_info_from_type ctr failed"); 374 } 375 if (mbedtls_cipher_setup(&ctx, info) != 0) { 376 return HandleError(&ctx, "mbedtls_cipher_setup ctr failed"); 377 } 378 if (mbedtls_cipher_setkey(&ctx, key->key, key->keyLen * BYTES_BIT_NUM, MBEDTLS_ENCRYPT) != 0) { 379 return HandleError(&ctx, "mbedtls_cipher_setkey ctr failed"); 380 } 381 if (mbedtls_cipher_set_iv(&ctx, key->iv, BLE_BROADCAST_IV_LEN) != 0) { 382 return HandleError(&ctx, "mbedtls_cipher_set_iv ctr failed"); 383 } 384 if (mbedtls_cipher_update(&ctx, input, inLen, encryptData, &len) != 0) { 385 return HandleError(&ctx, "mbedtls_cipher_update ctr failed"); 386 } 387 *encryptLen += len; 388 if (mbedtls_cipher_finish(&ctx, encryptData, &len) != 0) { 389 return HandleError(&ctx, "mbedtls_cipher_finish ctr failed"); 390 } 391 *encryptLen += len; 392 mbedtls_cipher_free(&ctx); 393 return SOFTBUS_OK; 394} 395 396int32_t SoftBusDecryptDataByCtr(AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, 397 unsigned char *decryptData, uint32_t *decryptLen) 398{ 399 return SoftBusEncryptDataByCtr(key, input, inLen, decryptData, decryptLen); 400} 401