summaryrefslogtreecommitdiff
path: root/cipher/cipher-gcm.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-11-19 23:26:26 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2013-11-20 18:35:38 +0200
commit018f08354b1b116672e82f9ce942884b288aaf9e (patch)
treeb4550be81a53ad3e618d57e41addabf1b687a5cc /cipher/cipher-gcm.c
parentc9537fbf8ff0af919cff2bebadc4c6e7caea8076 (diff)
downloadlibgcrypt-018f08354b1b116672e82f9ce942884b288aaf9e.tar.gz
GCM: Add stack burning
* cipher/cipher-gcm.c (do_ghash, ghash): Return stack burn depth. (setupM): Wipe 'tmp' buffer. (do_ghash_buf): Wipe 'tmp' buffer and add stack burning. -- Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/cipher-gcm.c')
-rw-r--r--cipher/cipher-gcm.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c
index fcfa357a..cf666ab8 100644
--- a/cipher/cipher-gcm.c
+++ b/cipher/cipher-gcm.c
@@ -108,7 +108,7 @@ do_fillM (unsigned char *h, u64 *M)
}
}
-static inline void
+static inline unsigned int
do_ghash (unsigned char *result, const unsigned char *buf, const u64 *gcmM)
{
u64 V[2];
@@ -158,6 +158,9 @@ do_ghash (unsigned char *result, const unsigned char *buf, const u64 *gcmM)
buf_put_be64 (result + 0, tmp[0]);
buf_put_be64 (result + 8, tmp[1]);
+
+ return (sizeof(V) + sizeof(T) + sizeof(tmp) +
+ sizeof(int)*2 + sizeof(void*)*5);
}
#else
@@ -214,7 +217,7 @@ do_fillM (unsigned char *h, u32 *M)
}
}
-static inline void
+static inline unsigned int
do_ghash (unsigned char *result, const unsigned char *buf, const u32 *gcmM)
{
byte V[16];
@@ -269,6 +272,9 @@ do_ghash (unsigned char *result, const unsigned char *buf, const u32 *gcmM)
buf_put_be32 (result + 4, tmp[1]);
buf_put_be32 (result + 8, tmp[2]);
buf_put_be32 (result + 12, tmp[3]);
+
+ return (sizeof(V) + sizeof(T) + sizeof(tmp) +
+ sizeof(int)*2 + sizeof(void*)*6);
}
#endif /* !HAVE_U64_TYPEDEF || SIZEOF_UNSIGNED_LONG != 8 */
@@ -291,7 +297,7 @@ bshift (unsigned long *b)
return c;
}
-static void
+static unsigned int
do_ghash (unsigned char *hsub, unsigned char *result, const unsigned char *buf)
{
unsigned long V[4];
@@ -333,6 +339,8 @@ do_ghash (unsigned char *hsub, unsigned char *result, const unsigned char *buf)
result[i + 3] = p[0];
}
#endif
+
+ return (sizeof(V) + sizeof(T) + sizeof(int)*2 + sizeof(void*)*5);
}
#define fillM(c, h) do { } while (0)
@@ -549,14 +557,15 @@ static inline void gfmul_pclmul_aggr4(void)
#endif /*GCM_USE_INTEL_PCLMUL*/
-static void
+static unsigned int
ghash (gcry_cipher_hd_t c, byte *result, const byte *buf,
unsigned int nblocks)
{
const unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
+ unsigned int burn;
if (nblocks == 0)
- return;
+ return 0;
if (0)
;
@@ -648,17 +657,20 @@ ghash (gcry_cipher_hd_t c, byte *result, const byte *buf,
"pxor %%xmm6, %%xmm6\n\t"
"pxor %%xmm7, %%xmm7\n\t"
::: "cc" );
+ burn = 0;
}
#endif
else
{
while (nblocks)
{
- GHASH (c, result, buf);
+ burn = GHASH (c, result, buf);
buf += blocksize;
nblocks--;
}
}
+
+ return burn + (burn ? 5*sizeof(void*) : 0);
}
@@ -721,6 +733,8 @@ setupM (gcry_cipher_hd_t c, byte *h)
"pxor %%xmm8, %%xmm8\n\t"
::: "cc" );
#endif
+
+ wipememory (tmp, sizeof(tmp));
}
#endif
else
@@ -792,12 +806,13 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte * buf,
unsigned char tmp[MAX_BLOCKSIZE];
unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
unsigned int nblocks;
+ unsigned int burn = 0;
nblocks = buflen / blocksize;
if (nblocks)
{
- ghash (c, hash, buf, nblocks);
+ burn = ghash (c, hash, buf, nblocks);
buf += blocksize * nblocks;
buflen -= blocksize * nblocks;
}
@@ -806,10 +821,12 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte * buf,
{
buf_cpy (tmp, buf, buflen);
memset (tmp + buflen, 0, blocksize - buflen);
- ghash (c, hash, tmp, 1);
+ burn = ghash (c, hash, tmp, 1);
+ wipememory (tmp, sizeof(tmp));
}
- /* TODO: burn stack */
+ if (burn)
+ _gcry_burn_stack (burn);
}