diff options
author | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2013-11-19 23:26:26 +0200 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-11-19 23:26:26 +0200 |
commit | 90cce18b9eced4f412ceeec5bcae18c4493322df (patch) | |
tree | 8018c676ab8f35e2e9b50938f90761e1454a6597 /cipher/cipher-internal.h | |
parent | 9816ae9d9931b75e4fdc9a5be10e6af447132313 (diff) | |
download | libgcrypt-90cce18b9eced4f412ceeec5bcae18c4493322df.tar.gz |
Initial implementation of GCM
* cipher/Makefile.am: Add 'cipher-gcm.c'.
* cipher/cipher-ccm.c (_gcry_ciphert_ccm_set_lengths)
(_gcry_cipher_ccm_authenticate, _gcry_cipher_ccm_tag)
(_gcry_cipher_ccm_encrypt, _gcry_cipher_ccm_decrypt): Change
'c->u_mode.ccm.tag' to 'c->marks.tag'.
* cipher/cipher-gcm.c: New.
* cipher/cipher-internal.h (GCM_USE_TABLES): New.
(gcry_cipher_handle): Add 'marks.tag', 'u_tag', 'length' and
'gcm_table'; Remove 'u_mode.ccm.tag'.
(_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
(_gcry_cipher_gcm_setiv, _gcry_cipher_gcm_authenticate)
(_gcry_cipher_gcm_get_tag, _gcry_cipher_gcm_check_tag): New.
* cipher/cipher.c (_gcry_cipher_open_internal, cipher_setkey)
(cipher_encrypt, cipher_decrypt, _gcry_cipher_authenticate)
(_gcry_cipher_gettag, _gcry_cipher_checktag): Add GCM mode handling.
* src/gcrypt.h.in (gcry_cipher_modes): Add GCRY_CIPHER_MODE_GCM.
(GCRY_GCM_BLOCK_LEN): New.
* tests/basic.c (check_gcm_cipher): New.
(check_ciphers): Add GCM check.
(check_cipher_modes): Call 'check_gcm_cipher'.
* tests/bench-slope.c (bench_gcm_encrypt_do_bench)
(bench_gcm_decrypt_do_bench, bench_gcm_authenticate_do_bench)
(gcm_encrypt_ops, gcm_decrypt_ops, gcm_authenticate_ops): New.
(cipher_modes): Add GCM enc/dec/auth.
(cipher_bench_one): Limit GCM to block ciphers with 16 byte block-size.
* tests/benchmark.c (cipher_bench): Add GCM.
--
Currently it is still quite slow.
Still no support for generate_iv(). Is it really necessary?
TODO: Merge/reuse cipher-internal state used by CCM.
Changelog entry will be present in final patch submission.
Changes since v1:
- 6x-7x speedup.
- added bench-slope support
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
[jk: mangle new file throught 'indent -nut']
[jk: few fixes]
[jk: changelog]
Diffstat (limited to 'cipher/cipher-internal.h')
-rw-r--r-- | cipher/cipher-internal.h | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index 44f43a40..7da9c680 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -35,6 +35,9 @@ # define NEED_16BYTE_ALIGNED_CONTEXT 1 #endif +/* Undef this symbol to trade GCM speed for 256 bytes of memory per context */ +#define GCM_USE_TABLES 1 + /* A VIA processor with the Padlock engine as well as the Intel AES_NI instructions require an alignment of most data on a 16 byte @@ -96,6 +99,7 @@ struct gcry_cipher_handle struct { unsigned int key:1; /* Set to 1 if a key has been set. */ unsigned int iv:1; /* Set to 1 if a IV has been set. */ + unsigned int tag:1; /* Set to 1 if a tag is finalized. */ } marks; /* The initialization vector. For best performance we make sure @@ -114,9 +118,19 @@ struct gcry_cipher_handle unsigned char ctr[MAX_BLOCKSIZE]; } u_ctr; + /* The interim tag for GCM mode. */ + union { + cipher_context_alignment_t iv_align; + unsigned char tag[MAX_BLOCKSIZE]; + } u_tag; + /* 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 */ +#ifdef GCM_USE_TABLES + unsigned char gcm_table[16 * 16]; /* pre-calculated table for GCM */ +#endif union { /* Mode specific storage for CCM mode. */ @@ -134,7 +148,6 @@ struct gcry_cipher_handle unsigned int nonce:1;/* Set to 1 if nonce has been set. */ unsigned int lengths:1; /* Set to 1 if CCM length parameters has been processed. */ - unsigned int tag:1; /* Set to 1 if tag has been finalized. */ } ccm; /* Mode specific storage for CMAC mode. */ struct { @@ -224,5 +237,26 @@ gcry_err_code_t _gcry_cipher_ccm_check_tag /* */ (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); +/*-- cipher-gcm.c --*/ +gcry_err_code_t _gcry_cipher_gcm_encrypt +/* */ (gcry_cipher_hd_t c, + unsigned char *outbuf, unsigned int outbuflen, + const unsigned char *inbuf, unsigned int inbuflen); +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_cipher_hd_t c, + const unsigned char *iv, unsigned int ivlen); +gcry_err_code_t _gcry_cipher_gcm_authenticate +/* */ (gcry_cipher_hd_t c, + const unsigned char *aadbuf, unsigned int aadbuflen); +gcry_err_code_t _gcry_cipher_gcm_get_tag +/* */ (gcry_cipher_hd_t c, + unsigned char *outtag, size_t taglen); +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*/ |