summaryrefslogtreecommitdiff
path: root/cipher/cipher-internal.h
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2013-11-19 23:26:26 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2013-11-19 23:26:26 +0200
commit90cce18b9eced4f412ceeec5bcae18c4493322df (patch)
tree8018c676ab8f35e2e9b50938f90761e1454a6597 /cipher/cipher-internal.h
parent9816ae9d9931b75e4fdc9a5be10e6af447132313 (diff)
downloadlibgcrypt-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.h36
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*/