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 "securec.h"
17 #include "tls_binlog_id.h"
18 #include "bsl_log_internal.h"
19 #include "bsl_log.h"
20 #include "bsl_sal.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_bytes.h"
23 #include "hitls.h"
24 #include "hitls_error.h"
25 #include "hitls_config.h"
26 #include "tls.h"
27 #include "rec.h"
28 #include "transcript_hash.h"
29 #include "hs_ctx.h"
30 #include "hs.h"
31 #include "send_process.h"
32 #ifdef HITLS_TLS_FEATURE_INDICATOR
33 #include "indicator.h"
34 #endif /* HITLS_TLS_FEATURE_INDICATOR */
35
36 #ifdef HITLS_TLS_PROTO_TLS
TlsSendHandShakeMsg(TLS_Ctx * ctx)37 static int32_t TlsSendHandShakeMsg(TLS_Ctx *ctx)
38 {
39 int32_t ret = HITLS_SUCCESS;
40 HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx;
41
42 uint32_t maxRecPayloadLen = 0;
43 ret = REC_GetMaxWriteSize(ctx, &maxRecPayloadLen);
44 if (ret != HITLS_SUCCESS) {
45 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17125, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
46 "GetMaxWriteSize fail", 0, 0, 0, 0);
47 return ret;
48 }
49 do {
50 uint32_t singleWrite = hsCtx->msgLen - hsCtx->msgOffset;
51 singleWrite = (singleWrite > maxRecPayloadLen) ? maxRecPayloadLen : singleWrite;
52 ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, &hsCtx->msgBuf[hsCtx->msgOffset], singleWrite);
53 if (ret != HITLS_SUCCESS) {
54 return ret;
55 }
56 hsCtx->msgOffset += singleWrite;
57 } while (hsCtx->msgOffset != hsCtx->msgLen);
58 hsCtx->msgOffset = 0;
59
60 /* Add hash data */
61 ret = VERIFY_Append(hsCtx->verifyCtx, hsCtx->msgBuf, hsCtx->msgLen);
62 if (ret != HITLS_SUCCESS) {
63 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15795, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
64 "verify append fail when send handshake msg.", 0, 0, 0, 0);
65 return ret;
66 }
67 #ifdef HITLS_TLS_FEATURE_INDICATOR
68 INDICATOR_MessageIndicate(1, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, hsCtx->msgBuf, hsCtx->msgLen,
69 ctx, ctx->config.tlsConfig.msgArg);
70 #endif /* HITLS_TLS_FEATURE_INDICATOR */
71
72 hsCtx->msgLen = 0;
73 return HITLS_SUCCESS;
74 }
75 #endif /* HITLS_TLS_PROTO_TLS */
76 #ifdef HITLS_TLS_PROTO_DTLS12
DtlsSendFragmentHsMsg(TLS_Ctx * ctx,uint32_t maxRecPayloadLen)77 int32_t DtlsSendFragmentHsMsg(TLS_Ctx *ctx, uint32_t maxRecPayloadLen)
78 {
79 int32_t ret = HITLS_SUCCESS;
80 HS_Ctx *hsCtx = ctx->hsCtx;
81 uint8_t *data = (uint8_t *)BSL_SAL_Calloc(1u, maxRecPayloadLen);
82 if (data == NULL) {
83 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID17126, "Calloc fail");
84 }
85
86 /* Copy the fragment header */
87 if (memcpy_s(data, maxRecPayloadLen, hsCtx->msgBuf, DTLS_HS_MSG_HEADER_SIZE) != EOK) {
88 BSL_SAL_FREE(data);
89 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMCPY_FAIL, BINLOG_ID15796, "memcpy fail");
90 }
91
92 uint32_t fragmentOffset = 0;
93 uint32_t fragmentLen = 0;
94 /* Obtain the length of the handshake msg body */
95 uint32_t packetLen = BSL_ByteToUint24(&hsCtx->msgBuf[DTLS_HS_MSGLEN_ADDR]);
96
97 while (packetLen > 0) {
98 /* Calculate the fragment length */
99 fragmentLen = packetLen;
100 if (packetLen > (maxRecPayloadLen - DTLS_HS_MSG_HEADER_SIZE)) {
101 fragmentLen = maxRecPayloadLen - DTLS_HS_MSG_HEADER_SIZE;
102 }
103
104 BSL_Uint24ToByte(fragmentOffset, &data[DTLS_HS_FRAGMENT_OFFSET_ADDR]);
105 BSL_Uint24ToByte(fragmentLen, &data[DTLS_HS_FRAGMENT_LEN_ADDR]);
106 /* Write fragmented data */
107 if (memcpy_s(&data[DTLS_HS_MSG_HEADER_SIZE], maxRecPayloadLen - DTLS_HS_MSG_HEADER_SIZE,
108 &hsCtx->msgBuf[DTLS_HS_MSG_HEADER_SIZE + fragmentOffset], fragmentLen) != EOK) {
109 BSL_SAL_FREE(data);
110 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMCPY_FAIL, BINLOG_ID17127, "memcpy fail");
111 }
112
113 /* Send to the record layer */
114 ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, data, fragmentLen + DTLS_HS_MSG_HEADER_SIZE);
115 if (ret != HITLS_SUCCESS) {
116 BSL_SAL_FREE(data);
117 return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17128, "Write fail");
118 }
119 #ifdef HITLS_BSL_UIO_UDP
120 REC_Ctx *recCtx = ctx->recCtx;
121 /* Adding to the retransmission queue */
122 if (BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
123 ret = REC_RetransmitListAppend(recCtx, REC_TYPE_HANDSHAKE, data, fragmentLen + DTLS_HS_MSG_HEADER_SIZE);
124 if (ret != HITLS_SUCCESS) {
125 break;
126 }
127 }
128 #endif /* HITLS_BSL_UIO_UDP */
129 fragmentOffset += fragmentLen;
130 packetLen -= fragmentLen;
131 }
132
133 BSL_SAL_FREE(data);
134 return ret;
135 }
136
DtlsSendHandShakeMsg(TLS_Ctx * ctx)137 static int32_t DtlsSendHandShakeMsg(TLS_Ctx *ctx)
138 {
139 int32_t ret;
140 HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx;
141 uint32_t maxRecPayloadLen = 0;
142 ret = REC_GetMaxWriteSize(ctx, &maxRecPayloadLen);
143 if (ret != HITLS_SUCCESS) {
144 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17129, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
145 "GetMaxWriteSize fail", 0, 0, 0, 0);
146 return ret;
147 }
148
149 /* No sharding required */
150 if (maxRecPayloadLen >= hsCtx->msgLen) {
151 /* Send to the record layer */
152 ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, hsCtx->msgBuf, hsCtx->msgLen);
153 if (ret != HITLS_SUCCESS) {
154 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15797, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
155 "send handshake msg to record fail.", 0, 0, 0, 0);
156 return ret;
157 }
158 #ifdef HITLS_BSL_UIO_UDP
159 /* Adding to the retransmission queue */
160 if (BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
161 ret = REC_RetransmitListAppend(ctx->recCtx, REC_TYPE_HANDSHAKE, hsCtx->msgBuf, hsCtx->msgLen);
162 if (ret != HITLS_SUCCESS) {
163 return ret;
164 }
165 }
166 #endif /* HITLS_BSL_UIO_UDP */
167 } else {
168 ret = DtlsSendFragmentHsMsg(ctx, maxRecPayloadLen);
169 if (ret != HITLS_SUCCESS) {
170 return ret;
171 }
172 }
173
174 /* Add hash data */
175 ret = VERIFY_Append(hsCtx->verifyCtx, hsCtx->msgBuf, hsCtx->msgLen);
176 if (ret != HITLS_SUCCESS) {
177 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15798, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
178 "verify append fail when send handshake msg.", 0, 0, 0, 0);
179 return ret;
180 }
181 #ifdef HITLS_TLS_FEATURE_INDICATOR
182 INDICATOR_MessageIndicate(1, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, hsCtx->msgBuf, hsCtx->msgLen,
183 ctx, ctx->config.tlsConfig.msgArg);
184 #endif /* HITLS_TLS_FEATURE_INDICATOR */
185
186 hsCtx->msgLen = 0;
187 hsCtx->nextSendSeq++;
188
189 return HITLS_SUCCESS;
190 }
191 #endif /* HITLS_TLS_PROTO_DTLS12 */
192
HS_SendMsg(TLS_Ctx * ctx)193 int32_t HS_SendMsg(TLS_Ctx *ctx)
194 {
195 uint32_t version = HS_GetVersion(ctx);
196 switch (version) {
197 #ifdef HITLS_TLS_PROTO_TLS
198 case HITLS_VERSION_TLS12:
199 case HITLS_VERSION_TLS13:
200 #ifdef HITLS_TLS_PROTO_TLCP11
201 case HITLS_VERSION_TLCP_DTLCP11:
202 #if defined(HITLS_TLS_PROTO_DTLCP11)
203 if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
204 return DtlsSendHandShakeMsg(ctx);
205 }
206 #endif
207 #endif
208 return TlsSendHandShakeMsg(ctx);
209 #endif /* HITLS_TLS_PROTO_TLS */
210 #ifdef HITLS_TLS_PROTO_DTLS12
211 case HITLS_VERSION_DTLS12:
212 return DtlsSendHandShakeMsg(ctx);
213 #endif
214 default:
215 break;
216 }
217
218 BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION);
219 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15799, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
220 "Send handshake msg of unsupported version.", 0, 0, 0, 0);
221 return HITLS_MSG_HANDLE_UNSUPPORT_VERSION;
222 }
223