Skip to content

ecc: reject compressed EC points with incorrect length#10591

Open
MarkAtwood wants to merge 1 commit into
wolfSSL:masterfrom
MarkAtwood:fix/ecc-reject-truncated-compressed-point
Open

ecc: reject compressed EC points with incorrect length#10591
MarkAtwood wants to merge 1 commit into
wolfSSL:masterfrom
MarkAtwood:fix/ecc-reject-truncated-compressed-point

Conversation

@MarkAtwood
Copy link
Copy Markdown
Contributor

Summary

wc_ecc_import_point_der_ex accepts a single byte 0x02 or 0x03 as a valid compressed EC point. It treats the missing X coordinate as zero, decompresses it (producing a valid on-curve point), and wc_ecc_check_key passes. This allows ECDH key agreement with a crafted 1-byte peer public key.

Fix

After identifying 0x02/0x03 format byte, verify that inLen == ecc_sets[curve_idx].size + 1 using unsigned comparison to avoid underflow. Only set compressed = 1 after the length check passes, keeping state consistent on the error path.

Reproducer

Call EC_POINT_oct2point with a 1-byte buffer containing 0x02 for any NIST curve. Before this fix it succeeds; after, it returns ECC_BAD_ARG_E.

Test Plan

  • 1-byte 0x02 input returns ECC_BAD_ARG_E
  • Valid compressed points still import correctly
  • Run existing wolfSSL test suite

wc_ecc_import_point_der_ex accepts a single byte 0x02 or 0x03 as a
valid compressed EC point. It treats the missing X coordinate as zero,
decompresses it (producing a valid on-curve point), and wc_ecc_check_key
passes. This allows ECDH key agreement with a crafted 1-byte peer
public key.

Add length validation for compressed points: after identifying 0x02/0x03
format byte, verify that inLen == ecc_sets[curve_idx].size + 1 using
unsigned comparison to avoid underflow. Only set compressed = 1 after
the length check passes, keeping state consistent on the error path.

Reproducer: call EC_POINT_oct2point with a 1-byte buffer containing 0x02
for any NIST curve. Before this fix it succeeds; after, it returns
ECC_BAD_ARG_E.
Copilot AI review requested due to automatic review settings June 3, 2026 23:29
@MarkAtwood MarkAtwood self-assigned this Jun 3, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens ECC point import by rejecting compressed EC point encodings whose byte length doesn’t match the expected SEC1/X9.63 compressed form length for the selected curve, preventing truncated inputs such as a bare 0x02/0x03 format byte from being treated as valid points.

Changes:

  • Add an exact-length check for compressed points in wc_ecc_import_point_der_ex() before enabling the compressed decode path.
  • Ensure compressed state is only set after the length check passes, returning ECC_BAD_ARG_E on mismatch.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread wolfcrypt/src/ecc.c
Comment on lines +9633 to +9638
if (inLen == (word32)ecc_sets[curve_idx].size + 1) {
compressed = 1;
}
else {
err = ECC_BAD_ARG_E;
}
Comment thread wolfcrypt/src/ecc.c
Comment on lines +9631 to +9638
/* Compressed point must be exactly 1 + field_element_size bytes.
* Reject truncated inputs (e.g. a bare 0x02/0x03 byte). */
if (inLen == (word32)ecc_sets[curve_idx].size + 1) {
compressed = 1;
}
else {
err = ECC_BAD_ARG_E;
}
Comment thread wolfcrypt/src/ecc.c
Comment on lines +9631 to +9638
/* Compressed point must be exactly 1 + field_element_size bytes.
* Reject truncated inputs (e.g. a bare 0x02/0x03 byte). */
if (inLen == (word32)ecc_sets[curve_idx].size + 1) {
compressed = 1;
}
else {
err = ECC_BAD_ARG_E;
}
@ColtonWilley
Copy link
Copy Markdown
Contributor

Jenkins retest this please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants