summaryrefslogtreecommitdiff
path: root/cipher/cipher-internal.h
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-11-20 15:01:51 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2013-11-20 18:26:59 +0200
commitbd4bd23a2511a4bce63c3217cca0d4ecf0c79532 (patch)
tree7daeddf89349cb6ef66c94a380d55d16e5ecc83a /cipher/cipher-internal.h
parent5a65ffabadd50f174ab7375faad7a726cce49e61 (diff)
downloadlibgcrypt-bd4bd23a2511a4bce63c3217cca0d4ecf0c79532.tar.gz
GCM: Use counter mode code for speed-up
* cipher/cipher-gcm.c (ghash): Add process for multiple blocks. (gcm_bytecounter_add, gcm_add32_be128, gcm_check_datalen) (gcm_check_aadlen_or_ivlen, do_ghash_buf): New functions. (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt) (_gcry_cipher_gcm_authenticate, _gcry_cipher_gcm_set_iv) (_gcry_cipher_gcm_tag): Adjust to use above new functions and counter mode functions for encryption/decryption. * cipher/cipher-internal.h (gcry_cipher_handle): Remove 'length'; Add 'u_mode.gcm.(addlen|datalen|tagiv|datalen_over_limits)'. (_gcry_cipher_gcm_setiv): Return gcry_err_code_t. * cipher/cipher.c (cipher_setiv): Return error code. (_gcry_cipher_setiv): Handle error code from 'cipher_setiv'. -- Patch changes GCM to use counter mode code for bulk speed up and also adds data length checks as given in NIST SP-800-38D section 5.2.1.1. Bit length requirements from section 5.2.1.1: len(plaintext) <= 2^39-256 bits == 2^36-32 bytes == 2^32-2 blocks len(aad) <= 2^64-1 bits ~= 2^61-1 bytes len(iv) <= 2^64-1 bit ~= 2^61-1 bytes Intel Haswell: Old: AES GCM enc | 3.00 ns/B 317.4 MiB/s 9.61 c/B GCM dec | 1.96 ns/B 486.9 MiB/s 6.27 c/B GCM auth | 0.848 ns/B 1124.7 MiB/s 2.71 c/B New: AES GCM enc | 1.12 ns/B 851.8 MiB/s 3.58 c/B GCM dec | 1.12 ns/B 853.7 MiB/s 3.57 c/B GCM auth | 0.843 ns/B 1131.4 MiB/s 2.70 c/B Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/cipher-internal.h')
-rw-r--r--cipher/cipher-internal.h14
1 files changed, 11 insertions, 3 deletions
diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h
index a6e62717..9287ef59 100644
--- a/cipher/cipher-internal.h
+++ b/cipher/cipher-internal.h
@@ -133,7 +133,6 @@ struct gcry_cipher_handle
/* Space to save an IV or CTR for chaining operations. */
unsigned char lastiv[MAX_BLOCKSIZE];
int unused; /* Number of unused bytes in LASTIV. */
- unsigned char length[MAX_BLOCKSIZE]; /* bit counters for GCM */
union {
/* Mode specific storage for CCM mode. */
@@ -169,6 +168,13 @@ struct gcry_cipher_handle
unsigned char tag[MAX_BLOCKSIZE];
} u_tag;
+ /* byte counters for GCM */
+ u32 aadlen[2];
+ u32 datalen[2];
+
+ /* encrypted tag counter */
+ unsigned char tagiv[MAX_BLOCKSIZE];
+
/* Pre-calculated table for GCM. */
#ifdef GCM_USE_TABLES
#if defined(HAVE_U64_TYPEDEF) && (SIZEOF_UNSIGNED_LONG == 8 \
@@ -181,6 +187,7 @@ struct gcry_cipher_handle
#endif
#endif
+ unsigned int datalen_over_limits:1;
#ifdef GCM_USE_INTEL_PCLMUL
unsigned int use_intel_pclmul:1;
#endif
@@ -274,9 +281,9 @@ gcry_err_code_t _gcry_cipher_gcm_decrypt
/* */ (gcry_cipher_hd_t c,
unsigned char *outbuf, unsigned int outbuflen,
const unsigned char *inbuf, unsigned int inbuflen);
-void _gcry_cipher_gcm_setiv
+gcry_err_code_t _gcry_cipher_gcm_setiv
/* */ (gcry_cipher_hd_t c,
- const unsigned char *iv, unsigned int ivlen);
+ const unsigned char *iv, size_t ivlen);
gcry_err_code_t _gcry_cipher_gcm_authenticate
/* */ (gcry_cipher_hd_t c,
const unsigned char *aadbuf, unsigned int aadbuflen);
@@ -287,4 +294,5 @@ gcry_err_code_t _gcry_cipher_gcm_check_tag
/* */ (gcry_cipher_hd_t c,
const unsigned char *intag, size_t taglen);
+
#endif /*G10_CIPHER_INTERNAL_H*/