• 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 "bsl_sal.h"
18 #include "tls_binlog_id.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_err_internal.h"
21 #include "bsl_bytes.h"
22 #include "hitls_error.h"
23 #include "hitls_config.h"
24 #include "bsl_errno.h"
25 #include "bsl_uio.h"
26 #include "rec_alert.h"
27 #ifdef HITLS_TLS_PROTO_TLS13
28 #include "hs_common.h"
29 #endif
30 #include "tls_config.h"
31 #include "record.h"
32 #ifdef HITLS_TLS_FEATURE_INDICATOR
33 #include "indicator.h"
34 #endif
35 #include "hs_ctx.h"
36 #include "hs.h"
37 #include "rec_crypto.h"
38 #include "bsl_list.h"
39 
GetReadConnState(const TLS_Ctx * ctx)40 RecConnState *GetReadConnState(const TLS_Ctx *ctx)
41 {
42     /** Obtains the record structure. */
43     RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
44     return recordCtx->readStates.currentState;
45 }
46 
IsNeedtoRead(const TLS_Ctx * ctx,const RecBuf * inBuf)47 static bool IsNeedtoRead(const TLS_Ctx *ctx, const RecBuf *inBuf)
48 {
49     (void)ctx;
50     uint32_t headLen = REC_TLS_RECORD_HEADER_LEN;
51 #ifdef HITLS_TLS_PROTO_DTLS12
52     if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
53         headLen = REC_DTLS_RECORD_HEADER_LEN;
54     }
55 #endif
56     uint32_t lengthOffset = headLen - sizeof(uint16_t);
57     uint32_t remain = inBuf->end - inBuf->start;
58     if (remain < headLen) {
59         return true;
60     }
61     uint8_t *recordHeader = &inBuf->buf[inBuf->start];
62     uint32_t recordLen = BSL_ByteToUint16(&recordHeader[lengthOffset]);
63     if (remain < headLen + recordLen) {
64         return true;
65     }
66     return false;
67 }
68 
REC_HaveReadSuiteInfo(const TLS_Ctx * ctx)69 bool REC_HaveReadSuiteInfo(const TLS_Ctx *ctx)
70 {
71     if (ctx == NULL || ctx->recCtx == NULL || ctx->recCtx->readStates.currentState == NULL) {
72         return false;
73     }
74     return ctx->recCtx->readStates.currentState->suiteInfo != NULL;
75 }
76 
77 
RecCastUintToRecType(TLS_Ctx * ctx,uint8_t value)78 static REC_Type RecCastUintToRecType(TLS_Ctx *ctx, uint8_t value)
79 {
80     (void)ctx;
81     REC_Type type;
82     /* Convert to the record type */
83     switch (value) {
84         case 20u:
85             type = REC_TYPE_CHANGE_CIPHER_SPEC;
86             break;
87         case 21u:
88             type = REC_TYPE_ALERT;
89             break;
90         case 22u:
91             type = REC_TYPE_HANDSHAKE;
92             break;
93         case 23u:
94             type = REC_TYPE_APP;
95             break;
96         default:
97             type = REC_TYPE_UNKNOWN;
98             break;
99     }
100 #ifdef HITLS_TLS_PROTO_TLS13
101     RecConnState *state = GetReadConnState(ctx);
102     if (HS_GetVersion(ctx) == HITLS_VERSION_TLS13 && state->suiteInfo != NULL) {
103         if (type != REC_TYPE_APP && type != REC_TYPE_ALERT &&
104             (type != REC_TYPE_CHANGE_CIPHER_SPEC || ctx->hsCtx == NULL)) {
105             type = REC_TYPE_UNKNOWN;
106         }
107     }
108 #endif /* HITLS_TLS_PROTO_TLS13 */
109     return type;
110 }
111 #define REC_GetMaxReadSize(ctx) REC_MAX_PLAIN_LENGTH
ProcessDecryptedRecord(TLS_Ctx * ctx,uint32_t dataLen,const REC_TextInput * encryptedMsg)112 static int32_t ProcessDecryptedRecord(TLS_Ctx *ctx, uint32_t dataLen,
113     const REC_TextInput *encryptedMsg)
114 {
115     /* The TLSPlaintext.length MUST NOT exceed 2^14. An endpoint that receives a record that exceeds
116     this length MUST terminate the connection with a record_overflow alert */
117     if (dataLen > REC_GetMaxReadSize(ctx)) {
118         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16165, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
119             "TLSPlaintext.length exceeds 2^14", 0, 0, 0, 0);
120         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW);
121     }
122 
123     if (encryptedMsg->type != REC_TYPE_APP && dataLen == 0) {
124         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16166, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
125             "get a record with invalid length", 0, 0, 0, 0);
126         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
127     }
128 
129     if (!IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask) &&
130         ctx->negotiatedInfo.version != HITLS_VERSION_TLS13 &&
131         ctx->method.isRecvCCS(ctx) &&
132         encryptedMsg->type != REC_TYPE_HANDSHAKE) {
133         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
134         return HITLS_REC_ERR_DATA_BETWEEN_CCS_AND_FINISHED;
135     }
136     return HITLS_SUCCESS;
137 }
138 
EmptyRecordProcess(TLS_Ctx * ctx,uint8_t type)139 static int32_t EmptyRecordProcess(TLS_Ctx *ctx, uint8_t type)
140 {
141     if (REC_HaveReadSuiteInfo(ctx)) {
142         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17255, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
143             "encryptedMsg->textLen is 0", 0, 0, 0, 0);
144         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC);
145     }
146     if (type == REC_TYPE_ALERT || type == REC_TYPE_APP) {
147         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17256, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "type err", 0, 0, 0, 0);
148         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
149     }
150     ctx->recCtx->emptyRecordCnt += 1;
151     if (ctx->recCtx->emptyRecordCnt > ctx->config.tlsConfig.emptyRecordsNum) {
152         BSL_LOG_BINLOG_FIXLEN(
153             BINLOG_ID16187, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "get too many empty records", 0, 0, 0, 0);
154         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
155     } else {
156         return HITLS_REC_NORMAL_RECV_BUF_EMPTY;
157     }
158 }
159 
RecordDecrypt(TLS_Ctx * ctx,RecBuf * decryptBuf,REC_TextInput * encryptedMsg)160 static int32_t RecordDecrypt(TLS_Ctx *ctx, RecBuf *decryptBuf, REC_TextInput *encryptedMsg)
161 {
162     if (encryptedMsg->textLen == 0) {
163         return EmptyRecordProcess(ctx, encryptedMsg->type);
164     } else {
165         ctx->recCtx->emptyRecordCnt = 0;
166     }
167 
168     RecConnState *state = GetReadConnState(ctx);
169     const RecCryptoFunc *funcs = RecGetCryptoFuncs(state->suiteInfo);
170     uint32_t offset = 0;
171     int32_t ret = HITLS_SUCCESS;
172     uint32_t minBufLen = 0;
173     ret = funcs->calPlantextBufLen(ctx, state->suiteInfo, encryptedMsg->textLen, &offset, &minBufLen);
174     if (ret != HITLS_SUCCESS) {
175         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16266, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
176             "Invalid record length %u", encryptedMsg->textLen, 0, 0, 0);
177         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC);
178     }
179     if ((minBufLen > decryptBuf->bufSize || ctx->peekFlag != 0) && minBufLen != 0) {
180         decryptBuf->buf = BSL_SAL_Calloc(minBufLen, sizeof(uint8_t));
181         if (decryptBuf->buf == NULL) {
182             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17257, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
183                 "Calloc fail", 0, 0, 0, 0);
184             return HITLS_MEMALLOC_FAIL;
185         }
186         decryptBuf->bufSize = minBufLen;
187         decryptBuf->isHoldBuffer = true;
188     }
189     decryptBuf->end = decryptBuf->bufSize;
190     /* The decrypted record body is in data */
191     ret = RecConnDecrypt(ctx, state, encryptedMsg, decryptBuf->buf, &decryptBuf->end);
192     if (ret != HITLS_SUCCESS) {
193         goto ERR;
194     }
195     if (!IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
196         ret = funcs->decryptPostProcess(ctx, state->suiteInfo, encryptedMsg, decryptBuf->buf, &decryptBuf->end);
197         if (ret != HITLS_SUCCESS) {
198             goto ERR;
199         }
200         RecConnSetSeqNum(state, RecConnGetSeqNum(state) + 1);
201     }
202     ret = ProcessDecryptedRecord(ctx, decryptBuf->end, encryptedMsg);
203     if (ret != HITLS_SUCCESS) {
204         goto ERR;
205     }
206     return HITLS_SUCCESS;
207 ERR:
208     if (decryptBuf->isHoldBuffer) {
209         BSL_SAL_FREE(decryptBuf->buf);
210     }
211     return ret;
212 }
213 
RecordUnexpectedMsg(TLS_Ctx * ctx,RecBuf * decryptBuf,REC_Type recordType)214 static int32_t RecordUnexpectedMsg(TLS_Ctx *ctx, RecBuf *decryptBuf, REC_Type recordType)
215 {
216     int32_t ret = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
217     ctx->recCtx->unexpectedMsgType = recordType;
218     switch (recordType) {
219         case REC_TYPE_HANDSHAKE:
220             ret = RecBufListAddBuffer(ctx->recCtx->hsRecList, decryptBuf);
221             break;
222         case REC_TYPE_APP:
223             ret = RecBufListAddBuffer(ctx->recCtx->appRecList, decryptBuf);
224             break;
225         case REC_TYPE_CHANGE_CIPHER_SPEC:
226         case REC_TYPE_ALERT:
227         default:
228             ret = ctx->method.unexpectedMsgProcessCb(ctx, recordType,
229                 decryptBuf->buf, decryptBuf->end, false);
230             if (decryptBuf->isHoldBuffer) {
231                 BSL_SAL_FREE(decryptBuf->buf);
232             }
233             return ret;
234     }
235     if (ret != HITLS_SUCCESS) {
236         if (decryptBuf->isHoldBuffer) {
237             BSL_SAL_FREE(decryptBuf->buf);
238         }
239         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17258, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
240             "process recordType fail", 0, 0, 0, 0);
241         return ret;
242     }
243     ret = RecDerefBufList(ctx);
244     if (ret != HITLS_SUCCESS) {
245         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17259, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
246             "RecDerefBufList fail", 0, 0, 0, 0);
247         return ret;
248     }
249     return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
250 }
251 
252 #ifdef HITLS_TLS_PROTO_DTLS12
DtlsCheckVersionField(const TLS_Ctx * ctx,uint16_t version,uint8_t type)253 int32_t DtlsCheckVersionField(const TLS_Ctx *ctx, uint16_t version, uint8_t type)
254 {
255     /* Tolerate alerts with non-negotiated version. For example, after the server sends server hello, the client
256      * replies with an earlier version alert */
257     if (ctx->negotiatedInfo.version == 0u || type == (uint8_t)REC_TYPE_ALERT) {
258         if ((version != HITLS_VERSION_DTLS10) && (version != HITLS_VERSION_DTLS12) &&
259             (version != HITLS_VERSION_TLCP_DTLCP11)) {
260             BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION);
261             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15436, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
262                 "get a record with illegal version(0x%x).", version, 0, 0, 0);
263             return HITLS_REC_INVALID_PROTOCOL_VERSION;
264         }
265     } else {
266         if (version != ctx->negotiatedInfo.version) {
267             BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION);
268             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15437, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
269                 "get a record with illegal version(0x%x).", version, 0, 0, 0);
270             return HITLS_REC_INVALID_PROTOCOL_VERSION;
271         }
272     }
273     return HITLS_SUCCESS;
274 }
275 
DtlsCheckRecordHeader(TLS_Ctx * ctx,const RecHdr * hdr)276 int32_t DtlsCheckRecordHeader(TLS_Ctx *ctx, const RecHdr *hdr)
277 {
278     /** Check the DTLS version, release the resource and return if the version is incorrect */
279     int32_t ret = DtlsCheckVersionField(ctx, hdr->version, hdr->type);
280     if (ret != HITLS_SUCCESS) {
281         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17261, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
282             "DtlsCheckVersionField fail, ret %d", ret, 0, 0, 0);
283         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION);
284     }
285 
286     if (RecCastUintToRecType(ctx, hdr->type) == REC_TYPE_UNKNOWN || hdr->bodyLen == 0) {
287         BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_RECV_UNEXPECTED_MSG);
288         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15438, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
289             "get a record with invalid type or body length(0)", 0, 0, 0, 0);
290         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
291     }
292 
293     RecConnState *state = GetReadConnState(ctx);
294 
295     uint32_t maxLenth = (state->suiteInfo != NULL) ? REC_MAX_CIPHER_TEXT_LEN : REC_MAX_PLAIN_LENGTH;
296     if (hdr->bodyLen > maxLenth) {
297         BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_TOO_BIG_LENGTH);
298         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15439, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
299             "get a record with invalid length", 0, 0, 0, 0);
300         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW);
301     }
302 
303     uint16_t epoch = REC_EPOCH_GET(hdr->epochSeq);
304     if (epoch == 0 && hdr->type == REC_TYPE_APP && BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_SCTP)) {
305         BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_RECV_UNEXPECTED_MSG);
306         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15440, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
307             "get a UNEXPECTE record msg: epoch 0's app msg.", 0, 0, 0, 0);
308         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
309         return HITLS_REC_ERR_RECV_UNEXPECTED_MSG;
310     }
311 
312     return HITLS_SUCCESS;
313 }
314 
315 /**
316 * @brief Read message data.
317 *
318 * @param uio [IN] UIO object.
319 * @param inBuf [IN] inBuf Read the buffer.
320 *
321 * @retval HITLS_SUCCESS is successfully read.
322 * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error
323 * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY Uncached data needs to be reread.
324  */
ReadDatagram(TLS_Ctx * ctx,RecBuf * inBuf)325 static int32_t ReadDatagram(TLS_Ctx *ctx, RecBuf *inBuf)
326 {
327     if (inBuf->end > inBuf->start) {
328         return HITLS_SUCCESS;
329     }
330     /* Attempt to read the message: The message is read of the whole message */
331     uint32_t recvLen = 0u;
332 #ifdef HITLS_TLS_CONFIG_STATE
333     ctx->rwstate = HITLS_READING;
334 #endif
335 #ifdef HITLS_TLS_FEATURE_FLIGHT
336     int32_t ret = BSL_UIO_Read(ctx->rUio, &(inBuf->buf[0]), inBuf->bufSize, &recvLen);
337 #else
338     int32_t ret = BSL_UIO_Read(ctx->uio, &(inBuf->buf[0]), inBuf->bufSize, &recvLen);
339 #endif
340     if (ret != BSL_SUCCESS) {
341         BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION);
342         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15441, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
343             "Record read: uio err.%d", ret, 0, 0, 0);
344         return HITLS_REC_ERR_IO_EXCEPTION;
345     }
346 #ifdef HITLS_TLS_CONFIG_STATE
347     ctx->rwstate = HITLS_NOTHING;
348 #endif
349     if (recvLen == 0) {
350         return HITLS_REC_NORMAL_RECV_BUF_EMPTY;
351     }
352 
353     inBuf->start = 0;
354     // successfully read
355     inBuf->end = recvLen;
356     return HITLS_SUCCESS;
357 }
358 
DtlsGetRecordHeader(const uint8_t * msg,uint32_t len,RecHdr * hdr)359 static int32_t DtlsGetRecordHeader(const uint8_t *msg, uint32_t len, RecHdr *hdr)
360 {
361     if (len < REC_DTLS_RECORD_HEADER_LEN) {
362         BSL_ERR_PUSH_ERROR(HITLS_REC_DECODE_ERROR);
363         BSL_LOG_BINLOG_FIXLEN(
364             BINLOG_ID15442, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Record:dtls packet's length err.", 0, 0, 0, 0);
365         return HITLS_REC_DECODE_ERROR;
366     }
367 
368     /* Parse the record header */
369     hdr->type = msg[0];
370     hdr->version = BSL_ByteToUint16(&msg[1]);
371     hdr->bodyLen = BSL_ByteToUint16(
372         &msg[REC_DTLS_RECORD_LENGTH_OFFSET]);  // The 11th to 12th bytes of DTLS are the message length.
373     hdr->epochSeq = BSL_ByteToUint64(&msg[REC_DTLS_RECORD_EPOCH_OFFSET]);
374     return HITLS_SUCCESS;
375 }
376 
377 /**
378  * @brief Attempt to read a dtls record message.
379  *
380  * @param ctx [IN] TLS context
381  * @param recordBody [OUT] record body
382  * @param hdr [OUT] record head
383  *
384  * @retval HITLS_SUCCESS succeeded.
385  * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again
386  * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error
387  */
TryReadOneDtlsRecord(TLS_Ctx * ctx,uint8_t ** recordBody,RecHdr * hdr)388 static int32_t TryReadOneDtlsRecord(TLS_Ctx *ctx, uint8_t **recordBody, RecHdr *hdr)
389 {
390     int32_t ret;
391     /** Obtain the record structure information */
392     RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
393     if (IsNeedtoRead(ctx, recordCtx->inBuf)) {
394         ret = RecDerefBufList(ctx);
395         if (ret != HITLS_SUCCESS) {
396             return ret;
397         }
398     }
399     /** Read the datagram message: The message may contain multiple records */
400     ret = ReadDatagram(ctx, recordCtx->inBuf);
401     if (ret != HITLS_SUCCESS) {
402         return ret;
403     }
404 
405     uint8_t *msg = &recordCtx->inBuf->buf[recordCtx->inBuf->start];
406     uint32_t len = recordCtx->inBuf->end - recordCtx->inBuf->start;
407 
408     ret = DtlsGetRecordHeader(msg, len, hdr);
409     if (ret != HITLS_SUCCESS) {
410         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17262, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
411             "DtlsGetRecordHeader fail, ret %d", ret, 0, 0, 0);
412         RecBufClean(recordCtx->inBuf);
413         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
414     }
415 
416 #ifdef HITLS_TLS_FEATURE_INDICATOR
417     INDICATOR_MessageIndicate(0, 0, RECORD_HEADER, msg, REC_DTLS_RECORD_HEADER_LEN, ctx,
418                               ctx->config.tlsConfig.msgArg);
419 #endif
420 
421     /* Check whether the record length is greater than the buffer size */
422     if ((REC_DTLS_RECORD_HEADER_LEN + (uint32_t)hdr->bodyLen) > len) {
423         RecBufClean(recordCtx->inBuf);
424         BSL_ERR_PUSH_ERROR(HITLS_REC_DECODE_ERROR);
425         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15443, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
426             "Record:dtls packet's length err.", 0, 0, 0, 0);
427         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW);
428     }
429 
430     /** Release the read record */
431     recordCtx->inBuf->start += REC_DTLS_RECORD_HEADER_LEN + hdr->bodyLen;
432 
433     /** Update the read content */
434     *recordBody = msg + REC_DTLS_RECORD_HEADER_LEN;
435 
436     return HITLS_SUCCESS;
437 }
438 
GenerateCryptMsg(const TLS_Ctx * ctx,const RecHdr * hdr,const uint8_t * recordBody,REC_TextInput * cryptMsg)439 static inline void GenerateCryptMsg(const TLS_Ctx *ctx,
440     const RecHdr *hdr, const uint8_t *recordBody, REC_TextInput *cryptMsg)
441 {
442     cryptMsg->negotiatedVersion = ctx->negotiatedInfo.version;
443 #ifdef HITLS_TLS_FEATURE_ETM
444     cryptMsg->isEncryptThenMac = ctx->negotiatedInfo.isEncryptThenMac;
445 #endif
446     cryptMsg->type = hdr->type;
447     cryptMsg->version = hdr->version;
448     cryptMsg->text = recordBody;
449     cryptMsg->textLen = hdr->bodyLen;
450     BSL_Uint64ToByte(hdr->epochSeq, cryptMsg->seq);
451 }
452 
453 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
454 /**
455  * @brief Check whether there are unprocessed handshake messages in the cache.
456  *
457  * @param unprocessedHsMsg [IN] Unprocessed handshake message handle
458  * @param curEpoch [IN] Current epoch
459  *
460  * @retval true: cached
461  * @retval false No cache
462  */
IsExistUnprocessedHsMsg(RecCtx * recCtx)463 static bool IsExistUnprocessedHsMsg(RecCtx *recCtx)
464 {
465     uint16_t curEpoch = recCtx->readEpoch;
466     UnprocessedHsMsg *unprocessedHsMsg = &recCtx->unprocessedHsMsg;
467 
468     /* Check whether there are cached handshake messages. */
469     if (unprocessedHsMsg->recordBody == NULL) {
470         return false;
471     }
472 
473     uint16_t epoch = REC_EPOCH_GET(unprocessedHsMsg->hdr.epochSeq);
474     if (curEpoch == epoch) {
475         /* The handshake message of the current epoch needs to be processed */
476         return true;
477     }
478 
479     if (curEpoch > epoch) {
480         /* Expired messages need to be cleaned up */
481         (void)memset_s(&unprocessedHsMsg->hdr, sizeof(unprocessedHsMsg->hdr), 0, sizeof(unprocessedHsMsg->hdr));
482         BSL_SAL_FREE(unprocessedHsMsg->recordBody);
483     }
484 
485     return false;
486 }
487 #endif /* HITLS_TLS_PROTO_DTLS12 && HITLS_BSL_UIO_UDP */
488 
IsExistUnprocessedAppMsg(RecCtx * recCtx)489 static bool IsExistUnprocessedAppMsg(RecCtx *recCtx)
490 {
491     UnprocessedAppMsg *unprocessedAppMsgList = &recCtx->unprocessedAppMsgList;
492     /* Check whether there are cached app messages. */
493     if (unprocessedAppMsgList->count == 0) {
494         return false;
495     }
496 
497     ListHead *node = NULL;
498     ListHead *tmpNode = NULL;
499     UnprocessedAppMsg *cur = NULL;
500     uint16_t curEpoch = recCtx->readEpoch;
501     LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(unprocessedAppMsgList->head)) {
502         cur = LIST_ENTRY(node, UnprocessedAppMsg, head);
503         uint16_t epoch = REC_EPOCH_GET(cur->hdr.epochSeq);
504         if (curEpoch == epoch) {
505             /* The app message of the current epoch needs to be processed */
506             return true;
507         }
508     }
509     return false;
510 }
511 
RecordBufferUnprocessedMsg(RecCtx * recordCtx,RecHdr * hdr,uint8_t * recordBody)512 int32_t RecordBufferUnprocessedMsg(RecCtx *recordCtx, RecHdr *hdr, uint8_t *recordBody)
513 {
514     if (hdr->type == REC_TYPE_HANDSHAKE) {
515 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
516         CacheNextEpochHsMsg(&recordCtx->unprocessedHsMsg, hdr, recordBody);
517 #endif
518     } else {
519         int32_t ret = UnprocessedAppMsgListAppend(&recordCtx->unprocessedAppMsgList, hdr, recordBody);
520         if (ret != HITLS_SUCCESS) {
521             return ret;
522         }
523     }
524     BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17263, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
525         "recv normal disorder message", 0, 0, 0, 0);
526     return HITLS_REC_NORMAL_RECV_DISORDER_MSG;
527 }
528 
DtlsRecordHeaderProcess(TLS_Ctx * ctx,uint8_t * recordBody,RecHdr * hdr)529 static int32_t DtlsRecordHeaderProcess(TLS_Ctx *ctx, uint8_t *recordBody, RecHdr *hdr)
530 {
531     int32_t ret = HITLS_SUCCESS;
532     RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
533 
534     ret = DtlsCheckRecordHeader(ctx, hdr);
535     if (ret != HITLS_SUCCESS) {
536         return ret;
537     }
538     uint16_t epoch = REC_EPOCH_GET(hdr->epochSeq);
539     if (epoch != recordCtx->readEpoch) {
540         /* Discard out-of-order messages in SCTP scenarios */
541         if (BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_SCTP)) {
542             return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
543         }
544 #if defined(HITLS_BSL_UIO_UDP)
545         /* Only the messages of the next epoch are cached */
546         if ((recordCtx->readEpoch + 1) == epoch) {
547             return RecordBufferUnprocessedMsg(recordCtx, hdr, recordBody);
548         }
549         /* After receiving the message of the previous epoch, the system discards the message. */
550         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
551 #endif
552     }
553 
554     bool isCcsRecv = ctx->method.isRecvCCS(ctx);
555     /* App messages arrive earlier than finished messages and need to be cached */
556     if (ctx->hsCtx != NULL && isCcsRecv == true && (hdr->type == REC_TYPE_APP || hdr->type == REC_TYPE_ALERT)) {
557         return RecordBufferUnprocessedMsg(recordCtx, hdr, recordBody);
558     }
559 
560     return HITLS_SUCCESS;
561 }
562 
GetUnprocessedMsg(RecCtx * recordCtx,REC_Type recordType,RecHdr * hdr)563 static uint8_t *GetUnprocessedMsg(RecCtx *recordCtx, REC_Type recordType, RecHdr *hdr)
564 {
565     uint8_t *recordBody = NULL;
566 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
567     if ((recordType == REC_TYPE_HANDSHAKE) && IsExistUnprocessedHsMsg(recordCtx)) {
568         (void)memcpy_s(hdr, sizeof(RecHdr), &recordCtx->unprocessedHsMsg.hdr, sizeof(RecHdr));
569         recordBody = recordCtx->unprocessedHsMsg.recordBody;
570         recordCtx->unprocessedHsMsg.recordBody = NULL;
571     }
572 #endif
573 
574     uint16_t curEpoch = recordCtx->readEpoch;
575     if ((recordType == REC_TYPE_APP) && IsExistUnprocessedAppMsg(recordCtx)) {
576         UnprocessedAppMsg *appMsg = UnprocessedAppMsgGet(&recordCtx->unprocessedAppMsgList, curEpoch);
577         if (appMsg == NULL) {
578             return NULL;
579         }
580         (void)memcpy_s(hdr, sizeof(RecHdr), &appMsg->hdr, sizeof(RecHdr));
581         recordBody = appMsg->recordBody;
582         appMsg->recordBody = NULL;
583         UnprocessedAppMsgFree(appMsg);
584     }
585     return recordBody;
586 }
587 
588 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
AntiReplay(TLS_Ctx * ctx,RecHdr * hdr)589 static int32_t AntiReplay(TLS_Ctx *ctx, RecHdr *hdr)
590 {
591     /* In non-UDP scenarios, anti-replay check is not required */
592     if (!BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
593         return HITLS_SUCCESS;
594     }
595 
596     RecConnState *state = GetReadConnState(ctx);
597     uint16_t epoch = REC_EPOCH_GET(hdr->epochSeq);
598     uint64_t secquence = REC_SEQ_GET(hdr->epochSeq);
599     if (RecAntiReplayCheck(&state->window, secquence) == true) {
600         return HITLS_REC_NORMAL_RECV_BUF_EMPTY;
601     }
602 
603     if (ctx->isDtlsListen && epoch != 0) {
604         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17264, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "epoch err", 0, 0, 0, 0);
605         return HITLS_REC_ERR_RECV_UNEXPECTED_MSG;
606     }
607 
608     return HITLS_SUCCESS;
609 }
610 #endif
611 
RecInBufInit(RecCtx * recordCtx,uint32_t bufSize)612 static int32_t RecInBufInit(RecCtx *recordCtx, uint32_t bufSize)
613 {
614     if (recordCtx->inBuf == NULL) {
615         recordCtx->inBuf = RecBufNew(bufSize);
616         if (recordCtx->inBuf == NULL) {
617             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17265, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
618                 "RecBufNew fail", 0, 0, 0, 0);
619             return HITLS_MEMALLOC_FAIL;
620         }
621     }
622     return HITLS_SUCCESS;
623 }
624 
DtlsTryReadAndCheckRecordMessage(TLS_Ctx * ctx,uint8_t ** recordBody,RecHdr * hdr)625 static int32_t DtlsTryReadAndCheckRecordMessage(TLS_Ctx *ctx, uint8_t **recordBody, RecHdr *hdr)
626 {
627     int32_t ret = HITLS_SUCCESS;
628     /* Read the new record message */
629     ret = TryReadOneDtlsRecord(ctx, recordBody, hdr);
630     if (ret != HITLS_SUCCESS) {
631         return ret;
632     }
633 
634     /* Check the record message header. If the message header is not the expected message, cache the message */
635     return DtlsRecordHeaderProcess(ctx, *recordBody, hdr);
636 }
637 
DtlsGetRecord(TLS_Ctx * ctx,REC_Type recordType,RecHdr * hdr,uint8_t ** recordBody,uint8_t ** cachRecord)638 static int32_t DtlsGetRecord(TLS_Ctx *ctx, REC_Type recordType, RecHdr *hdr, uint8_t **recordBody, uint8_t **cachRecord)
639 {
640     RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
641     int32_t ret = RecInBufInit(recordCtx, RecGetInitBufferSize(ctx, true));
642     if (ret != HITLS_SUCCESS) {
643         return ret;
644     }
645     /* Check if there are cached messages that need to be processed */
646     *recordBody = GetUnprocessedMsg(recordCtx, recordType, hdr);
647     *cachRecord = *recordBody;
648     /* There are no cached messages to process */
649     if (*recordBody == NULL) {
650         ret = DtlsTryReadAndCheckRecordMessage(ctx, recordBody, hdr);
651         if (ret != HITLS_SUCCESS) {
652             return ret;
653         }
654     }
655 #if defined(HITLS_BSL_UIO_UDP)
656     ret = AntiReplay(ctx, hdr);
657     if (ret != HITLS_SUCCESS) {
658         BSL_SAL_FREE(*cachRecord);
659     }
660 #endif
661     return ret;
662 }
663 
DtlsProcessBufList(TLS_Ctx * ctx,REC_Type recordType,RecBufList * bufList,RecBuf * decryptBuf)664 static int32_t DtlsProcessBufList(TLS_Ctx *ctx, REC_Type recordType, RecBufList *bufList, RecBuf *decryptBuf)
665 {
666     (void)recordType;
667     int32_t ret = RecBufListAddBuffer(bufList, decryptBuf);
668     if (ret != HITLS_SUCCESS) {
669         if (decryptBuf->isHoldBuffer) {
670             BSL_SAL_FREE(decryptBuf->buf);
671         }
672         return ret;
673     }
674     ret = RecDerefBufList(ctx);
675     if (ret != HITLS_SUCCESS) {
676         return ret;
677     }
678 
679 return HITLS_SUCCESS;
680 }
681 
682 /**
683  * @brief Read a record in the DTLS protocol.
684  *
685  * @param ctx [IN] TLS context
686  * @param recordType [IN] Record type
687  * @param data [OUT] Read data
688  * @param len [OUT] Length of the data to be read
689  * @param bufSize [IN] buffer length
690  *
691  * @retval HITLS_SUCCESS succeeded.
692  * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again
693  * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error
694  * @retval HITLS_REC_NORMAL_RECV_UNEXPECT_MSG Unexpected message received
695  * @retval HITLS_REC_NORMAL_RECV_DISORDER_MSG Receives out-of-order messages.
696  *
697  */
DtlsRecordRead(TLS_Ctx * ctx,REC_Type recordType,uint8_t * data,uint32_t * len,uint32_t bufSize)698 int32_t DtlsRecordRead(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *len, uint32_t bufSize)
699 {
700     RecBufList *bufList = (recordType == REC_TYPE_HANDSHAKE) ? ctx->recCtx->hsRecList : ctx->recCtx->appRecList;
701     if (!RecBufListEmpty(bufList)) {
702         return RecBufListGetBuffer(bufList, data, bufSize, len, (ctx->peekFlag != 0 && (recordType == REC_TYPE_APP)));
703     }
704     RecHdr hdr = {0};
705     /* Pointer for storing buffered messages, which is used during release */
706     uint8_t *recordBody = NULL;
707     uint8_t *cachRecord = NULL;
708     int32_t ret = DtlsGetRecord(ctx, recordType, &hdr, &recordBody, &cachRecord);
709     if (ret != HITLS_SUCCESS) {
710         return ret;
711     }
712     /* Construct parameters before decryption */
713     REC_TextInput cryptMsg = {0};
714     GenerateCryptMsg(ctx, &hdr, recordBody, &cryptMsg);
715     RecBuf decryptBuf = { .buf = data, .bufSize = bufSize };
716     ret = RecordDecrypt(ctx, &decryptBuf, &cryptMsg);
717     BSL_SAL_FREE(cachRecord);
718     if (ret != HITLS_SUCCESS) {
719         return ret;
720     }
721 #if defined(HITLS_BSL_UIO_UDP)
722     /* In UDP scenarios, update the sliding window flag */
723     if (BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
724         RecAntiReplayUpdate(&GetReadConnState(ctx)->window, REC_SEQ_GET(hdr.epochSeq));
725     }
726 #endif
727     RecClearAlertCount(ctx, cryptMsg.type);
728     /* An unexpected packet is received */
729     // decryptBuf.isHoldBuffer == false
730     if (recordType != cryptMsg.type) {
731         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16513, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
732             "expect type %d, receive type %d", recordType, cryptMsg.type, 0, 0);
733         return RecordUnexpectedMsg(ctx, &decryptBuf, cryptMsg.type);
734     }
735     if (decryptBuf.buf == data) {
736         /* Update the read length */
737         *len = decryptBuf.end;
738 
739         return HITLS_SUCCESS;
740     }
741     ret = DtlsProcessBufList(ctx, recordType, bufList, &decryptBuf);
742     if (ret != HITLS_SUCCESS) {
743         return ret;
744     }
745     return RecBufListGetBuffer(bufList, data, bufSize, len, (ctx->peekFlag != 0 && (recordType == REC_TYPE_APP)));
746 }
747 
748 #endif /* HITLS_TLS_PROTO_DTLS12 */
749 
750 #ifdef HITLS_TLS_PROTO_TLS
VersionProcess(TLS_Ctx * ctx,uint16_t version,uint8_t type)751 static int32_t VersionProcess(TLS_Ctx *ctx, uint16_t version, uint8_t type)
752 {
753     if ((ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) && (version != HITLS_VERSION_TLS12)) {
754             /* If the negotiated version is tls1.3, the record version must be tls1.2 */
755             BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION);
756             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15448, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
757                 "get a record with illegal version(0x%x).", version, 0, 0, 0);
758             ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
759             return HITLS_REC_INVALID_PROTOCOL_VERSION;
760     } else if ((ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) && (version != ctx->negotiatedInfo.version)) {
761         BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION);
762         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15449, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
763             "get a record with illegal version(0x%x).", version, 0, 0, 0);
764         if (((version & 0xff00u) == (ctx->negotiatedInfo.version & 0xff00u)) && type == REC_TYPE_ALERT) {
765             return HITLS_SUCCESS;
766         }
767         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION);
768         return HITLS_REC_INVALID_PROTOCOL_VERSION;
769     }
770     return HITLS_SUCCESS;
771 }
772 
TlsCheckVersionField(TLS_Ctx * ctx,uint16_t version,uint8_t type)773 int32_t TlsCheckVersionField(TLS_Ctx *ctx, uint16_t version, uint8_t type)
774 {
775     if (ctx->negotiatedInfo.version == 0u) {
776 #ifdef HITLS_TLS_PROTO_TLCP11
777         if (((version >> 8u) != HITLS_VERSION_TLS_MAJOR) && (version != HITLS_VERSION_TLCP_DTLCP11)) {
778 #else
779         if ((version >> 8u) != HITLS_VERSION_TLS_MAJOR) {
780 #endif
781             BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION);
782             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16132, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
783                 "get a record with illegal version(0x%x).", version, 0, 0, 0);
784             ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION);
785             return HITLS_REC_INVALID_PROTOCOL_VERSION;
786         }
787     } else {
788         return VersionProcess(ctx, version, type);
789     }
790     return HITLS_SUCCESS;
791 }
792 
793 int32_t TlsCheckRecordHeader(TLS_Ctx *ctx, const RecHdr *recordHdr)
794 {
795     if (RecCastUintToRecType(ctx, recordHdr->type) == REC_TYPE_UNKNOWN) {
796         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15450, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
797             "get a record with invalid type", 0, 0, 0, 0);
798         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
799     }
800 
801     int32_t ret = TlsCheckVersionField(ctx, recordHdr->version, recordHdr->type);
802     if (ret != HITLS_SUCCESS) {
803         return HITLS_REC_INVALID_PROTOCOL_VERSION;
804     }
805 
806     if (recordHdr->bodyLen + REC_TLS_RECORD_HEADER_LEN > RecGetInitBufferSize(ctx, true)) {
807         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15451, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
808             "get a record with invalid length", 0, 0, 0, 0);
809         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW);
810     }
811 #ifdef HITLS_TLS_PROTO_TLS13
812     if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13 && recordHdr->bodyLen > REC_MAX_TLS13_ENCRYPTED_LEN) {
813         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16125, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
814             "get a record with invalid length", 0, 0, 0, 0);
815         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW);
816     }
817 #endif
818     return HITLS_SUCCESS;
819 }
820 
821 /**
822  * @brief   Read data from the uio of the TLS context into inBuf
823  *
824  * @param   ctx [IN] TLS context
825  * @param   inBuf [IN] inBuf Read buffer.
826  * @param   len [IN] len The length to read, it takes the value of the record header length (5
827  * bytes) or the entire record length (header + body)
828  *
829  * @retval  HITLS_SUCCESS Read successfully
830  * @retval  HITLS_REC_ERR_IO_EXCEPTION IO error
831  * @retval  HITLS_REC_NORMAL_RECV_BUF_EMPTY No cached data needs to be re-read
832  * @retval  HITLS_REC_NORMAL_IO_EOF
833  */
834 int32_t StreamRead(TLS_Ctx *ctx, RecBuf *inBuf, uint32_t len)
835 {
836     uint32_t bytesInRbuf = inBuf->end - inBuf->start;
837     bool readAheadFlag = (ctx->config.tlsConfig.readAhead != 0);
838     if (bytesInRbuf == 0) {
839         inBuf->start = 0;
840         inBuf->end = 0;
841     }
842 
843     // there are enough data in the read buffer
844     if (bytesInRbuf >= len) {
845         return HITLS_SUCCESS;
846     }
847     // right-side available space is less then required len, move data leftwards
848     if (inBuf->bufSize - inBuf->end < len) {
849         for (uint32_t i = 0; i < bytesInRbuf; i++) {
850             inBuf->buf[i] = inBuf->buf[inBuf->start + i];
851         }
852 
853         inBuf->start = 0;
854         inBuf->end = bytesInRbuf;
855     }
856     uint32_t upperBnd = (!readAheadFlag && inBuf->bufSize >= inBuf->start + len - inBuf->end)
857                             ? inBuf->start + len
858                             : inBuf->bufSize;
859     do {
860         uint32_t recvLen = 0u;
861 #ifdef HITLS_TLS_CONFIG_STATE
862         ctx->rwstate = HITLS_READING;
863 #endif
864 
865 #ifdef HITLS_TLS_FEATURE_FLIGHT
866         int32_t ret = BSL_UIO_Read(ctx->rUio, &(inBuf->buf[inBuf->end]), upperBnd - inBuf->end, &recvLen);
867 #else
868         int32_t ret = BSL_UIO_Read(ctx->uio,  &(inBuf->buf[inBuf->end]), upperBnd - inBuf->end, &recvLen);
869 #endif
870         if (ret != BSL_SUCCESS) {
871             if (ret == BSL_UIO_IO_EOF) {
872                 return HITLS_REC_NORMAL_IO_EOF;
873             }
874             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15452, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
875                 "Fail to call BSL_UIO_Read in StreamRead: [%d]", ret, 0, 0, 0);
876             return HITLS_REC_ERR_IO_EXCEPTION;
877         }
878 
879 #ifdef HITLS_TLS_CONFIG_STATE
880         ctx->rwstate = HITLS_NOTHING;
881 #endif
882         if (recvLen == 0) {
883             return HITLS_REC_NORMAL_RECV_BUF_EMPTY;
884         }
885 
886         inBuf->end += recvLen;
887     } while (inBuf->end - inBuf->start < len);
888 
889     return HITLS_SUCCESS;
890 }
891 
892 /**
893  * @brief Attempt to read a tls record message.
894  *
895  * @param ctx [IN] TLS context
896  * @param recordBody [OUT] record body
897  * @param hdr [OUT] record head
898  *
899  * @retval HITLS_SUCCESS
900  * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again
901  * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error
902  */
903 int32_t TryReadOneTlsRecord(TLS_Ctx *ctx, uint8_t **recordBody, RecHdr *recHeader)
904 {
905     /* Buffer for reading data */
906     RecBuf *inBuf = ctx->recCtx->inBuf;
907     if (IsNeedtoRead(ctx, inBuf)) {
908         RecDerefBufList(ctx);
909     }
910     // read record header
911     int32_t ret = StreamRead(ctx, inBuf, REC_TLS_RECORD_HEADER_LEN);
912     if (ret != HITLS_SUCCESS) {
913         return ret;
914     }
915 
916     const uint8_t *recordHeader = &inBuf->buf[inBuf->start];
917     recHeader->type = recordHeader[0];
918     recHeader->version = BSL_ByteToUint16(recordHeader + sizeof(uint8_t));
919     recHeader->bodyLen = BSL_ByteToUint16(recordHeader + REC_TLS_RECORD_LENGTH_OFFSET);
920 
921     ret = TlsCheckRecordHeader(ctx, recHeader);
922     if (ret != HITLS_SUCCESS) {
923 #ifdef HITLS_TLS_FEATURE_INDICATOR
924         INDICATOR_MessageIndicate(0, 0, RECORD_HEADER, recordHeader, REC_TLS_RECORD_HEADER_LEN, ctx,
925             ctx->config.tlsConfig.msgArg);
926 #endif
927         return ret;
928     }
929 
930 #ifdef HITLS_TLS_FEATURE_INDICATOR
931     INDICATOR_MessageIndicate(0, recHeader->version, RECORD_HEADER, recordHeader, REC_TLS_RECORD_HEADER_LEN, ctx,
932         ctx->config.tlsConfig.msgArg);
933 #endif
934 
935     uint32_t recHeaderAndBodyLen = REC_TLS_RECORD_HEADER_LEN + (uint32_t)recHeader->bodyLen;
936 
937     // read a whole record: head + body
938     ret = StreamRead(ctx, inBuf, recHeaderAndBodyLen);
939     if (ret != HITLS_SUCCESS) {
940         return ret;
941     }
942 
943     *recordBody = &inBuf->buf[inBuf->start] + REC_TLS_RECORD_HEADER_LEN;
944 
945     inBuf->start += recHeaderAndBodyLen;
946     return HITLS_SUCCESS;
947 }
948 
949 int32_t RecordDecryptPrepare(TLS_Ctx *ctx, uint16_t version, REC_Type recordType, REC_TextInput *cryptMsg)
950 {
951     (void)recordType;
952     (void)version;
953     RecConnState *state = GetReadConnState(ctx);
954     if (state->isWrapped == true) {
955         BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_SN_WRAPPING);
956         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15454, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
957             "Record read: sequence number wrap.", 0, 0, 0, 0);
958         return HITLS_REC_ERR_SN_WRAPPING;
959     }
960     if (state->seq == REC_TLS_SN_MAX_VALUE) {
961         state->isWrapped = true;
962     }
963 
964     if (ctx->peekFlag != 0 && recordType != REC_TYPE_APP) {
965         BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
966         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16170, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
967             "Peek mode applies only if record type is application.", 0, 0, 0, 0);
968         return HITLS_INTERNAL_EXCEPTION;
969     }
970 
971     RecHdr recordHeader = { 0 };
972     uint8_t *recordBody = NULL;
973     // read header and body from ctx
974     int32_t ret = TryReadOneTlsRecord(ctx, &recordBody, &recordHeader);
975     if (ret != HITLS_SUCCESS) {
976         return ret;
977     }
978     uint32_t recordBodyLen = (uint32_t)recordHeader.bodyLen;
979 #ifdef HITLS_TLS_PROTO_TLS13
980     if (HS_GetVersion(ctx) == HITLS_VERSION_TLS13) {
981         if ((recordHeader.type == REC_TYPE_CHANGE_CIPHER_SPEC || recordHeader.type == REC_TYPE_ALERT) &&
982             recordBodyLen != 0) {
983             ctx->recCtx->unexpectedMsgType = recordHeader.type;
984             /* In the TLS1.3 scenario, process unencrypted CCS and Alert messages received */
985             return ctx->method.unexpectedMsgProcessCb(ctx, recordHeader.type, recordBody, recordBodyLen, true);
986         }
987     }
988 #endif
989 
990     cryptMsg->negotiatedVersion = ctx->negotiatedInfo.version;
991 #ifdef HITLS_TLS_FEATURE_ETM
992     cryptMsg->isEncryptThenMac = ctx->negotiatedInfo.isEncryptThenMac;
993 #endif
994     cryptMsg->type = recordHeader.type;
995     cryptMsg->version = recordHeader.version;
996     cryptMsg->text = recordBody;
997     cryptMsg->textLen = recordBodyLen;
998     BSL_Uint64ToByte(state->seq, cryptMsg->seq);
999     return HITLS_SUCCESS;
1000 }
1001 
1002 /**
1003  * @brief Read a record in the TLS protocol.
1004  * @attention: Handle record and handle transporting state to receive unexpected record type messages
1005  * @param ctx [IN] TLS context
1006  * @param recordType [IN] Record type
1007  * @param data [OUT] Read data
1008  * @param readLen [OUT] Length of the read data
1009  * @param num [IN] The read buffer has num bytes
1010  *
1011  * @retval HITLS_SUCCESS
1012  * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY Need to re-read
1013  * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error
1014  * @retval HITLS_REC_ERR_SN_WRAPPING The sequence number is rewound.
1015  * @retval HITLS_REC_NORMAL_RECV_UNEXPECT_MSG Unexpected message received.
1016  *
1017  */
1018 int32_t TlsRecordRead(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num)
1019 {
1020     RecBufList *bufList = (recordType == REC_TYPE_HANDSHAKE) ? ctx->recCtx->hsRecList : ctx->recCtx->appRecList;
1021     if (!RecBufListEmpty(bufList)) {
1022         return RecBufListGetBuffer(bufList, data, num, readLen, (ctx->peekFlag != 0 && (recordType == REC_TYPE_APP)));
1023     }
1024     REC_TextInput encryptedMsg = { 0 };
1025     int32_t ret = RecordDecryptPrepare(ctx, ctx->negotiatedInfo.version, recordType, &encryptedMsg);
1026     if (ret != HITLS_SUCCESS) {
1027         return ret;
1028     }
1029     RecBuf decryptBuf = {0};
1030     decryptBuf.buf = data;
1031     decryptBuf.bufSize = num;
1032     ret = RecordDecrypt(ctx, &decryptBuf, &encryptedMsg);
1033     if (ret != HITLS_SUCCESS) {
1034         return ret;
1035     }
1036     RecClearAlertCount(ctx, encryptedMsg.type);
1037     /* An unexpected message is received */
1038     if (recordType != encryptedMsg.type) {
1039         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17260, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
1040             "expect type %d, receive type %d", recordType, encryptedMsg.type, 0, 0);
1041         return RecordUnexpectedMsg(ctx, &decryptBuf, encryptedMsg.type);
1042     }
1043     if (decryptBuf.buf == data) {
1044         /* Update the read length */
1045         *readLen = decryptBuf.end;
1046         return HITLS_SUCCESS;
1047     }
1048     ret = RecBufListAddBuffer(bufList, &decryptBuf);
1049     if (ret != HITLS_SUCCESS) {
1050         if (decryptBuf.isHoldBuffer) {
1051             BSL_SAL_FREE(decryptBuf.buf);
1052         }
1053         return ret;
1054     }
1055     return RecBufListGetBuffer(bufList, data, num, readLen, (ctx->peekFlag != 0 && (recordType == REC_TYPE_APP)));
1056 }
1057 #endif /* HITLS_TLS_PROTO_TLS */
1058 
1059 uint32_t APP_GetReadPendingBytes(const TLS_Ctx *ctx)
1060 {
1061     if (ctx == NULL || ctx->recCtx == NULL || RecBufListEmpty(ctx->recCtx->appRecList)) {
1062         return 0;
1063     }
1064     RecBuf *recBuf = (RecBuf *)BSL_LIST_GET_FIRST(ctx->recCtx->appRecList);
1065     if (recBuf == NULL) {
1066         return 0;
1067     }
1068     return recBuf->end - recBuf->start;
1069 }