diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-11-19 23:26:26 +0200 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-11-20 18:35:38 +0200 |
commit | 018f08354b1b116672e82f9ce942884b288aaf9e (patch) | |
tree | b4550be81a53ad3e618d57e41addabf1b687a5cc /cipher/cipher-gcm.c | |
parent | c9537fbf8ff0af919cff2bebadc4c6e7caea8076 (diff) | |
download | libgcrypt-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.c | 35 |
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); } |