diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-11-20 15:01:51 +0200 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-11-20 18:26:59 +0200 |
commit | bd4bd23a2511a4bce63c3217cca0d4ecf0c79532 (patch) | |
tree | 7daeddf89349cb6ef66c94a380d55d16e5ecc83a /cipher/cipher.c | |
parent | 5a65ffabadd50f174ab7375faad7a726cce49e61 (diff) | |
download | libgcrypt-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.c')
-rw-r--r-- | cipher/cipher.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/cipher/cipher.c b/cipher/cipher.c index bba6abb8..a3c2c6fe 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -600,29 +600,25 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, size_t keylen) else c->marks.key = 0; - return gcry_error (ret); } /* Set the IV to be used for the encryption context C to IV with length IVLEN. The length should match the required length. */ -static void +static gcry_err_code_t cipher_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) { /* GCM has its own IV handler */ if (c->mode == GCRY_CIPHER_MODE_GCM) - { - _gcry_cipher_gcm_setiv (c, iv, ivlen); - return; - } + return _gcry_cipher_gcm_setiv (c, iv, ivlen); /* If the cipher has its own IV handler, we use only this one. This is currently used for stream ciphers requiring a nonce. */ if (c->spec->setiv) { c->spec->setiv (&c->context.c, iv, ivlen); - return; + return 0; } memset (c->u_iv.iv, 0, c->spec->blocksize); @@ -642,6 +638,8 @@ cipher_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) else c->marks.iv = 0; c->unused = 0; + + return 0; } @@ -973,7 +971,7 @@ _gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen) break; default: - cipher_setiv (hd, iv, ivlen); + rc = cipher_setiv (hd, iv, ivlen); break; } return gpg_error (rc); |