• 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 #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