summaryrefslogtreecommitdiff
path: root/cipher/cipher-gcm.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-11-20 15:44:27 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2013-11-21 11:58:09 +0200
commitdbfa651618693da7ea73b4d2d00d4efd411bfb46 (patch)
tree64bfe4135eb663dacc8459af97fef7ad1e4b5142 /cipher/cipher-gcm.c
parentfb1e52e3fe231671de546eacd6becd31c26c4f7b (diff)
downloadlibgcrypt-dbfa651618693da7ea73b4d2d00d4efd411bfb46.tar.gz
GCM: Move gcm_table initialization to setkey
* cipher/cipher-gcm.c: Change all 'c->u_iv.iv' to 'c->u_mode.gcm.u_ghash_key.key'. (_gcry_cipher_gcm_setkey): New. (_gcry_cipher_gcm_initiv): Move ghash initialization to function above. * cipher/cipher-internal.h (gcry_cipher_handle): Add 'u_mode.gcm.u_ghash_key'; Reorder 'u_mode.gcm' members for partial clearing in gcry_cipher_reset. (_gcry_cipher_gcm_setkey): New prototype. * cipher/cipher.c (cipher_setkey): Add GCM setkey. (cipher_reset): Clear 'u_mode' only partially for GCM. -- GHASH tables can be generated at setkey time. No need to regenerate for every new IV. Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/cipher-gcm.c')
-rw-r--r--cipher/cipher-gcm.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c
index 42cfc1ea..457e337a 100644
--- a/cipher/cipher-gcm.c
+++ b/cipher/cipher-gcm.c
@@ -344,7 +344,7 @@ do_ghash (unsigned char *hsub, unsigned char *result, const unsigned char *buf)
}
#define fillM(c, h) do { } while (0)
-#define GHASH(c, result, buf) do_ghash (c->u_iv.iv, result, buf)
+#define GHASH(c, result, buf) do_ghash (c->u_mode.gcm.u_ghash_key.key, result, buf)
#endif /* !GCM_USE_TABLES */
@@ -581,7 +581,7 @@ ghash (gcry_cipher_hd_t c, byte *result, const byte *buf,
"pshufb %[be_mask], %%xmm1\n\t" /* be => le */
:
: [hash] "m" (*result), [be_mask] "m" (*be_mask),
- [hsub] "m" (*c->u_iv.iv));
+ [hsub] "m" (*c->u_mode.gcm.u_ghash_key.key));
#ifdef __x86_64__
if (nblocks >= 4)
@@ -687,9 +687,9 @@ setupM (gcry_cipher_hd_t c, byte *h)
c->u_mode.gcm.use_intel_pclmul = 1;
/* Swap endianness of hsub. */
- tmp[0] = buf_get_be64(c->u_iv.iv + 8);
- tmp[1] = buf_get_be64(c->u_iv.iv + 0);
- buf_cpy (c->u_iv.iv, tmp, GCRY_GCM_BLOCK_LEN);
+ tmp[0] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 8);
+ tmp[1] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 0);
+ buf_cpy (c->u_mode.gcm.u_ghash_key.key, tmp, GCRY_GCM_BLOCK_LEN);
#ifdef __x86_64__
asm volatile ("movdqu %[h_1], %%xmm0\n\t"
@@ -982,6 +982,17 @@ _gcry_cipher_gcm_authenticate (gcry_cipher_hd_t c,
}
+void
+_gcry_cipher_gcm_setkey (gcry_cipher_hd_t c)
+{
+ memset (c->u_mode.gcm.u_ghash_key.key, 0, GCRY_GCM_BLOCK_LEN);
+
+ c->spec->encrypt (&c->context.c, c->u_mode.gcm.u_ghash_key.key,
+ c->u_mode.gcm.u_ghash_key.key);
+ setupM (c, c->u_mode.gcm.u_ghash_key.key);
+}
+
+
static gcry_err_code_t
_gcry_cipher_gcm_initiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
{
@@ -995,10 +1006,6 @@ _gcry_cipher_gcm_initiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
if (ivlen == 0)
return GPG_ERR_INV_LENGTH;
- c->spec->encrypt (&c->context.c, c->u_iv.iv, c->u_mode.gcm.u_tag.tag);
-
- setupM (c, c->u_iv.iv);
-
if (ivlen != GCRY_GCM_BLOCK_LEN - 4)
{
u32 iv_bytes[2] = {0, 0};