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 "encrypt_utils.h"
17
18 #include "mbedtls/base64.h"
19 #include "mbedtls/gcm.h"
20 #include "mbedtls/md.h"
21
22 #include "mbedtls/ctr_drbg.h"
23 #include "mbedtls/entropy.h"
24
25 #include <random>
26 #include <cstdint>
27 #include <cstring>
28 #include "device_manager_errno.h"
29 #include "device_manager_log.h"
30 #include "securec.h"
31
32 namespace OHOS {
33 namespace DistributedHardware {
MbedtlsBase64Encode(uint8_t * dst,size_t dlen,size_t * olen,const uint8_t * src,size_t slen)34 int32_t EncryptUtils::MbedtlsBase64Encode(uint8_t *dst, size_t dlen, size_t *olen,
35 const uint8_t *src, size_t slen)
36 {
37 return mbedtls_base64_encode(dst, dlen, olen, src, slen);
38 }
39
MbedtlsBase64Decode(uint8_t * dst,size_t dlen,size_t * olen,const uint8_t * src,size_t slen)40 int32_t EncryptUtils::MbedtlsBase64Decode(uint8_t *dst, size_t dlen, size_t *olen,
41 const uint8_t *src, size_t slen)
42 {
43 return mbedtls_base64_decode(dst, dlen, olen, src, slen);
44 }
45
GenRandInt(int32_t randMin,int32_t randMax)46 int32_t EncryptUtils::GenRandInt(int32_t randMin, int32_t randMax)
47 {
48 #if (defined(__LINUX__) || defined(__LITEOS_A__))
49 std::random_device randDevice;
50 std::mt19937 genRand(randDevice());
51 std::uniform_int_distribution<int> disRand(randMin, randMax);
52 return disRand(genRand);
53 #else
54 return (randMin + random() % (randMax - randMin));
55 #endif
56 }
57
GenRandLongLong(int64_t randMin,int64_t randMax)58 int64_t EncryptUtils::GenRandLongLong(int64_t randMin, int64_t randMax)
59 {
60 std::random_device randDevice;
61 std::mt19937 genRand(randDevice());
62 std::uniform_int_distribution<long long> disRand(randMin, randMax);
63 return disRand(genRand);
64 }
65
GetRandomData(uint8_t * randStr,uint32_t len)66 int32_t EncryptUtils::GetRandomData(uint8_t *randStr, uint32_t len)
67 {
68 mbedtls_entropy_context *entropy = nullptr;
69 mbedtls_ctr_drbg_context *ctrDrbg = nullptr;
70 int32_t ret = DEVICEMANAGER_FAILED;
71 do {
72 if (randStr == nullptr || len == 0) {
73 break;
74 }
75 entropy = (mbedtls_entropy_context *)malloc(sizeof(mbedtls_entropy_context));
76 if (entropy == nullptr) {
77 break;
78 }
79 ctrDrbg = (mbedtls_ctr_drbg_context *)malloc(sizeof(mbedtls_ctr_drbg_context));
80 if (ctrDrbg == nullptr) {
81 break;
82 }
83 mbedtls_ctr_drbg_init(ctrDrbg);
84 mbedtls_entropy_init(entropy);
85 ret = mbedtls_ctr_drbg_seed(ctrDrbg, mbedtls_entropy_func, entropy, nullptr, 0);
86 if (ret != 0) {
87 break;
88 }
89 ret = mbedtls_ctr_drbg_random(ctrDrbg, randStr, len);
90 if (ret != 0) {
91 break;
92 }
93 ret = DEVICEMANAGER_OK;
94 } while (0);
95 if (entropy != nullptr) {
96 free(entropy);
97 }
98 if (ctrDrbg != nullptr) {
99 free(ctrDrbg);
100 }
101 return ret;
102 }
103
MbedtlsEncrypt(const uint8_t * plainText,int32_t plainTextLen,uint8_t * cipherText,int32_t cipherTextLen,int32_t * outLen)104 int32_t EncryptUtils::MbedtlsEncrypt(const uint8_t *plainText, int32_t plainTextLen, uint8_t *cipherText,
105 int32_t cipherTextLen, int32_t *outLen)
106 {
107 // Security algorithms do not support open source. Customize if required
108 if (memcpy_s(cipherText, cipherTextLen, plainText, plainTextLen) != DEVICEMANAGER_OK) {
109 return DEVICEMANAGER_COPY_FAILED;
110 }
111 *outLen = plainTextLen;
112 return DEVICEMANAGER_OK;
113 }
114
MbedtlsDecrypt(const uint8_t * cipherText,int32_t cipherTextLen,uint8_t * plainText,int32_t plainTextLen,int32_t * outLen)115 int32_t EncryptUtils::MbedtlsDecrypt(const uint8_t *cipherText, int32_t cipherTextLen, uint8_t *plainText,
116 int32_t plainTextLen, int32_t *outLen)
117 {
118 // Security algorithms do not support open source. Customize if required
119 (void)outLen;
120 if (memcpy_s(plainText, plainTextLen, cipherText, cipherTextLen) != DEVICEMANAGER_OK) {
121 return DEVICEMANAGER_COPY_FAILED;
122 }
123 return DEVICEMANAGER_OK;
124 }
125
MbedtlsGenRandomStr(char * szOut,int32_t szOutLen,bool numberOnly)126 bool EncryptUtils::MbedtlsGenRandomStr(char *szOut, int32_t szOutLen, bool numberOnly)
127 {
128 const int32_t MIN_OUT_LENGTH = 2;
129 if (szOut == nullptr || szOutLen <= MIN_OUT_LENGTH) {
130 return false;
131 }
132 szOut[--szOutLen] = 0;
133 GetRandomData((uint8_t*)szOut, szOutLen);
134 const int32_t NUMBER_COUNT = 10;
135 const int32_t ALPHA_COUNT = 26;
136 const int32_t ALPHA_BYTE_COUNT = 2;
137 int32_t M = numberOnly ? NUMBER_COUNT : (NUMBER_COUNT + ALPHA_BYTE_COUNT * ALPHA_COUNT);
138 for (int32_t i = 0; i < szOutLen; i++) {
139 // 0~9,A~Z,a~z
140 uint32_t idx = ((uint32_t)szOut[i] % M);
141 char base;
142 if (idx < NUMBER_COUNT) {
143 base = '0';
144 } else if (idx >= NUMBER_COUNT && idx < (NUMBER_COUNT + ALPHA_COUNT)) {
145 base = 'A';
146 idx -= NUMBER_COUNT;
147 } else {
148 base = 'a';
149 idx -= (NUMBER_COUNT + ALPHA_COUNT);
150 }
151 szOut[i] = base + idx;
152 }
153 return true;
154 }
155 } // namespace DistributedHardware
156 } // namespace OHOS
157