• 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 "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 }