Summary
TPM2_ASN_RsaUnpadPkcsv15 in src/tpm2_asn.c reads one byte past the end of
the input buffer when the PKCS#1 v1.5 padding consists entirely of 0xFF
bytes after the 0x00 0x01 header and contains no 0x00 separator. The
minimum input that triggers the read is 3 bytes: 00 01 FF.
Affected code
wolfTPM src/tpm2_asn.c, function TPM2_ASN_RsaUnpadPkcsv15 (lines 369-391
at commit adb15eecfed32b3fdb48e0fe1aa2a826808a59ae, master HEAD as of
2026-05-27):
if (sig[idx++] == 0x00 && sig[idx++] == 0x01) {
while (idx < *sigSz) {
if (sig[idx] != 0xFF)
break;
idx++;
}
if (sig[idx++] == 0x00) { /* <-- OOB read when loop exited with idx == *sigSz */
The while loop has two exit conditions:
- it encounters a non-
0xFF byte, in which case idx < *sigSz, or
- it runs off the end, in which case
idx == *sigSz.
The subsequent sig[idx++] == 0x00 check does not distinguish between these
cases and dereferences sig[*sigSz] in case (2).
Reproducer
Standalone PoC, function body copied verbatim from tpm2_asn.c:369-391,
built with gcc 13.3 on Ubuntu 24.04 using -fsanitize=address,undefined:
uint8_t* buf = malloc(3);
buf[0] = 0x00; buf[1] = 0x01; buf[2] = 0xFF;
uint8_t* sig = buf;
int sigSz = 3;
TPM2_ASN_RsaUnpadPkcsv15(&sig, &sigSz);
ASan output:
==481294==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000000013
READ of size 1 at 0x502000000013 thread T0
#0 in TPM2_ASN_RsaUnpadPkcsv15 src/tpm2_asn.c:384
#1 in main poc.c:56
0x502000000013 is located 0 bytes after 3-byte region [0x502000000010,0x502000000013)
allocated by thread T0 here:
#0 in malloc
#1 in main poc.c:46
SUMMARY: AddressSanitizer: heap-buffer-overflow in TPM2_ASN_RsaUnpadPkcsv15
(Full log and the single-file PoC are available on request — happy to attach
them to this advisory.)
Impact
The function is a WOLFTPM_API export and is reachable from application
code that verifies signed payloads, e.g.
examples/endorsement/verify_ek_cert.c:287. The read is 1 byte, so the
direct impact is bounded:
- Information disclosure of one heap byte adjacent to the signature buffer
(or, depending on the allocator and heap layout, a crash via the ASan
redzone / a guard page).
- If the byte happens to equal
0x00, the function returns success (rc = 0)
with *sigSz set to one less than the original allocation length, which
may cause the caller to consume one byte of uninitialised / adjacent
memory as legitimate signed content.
Exploitability depends on whether attacker-controlled buffers can reach this
function in a deployment. The existing OSS-Fuzz harness
(fuzz_asn_cert.c) does not call this function, which is likely why ASan
has not flagged it in CI to date.
Suggested fix
--- a/src/tpm2_asn.c
+++ b/src/tpm2_asn.c
@@ -381,7 +381,7 @@ int TPM2_ASN_RsaUnpadPkcsv15(uint8_t** pSig, int* sigSz)
idx++;
}
- if (sig[idx++] == 0x00) {
+ if (idx < *sigSz && sig[idx++] == 0x00) {
rc = 0;
*pSig = &sig[idx];
Equivalently, the while loop guard can be tightened to idx < *sigSz - 1
so that the byte-after-padding check is always in bounds.
How it was found
Static review of tpm2_asn.c, followed by a standalone reproducer compiled
with ASan to confirm. I'm not aware of any in-the-wild exploitation; this is
a routine code-audit finding.
Summary
TPM2_ASN_RsaUnpadPkcsv15insrc/tpm2_asn.creads one byte past the end ofthe input buffer when the PKCS#1 v1.5 padding consists entirely of
0xFFbytes after the
0x00 0x01header and contains no0x00separator. Theminimum input that triggers the read is 3 bytes:
00 01 FF.Affected code
wolfTPM
src/tpm2_asn.c, functionTPM2_ASN_RsaUnpadPkcsv15(lines 369-391at commit
adb15eecfed32b3fdb48e0fe1aa2a826808a59ae, master HEAD as of2026-05-27):
The
whileloop has two exit conditions:0xFFbyte, in which caseidx < *sigSz, oridx == *sigSz.The subsequent
sig[idx++] == 0x00check does not distinguish between thesecases and dereferences
sig[*sigSz]in case (2).Reproducer
Standalone PoC, function body copied verbatim from
tpm2_asn.c:369-391,built with gcc 13.3 on Ubuntu 24.04 using
-fsanitize=address,undefined:ASan output:
(Full log and the single-file PoC are available on request — happy to attach
them to this advisory.)
Impact
The function is a
WOLFTPM_APIexport and is reachable from applicationcode that verifies signed payloads, e.g.
examples/endorsement/verify_ek_cert.c:287. The read is 1 byte, so thedirect impact is bounded:
(or, depending on the allocator and heap layout, a crash via the ASan
redzone / a guard page).
0x00, the function returns success (rc = 0)with
*sigSzset to one less than the original allocation length, whichmay cause the caller to consume one byte of uninitialised / adjacent
memory as legitimate signed content.
Exploitability depends on whether attacker-controlled buffers can reach this
function in a deployment. The existing OSS-Fuzz harness
(
fuzz_asn_cert.c) does not call this function, which is likely why ASanhas not flagged it in CI to date.
Suggested fix
Equivalently, the
whileloop guard can be tightened toidx < *sigSz - 1so that the byte-after-padding check is always in bounds.
How it was found
Static review of
tpm2_asn.c, followed by a standalone reproducer compiledwith ASan to confirm. I'm not aware of any in-the-wild exploitation; this is
a routine code-audit finding.