Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- 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