From d337fbc4cb1ded1d58a1c4fe92aa9988d68ec1f3 Mon Sep 17 00:00:00 2001
From: Gilles Peskine <Gilles.Peskine@arm.com>
Date: Tue, 14 Sep 2021 00:13:05 +0200
Subject: [PATCH] x86_64 MULADDC assembly: add missing constraints about memory

MULADDC_CORE reads from (%%rsi) and writes to (%%rdi). This fragment is
repeated up to 16 times, and %%rsi and %%rdi are s and d on entry
respectively. Hence the complete asm statement reads 16 64-bit words
from memory starting at s, and writes 16 64-bit words starting at d.

Without any declaration of modified memory, Clang 12 and Clang 13 generated
non-working code for mbedtls_mpi_mod_exp. The constraints make the unit
tests pass with Clang 12.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
---
 ChangeLog.d/muladdc-amd64-memory.txt | 3 +++
 library/bn_mul.h                     | 6 +++---
 2 files changed, 6 insertions(+), 3 deletions(-)
 create mode 100644 ChangeLog.d/muladdc-amd64-memory.txt

diff --git a/ChangeLog.d/muladdc-amd64-memory.txt b/ChangeLog.d/muladdc-amd64-memory.txt
new file mode 100644
index 000000000..1803e423d
--- /dev/null
+++ b/ChangeLog.d/muladdc-amd64-memory.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix missing constraints on x86_64 assembly code for bignum multiplication
+     that broke some bignum operations with (at least) Clang 12. Fixes #4786.
diff --git a/library/bn_mul.h b/library/bn_mul.h
index 6ddffc476..328e76500 100644
--- a/library/bn_mul.h
+++ b/library/bn_mul.h
@@ -225,9 +225,9 @@
         "addq   $8, %%rdi\n"
 
 #define MULADDC_STOP                        \
-        : "+c" (c), "+D" (d), "+S" (s)      \
-        : "b" (b)                           \
-        : "rax", "rdx", "r8"                \
+        : "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \
+        : "b" (b), "m" (*(const uint64_t (*)[16]) s)                 \
+        : "rax", "rdx", "r8"                                         \
     );
 
 #endif /* AMD64 */