aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/modes/aead/gcm/clmul_cpu/clmul_cpu.cpp36
-rw-r--r--src/lib/modes/aead/gcm/clmul_cpu/info.txt2
-rw-r--r--src/lib/utils/cpuid/cpuid.h2
-rw-r--r--src/lib/utils/simd/simd_32.h1
4 files changed, 39 insertions, 2 deletions
diff --git a/src/lib/modes/aead/gcm/clmul_cpu/clmul_cpu.cpp b/src/lib/modes/aead/gcm/clmul_cpu/clmul_cpu.cpp
index 2a41121d1..fb482afe7 100644
--- a/src/lib/modes/aead/gcm/clmul_cpu/clmul_cpu.cpp
+++ b/src/lib/modes/aead/gcm/clmul_cpu/clmul_cpu.cpp
@@ -1,6 +1,6 @@
/*
-* Hook for CLMUL/PMULL
-* (C) 2013,2017,2019 Jack Lloyd
+* Hook for CLMUL/PMULL/VPMSUM
+* (C) 2013,2017,2019,2020 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -26,6 +26,9 @@ BOTAN_FORCE_INLINE SIMD_4x32 BOTAN_FUNC_ISA(BOTAN_VPERM_ISA) reverse_vector(cons
const uint8_t maskb[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const uint8x16_t mask = vld1q_u8(maskb);
return SIMD_4x32(vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(in.raw()), mask)));
+#elif defined(BOTAN_SIMD_USE_ALTIVEC)
+ const __vector unsigned char mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0};
+ return SIMD_4x32(vec_perm(in.raw(), in.raw(), mask));
#endif
}
@@ -40,6 +43,35 @@ BOTAN_FORCE_INLINE SIMD_4x32 BOTAN_FUNC_ISA(BOTAN_CLMUL_ISA) clmul(const SIMD_4x
const uint64_t a = vgetq_lane_u64(vreinterpretq_u64_u32(x.raw()), M & 0x01);
const uint64_t b = vgetq_lane_u64(vreinterpretq_u64_u32(H.raw()), (M & 0x10) >> 4);
return SIMD_4x32(reinterpret_cast<uint32x4_t>(vmull_p64(a, b)));
+#elif defined(BOTAN_SIMD_USE_ALTIVEC)
+ const SIMD_4x32 mask_lo = SIMD_4x32(0, 0, 0xFFFFFFFF, 0xFFFFFFFF);
+
+ SIMD_4x32 i1 = x;
+ SIMD_4x32 i2 = H;
+
+ if(M == 0x11)
+ {
+ i1 &= mask_lo;
+ i2 &= mask_lo;
+ }
+ else if(M == 0x10)
+ {
+ i1 = i1.shift_elems_left<2>();
+ }
+ else if(M == 0x01)
+ {
+ i2 = i2.shift_elems_left<2>();
+ }
+ else if(M == 0x00)
+ {
+ i1 = mask_lo.andc(i1);
+ i2 = mask_lo.andc(i2);
+ }
+
+ return SIMD_4x32((__vector unsigned int)__builtin_crypto_vpmsumd(
+ (__vector unsigned long)i1.raw(),
+ (__vector unsigned long)i2.raw())
+ );
#endif
}
diff --git a/src/lib/modes/aead/gcm/clmul_cpu/info.txt b/src/lib/modes/aead/gcm/clmul_cpu/info.txt
index bc018c2ed..938a8c61d 100644
--- a/src/lib/modes/aead/gcm/clmul_cpu/info.txt
+++ b/src/lib/modes/aead/gcm/clmul_cpu/info.txt
@@ -19,12 +19,14 @@ x86_64:ssse3
x86_64:aesni
arm64:neon
arm64:armv8crypto
+ppc64:powercrypto
</isa>
<arch>
x86_32
x86_64
arm64
+ppc64
</arch>
<cc>
diff --git a/src/lib/utils/cpuid/cpuid.h b/src/lib/utils/cpuid/cpuid.h
index 77b0c99f6..d9e6b97b3 100644
--- a/src/lib/utils/cpuid/cpuid.h
+++ b/src/lib/utils/cpuid/cpuid.h
@@ -344,6 +344,8 @@ class BOTAN_PUBLIC_API(2,1) CPUID final
return has_clmul();
#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
return has_arm_pmull();
+#elif defined(BOTAN_TARGET_ARCH_IS_PPC64)
+ return has_power_crypto();
#else
return false;
#endif
diff --git a/src/lib/utils/simd/simd_32.h b/src/lib/utils/simd/simd_32.h
index 23daf00e4..5cbc32a18 100644
--- a/src/lib/utils/simd/simd_32.h
+++ b/src/lib/utils/simd/simd_32.h
@@ -46,6 +46,7 @@
#elif defined(BOTAN_SIMD_USE_ALTIVEC)
#define BOTAN_SIMD_ISA "altivec"
#define BOTAN_VPERM_ISA "altivec"
+ #define BOTAN_CLMUL_ISA "crypto"
#endif
namespace Botan {