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 "das_version_util.h"
17 #include "common_defs.h"
18 #include "hc_log.h"
19 #include "hc_types.h"
20 #include "json_utils.h"
21 #include "string_util.h"
22
23 #define BIND_PRIORITY_LEN 5
24 #define AUTH_PRIORITY_LEN 5
25
26 typedef struct PriorityMapT {
27 uint32_t alg;
28 ProtocolType type;
29 } PriorityMap;
30
31 VersionStruct g_defaultVersion = { 1, 0, 0 };
32 PriorityMap g_bindPriorityList[BIND_PRIORITY_LEN] = {
33 { EC_PAKE_V2, PAKE_V2 },
34 { DL_PAKE_V2, PAKE_V2 },
35 { EC_PAKE_V1, PAKE_V1 },
36 { DL_PAKE_V1, PAKE_V1 },
37 { ISO_ALG, ISO }
38 };
39 PriorityMap g_authPriorityList[AUTH_PRIORITY_LEN] = {
40 { PSK_SPEKE | EC_PAKE_V2, PAKE_V2 },
41 { PSK_SPEKE | EC_PAKE_V1, PAKE_V1 },
42 { ISO_ALG, ISO }
43 };
44
GetVersionFromJson(const CJson * jsonObj,VersionStruct * minVer,VersionStruct * maxVer)45 int32_t GetVersionFromJson(const CJson* jsonObj, VersionStruct *minVer, VersionStruct *maxVer)
46 {
47 CHECK_PTR_RETURN_ERROR_CODE(jsonObj, "jsonObj");
48 CHECK_PTR_RETURN_ERROR_CODE(minVer, "minVer");
49 CHECK_PTR_RETURN_ERROR_CODE(maxVer, "maxVer");
50
51 const char *minStr = GetStringFromJson(jsonObj, FIELD_MIN_VERSION);
52 CHECK_PTR_RETURN_ERROR_CODE(minStr, "minStr");
53 const char *maxStr = GetStringFromJson(jsonObj, FIELD_CURRENT_VERSION);
54 CHECK_PTR_RETURN_ERROR_CODE(maxStr, "maxStr");
55
56 int32_t minRet = StringToVersion(minStr, minVer);
57 int32_t maxRet = StringToVersion(maxStr, maxVer);
58 if (minRet != HC_SUCCESS || maxRet != HC_SUCCESS) {
59 LOGE("Convert version string to struct failed.");
60 return HC_ERROR;
61 }
62 return HC_SUCCESS;
63 }
64
AddVersionToJson(CJson * jsonObj,const VersionStruct * minVer,const VersionStruct * maxVer)65 int32_t AddVersionToJson(CJson *jsonObj, const VersionStruct *minVer, const VersionStruct *maxVer)
66 {
67 CHECK_PTR_RETURN_ERROR_CODE(jsonObj, "jsonObj");
68 CHECK_PTR_RETURN_ERROR_CODE(minVer, "minVer");
69 CHECK_PTR_RETURN_ERROR_CODE(maxVer, "maxVer");
70
71 char minStr[TMP_VERSION_STR_LEN] = { 0 };
72 int32_t minRet = VersionToString(minVer, minStr, TMP_VERSION_STR_LEN);
73 char maxStr[TMP_VERSION_STR_LEN] = { 0 };
74 int32_t maxRet = VersionToString(maxVer, maxStr, TMP_VERSION_STR_LEN);
75 if (minRet != HC_SUCCESS || maxRet != HC_SUCCESS) {
76 return HC_ERROR;
77 }
78 CJson* version = CreateJson();
79 if (version == NULL) {
80 LOGE("CreateJson for version failed.");
81 return HC_ERR_JSON_CREATE;
82 }
83 if (AddStringToJson(version, FIELD_MIN_VERSION, minStr) != HC_SUCCESS) {
84 LOGE("Add min version to json failed.");
85 FreeJson(version);
86 return HC_ERR_JSON_ADD;
87 }
88 if (AddStringToJson(version, FIELD_CURRENT_VERSION, maxStr) != HC_SUCCESS) {
89 LOGE("Add max version to json failed.");
90 FreeJson(version);
91 return HC_ERR_JSON_ADD;
92 }
93 if (AddObjToJson(jsonObj, FIELD_VERSION, version) != HC_SUCCESS) {
94 LOGE("Add version object to json failed.");
95 FreeJson(version);
96 return HC_ERR_JSON_ADD;
97 }
98 FreeJson(version);
99 return HC_SUCCESS;
100 }
101
IsVersionEqual(VersionStruct * src,VersionStruct * des)102 bool IsVersionEqual(VersionStruct *src, VersionStruct *des)
103 {
104 if ((src->first == des->first) && (src->second == des->second) && (src->third == des->third)) {
105 return true;
106 }
107 return false;
108 }
109
NegotiateVersion(VersionStruct * minVersionPeer,VersionStruct * curVersionPeer,VersionStruct * curVersionSelf)110 int32_t NegotiateVersion(VersionStruct *minVersionPeer, VersionStruct *curVersionPeer,
111 VersionStruct *curVersionSelf)
112 {
113 (void)minVersionPeer;
114 if (IsVersionEqual(curVersionPeer, &g_defaultVersion)) {
115 curVersionSelf->first = g_defaultVersion.first;
116 curVersionSelf->second = g_defaultVersion.second;
117 curVersionSelf->third = g_defaultVersion.third;
118 return HC_SUCCESS;
119 }
120 curVersionSelf->third = curVersionSelf->third & curVersionPeer->third;
121 if (curVersionSelf->third == 0) {
122 LOGE("Unsupported version!");
123 return HC_ERR_UNSUPPORTED_VERSION;
124 }
125 return HC_SUCCESS;
126 }
127
GetBindPrototolType(VersionStruct * curVersion)128 static ProtocolType GetBindPrototolType(VersionStruct *curVersion)
129 {
130 if (IsVersionEqual(curVersion, &g_defaultVersion)) {
131 return PAKE_V1;
132 }
133 for (int i = 0; i < BIND_PRIORITY_LEN; i++) {
134 if ((curVersion->third & g_bindPriorityList[i].alg) == g_bindPriorityList[i].alg) {
135 return g_bindPriorityList[i].type;
136 }
137 }
138 return PROTOCOL_TYPE_NONE;
139 }
140
GetAuthPrototolType(VersionStruct * curVersion)141 static ProtocolType GetAuthPrototolType(VersionStruct *curVersion)
142 {
143 if (IsVersionEqual(curVersion, &g_defaultVersion)) {
144 LOGE("Not support STS.");
145 return PROTOCOL_TYPE_NONE;
146 }
147 for (int i = 0; i < AUTH_PRIORITY_LEN; i++) {
148 if ((curVersion->third & g_authPriorityList[i].alg) == g_authPriorityList[i].alg) {
149 return g_authPriorityList[i].type;
150 }
151 }
152 return PROTOCOL_TYPE_NONE;
153 }
154
GetPrototolType(VersionStruct * curVersion,OperationCode opCode)155 ProtocolType GetPrototolType(VersionStruct *curVersion, OperationCode opCode)
156 {
157 switch (opCode) {
158 case OP_BIND:
159 case AUTH_KEY_AGREEMENT:
160 return GetBindPrototolType(curVersion);
161 case AUTHENTICATE:
162 case OP_UNBIND:
163 return GetAuthPrototolType(curVersion);
164 default:
165 LOGE("Unsupported opCode: %d.", opCode);
166 }
167 return PROTOCOL_TYPE_NONE;
168 }
169
GetSupportedPakeAlg(VersionStruct * curVersion,ProtocolType protocolType)170 PakeAlgType GetSupportedPakeAlg(VersionStruct *curVersion, ProtocolType protocolType)
171 {
172 PakeAlgType pakeAlgType = PAKE_ALG_NONE;
173 if (protocolType == PAKE_V2) {
174 pakeAlgType = ((curVersion->third & EC_PAKE_V2) >> ALG_OFFSET_FOR_PAKE_V2) |
175 ((curVersion->third & DL_PAKE_V2) >> ALG_OFFSET_FOR_PAKE_V2);
176 } else if (protocolType == PAKE_V1) {
177 pakeAlgType = ((curVersion->third & EC_PAKE_V1) >> ALG_OFFSET_FOR_PAKE_V1) |
178 ((curVersion->third & DL_PAKE_V1) >> ALG_OFFSET_FOR_PAKE_V1);
179 } else {
180 LOGE("Invalid protocolType: %d.", protocolType);
181 }
182 return pakeAlgType;
183 }
184
IsSupportedPsk(VersionStruct * curVersion)185 bool IsSupportedPsk(VersionStruct *curVersion)
186 {
187 return ((curVersion->third & PSK_SPEKE) != 0);
188 }