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 "securec.h"
16 #include "bsl_sal.h"
17 #include "tls_binlog_id.h"
18 #include "bsl_log_internal.h"
19 #include "bsl_log.h"
20 #include "bsl_err_internal.h"
21 #include "bsl_bytes.h"
22 #include "hitls_error.h"
23 #include "hitls_config.h"
24 #include "rec.h"
25 #include "bsl_uio.h"
26 #include "rec_write.h"
27 #include "rec_read.h"
28 #include "rec_crypto.h"
29 #include "hs.h"
30 #include "alert.h"
31 #include "record.h"
32
33 // Release RecStatesSuite
RecConnStatesDeinit(RecCtx * recordCtx)34 static void RecConnStatesDeinit(RecCtx *recordCtx)
35 {
36 RecConnStateFree(recordCtx->readStates.currentState);
37 RecConnStateFree(recordCtx->writeStates.currentState);
38 return;
39 }
40
41 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
RecCmpPmtu(const TLS_Ctx * ctx,uint32_t * recSize)42 static void RecCmpPmtu(const TLS_Ctx *ctx, uint32_t *recSize)
43 {
44 if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask) &&
45 BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
46 uint32_t pmtuLimit = ctx->config.pmtu - REC_IP_UDP_HEAD_SIZE;
47 /* If miniaturization is enabled in the dtls over udp scenario, the mtu size is used */
48 *recSize = (*recSize > pmtuLimit) ? pmtuLimit : *recSize;
49 }
50 }
51 #endif
52
RecGetDefaultBufferSize(bool isDtls,bool isRead)53 static uint32_t RecGetDefaultBufferSize(bool isDtls, bool isRead)
54 {
55 (void)isDtls;
56 uint32_t recHeaderLen =
57 #ifdef HITLS_TLS_PROTO_DTLS12
58 isDtls ? REC_DTLS_RECORD_HEADER_LEN :
59 #endif
60 REC_TLS_RECORD_HEADER_LEN;
61 uint32_t overHead = REC_MAX_WRITE_ENCRYPTED_OVERHEAD;
62 if (isRead) {
63 overHead = REC_MAX_READ_ENCRYPTED_OVERHEAD;
64 }
65 return recHeaderLen + REC_MAX_PLAIN_TEXT_LENGTH + overHead;
66 }
67
RecGetReadBufferSize(const TLS_Ctx * ctx)68 static uint32_t RecGetReadBufferSize(const TLS_Ctx *ctx)
69 {
70 uint32_t recSize = RecGetDefaultBufferSize(IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask), true);
71 if (ctx->negotiatedInfo.recordSizeLimit != 0 &&
72 ctx->negotiatedInfo.recordSizeLimit <= REC_MAX_PLAIN_TEXT_LENGTH) {
73 recSize -= REC_MAX_PLAIN_TEXT_LENGTH - ctx->negotiatedInfo.recordSizeLimit;
74 if (HS_GetVersion(ctx) == HITLS_VERSION_TLS13) {
75 recSize--;
76 }
77 }
78 return recSize;
79 }
80
RecGetWriteBufferSize(const TLS_Ctx * ctx)81 static uint32_t RecGetWriteBufferSize(const TLS_Ctx *ctx)
82 {
83 uint32_t recSize = RecGetDefaultBufferSize(IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask), false);
84 if (ctx->negotiatedInfo.peerRecordSizeLimit != 0) {
85 recSize -= REC_MAX_PLAIN_TEXT_LENGTH - ctx->negotiatedInfo.peerRecordSizeLimit;
86 if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) {
87 recSize--;
88 }
89 }
90 #if defined(HITLS_BSL_UIO_UDP)
91 RecCmpPmtu(ctx, &recSize);
92 #endif
93 return recSize;
94 }
95
RecGetInitBufferSize(const TLS_Ctx * ctx,bool isRead)96 uint32_t RecGetInitBufferSize(const TLS_Ctx *ctx, bool isRead)
97 {
98 /* If the TLS protocol is used, there is no PMTU limit */
99 return isRead ? RecGetReadBufferSize(ctx) : RecGetWriteBufferSize(ctx);
100 }
101
RecDerefBufList(TLS_Ctx * ctx)102 int32_t RecDerefBufList(TLS_Ctx *ctx)
103 {
104 int32_t ret = RecBufListDereference(ctx->recCtx->appRecList);
105 if (ret != HITLS_SUCCESS) {
106 return ret;
107 }
108 return RecBufListDereference(ctx->recCtx->hsRecList);
109 }
110
111
InnerRecRead(TLS_Ctx * ctx,REC_Type recordType,uint8_t * data,uint32_t * readLen,uint32_t num)112 static int32_t InnerRecRead(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num)
113 {
114 (void)recordType;
115 (void)readLen;
116 #ifdef HITLS_TLS_CONFIG_STATE
117 ctx->rwstate = HITLS_NOTHING;
118 #endif
119
120 #ifdef HITLS_TLS_PROTO_DTLS12
121 if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
122 return DtlsRecordRead(ctx, recordType, data, readLen, num);
123 }
124 #endif
125 #ifdef HITLS_TLS_PROTO_TLS
126 return TlsRecordRead(ctx, recordType, data, readLen, num);
127 #else
128 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17294, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
129 "internal exception occurs", 0, 0, 0, 0);
130 return HITLS_INTERNAL_EXCEPTION;
131 #endif
132 }
InnerRecWrite(TLS_Ctx * ctx,REC_Type recordType,const uint8_t * data,uint32_t num)133 static int32_t InnerRecWrite(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num)
134 {
135 #ifdef HITLS_TLS_CONFIG_STATE
136 ctx->rwstate = HITLS_NOTHING;
137 #endif
138
139 uint32_t maxWriteSize;
140 int32_t ret = REC_GetMaxWriteSize(ctx, &maxWriteSize);
141 if (ret != HITLS_SUCCESS) {
142 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17295, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
143 "GetMaxWriteSize fail", 0, 0, 0, 0);
144 return ret;
145 }
146 if (num > maxWriteSize) {
147 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15539, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
148 "Record wrtie: plain length is too long.", 0, 0, 0, 0);
149 BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_TOO_BIG_LENGTH);
150 return HITLS_REC_ERR_TOO_BIG_LENGTH;
151 }
152
153 #ifdef HITLS_TLS_PROTO_DTLS12
154 if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
155 /* DTLS */
156 return DtlsRecordWrite(ctx, recordType, data, num);
157 }
158 #endif
159 #ifdef HITLS_TLS_PROTO_TLS
160 return TlsRecordWrite(ctx, recordType, data, num);
161 #else
162 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17296, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
163 "internal exception occurs", 0, 0, 0, 0);
164 return HITLS_INTERNAL_EXCEPTION;
165 #endif
166 }
167
RecConnStatesInit(RecCtx * recordCtx)168 static int32_t RecConnStatesInit(RecCtx *recordCtx)
169 {
170 recordCtx->recRead = InnerRecRead;
171 recordCtx->recWrite = InnerRecWrite;
172 recordCtx->readStates.currentState = RecConnStateNew();
173 if (recordCtx->readStates.currentState == NULL) {
174 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17297, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
175 "StateNew fail", 0, 0, 0, 0);
176 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
177 return HITLS_MEMALLOC_FAIL;
178 }
179
180 recordCtx->writeStates.currentState = RecConnStateNew();
181 if (recordCtx->writeStates.currentState == NULL) {
182 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17298, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
183 "StateNew fail", 0, 0, 0, 0);
184 RecConnStateFree(recordCtx->readStates.currentState);
185 recordCtx->readStates.currentState = NULL;
186 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
187 return HITLS_MEMALLOC_FAIL;
188 }
189 return HITLS_SUCCESS;
190 }
191
RecBufInit(TLS_Ctx * ctx,RecCtx * newRecCtx)192 static int RecBufInit(TLS_Ctx *ctx, RecCtx *newRecCtx)
193 {
194 newRecCtx->inBuf = RecBufNew(RecGetInitBufferSize(ctx, true));
195 if (newRecCtx->inBuf == NULL) {
196 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
197 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15532, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
198 "Record: malloc fail.", 0, 0, 0, 0);
199 return HITLS_MEMALLOC_FAIL;
200 }
201
202 newRecCtx->outBuf = RecBufNew(RecGetInitBufferSize(ctx, false));
203 if (newRecCtx->outBuf == NULL) {
204 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
205 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15533, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
206 "Record: malloc fail.", 0, 0, 0, 0);
207 return HITLS_MEMALLOC_FAIL;
208 }
209 newRecCtx->hsRecList = RecBufListNew();
210 newRecCtx->appRecList = RecBufListNew();
211 if (newRecCtx->hsRecList == NULL || newRecCtx->appRecList == NULL) {
212 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17299, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
213 "BufListNew fail", 0, 0, 0, 0);
214 return HITLS_MEMALLOC_FAIL;
215 }
216 return HITLS_SUCCESS;
217 }
218
RecDeInit(RecCtx * recordCtx)219 static void RecDeInit(RecCtx *recordCtx)
220 {
221 RecBufFree(recordCtx->outBuf);
222 RecBufFree(recordCtx->inBuf);
223 RecBufListFree(recordCtx->hsRecList);
224 RecBufListFree(recordCtx->appRecList);
225
226 RecConnStatesDeinit(recordCtx);
227 RecConnStateFree(recordCtx->readStates.pendingState);
228 RecConnStateFree(recordCtx->writeStates.pendingState);
229 RecConnStateFree(recordCtx->readStates.outdatedState);
230 RecConnStateFree(recordCtx->writeStates.outdatedState);
231
232 #ifdef HITLS_TLS_PROTO_DTLS12
233 UnprocessedAppMsgListDeinit(&recordCtx->unprocessedAppMsgList);
234 #if defined(HITLS_BSL_UIO_UDP)
235 BSL_SAL_FREE(recordCtx->unprocessedHsMsg.recordBody);
236 REC_RetransmitListClean(recordCtx);
237 #endif
238 #endif /* HITLS_TLS_PROTO_DTLS12 */
239 }
240
REC_Init(TLS_Ctx * ctx)241 int32_t REC_Init(TLS_Ctx *ctx)
242 {
243 if (ctx == NULL) {
244 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17300, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "ctx null", 0, 0, 0, 0);
245 BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
246 return HITLS_NULL_INPUT;
247 }
248
249 if (ctx->recCtx != NULL) {
250 return HITLS_SUCCESS;
251 }
252
253 RecCtx *newRecCtx = (RecCtx *)BSL_SAL_Calloc(1, sizeof(RecCtx));
254 if (newRecCtx == NULL) {
255 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15531, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
256 "Record: malloc fail.", 0, 0, 0, 0);
257 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
258 return HITLS_MEMALLOC_FAIL;
259 }
260 #ifdef HITLS_TLS_PROTO_DTLS12
261 UnprocessedAppMsgListInit(&newRecCtx->unprocessedAppMsgList);
262 #ifdef HITLS_BSL_UIO_UDP
263 LIST_INIT(&newRecCtx->retransmitList.head);
264 #endif
265 #endif
266 int32_t ret = RecBufInit(ctx, newRecCtx);
267 if (ret != HITLS_SUCCESS) {
268 goto ERR;
269 }
270
271 ret = RecConnStatesInit(newRecCtx);
272 if (ret != HITLS_SUCCESS) {
273 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15534, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
274 "Record: init connect state fail.", 0, 0, 0, 0);
275 goto ERR;
276 }
277
278 ctx->recCtx = newRecCtx;
279 return HITLS_SUCCESS;
280 ERR:
281 RecDeInit(newRecCtx);
282 BSL_SAL_FREE(newRecCtx);
283 return ret;
284 }
285
REC_DeInit(TLS_Ctx * ctx)286 void REC_DeInit(TLS_Ctx *ctx)
287 {
288 if (ctx != NULL && ctx->recCtx != NULL) {
289 RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
290 RecDeInit(recordCtx);
291 BSL_SAL_FREE(ctx->recCtx);
292 }
293 return;
294 }
295
REC_ReadHasPending(const TLS_Ctx * ctx)296 bool REC_ReadHasPending(const TLS_Ctx *ctx)
297 {
298 if ((ctx == NULL) || (ctx->recCtx == NULL)) {
299 return false;
300 }
301
302 RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
303 RecBuf *inBuf = recordCtx->inBuf;
304
305 if (inBuf == NULL) {
306 return false;
307 }
308
309 if (inBuf->end != inBuf->start) {
310 return true;
311 }
312
313 return false;
314 }
315
REC_Read(TLS_Ctx * ctx,REC_Type recordType,uint8_t * data,uint32_t * readLen,uint32_t num)316 int32_t REC_Read(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num)
317 {
318 if ((ctx == NULL) || (ctx->recCtx == NULL) || (data == NULL) || (ctx->alertCtx == NULL)) {
319 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15535, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
320 "Record: input invalid parameter.", 0, 0, 0, 0);
321 BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
322 return HITLS_INTERNAL_EXCEPTION;
323 }
324 return ctx->recCtx->recRead(ctx, recordType, data, readLen, num);
325 }
326
REC_Write(TLS_Ctx * ctx,REC_Type recordType,const uint8_t * data,uint32_t num)327 int32_t REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num)
328 {
329 if ((ctx == NULL) || (ctx->recCtx == NULL) ||
330 (num != 0 && data == NULL) ||
331 (num == 0 && recordType != REC_TYPE_APP)) {
332 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15537, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
333 "Record write: input null pointer.", 0, 0, 0, 0);
334 BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
335 return HITLS_NULL_INPUT;
336 }
337 return ctx->recCtx->recWrite(ctx, recordType, data, num);
338 }
339
340 #if defined(HITLS_BSL_UIO_UDP)
REC_ActiveOutdatedWriteState(TLS_Ctx * ctx)341 void REC_ActiveOutdatedWriteState(TLS_Ctx *ctx)
342 {
343 RecCtx *recCtx = (RecCtx *)ctx->recCtx;
344 RecConnStates *writeStates = &recCtx->writeStates;
345 writeStates->pendingState = writeStates->currentState;
346 writeStates->currentState = writeStates->outdatedState;
347 writeStates->outdatedState = NULL;
348 return;
349 }
350
REC_DeActiveOutdatedWriteState(TLS_Ctx * ctx)351 void REC_DeActiveOutdatedWriteState(TLS_Ctx *ctx)
352 {
353 RecCtx *recCtx = (RecCtx *)ctx->recCtx;
354 RecConnStates *writeStates = &recCtx->writeStates;
355 writeStates->outdatedState = writeStates->currentState;
356 writeStates->currentState = writeStates->pendingState;
357 writeStates->pendingState = NULL;
358 return;
359 }
360 #endif /* HITLS_TLS_PROTO_DTLS12 && HITLS_BSL_UIO_UDP */
361
FreeDataAndState(RecConnSuitInfo * clientSuitInfo,RecConnSuitInfo * serverSuitInfo,RecConnState * readState,RecConnState * writeState)362 static void FreeDataAndState(RecConnSuitInfo *clientSuitInfo, RecConnSuitInfo *serverSuitInfo,
363 RecConnState *readState, RecConnState *writeState)
364 {
365 BSL_SAL_CleanseData((void *)clientSuitInfo, sizeof(RecConnSuitInfo));
366 BSL_SAL_CleanseData((void *)serverSuitInfo, sizeof(RecConnSuitInfo));
367 RecConnStateFree(readState);
368 RecConnStateFree(writeState);
369 }
370
REC_InitPendingState(const TLS_Ctx * ctx,const REC_SecParameters * param)371 int32_t REC_InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *param)
372 {
373 if (ctx == NULL || ctx->recCtx == NULL || param == NULL) {
374 BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
375 return RETURN_ERROR_NUMBER_PROCESS(HITLS_INTERNAL_EXCEPTION, BINLOG_ID15540, "Record: ctx null");
376 }
377
378 int32_t ret = HITLS_MEMALLOC_FAIL;
379 RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
380 RecConnSuitInfo clientSuitInfo = {0};
381 RecConnSuitInfo serverSuitInfo = {0};
382 RecConnSuitInfo *out = NULL;
383 RecConnSuitInfo *in = NULL;
384
385 RecConnState *readState = RecConnStateNew();
386 RecConnState *writeState = RecConnStateNew();
387 if (readState == NULL || writeState == NULL) {
388 (void)RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17301, "StateNew fail");
389 goto ERR;
390 }
391
392 /* 1.Generate a secret */
393 ret = RecConnKeyBlockGen(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
394 param, &clientSuitInfo, &serverSuitInfo);
395 if (ret != HITLS_SUCCESS) {
396 (void)RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17302, "KeyBlockGen fail");
397 goto ERR;
398 }
399
400 /* 2.Set the corresponding read/write pending state */
401 out = (param->isClient == true) ? &clientSuitInfo : &serverSuitInfo;
402 in = (param->isClient == true) ? &serverSuitInfo : &clientSuitInfo;
403 ret = RecConnStateSetCipherInfo(writeState, out);
404 if (ret != HITLS_SUCCESS) {
405 (void)RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17303, "SetCipherInfo fail");
406 goto ERR;
407 }
408 ret = RecConnStateSetCipherInfo(readState, in);
409 if (ret != HITLS_SUCCESS) {
410 (void)RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17304, "SetCipherInfo fail");
411 goto ERR;
412 }
413
414 /* Clear sensitive information */
415 FreeDataAndState(&clientSuitInfo, &serverSuitInfo,
416 recordCtx->readStates.pendingState, recordCtx->writeStates.pendingState);
417 recordCtx->readStates.pendingState = readState;
418 recordCtx->writeStates.pendingState = writeState;
419 return HITLS_SUCCESS;
420 ERR:
421 /* Clear sensitive information */
422 FreeDataAndState(&clientSuitInfo, &serverSuitInfo, readState, writeState);
423 BSL_ERR_PUSH_ERROR(ret);
424 return ret;
425 }
426
427 #ifdef HITLS_TLS_PROTO_TLS13
REC_TLS13InitPendingState(const TLS_Ctx * ctx,const REC_SecParameters * param,bool isOut)428 int32_t REC_TLS13InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *param, bool isOut)
429 {
430 if (ctx == NULL || ctx->recCtx == NULL || param == NULL) {
431 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15542, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
432 "Record: ctx null", 0, 0, 0, 0);
433 BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
434 return HITLS_INTERNAL_EXCEPTION;
435 }
436
437 RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
438 RecConnSuitInfo suitInfo = {0};
439 RecConnState *state = RecConnStateNew();
440 if (state == NULL) {
441 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17305, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
442 "StateNew fail", 0, 0, 0, 0);
443 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
444 return HITLS_MEMALLOC_FAIL;
445 }
446
447 /* 1.Generate a secret */
448 int32_t ret = RecTLS13ConnKeyBlockGen(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx), param, &suitInfo);
449 if (ret != HITLS_SUCCESS) {
450 RecConnStateFree(state);
451 return ret;
452 }
453
454 /* 2.Set the corresponding read/write pending state */
455 RecConnStates *curState = NULL;
456 if (isOut) {
457 curState = &(recordCtx->writeStates);
458 } else {
459 curState = &(recordCtx->readStates);
460 }
461
462 ret = RecConnStateSetCipherInfo(state, &suitInfo);
463 if (ret != HITLS_SUCCESS) {
464 RecConnStateFree(state);
465 return ret;
466 }
467
468 RecConnStateFree(curState->pendingState);
469 curState->pendingState = state;
470 return HITLS_SUCCESS;
471 }
472 #endif /* HITLS_TLS_PROTO_TLS13 */
473
REC_ActivePendingState(TLS_Ctx * ctx,bool isOut)474 int32_t REC_ActivePendingState(TLS_Ctx *ctx, bool isOut)
475 {
476 RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
477 RecConnStates *states = (isOut == true) ? &recordCtx->writeStates : &recordCtx->readStates;
478
479 if (states->pendingState == NULL) {
480 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15543, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
481 "Record: pending state should not be null.", 0, 0, 0, 0);
482 BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
483 return HITLS_INTERNAL_EXCEPTION;
484 }
485
486 RecConnStateFree(states->outdatedState);
487 states->outdatedState = states->currentState;
488 states->currentState = states->pendingState;
489 states->pendingState = NULL;
490 RecConnSetSeqNum(states->currentState, 0);
491
492 #ifdef HITLS_TLS_PROTO_DTLS12
493 if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
494 if (isOut) {
495 ++recordCtx->writeEpoch;
496 RecConnSetEpoch(states->currentState, recordCtx->writeEpoch);
497 } else {
498 ++recordCtx->readEpoch;
499 RecConnSetEpoch(states->currentState, recordCtx->readEpoch);
500 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
501 RecAntiReplayReset(&states->currentState->window);
502 #endif
503 }
504 }
505 #endif /* HITLS_TLS_PROTO_DTLS12 */
506
507 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15544, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
508 "Record: active pending state.", 0, 0, 0, 0);
509 return HITLS_SUCCESS;
510 }
511
REC_GetRecordSizeLimitWriteLen(const TLS_Ctx * ctx)512 static uint32_t REC_GetRecordSizeLimitWriteLen(const TLS_Ctx *ctx)
513 {
514 uint32_t defaultLen = REC_MAX_PLAIN_TEXT_LENGTH;
515 if (ctx->negotiatedInfo.recordSizeLimit != 0) {
516 defaultLen = ctx->negotiatedInfo.peerRecordSizeLimit;
517 if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) {
518 defaultLen--;
519 }
520 }
521 return defaultLen;
522 }
523
REC_GetMaxWriteSize(const TLS_Ctx * ctx,uint32_t * len)524 int32_t REC_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len)
525 {
526 if (ctx == NULL || ctx->recCtx == NULL || len == NULL) {
527 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15545, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Record: input null pointer.",
528 0, 0, 0, 0);
529 BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
530 return HITLS_NULL_INPUT;
531 }
532
533 *len = REC_GetRecordSizeLimitWriteLen(ctx);
534 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
535 bool isUdp = false;
536 RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
537 RecConnState *currentState = recordCtx->writeStates.currentState;
538 uint32_t overHead;
539 BSL_UIO *uio = ctx->uio;
540 while (uio != NULL) {
541 if (BSL_UIO_GetUioChainTransportType(uio, BSL_UIO_UDP)) {
542 isUdp = true;
543 break;
544 }
545 uio = BSL_UIO_Next(uio);
546 }
547 if (!isUdp) {
548 /* In non-UDP scenarios, there is no PMTU limit and the maximum plaintext length is returned */
549 return HITLS_SUCCESS;
550 }
551
552 /* In UDP scenarios, handshake packets and application data packets with miniaturization enabled have the MTU limit
553 */
554 uint32_t encryptLen =
555 RecGetCryptoFuncs(currentState->suiteInfo)->calCiphertextLen(ctx, currentState->suiteInfo, 0, false);
556 overHead = REC_IP_UDP_HEAD_SIZE + REC_DTLS_RECORD_HEADER_LEN + encryptLen;
557 if (ctx->config.pmtu <= overHead) {
558 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17306, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "pmtu too small", 0, 0, 0, 0);
559 BSL_ERR_PUSH_ERROR(HITLS_REC_PMTU_TOO_SMALL);
560 return HITLS_REC_PMTU_TOO_SMALL;
561 }
562
563 *len = (*len > ctx->config.pmtu - overHead) ? (ctx->config.pmtu - overHead) : *len;
564 #endif /* HITLS_TLS_PROTO_DTLS12 && HITLS_BSL_UIO_UDP */
565 return HITLS_SUCCESS;
566 }
567
REC_GetUnexpectedMsgType(TLS_Ctx * ctx)568 REC_Type REC_GetUnexpectedMsgType(TLS_Ctx *ctx)
569 {
570 return ctx->recCtx->unexpectedMsgType;
571 }
572
RecClearAlertCount(TLS_Ctx * ctx,REC_Type recordType)573 void RecClearAlertCount(TLS_Ctx *ctx, REC_Type recordType)
574 {
575 if (recordType != REC_TYPE_ALERT) {
576 ALERT_ClearWarnCount(ctx);
577 }
578 return;
579 }