aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan/plugins
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2015-03-31 10:57:04 +0200
committerMartin Willi <martin@revosec.ch>2015-04-15 11:35:28 +0200
commitedab6c658c7d0c2d21877bf7aaad218c4b1c8167 (patch)
tree21283748aede7cfe0e43b9bc057251e937364e84 /src/libstrongswan/plugins
parent0eb593b0bb23be06ff23d96d260a405876823c4d (diff)
downloadstrongswan-edab6c658c7d0c2d21877bf7aaad218c4b1c8167.tar.bz2
strongswan-edab6c658c7d0c2d21877bf7aaad218c4b1c8167.tar.xz
aesni: Calculate GHASH for 4 blocks of associated data in parallel
While associated data is usually not that large, in some specific cases this can bring a significant performance boost.
Diffstat (limited to 'src/libstrongswan/plugins')
-rw-r--r--src/libstrongswan/plugins/aesni/aesni_gcm.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/libstrongswan/plugins/aesni/aesni_gcm.c b/src/libstrongswan/plugins/aesni/aesni_gcm.c
index cdfd2b054..f6bbea2c6 100644
--- a/src/libstrongswan/plugins/aesni/aesni_gcm.c
+++ b/src/libstrongswan/plugins/aesni/aesni_gcm.c
@@ -269,14 +269,30 @@ static __m128i ghash(__m128i h, __m128i y, __m128i x)
*/
static __m128i icv_header(private_aesni_gcm_t *this, void *assoc, size_t alen)
{
- u_int blocks, rem, i;
+ u_int blocks, pblocks, rem, i;
+ __m128i h1, h2, h3, h4, d1, d2, d3, d4;
__m128i y, last, *ab;
+ h1 = this->hhhh;
+ h2 = this->hhh;
+ h3 = this->hh;
+ h4 = this->h;
+
y = _mm_setzero_si128();
ab = assoc;
blocks = alen / AES_BLOCK_SIZE;
+ pblocks = blocks - (blocks % GCM_CRYPT_PARALLELISM);
rem = alen % AES_BLOCK_SIZE;
- for (i = 0; i < blocks; i++)
+ for (i = 0; i < pblocks; i += GCM_CRYPT_PARALLELISM)
+ {
+ d1 = _mm_loadu_si128(ab + i + 0);
+ d2 = _mm_loadu_si128(ab + i + 1);
+ d3 = _mm_loadu_si128(ab + i + 2);
+ d4 = _mm_loadu_si128(ab + i + 3);
+ y = _mm_xor_si128(y, d1);
+ y = mult4xor(h1, h2, h3, h4, y, d2, d3, d4);
+ }
+ for (i = pblocks; i < blocks; i++)
{
y = ghash(this->h, y, _mm_loadu_si128(ab + i));
}