From: Ming Lu <ming.lu@citrix.com>
Subject: CA-430076: Variable-time comparison of pool_secret

The [String.equal] will take variable time according to how similar the
two strings are in comparison. An attacker can have a byte-at-a-time
timing oracle on the pool_secret, making practical secret recovery attacks
significantly more feasible.

[Eqaf.equal] instead has data-invariant timing if and only if both
strings being compared have the same length. In such case, it does not
depend on the contents of the strings being compared, so the time taken
to reject a guess reveals nothing about how much of it is correct.

When the lengths differ, [Eqaf.equal] returns early, which reveals
whether a guess has the same length as the secret. This is not new. And
enough entropy in secret has been enforced. So it's not a critical issue.

This is XSA-529 / CVE-2026-102705.

Signed-off-by: Ming Lu <ming.lu@citrix.com>
Reviewed-by: Andrii Sultanov <andriy.sultanov@vates.tech>

diff --git a/ocaml/xapi-types/dune b/ocaml/xapi-types/dune
index 8122674acf8e..5c72e0b97526 100644
--- a/ocaml/xapi-types/dune
+++ b/ocaml/xapi-types/dune
@@ -14,6 +14,7 @@
   (flags (:standard -w -33))
   (libraries
     astring
+    eqaf
     rpclib.core
     rpclib.json
     rpclib.xml
diff --git a/ocaml/xapi-types/secretString.ml b/ocaml/xapi-types/secretString.ml
index b552e46edfd6..712939dde939 100644
--- a/ocaml/xapi-types/secretString.ml
+++ b/ocaml/xapi-types/secretString.ml
@@ -22,7 +22,7 @@ let write_to_file = Xapi_stdext_unix.Unixext.write_string_to_file ~perms:0o600
 
 let write_to_channel c s = output_string c s
 
-let equal = String.equal
+let equal = Eqaf.equal
 
 let length = String.length
 
