From cfcda0a095b8e2a17077a82110b4e6d47c437d4d Mon Sep 17 00:00:00 2001 From: makejian Date: Wed, 17 Jun 2026 15:13:56 +0800 Subject: [PATCH] Fix TriCore MULADDC clobber list missing carry register The TriCore MULADDC inline assembly in library/bn_mul.h uses d5 as the high half of the e4 carry-in register pair (it zeroes d5 in the INIT macro and feeds e4 = d5:d4 to madd.u), but d5 is not listed in the asm clobber list. On TriCore 1.8 (AURIX TC4xx, gcc -mtc18) the compiler may allocate a live value in d5 around the asm block because it believes the asm does not touch it; the asm then overwrites d5, corrupting the carry chain. This makes mbedtls_mpi_core_mla() compute a wrong result, which in turn makes mbedtls_mpi_div_mpi() return an incorrect quotient and mbedtls_mpi_mod_mpi() loop forever. Declare all data registers the asm actually writes (d2, d3 and d5, in addition to the existing ones) so the compiler does not reuse them across the asm block. This keeps the optimized assembly enabled on all TriCore targets instead of relying on the compiler happening not to use d5, which is what hid the bug on older TriCore ISAs. Signed-off-by: makejian --- ChangeLog.d/fix-tricore-muladdc-clobber.txt | 8 ++++++++ library/bn_mul.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 ChangeLog.d/fix-tricore-muladdc-clobber.txt diff --git a/ChangeLog.d/fix-tricore-muladdc-clobber.txt b/ChangeLog.d/fix-tricore-muladdc-clobber.txt new file mode 100644 index 0000000000..66ff793d2b --- /dev/null +++ b/ChangeLog.d/fix-tricore-muladdc-clobber.txt @@ -0,0 +1,8 @@ +Bugfix + * Fix the TriCore MULADDC inline assembly in library/bn_mul.h which was + missing register d5 (the high half of the e4 carry-in pair) from its + clobber list. On TriCore 1.8 (AURIX TC4xx) the compiler could allocate + a live value in d5 across the asm block, which the asm then overwrote, + corrupting the carry chain. This produced wrong results in + mbedtls_mpi_core_mla, making mbedtls_mpi_mod_mpi loop forever. Declare + all data registers the asm writes so the compiler does not reuse them. diff --git a/library/bn_mul.h b/library/bn_mul.h index 0738469db4..84053a1c46 100644 --- a/library/bn_mul.h +++ b/library/bn_mul.h @@ -653,7 +653,8 @@ "st.a %2, %%a2 \n\t" \ : "=m" (c), "=m" (d), "=m" (s) \ : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "d0", "d1", "e2", "d4", "a2", "a3" \ + : "d0", "d1", "d2", "d3", "d4", "d5", \ + "a2", "a3" \ ); #endif /* TriCore */