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 #include "bsl_sal.h"
17 #include "tls_binlog_id.h"
18 #include "hitls_error.h"
19 #include "hitls_sni.h"
20 #include "bsl_err_internal.h"
21 #ifdef HITLS_TLS_FEATURE_INDICATOR
22 #include "indicator.h"
23 #endif /* HITLS_TLS_FEATURE_INDICATOR */
24 #include "hs_reass.h"
25 #include "hs_common.h"
26 #include "hs_verify.h"
27 #include "hs_kx.h"
28 #include "hs.h"
29 #include "parse.h"
30
31 #define DTLS_OVER_UDP_DEFAULT_SIZE 2048u
32 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
33 #define EXTRA_DATA_SIZE 128u
34 #endif
35 #ifdef HITLS_TLS_FEATURE_FLIGHT
UIO_Init(TLS_Ctx * ctx)36 static int32_t UIO_Init(TLS_Ctx *ctx)
37 {
38 if (ctx->bUio != NULL) {
39 return HITLS_SUCCESS;
40 }
41 int32_t ret = HITLS_SUCCESS;
42 BSL_UIO *bUio = BSL_UIO_New(BSL_UIO_BufferMethod());
43 if (bUio == NULL) {
44 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17172, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN, "UIO_New fail", 0, 0, 0, 0);
45 return HITLS_MEMALLOC_FAIL;
46 }
47
48 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
49 uint32_t bufferLen = (uint32_t)ctx->config.pmtu;
50 if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask) &&
51 BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
52 ret = BSL_UIO_Ctrl(bUio, BSL_UIO_SET_BUFFER_SIZE, sizeof(uint32_t), &bufferLen);
53 if (ret != BSL_SUCCESS) {
54 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17173, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN,
55 "SET_BUFFER_SIZE fail, ret %d", ret, 0, 0, 0);
56 BSL_UIO_Free(bUio);
57 BSL_ERR_PUSH_ERROR(HITLS_UIO_FAIL);
58 return HITLS_UIO_FAIL;
59 }
60 }
61 #endif
62 ctx->bUio = bUio;
63 ret = BSL_UIO_Append(bUio, ctx->uio);
64 if (ret != BSL_SUCCESS) {
65 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17174, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN,
66 "UIO_Append fail, ret %d", ret, 0, 0, 0);
67 BSL_UIO_Free(bUio);
68 ctx->bUio = NULL;
69 return ret;
70 }
71
72 ctx->uio = bUio;
73 return HITLS_SUCCESS;
74 }
75
UIO_Deinit(TLS_Ctx * ctx)76 static int32_t UIO_Deinit(TLS_Ctx *ctx)
77 {
78 if (ctx->bUio == NULL) {
79 return HITLS_SUCCESS;
80 }
81
82 ctx->uio = BSL_UIO_PopCurrent(ctx->uio);
83 BSL_UIO_FreeChain(ctx->bUio);
84 ctx->bUio = NULL;
85
86 return HITLS_SUCCESS;
87 }
88 #endif /* HITLS_TLS_FEATURE_FLIGHT */
GetMsgSize(const TLS_Ctx * ctx)89 static uint32_t GetMsgSize(const TLS_Ctx *ctx)
90 {
91 (void)ctx;
92 uint32_t msgSize = DTLS_OVER_UDP_DEFAULT_SIZE;
93 #if defined(HITLS_BSL_UIO_UDP)
94 /* check whether DTLS over udp */
95 if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask) &&
96 BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
97 /* Before calling this function, the user has set pmtu or pmtu to the default value 1500. */
98 msgSize = (msgSize > ctx->config.pmtu) ? msgSize : (ctx->config.pmtu + EXTRA_DATA_SIZE);
99 } else
100 #endif /* HITLS_BSL_UIO_UDP */
101 {
102 msgSize = REC_MAX_PLAIN_DECRYPTO_MAX_LENGTH;
103 }
104 return msgSize;
105 }
106
HsInitChangeState(TLS_Ctx * ctx)107 static int32_t HsInitChangeState(TLS_Ctx *ctx)
108 {
109 if (ctx->isClient) {
110 return HS_ChangeState(ctx, TRY_SEND_CLIENT_HELLO);
111 }
112 #ifdef HITLS_TLS_FEATURE_RENEGOTIATION
113 // the server sends a hello request first during renegotiation
114 if (ctx->negotiatedInfo.isRenegotiation) {
115 return HS_ChangeState(ctx, TRY_SEND_HELLO_REQUEST);
116 }
117 #endif /* HITLS_TLS_FEATURE_RENEGOTIATION */
118 return HS_ChangeState(ctx, TRY_RECV_CLIENT_HELLO);
119 }
120
NewHsCtxConfig(TLS_Ctx * ctx,HS_Ctx * hsCtx)121 int32_t NewHsCtxConfig(TLS_Ctx *ctx, HS_Ctx *hsCtx)
122 {
123 (void)ctx;
124 if (VERIFY_Init(hsCtx) != HITLS_SUCCESS) {
125 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID17178, "VERIFY_Init fail");
126 }
127 #ifdef HITLS_TLS_FEATURE_FLIGHT
128 if (ctx->config.tlsConfig.isFlightTransmitEnable == true && UIO_Init(ctx) != HITLS_SUCCESS) {
129 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID17179, "UIO_Init fail");
130 }
131 #endif /* HITLS_TLS_FEATURE_FLIGHT */
132 hsCtx->kxCtx = HS_KeyExchCtxNew();
133 if (hsCtx->kxCtx == NULL) {
134 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID17180, "KeyExchCtxNew fail");
135 }
136 #ifdef HITLS_TLS_PROTO_TLS13
137 hsCtx->firstClientHello = NULL;
138 #endif /* HITLS_TLS_PROTO_TLS13 */
139 #ifdef HITLS_TLS_PROTO_DTLS12
140 hsCtx->reassMsg = HS_ReassNew();
141 if (hsCtx->reassMsg == NULL) {
142 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID17181, "ReassNew fail");
143 }
144 #endif
145 #ifdef HITLS_TLS_FEATURE_INDICATOR
146 INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_HANDSHAKE_START, INDICATE_VALUE_SUCCESS);
147 #endif /* HITLS_TLS_FEATURE_INDICATOR */
148 return HITLS_SUCCESS;
149 }
150
HS_Init(TLS_Ctx * ctx)151 int32_t HS_Init(TLS_Ctx *ctx)
152 {
153 int32_t ret = HITLS_SUCCESS;
154 if (ctx == NULL) {
155 BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
156 return RETURN_ERROR_NUMBER_PROCESS(HITLS_NULL_INPUT, BINLOG_ID17175, "ctx null");
157 }
158 // prevent multiple init in the ctx->hsCtx
159 if (ctx->hsCtx != NULL) {
160 return HITLS_SUCCESS;
161 }
162 HS_Ctx *hsCtx = (HS_Ctx *)BSL_SAL_Calloc(1u, sizeof(HS_Ctx));
163 if (hsCtx == NULL) {
164 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID17176, "Calloc fail");
165 }
166 ctx->hsCtx = hsCtx;
167 hsCtx->clientRandom = ctx->negotiatedInfo.clientRandom;
168 hsCtx->serverRandom = ctx->negotiatedInfo.serverRandom;
169 hsCtx->bufferLen = GetMsgSize(ctx);
170 hsCtx->msgBuf = BSL_SAL_Malloc(hsCtx->bufferLen);
171 if (hsCtx->msgBuf == NULL) {
172 (void)RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID17177, "Malloc fail");
173 goto ERR;
174 }
175 ret = NewHsCtxConfig(ctx, hsCtx);
176 if (ret != HITLS_SUCCESS) {
177 goto ERR;
178 }
179 return HsInitChangeState(ctx);
180 ERR:
181 HS_DeInit(ctx);
182 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
183 return HITLS_MEMALLOC_FAIL;
184 }
185
HS_DeInit(TLS_Ctx * ctx)186 void HS_DeInit(TLS_Ctx *ctx)
187 {
188 if (ctx == NULL || ctx->hsCtx == NULL) {
189 return;
190 }
191 HS_Ctx *hsCtx = ctx->hsCtx;
192
193 BSL_SAL_FREE(hsCtx->msgBuf);
194 #if defined(HITLS_TLS_FEATURE_SESSION) || defined(HITLS_TLS_PROTO_TLS13)
195 BSL_SAL_FREE(hsCtx->sessionId);
196 #endif /* HITLS_TLS_FEATURE_SESSION || HITLS_TLS_PROTO_TLS13 */
197 #ifdef HITLS_TLS_FEATURE_SNI
198 BSL_SAL_FREE(hsCtx->serverName);
199 #endif /* HITLS_TLS_FEATURE_SNI */
200 #ifdef HITLS_TLS_FEATURE_SESSION_TICKET
201 BSL_SAL_FREE(hsCtx->ticket);
202 #endif /* HITLS_TLS_FEATURE_SESSION_TICKET */
203 #ifdef HITLS_TLS_PROTO_TLS13
204 if (ctx->hsCtx->firstClientHello != NULL) {
205 HS_Msg hsMsg = {0};
206 hsMsg.type = CLIENT_HELLO;
207 hsMsg.body.clientHello = *ctx->hsCtx->firstClientHello;
208 HS_CleanMsg(&hsMsg);
209 BSL_SAL_FREE(ctx->hsCtx->firstClientHello);
210 }
211 #endif /* HITLS_TLS_PROTO_TLS13 */
212 /* clear sensitive information */
213 BSL_SAL_CleanseData(hsCtx->masterKey, MAX_DIGEST_SIZE);
214 if (hsCtx->peerCert != NULL) {
215 SAL_CERT_PairFree(ctx->config.tlsConfig.certMgrCtx, hsCtx->peerCert);
216 hsCtx->peerCert = NULL;
217 }
218
219 VERIFY_Deinit(hsCtx);
220 #ifdef HITLS_TLS_FEATURE_FLIGHT
221 if (ctx->config.tlsConfig.isFlightTransmitEnable == true) {
222 UIO_Deinit(ctx);
223 }
224 #endif /* HITLS_TLS_FEATURE_FLIGHT */
225 HS_KeyExchCtxFree(hsCtx->kxCtx);
226 #ifdef HITLS_TLS_PROTO_DTLS12
227 HS_ReassFree(hsCtx->reassMsg);
228 #endif
229 BSL_SAL_FREE(ctx->hsCtx);
230 return;
231 }