1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15 #include "hitls_build.h"
16 #ifdef HITLS_TLS_HOST_CLIENT
17 #include <stdint.h>
18 #include "securec.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_log.h"
21 #include "bsl_err_internal.h"
22 #include "tls_binlog_id.h"
23 #include "tls.h"
24 #include "bsl_bytes.h"
25 #include "hitls_error.h"
26 #include "hitls_security.h"
27 #ifdef HITLS_TLS_FEATURE_SECURITY
28 #include "security.h"
29 #endif
30 #include "cipher_suite.h"
31 #include "hs_ctx.h"
32 #include "pack_common.h"
33 #include "pack_extensions.h"
34 #include "hs_common.h"
35
36 #define SINGLE_CIPHER_SUITE_SIZE 2u
37 #define CIPHER_SUITES_LEN_SIZE 2u
38
39 // Pack the version content of the client Hello message.
PackClientVersion(const TLS_Ctx * ctx,uint16_t version,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)40 static int32_t PackClientVersion(const TLS_Ctx *ctx, uint16_t version, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
41 {
42 (void)bufLen;
43 (void)ctx;
44 uint32_t offset = 0u;
45 #ifdef HITLS_TLS_FEATURE_SECURITY
46 const TLS_Config *tlsConfig = &ctx->config.tlsConfig;
47 int32_t ret = SECURITY_CfgCheck((const HITLS_Config *)tlsConfig, HITLS_SECURITY_SECOP_VERSION, 0, version, NULL);
48 if (ret != SECURITY_SUCCESS) {
49 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16924, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
50 "CfgCheck fail, ret %d", ret, 0, 0, 0);
51 ctx->method.sendAlert((TLS_Ctx *)(uintptr_t)ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY);
52 BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSECURE_VERSION);
53 return HITLS_PACK_UNSECURE_VERSION;
54 }
55 #endif /* HITLS_TLS_FEATURE_SECURITY */
56 BSL_Uint16ToByte(version, &buf[offset]);
57 offset += sizeof(uint16_t);
58
59 *usedLen = offset;
60 return HITLS_SUCCESS;
61 }
62 #ifdef HITLS_TLS_PROTO_DTLS12
63 // Pack the cookie content of the client Hello message.
PackClientCookie(const uint8_t * cookie,uint8_t cookieLen,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)64 static int32_t PackClientCookie(const uint8_t *cookie, uint8_t cookieLen,
65 uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
66 {
67 uint32_t offset = 0u;
68
69 if (bufLen < (sizeof(uint8_t) + cookieLen)) {
70 BSL_ERR_PUSH_ERROR(HITLS_PACK_COOKIE_ERR);
71 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15730, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
72 "the buffer length of cookie is not enough.", 0, 0, 0, 0);
73 return HITLS_PACK_COOKIE_ERR;
74 }
75
76 buf[offset] = cookieLen;
77 offset += sizeof(uint8_t);
78 if (cookieLen == 0u) {
79 *usedLen = offset;
80 return HITLS_SUCCESS;
81 }
82
83 (void)memcpy_s(&buf[offset], bufLen - offset, cookie, cookieLen);
84 offset += cookieLen;
85
86 *usedLen = offset;
87 return HITLS_SUCCESS;
88 }
89 #endif /* HITLS_TLS_PROTO_DTLS12 */
PackCipherSuites(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * offset,bool isTls13)90 static int32_t PackCipherSuites(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *offset, bool isTls13)
91 {
92 uint16_t *cipherSuites = NULL;
93 uint32_t cipherSuitesSize = 0;
94 uint32_t tmpOffset = *offset;
95 #ifdef HITLS_TLS_PROTO_TLS13
96 if (isTls13) {
97 cipherSuites = ctx->config.tlsConfig.tls13CipherSuites;
98 cipherSuitesSize = ctx->config.tlsConfig.tls13cipherSuitesSize;
99 } else {
100 cipherSuites = ctx->config.tlsConfig.cipherSuites;
101 cipherSuitesSize = ctx->config.tlsConfig.cipherSuitesSize;
102 }
103 #else
104 (void)isTls13;
105 cipherSuites = ctx->config.tlsConfig.cipherSuites;
106 cipherSuitesSize = ctx->config.tlsConfig.cipherSuitesSize;
107 #endif /* HITLS_TLS_PROTO_TLS13 */
108
109 for (uint32_t i = 0; i < cipherSuitesSize; i++) {
110 if (!IsCipherSuiteAllowed(ctx, cipherSuites[i])) {
111 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15845, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
112 "The cipher suite [0x%04x] is NOT supported, index=[%u].", cipherSuites[i], i, 0, 0);
113 continue;
114 }
115 if (tmpOffset + sizeof(uint16_t) > bufLen) {
116 BSL_ERR_PUSH_ERROR(HITLS_PACK_CLIENT_CIPHER_SUITE_ERR);
117 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15733, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
118 "pack cipher suite error, the buffer length is not enough.", 0, 0, 0, 0);
119 return HITLS_PACK_CLIENT_CIPHER_SUITE_ERR;
120 }
121 BSL_Uint16ToByte(cipherSuites[i], &buf[tmpOffset]);
122 tmpOffset += sizeof(uint16_t);
123 }
124
125 *offset = tmpOffset;
126 return HITLS_SUCCESS;
127 }
128
PackScsvCipherSuites(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * offset)129 static int32_t PackScsvCipherSuites(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *offset)
130 {
131 uint32_t tmpOffset = *offset;
132 /* If the local is not in the renegotiation state, the SCSV algorithm set needs to be packed. */
133 if (!ctx->negotiatedInfo.isRenegotiation) {
134 if (tmpOffset + sizeof(uint16_t) > bufLen) {
135 BSL_ERR_PUSH_ERROR(HITLS_PACK_CLIENT_CIPHER_SUITE_ERR);
136 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15338, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
137 "pack cipher suite error, the buffer length is not enough.", 0, 0, 0, 0);
138 return HITLS_PACK_CLIENT_CIPHER_SUITE_ERR;
139 }
140 BSL_Uint16ToByte(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, &buf[tmpOffset]);
141 tmpOffset += sizeof(uint16_t);
142 }
143 #ifdef HITLS_TLS_FEATURE_MODE_FALL_BACK_SCSV
144 if ((ctx->config.tlsConfig.modeSupport & HITLS_MODE_SEND_FALLBACK_SCSV) != 0) {
145 if (tmpOffset + sizeof(uint16_t) > bufLen) {
146 BSL_ERR_PUSH_ERROR(HITLS_PACK_CLIENT_CIPHER_SUITE_ERR);
147 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15337, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
148 "pack cipher suite error, the buffer length is not enough.", 0, 0, 0, 0);
149 return HITLS_PACK_CLIENT_CIPHER_SUITE_ERR;
150 }
151 BSL_Uint16ToByte(TLS_FALLBACK_SCSV, &buf[tmpOffset]);
152 tmpOffset += sizeof(uint16_t);
153 }
154 #endif
155 *offset = tmpOffset;
156 return HITLS_SUCCESS;
157 }
158
159 // Pack the cipher suites content of the client hello message.
PackClientCipherSuites(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)160 static int32_t PackClientCipherSuites(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
161 {
162 int32_t ret = HITLS_SUCCESS;
163 uint16_t cipherSuitesLen = 0u;
164 /* Finally fill in the length of the cipher suites */
165 uint32_t offset = CIPHER_SUITES_LEN_SIZE;
166 #ifdef HITLS_TLS_PROTO_TLS13
167 if (ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13) {
168 ret = PackCipherSuites(ctx, buf, bufLen, &offset, 1);
169 if (ret != HITLS_SUCCESS) {
170 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16925, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
171 "PackCipherSuites fail", 0, 0, 0, 0);
172 return ret;
173 }
174 }
175 #endif /* HITLS_TLS_PROTO_TLS13 */
176 if (ctx->config.tlsConfig.minVersion != HITLS_VERSION_TLS13) {
177 ret = PackCipherSuites(ctx, buf, bufLen, &offset, 0);
178 if (ret != HITLS_SUCCESS) {
179 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16926, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
180 "PackCipherSuites fail", 0, 0, 0, 0);
181 return ret;
182 }
183 }
184
185 if (offset == SINGLE_CIPHER_SUITE_SIZE) {
186 BSL_ERR_PUSH_ERROR(HITLS_PACK_CLIENT_CIPHER_SUITE_ERR);
187 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15732, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
188 "pack cipher suite error, no cipher suite.", 0, 0, 0, 0);
189 return HITLS_PACK_CLIENT_CIPHER_SUITE_ERR;
190 }
191
192 ret = PackScsvCipherSuites(ctx, buf, bufLen, &offset);
193 if (ret != HITLS_SUCCESS) {
194 return ret;
195 }
196 /* The cipher suite has been filled. Each cipher suite takes two bytes, so the length of the filled cipher suite can
197 * be calculated according to offset */
198 cipherSuitesLen = (uint16_t)(offset - CIPHER_SUITES_LEN_SIZE);
199 BSL_Uint16ToByte(cipherSuitesLen, &buf[0]);
200 *usedLen = offset;
201 return HITLS_SUCCESS;
202 }
203
204 // Pack the content of the method for compressing the client Hello message.
PackClientCompressionMethod(uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)205 static int32_t PackClientCompressionMethod(uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
206 {
207 uint32_t offset = 0u;
208
209 if (bufLen < sizeof(uint8_t) + sizeof(uint8_t)) {
210 BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH);
211 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15734, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
212 "pack compression method error, the buffer length is not enough.", 0, 0, 0, 0);
213 return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH;
214 }
215
216 buf[offset] = 1;
217 offset += sizeof(uint8_t);
218 buf[offset] = 0; /* Compression methods Currently support uncompressed */
219 offset += sizeof(uint8_t);
220
221 *usedLen = offset;
222 return HITLS_SUCCESS;
223 }
224
225 // Pack the session and cookie content of the client hello message.
PackSessionAndCookie(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)226 static int32_t PackSessionAndCookie(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
227 {
228 int32_t ret = HITLS_SUCCESS;
229 uint32_t offset = 0u;
230 uint32_t len = 0;
231 (void)len;
232 (void)ret;
233 (void)ctx;
234 (void)bufLen;
235 #if defined(HITLS_TLS_FEATURE_SESSION_ID) || defined(HITLS_TLS_PROTO_TLS13)
236 HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx;
237 len = 0u;
238 ret = PackSessionId(hsCtx->sessionId, hsCtx->sessionIdSize, &buf[offset], bufLen - offset, &len);
239 if (ret != HITLS_SUCCESS) {
240 (void)memset_s(hsCtx->sessionId, hsCtx->sessionIdSize, 0, hsCtx->sessionIdSize);
241 return ret;
242 }
243 offset += len;
244 #else // Session recovery is not supported.
245 /* SessionId (Session is not supported yet and the length field is initialized with a value of 0) */
246 buf[offset] = 0;
247 offset += sizeof(uint8_t);
248 #endif
249
250 #ifdef HITLS_TLS_PROTO_DTLS12
251 const TLS_Config *tlsConfig = &ctx->config.tlsConfig;
252 if (IS_SUPPORT_DATAGRAM(tlsConfig->originVersionMask)) {
253 len = 0u;
254 ret = PackClientCookie(ctx->negotiatedInfo.cookie, (uint8_t)ctx->negotiatedInfo.cookieSize,
255 &buf[offset], bufLen - offset, &len);
256 if (ret != HITLS_SUCCESS) {
257 (void)memset_s(ctx->negotiatedInfo.cookie, ctx->negotiatedInfo.cookieSize,
258 0, ctx->negotiatedInfo.cookieSize);
259 return ret;
260 }
261 offset += len;
262 }
263 #endif
264
265 *usedLen = offset;
266 return HITLS_SUCCESS;
267 }
268
269 // Pack the mandatory content of the ClientHello message.
PackClientHelloMandatoryField(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)270 static int32_t PackClientHelloMandatoryField(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
271 {
272 /* The bufLen must be able to assemble at least the version number (2 bytes),
273 random number (32 bytes), and session ID (1 byte) */
274 if (bufLen < (sizeof(uint16_t) + HS_RANDOM_SIZE + sizeof(uint8_t))) {
275 return PackBufLenError(BINLOG_ID16078, BINGLOG_STR("client hello"));
276 }
277 int32_t ret = HITLS_SUCCESS;
278 uint32_t offset = 0u;
279 uint32_t len = 0u;
280 const TLS_Config *tlsConfig = &ctx->config.tlsConfig;
281 if (ctx->hsCtx->clientRandom == NULL) {
282 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16927, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
283 "clientRandom null", 0, 0, 0, 0);
284 BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
285 return HITLS_NULL_INPUT;
286 }
287 uint16_t version =
288 #ifdef HITLS_TLS_PROTO_TLS13
289 (tlsConfig->maxVersion == HITLS_VERSION_TLS13) ? HITLS_VERSION_TLS12 :
290 #endif
291 tlsConfig->maxVersion;
292 ret = PackClientVersion(ctx, version, buf, bufLen, &len);
293 if (ret != HITLS_SUCCESS) {
294 return ret;
295 }
296 offset += len;
297
298 (void)memcpy_s(&buf[offset], bufLen - offset, ctx->hsCtx->clientRandom, HS_RANDOM_SIZE);
299 offset += HS_RANDOM_SIZE;
300
301 len = 0u;
302 ret = PackSessionAndCookie(ctx, &buf[offset], bufLen - offset, &len);
303 if (ret != HITLS_SUCCESS) {
304 return ret;
305 }
306 offset += len;
307
308 len = 0u;
309 ret = PackClientCipherSuites(ctx, &buf[offset], bufLen - offset, &len);
310 if (ret != HITLS_SUCCESS) {
311 return ret;
312 }
313 offset += len;
314
315 len = 0u;
316 ret = PackClientCompressionMethod(&buf[offset], bufLen - offset, &len);
317 if (ret != HITLS_SUCCESS) {
318 return ret;
319 }
320 offset += len;
321
322 *usedLen = offset;
323 return HITLS_SUCCESS;
324 }
325
326 // Pack the ClientHello message to form the Handshake body.
PackClientHello(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)327 int32_t PackClientHello(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
328 {
329 int32_t ret = HITLS_SUCCESS;
330 uint32_t offset = 0u;
331 uint32_t msgLen = 0u;
332 uint32_t exMsgLen = 0u;
333
334 ret = PackClientHelloMandatoryField(ctx, buf, bufLen, &msgLen);
335 if (ret != HITLS_SUCCESS) {
336 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15735, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
337 "pack client hello mandatory content fail.", 0, 0, 0, 0);
338 return ret;
339 }
340 offset += msgLen;
341 exMsgLen = 0u;
342 ret = PackClientExtension(ctx, &buf[offset], bufLen - offset, &exMsgLen);
343 if (ret != HITLS_SUCCESS) {
344 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15736, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
345 "pack client hello extension content fail.", 0, 0, 0, 0);
346 return ret;
347 }
348 offset += exMsgLen;
349
350 *usedLen = offset;
351 return HITLS_SUCCESS;
352 }
353
354 #endif /* HITLS_TLS_HOST_CLIENT */