diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-10-22 17:07:53 +0300 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-10-22 19:48:19 +0300 |
commit | 335d9bf7b035815750b63a3a8334d6ce44dc4449 (patch) | |
tree | 75a9ff903f9b7d2bd3f92dc459962ac7741e68c8 /cipher/Makefile.am | |
parent | 95654041f2aa62f71aac4d8614dafe8433d10f95 (diff) | |
download | libgcrypt-335d9bf7b035815750b63a3a8334d6ce44dc4449.tar.gz |
Add Counter with CBC-MAC mode (CCM)
* cipher/Makefile.am: Add 'cipher-ccm.c'.
* cipher/cipher-ccm.c: New.
* cipher/cipher-internal.h (gcry_cipher_handle): Add 'u_mode'.
(_gcry_cipher_ccm_encrypt, _gcry_cipher_ccm_decrypt)
(_gcry_cipher_ccm_set_nonce, _gcry_cipher_ccm_authenticate)
(_gcry_cipher_ccm_get_tag, _gcry_cipher_ccm_check_tag)
(_gcry_cipher_ccm_set_lengths): New prototypes.
* cipher/cipher.c (gcry_cipher_open, cipher_encrypt, cipher_decrypt)
(_gcry_cipher_setiv, _gcry_cipher_authenticate, _gcry_cipher_gettag)
(_gcry_cipher_checktag, gry_cipher_ctl): Add handling for CCM mode.
* doc/gcrypt.texi: Add documentation for GCRY_CIPHER_MODE_CCM.
* src/gcrypt.h.in (gcry_cipher_modes): Add 'GCRY_CIPHER_MODE_CCM'.
(gcry_ctl_cmds): Add 'GCRYCTL_SET_CCM_LENGTHS'.
(GCRY_CCM_BLOCK_LEN): New.
* tests/basic.c (check_ccm_cipher): New.
(check_cipher_modes): Call 'check_ccm_cipher'.
* tests/benchmark.c (ccm_aead_init): New.
(cipher_bench): Add handling for AEAD modes and add CCM benchmarking.
--
Patch adds CCM (Counter with CBC-MAC) mode as defined in RFC 3610 and NIST
Special Publication 800-38C.
Example for encrypting message (split in two buffers; buf1, buf2) and
authenticating additional non-encrypted data (split in two buffers; aadbuf1,
aadbuf2) with authentication tag length of eigth bytes:
size_t params[3];
taglen = 8;
gcry_cipher_setkey(h, key, len(key));
gcry_cipher_setiv(h, nonce, len(nonce));
params[0] = len(buf1) + len(buf2); /* 0: enclen */
params[1] = len(aadbuf1) + len(aadbuf2); /* 1: aadlen */
params[2] = taglen; /* 2: authtaglen */
gcry_cipher_ctl(h, GCRYCTL_SET_CCM_LENGTHS, params, sizeof(size_t) * 3);
gcry_cipher_authenticate(h, aadbuf1, len(aadbuf1));
gcry_cipher_authenticate(h, aadbuf2, len(aadbuf2));
gcry_cipher_encrypt(h, buf1, len(buf1), buf1, len(buf1));
gcry_cipher_encrypt(h, buf2, len(buf2), buf2, len(buf2));
gcry_cipher_gettag(h, tag, taglen);
Example for decrypting above message and checking authentication tag:
size_t params[3];
taglen = 8;
gcry_cipher_setkey(h, key, len(key));
gcry_cipher_setiv(h, nonce, len(nonce));
params[0] = len(buf1) + len(buf2); /* 0: enclen */
params[1] = len(aadbuf1) + len(aadbuf2); /* 1: aadlen */
params[2] = taglen; /* 2: authtaglen */
gcry_cipher_ctl(h, GCRYCTL_SET_CCM_LENGTHS, params, sizeof(size_t) * 3);
gcry_cipher_authenticate(h, aadbuf1, len(aadbuf1));
gcry_cipher_authenticate(h, aadbuf2, len(aadbuf2));
gcry_cipher_decrypt(h, buf1, len(buf1), buf1, len(buf1));
gcry_cipher_decrypt(h, buf2, len(buf2), buf2, len(buf2));
err = gcry_cipher_checktag(h, tag, taglen);
if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
{ /* Authentication failed. */ }
else if (err == 0)
{ /* Authentication ok. */ }
Example for encrypting message without additional authenticated data:
size_t params[3];
taglen = 10;
gcry_cipher_setkey(h, key, len(key));
gcry_cipher_setiv(h, nonce, len(nonce));
params[0] = len(buf1); /* 0: enclen */
params[1] = 0; /* 1: aadlen */
params[2] = taglen; /* 2: authtaglen */
gcry_cipher_ctl(h, GCRYCTL_SET_CCM_LENGTHS, params, sizeof(size_t) * 3);
gcry_cipher_encrypt(h, buf1, len(buf1), buf1, len(buf1));
gcry_cipher_gettag(h, tag, taglen);
To reset CCM state for cipher handle, one can either set new nonce or use
'gcry_cipher_reset'.
This implementation reuses existing CTR mode code for encryption/decryption
and is there for able to process multiple buffers that are not multiple of
blocksize. AAD data maybe also be passed into gcry_cipher_authenticate
in non-blocksize chunks.
[v4]: GCRYCTL_SET_CCM_PARAMS => GCRY_SET_CCM_LENGTHS
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/Makefile.am')
-rw-r--r-- | cipher/Makefile.am | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/cipher/Makefile.am b/cipher/Makefile.am index a2b2c8af..b0efd89d 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -40,6 +40,7 @@ libcipher_la_LIBADD = $(GCRYPT_MODULES) libcipher_la_SOURCES = \ cipher.c cipher-internal.h \ cipher-cbc.c cipher-cfb.c cipher-ofb.c cipher-ctr.c cipher-aeswrap.c \ +cipher-ccm.c \ cipher-selftest.c cipher-selftest.h \ pubkey.c pubkey-internal.h pubkey-util.c \ md.c \ |