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 }