1 /*
2 * Copyright (c) 2023-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 "dm_softbus_adapter_crypto.h"
17
18 #include "dm_log.h"
19 #include "md.h"
20 #include "securec.h"
21 #include <sstream>
22 #include <string>
23
24 namespace OHOS {
25 namespace DistributedHardware {
26
27 namespace {
28 constexpr int SHA_HASH_LEN = 32;
29 constexpr int SHORT_DEVICE_ID_HASH_LENGTH = 16;
30 constexpr int HEXIFY_UNIT_LEN = 2;
31 constexpr int HEX_DIGIT_MAX_NUM = 16;
32 constexpr int DEC_MAX_NUM = 10;
33 constexpr int HEX_MAX_BIT_NUM = 4;
34 constexpr int ERR_DM_INPUT_PARA_INVALID = -20006;
35 constexpr int DM_OK = 0;
36 constexpr int ERR_DM_FAILED = -20000;
37 #define HEXIFY_LEN(len) ((len) * HEXIFY_UNIT_LEN + 1)
38 } // namespace
39
DmGenerateStrHash(const unsigned char * str,uint32_t len,unsigned char * hash)40 int32_t DmGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash)
41 {
42 if (str == nullptr || hash == nullptr || len == 0) {
43 return ERR_DM_INPUT_PARA_INVALID;
44 }
45
46 mbedtls_md_context_t ctx;
47 const mbedtls_md_info_t *info = NULL;
48 mbedtls_md_init(&ctx);
49
50 info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
51 if (mbedtls_md_setup(&ctx, info, 0) != 0) {
52 mbedtls_md_free(&ctx);
53 return ERR_DM_FAILED;
54 }
55 if (mbedtls_md_starts(&ctx) != 0) {
56 mbedtls_md_free(&ctx);
57 return ERR_DM_FAILED;
58 }
59 if (mbedtls_md_update(&ctx, str, len) != 0) {
60 mbedtls_md_free(&ctx);
61 return ERR_DM_FAILED;
62 }
63 if (mbedtls_md_finish(&ctx, hash) != 0) {
64 mbedtls_md_free(&ctx);
65 return ERR_DM_FAILED;
66 }
67
68 mbedtls_md_free(&ctx);
69 return DM_OK;
70 }
71
ConvertBytesToHexString(char * outBuf,uint32_t outBufLen,const unsigned char * inBuf,uint32_t inLen)72 int32_t ConvertBytesToHexString(char *outBuf, uint32_t outBufLen, const unsigned char *inBuf,
73 uint32_t inLen)
74 {
75 if ((outBuf == nullptr) || (inBuf == nullptr) || (outBufLen < HEXIFY_LEN(inLen))) {
76 return ERR_DM_INPUT_PARA_INVALID;
77 }
78
79 while (inLen > 0) {
80 unsigned char h = *inBuf / HEX_DIGIT_MAX_NUM;
81 unsigned char l = *inBuf % HEX_DIGIT_MAX_NUM;
82 if (h < DEC_MAX_NUM) {
83 *outBuf++ = '0' + h;
84 } else {
85 *outBuf++ = 'a' + h - DEC_MAX_NUM;
86 }
87 if (l < DEC_MAX_NUM) {
88 *outBuf++ = '0' + l;
89 } else {
90 *outBuf++ = 'a' + l - DEC_MAX_NUM;
91 }
92 ++inBuf;
93 inLen--;
94 }
95 return DM_OK;
96 }
97
ConvertHexStringToBytes(unsigned char * outBuf,uint32_t outBufLen,const char * inBuf,uint32_t inLen)98 int32_t DmSoftbusAdapterCrypto::ConvertHexStringToBytes(unsigned char *outBuf, uint32_t outBufLen, const char *inBuf,
99 uint32_t inLen)
100 {
101 (void)outBufLen;
102 if ((outBuf == NULL) || (inBuf == NULL) || (inLen % HEXIFY_UNIT_LEN != 0)) {
103 LOGE("invalid param");
104 return ERR_DM_FAILED;
105 }
106
107 uint32_t outLen = inLen / HEXIFY_UNIT_LEN;
108 uint32_t i = 0;
109 while (i < outLen) {
110 unsigned char c = *inBuf++;
111 if ((c >= '0') && (c <= '9')) {
112 c -= '0';
113 } else if ((c >= 'a') && (c <= 'f')) {
114 c -= 'a' - DEC_MAX_NUM;
115 } else if ((c >= 'A') && (c <= 'F')) {
116 c -= 'A' - DEC_MAX_NUM;
117 } else {
118 LOGE("HexToString Error! %c", c);
119 return ERR_DM_FAILED;
120 }
121 unsigned char c2 = *inBuf++;
122 if ((c2 >= '0') && (c2 <= '9')) {
123 c2 -= '0';
124 } else if ((c2 >= 'a') && (c2 <= 'f')) {
125 c2 -= 'a' - DEC_MAX_NUM;
126 } else if ((c2 >= 'A') && (c2 <= 'F')) {
127 c2 -= 'A' - DEC_MAX_NUM;
128 } else {
129 LOGE("HexToString Error! %c", c2);
130 return ERR_DM_FAILED;
131 }
132 *outBuf++ = (c << HEX_MAX_BIT_NUM) | c2;
133 i++;
134 }
135 return DM_OK;
136 }
137
GetUdidHash(const std::string & udid,unsigned char * udidHash)138 int32_t DmSoftbusAdapterCrypto::GetUdidHash(const std::string &udid, unsigned char *udidHash)
139 {
140 char hashResult[SHA_HASH_LEN] = {0};
141 int32_t ret = DmGenerateStrHash((const uint8_t *)udid.c_str(), strlen(udid.c_str()), (uint8_t *)hashResult);
142 if (ret != DM_OK) {
143 LOGE("GenerateStrHash failed");
144 return ret;
145 }
146 ret = ConvertBytesToHexString((char *)udidHash, SHORT_DEVICE_ID_HASH_LENGTH + 1, (const uint8_t *)hashResult,
147 SHORT_DEVICE_ID_HASH_LENGTH / HEXIFY_UNIT_LEN);
148 if (ret != DM_OK) {
149 LOGE("ConvertBytesToHexString failed");
150 return ret;
151 }
152 return DM_OK;
153 }
154
GetGroupIdHash(const std::string & groupId)155 std::string DmSoftbusAdapterCrypto::GetGroupIdHash(const std::string &groupId)
156 {
157 char hashResult[SHA_HASH_LEN] = {0};
158 int32_t ret = DmGenerateStrHash(reinterpret_cast<const uint8_t *>(groupId.c_str()), strlen(groupId.c_str()),
159 reinterpret_cast<uint8_t *>(hashResult));
160 if (ret != DM_OK) {
161 LOGE("GenerateStrHash failed");
162 return "";
163 }
164
165 std::stringstream ss;
166 for (int i = 0; i < SHA_HASH_LEN; i++) {
167 ss << std::hex << (int)hashResult[i];
168 }
169 return ss.str().substr(0, SHORT_DEVICE_ID_HASH_LENGTH);
170 }
171 } // namespace DistributedHardware
172 } // namespace OHOS