summaryrefslogtreecommitdiff
path: root/cipher/rijndael-ssse3-amd64.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2016-12-10 12:29:12 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2016-12-10 12:29:12 +0200
commit2d2e5286d53e1f62fe040dff4c6e01961f00afe2 (patch)
tree6e1b88b6ec0ef96de23a0c67278276edb1de626f /cipher/rijndael-ssse3-amd64.c
parent161d339f48c03be7fd0f4249d730f7f1767ef8e4 (diff)
downloadlibgcrypt-2d2e5286d53e1f62fe040dff4c6e01961f00afe2.tar.gz
OCB: Move large L handling from bottom to upper level
* cipher/cipher-ocb.c (_gcry_cipher_ocb_get_l): Remove. (ocb_get_L_big): New. (_gcry_cipher_ocb_authenticate): L-big handling done in upper processing loop, so that lower level never sees the case where 'aad_nblocks % 65536 == 0'; Add missing stack burn. (ocb_aad_finalize): Add missing stack burn. (ocb_crypt): L-big handling done in upper processing loop, so that lower level never sees the case where 'data_nblocks % 65536 == 0'. * cipher/cipher-internal.h (_gcry_cipher_ocb_get_l): Remove. (ocb_get_l): Remove 'l_tmp' usage and simplify since input is more limited now, 'N is not multiple of 65536'. * cipher/rijndael-aesni.c (get_l): Remove. (aesni_ocb_enc, aesni_ocb_dec, _gcry_aes_aesni_ocb_auth): Remove l_tmp; Use 'ocb_get_l'. * cipher/rijndael-ssse3-amd64.c (get_l): Remove. (ssse3_ocb_enc, ssse3_ocb_dec, _gcry_aes_ssse3_ocb_auth): Remove l_tmp; Use 'ocb_get_l'. * cipher/camellia-glue.c: Remove OCB l_tmp usage. * cipher/rijndael-armv8-ce.c: Ditto. * cipher/rijndael.c: Ditto. * cipher/serpent.c: Ditto. * cipher/twofish.c: Ditto. -- Move large L value generation to up-most level to simplify lower level ocb_get_l for greater performance and simpler implementation. This helps implementing OCB in assembly as 'ocb_get_l' no longer has function call on slow-path. Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/rijndael-ssse3-amd64.c')
-rw-r--r--cipher/rijndael-ssse3-amd64.c96
1 files changed, 3 insertions, 93 deletions
diff --git a/cipher/rijndael-ssse3-amd64.c b/cipher/rijndael-ssse3-amd64.c
index 937d8682..a8e89d40 100644
--- a/cipher/rijndael-ssse3-amd64.c
+++ b/cipher/rijndael-ssse3-amd64.c
@@ -527,92 +527,10 @@ _gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
}
-static inline const unsigned char *
-get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i, unsigned char *iv,
- unsigned char *ctr, const void **aes_const_ptr,
- byte ssse3_state[SSSE3_STATE_SIZE], int encrypt)
-{
- const unsigned char *l;
- unsigned int ntz;
-
- if (i & 1)
- return c->u_mode.ocb.L[0];
- else if (i & 2)
- return c->u_mode.ocb.L[1];
- else if (i & 0xffffffffU)
- {
- asm ("rep;bsf %k[low], %k[ntz]\n\t"
- : [ntz] "=r" (ntz)
- : [low] "r" (i & 0xffffffffU)
- : "cc");
- }
- else
- {
- if (OCB_L_TABLE_SIZE < 32)
- {
- ntz = 32;
- }
- else if (i)
- {
- asm ("rep;bsf %k[high], %k[ntz]\n\t"
- : [ntz] "=r" (ntz)
- : [high] "r" (i >> 32)
- : "cc");
- ntz += 32;
- }
- else
- {
- ntz = 64;
- }
- }
-
- if (ntz < OCB_L_TABLE_SIZE)
- {
- l = c->u_mode.ocb.L[ntz];
- }
- else
- {
- /* Store Offset & Checksum before calling external function */
- asm volatile ("movdqu %%xmm7, %[iv]\n\t"
- "movdqu %%xmm6, %[ctr]\n\t"
- : [iv] "=m" (*iv),
- [ctr] "=m" (*ctr)
- :
- : "memory" );
-
- /* Restore SSSE3 state. */
- vpaes_ssse3_cleanup();
-
- l = _gcry_cipher_ocb_get_l (c, l_tmp, i);
-
- /* Save SSSE3 state. */
- if (encrypt)
- {
- vpaes_ssse3_prepare_enc (*aes_const_ptr);
- }
- else
- {
- vpaes_ssse3_prepare_dec (*aes_const_ptr);
- }
-
- /* Restore Offset & Checksum */
- asm volatile ("movdqu %[iv], %%xmm7\n\t"
- "movdqu %[ctr], %%xmm6\n\t"
- : /* No output */
- : [iv] "m" (*iv),
- [ctr] "m" (*ctr)
- : "memory" );
- }
-
- return l;
-}
-
-
static void
ssse3_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks)
{
- union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
RIJNDAEL_context *ctx = (void *)&c->context.c;
unsigned char *outbuf = outbuf_arg;
const unsigned char *inbuf = inbuf_arg;
@@ -635,8 +553,7 @@ ssse3_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg,
{
const unsigned char *l;
- l = get_l(c, l_tmp.x1, ++n, c->u_iv.iv, c->u_ctr.ctr, &aes_const_ptr,
- ssse3_state, 1);
+ l = ocb_get_l(c, ++n);
/* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
/* Checksum_i = Checksum_{i-1} xor P_i */
@@ -671,7 +588,6 @@ ssse3_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg,
:
: "memory" );
- wipememory(&l_tmp, sizeof(l_tmp));
vpaes_ssse3_cleanup ();
}
@@ -679,7 +595,6 @@ static void
ssse3_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks)
{
- union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
RIJNDAEL_context *ctx = (void *)&c->context.c;
unsigned char *outbuf = outbuf_arg;
const unsigned char *inbuf = inbuf_arg;
@@ -702,8 +617,7 @@ ssse3_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg,
{
const unsigned char *l;
- l = get_l(c, l_tmp.x1, ++n, c->u_iv.iv, c->u_ctr.ctr, &aes_const_ptr,
- ssse3_state, 0);
+ l = ocb_get_l(c, ++n);
/* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
/* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
@@ -738,7 +652,6 @@ ssse3_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg,
:
: "memory" );
- wipememory(&l_tmp, sizeof(l_tmp));
vpaes_ssse3_cleanup ();
}
@@ -758,7 +671,6 @@ void
_gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
size_t nblocks)
{
- union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
RIJNDAEL_context *ctx = (void *)&c->context.c;
const unsigned char *abuf = abuf_arg;
u64 n = c->u_mode.ocb.aad_nblocks;
@@ -780,8 +692,7 @@ _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
{
const unsigned char *l;
- l = get_l(c, l_tmp.x1, ++n, c->u_mode.ocb.aad_offset,
- c->u_mode.ocb.aad_sum, &aes_const_ptr, ssse3_state, 1);
+ l = ocb_get_l(c, ++n);
/* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
/* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
@@ -812,7 +723,6 @@ _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
:
: "memory" );
- wipememory(&l_tmp, sizeof(l_tmp));
vpaes_ssse3_cleanup ();
}