From d8206b8bc40ea114c7eeb54879f9797d4dec13eb Mon Sep 17 00:00:00 2001 From: deadcafe Date: Thu, 22 Oct 2026 00:04:00 +0530 Subject: [PATCH] Fix TPM2_ASN_TrimZeros skipping bytes The loop advanced both idx and the in pointer, so each check after the first read two bytes past the intended one. An ECDSA R or S starting 00 <0x80 00 <0x80 lost a significant byte, and wolfTPM2_PK_EccSign then DER-encoded a wrong signature that the TLS peer rejected (-330). Only advance idx and return in + idx. Add a unit test using the S bytes from the failing CI run. --- src/tpm2_asn.c | 3 +-- tests/unit_tests.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/tpm2_asn.c b/src/tpm2_asn.c index dff4df3d1..7b1053e60 100644 --- a/src/tpm2_asn.c +++ b/src/tpm2_asn.c @@ -34,10 +34,9 @@ byte* TPM2_ASN_TrimZeros(byte* in, word32* len) word32 idx = 0; while (idx+1 < *len && in[idx] == 0 && (in[idx+1] & 0x80) == 0) { idx++; - in++; } *len -= idx; - return in; + return in + idx; } int TPM2_ASN_GetLength_ex(const uint8_t* input, word32* inOutIdx, int* len, diff --git a/tests/unit_tests.c b/tests/unit_tests.c index 9347c5d0e..e15a18ca2 100644 --- a/tests/unit_tests.c +++ b/tests/unit_tests.c @@ -8840,6 +8840,36 @@ static void test_TPM2_ASN_RsaUnpadPkcsv15(void) #endif } +static void test_TPM2_ASN_TrimZeros(void) +{ +#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_ASN) + /* ECDSA S from a failed CI run: only the first zero may go */ + byte s[] = { 0x00, 0x71, 0x00, 0x4F, 0x95 }; + byte hi[] = { 0x00, 0x80, 0x01 }; + byte two[] = { 0x00, 0x00, 0x05 }; + byte* p; + word32 len; + + len = (word32)sizeof(s); + p = TPM2_ASN_TrimZeros(s, &len); + AssertIntEQ(len, 4); + AssertTrue(p == &s[1]); + + /* A zero before a high bit byte is kept */ + len = (word32)sizeof(hi); + p = TPM2_ASN_TrimZeros(hi, &len); + AssertIntEQ(len, 3); + AssertTrue(p == &hi[0]); + + len = (word32)sizeof(two); + p = TPM2_ASN_TrimZeros(two, &len); + AssertIntEQ(len, 1); + AssertTrue(p == &two[2]); + + printf("Test TPM Wrapper: %-40s Passed\n", "ASN TrimZeros:"); +#endif +} + #if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_ASN) #include #endif @@ -11371,6 +11401,7 @@ int unit_tests(int argc, char *argv[]) test_wolfTPM2_CryptoDevCb_MlDsaKeyId(); test_TPM2_ASN_DecodeX509Cert_Errors(); test_TPM2_ASN_RsaUnpadPkcsv15(); + test_TPM2_ASN_TrimZeros(); test_TPM2_ASN_DecodeX509Cert_Valid(); test_TPM2_ASN_DecodeTag_Errors(); #if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFTPM2_PEM_DECODE) && \