Fix silent key truncation on short BIO_write in key encoders - #481
Fix silent key truncation on short BIO_write in key encoders#481sameehj wants to merge 2 commits into
Conversation
The key encoders write DER/PEM output with a single BIO_write and treat any positive return as success, so a short write silently truncates the encoding. Add a deterministic test that encodes an EC public key through a BIO that accepts one byte per write and confirms no bytes are lost. Fenrir 11560.
BIO_write may write fewer bytes than requested. The key encoders checked only for a non-positive return, so a short write truncated the DER/PEM output while still reporting success. Add wp_write_bio, which loops until all bytes are written, and use it in the RSA, ECC, ECX, DH and ML-DSA encoders. Fenrir 11560.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #481
Scan targets checked: wolfprovider-bugs, wolfprovider-src
Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
| #endif | ||
| #endif | ||
| #ifdef WP_HAVE_EC_P256 | ||
| TEST_DECL(test_ecc_encode_short_write_bio, NULL), |
There was a problem hiding this comment.
New test registered outside the WP_HAVE_ECDH guard that surrounds its definition · Incorrect macro expansion
test_ecc_encode_short_write_bio is defined in test/test_ecc.c:1153, inside the #ifdef WP_HAVE_ECDH block spanning lines 721-1634, and declared in test/unit.h:473 inside the #ifdef WP_HAVE_ECDH block starting at line 430, but registered under #ifdef WP_HAVE_EC_P256 alone. A build with P-256 and ECDSA but without HAVE_ECC_DHE fails to compile and link unit.test.
Fix: Move the definition and declaration out of the WP_HAVE_ECDH blocks so all three sites are gated identically on WP_HAVE_EC_P256.
PR body
BIO_writeis allowed to write fewer bytes than requested (a "short write"),which returns a positive value smaller than
keyLen. The old check onlyrejected
rc <= 0, so a short write was reported as success while the DER/PEMoutput was silently truncated. Application-supplied BIOs (sockets, pipes,
non-blocking or custom sinks) can legitimately short-write, so a caller could
receive and persist a corrupt, incomplete key with no error.
Fix
Add a shared helper
wp_write_bio()insrc/wp_internal.cthat loops untilevery byte is written, and use it in all five encoders. The helper mirrors the
existing
wp_read_der_biostyle (WOLFPROV_ENTER/LEAVE,okflag, Doxygenheader). Each iteration either advances past the bytes written or fails, so
there is no busy-loop or hang.
Encoder sinks are used synchronously, so a non-positive return is treated as a
hard failure rather than spinning on
BIO_should_retry— it fails closedinstead of truncating.
Testing
New deterministic regression test
test_ecc_encode_short_write_bio(unit case143). It builds a custom BIO that accepts exactly one byte per write, encodes a
P-256 key as DER and PEM
SubjectPublicKeyInfothrough it, and asserts thecaptured bytes equal the full reference encoding from
OSSL_ENCODER_to_data.No threads or timing — binary pass/fail.
Before/after (case number:
./test/unit.test --list | grep short_write):./test/unit.test 143fails withShort write truncated output: 1 of 91 bytes../test/unit.test 143passes for DER and PEM.Fenrir
Addresses Fenrir finding 11560 (short-write truncation in key encoders).