Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Defragment incoming TLS handshake messages #9872
Defragment incoming TLS handshake messages #9872
Changes from all commits
ac2cf1f
5f7c2c2
cad11ad
3dfe75e
aaa152e
b70e76a
afa11db
eb77e5b
cf4e6a1
dd14c0a
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing in #9989 reveals a bug: defragmentation of encrypted records does not work correctly in TLS 1.2 when the symmetric encryption is CBC (EtM or not), CCM or GCM. It works with any TLS 1.3 cipher suite, and with ChachaPoly and null encryption in TLS 1.2. The problematic cases are exactly the ones where the record includes an explicit IV (always 8 bytes).
In the initial handshake, only the Finished message is likely to be affected, and it's only 16 bytes, so this happens when the fragment size is less than 16 bytes. This can happen with larger fragment sizes during renegotiation.
In problematic scenarios, the fragment reassembly loop looks for the second fragment 8 bytes too early in the buffer. There is an 8-byte gap between the fragments, but the reassembly expects them to be consecutive.
It's not 100% clear to me yet, but I think the offset update here isn't correct. As far as I can tell from looking at an example in a debugger, at the end of the first incomplete fragment,
ssl->in_msg
andssl->in_hdr
end up pointing 8 bytes past the end of the end of the fragment.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I was trying to analyze and fix https://github.com/Mbed-TLS/mbedtls/pull/9872/files#r1967669302, I tried to make sense of what the various pointers and offsets should be at any given point (
ssl->in_msg
,ssl->in_hdr
,ssl->in_hsfraglen
, etc., as well as the various record fields while processing records), and I have a hard time figuring out whether the value I'm seeing is the value that should be there at any given point during parsing. I'm not sure if the reassembly loop should be changed, or if it's getting unexpected data.One of the difficulties in understanding the code is that fragment accumulation is completely disconnected from fragment reassembly, so reassembly has to re-parse data. I would find it easier to understand if the structure of the code was: when we have finished parsing a fragment, if it wasn't the initial fragment, then merge it with the initial fragment. With this structure, there'd be fewer moving parts. Fragment reassembly would have access to the offsets and record data from the latest fragment, and wouldn't need to do any parsing, so it would be easier to figure out offsets. There would also be fewer opportunities for parsing errors or integer/buffer overflows. In addition, the input buffer would fill out less quickly — the current structure adds a 5- or 13-byte overhead per fragment. @rojer Did you try doing fragment reassembly incrementally? Are there any difficulties in doing it that way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, i don't see any reason why it couldn't be done that way. this just happened to be the way i went at it at the time.