Signed-off-by: Richard Henderson <[email protected]>
---
host/include/generic/host/crypto/clmul.h | 2 ++
include/crypto/clmul.h | 7 +++++++
crypto/clmul.c | 17 +++++++++++++++++
3 files changed, 26 insertions(+)
diff --git a/host/include/generic/host/crypto/clmul.h
b/host/include/generic/host/crypto/clmul.h
index 3fbb1576cf..7f70afeb57 100644
--- a/host/include/generic/host/crypto/clmul.h
+++ b/host/include/generic/host/crypto/clmul.h
@@ -23,4 +23,6 @@
#define clmul_32x2_even clmul_32x2_even_gen
#define clmul_32x2_odd clmul_32x2_odd_gen
+#define clmul_64 clmul_64_gen
+
#endif /* GENERIC_HOST_CRYPTO_CLMUL_H */
diff --git a/include/crypto/clmul.h b/include/crypto/clmul.h
index ce43c9aeb1..8b4c263459 100644
--- a/include/crypto/clmul.h
+++ b/include/crypto/clmul.h
@@ -111,6 +111,13 @@ Int128 clmul_32x2_even_gen(Int128, Int128);
*/
Int128 clmul_32x2_odd_gen(Int128, Int128);
+/**
+ * clmul_64:
+ *
+ * Perform a 64x64->128 carry-less multiply.
+ */
+Int128 clmul_64_gen(uint64_t, uint64_t);
+
#include "host/crypto/clmul.h"
#endif /* CRYPTO_CLMUL_H */
diff --git a/crypto/clmul.c b/crypto/clmul.c
index c197cd5f21..0be06073f0 100644
--- a/crypto/clmul.c
+++ b/crypto/clmul.c
@@ -144,3 +144,20 @@ Int128 clmul_32x2_odd_gen(Int128 n, Int128 m)
rh = clmul_32_gen(int128_gethi(n) >> 32, int128_gethi(m) >> 32);
return int128_make128(rl, rh);
}
+
+Int128 clmul_64_gen(uint64_t n, uint64_t m)
+{
+ uint64_t rl = 0, rh = 0;
+
+ /* Bit 0 can only influence the low 64-bit result. */
+ if (n & 1) {
+ rl = m;
+ }
+
+ for (int i = 1; i < 64; ++i) {
+ uint64_t mask = -((n >> i) & 1);
+ rl ^= (m << i) & mask;
+ rh ^= (m >> (64 - i)) & mask;
+ }
+ return int128_make128(rl, rh);
+}
--
2.34.1