• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */