[PATCH 1/2] [v2] Add API to support AEAD cipher modes
Jussi Kivilinna
jussi.kivilinna at iki.fi
Sun Oct 20 14:03:13 CEST 2013
* cipher/cipher.c (_gcry_cipher_setaad, _gcry_cipher_checktag)
(_gcry_cipher_gettag): New.
* doc/gcrypt.texi: Add documentation for new API functions.
* src/visibility.c (gcry_cipher_setaad, gcry_cipher_checktag)
(gcry_cipher_gettag): New.
* src/gcrypt.h.in, src/visibility.h: add declarations of these
functions.
* src/libgcrypt.defs, src/libgcrypt.vers: export functions.
--
Authenticated Encryption with Associated Data (AEAD) cipher modes
provide authentication tag that can be used to authenticate message. At
the same time it allows one to specify additional (unencrypted data)
that will be authenticated together with the message. This class of
cipher modes requires additional API present in this commit.
This patch is based on original patch by Dmitry Eremin-Solenikov.
Changes in v2:
- Change gcry_cipher_tag to gcry_cipher_checktag and gcry_cipher_gettag
for giving tag (checktag) for decryption and reading tag (gettag) after
encryption.
- Change gcry_cipher_authenticate to gcry_cipher_setaad, since
additional parameters needed for some AEAD modes (in this case CCM,
which needs the length of encrypted data and tag for MAC
initialization).
- Add some documentation.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
cipher/cipher.c | 36 ++++++++++++++++++++++++++++++++++++
doc/gcrypt.texi | 42 ++++++++++++++++++++++++++++++++++++++++++
src/gcrypt.h.in | 14 ++++++++++++++
src/libgcrypt.def | 3 +++
src/libgcrypt.vers | 1 +
src/visibility.c | 28 ++++++++++++++++++++++++++++
src/visibility.h | 9 +++++++++
7 files changed, 133 insertions(+)
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 75d42d1..60f1f0e 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -910,6 +910,42 @@ _gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
return 0;
}
+gcry_error_t
+_gcry_cipher_setaad (gcry_cipher_hd_t hd, const void *aad, size_t aadlen,
+ size_t encryptedlen, size_t taglen)
+{
+ log_fatal ("gcry_cipher_setaad: invalid mode %d\n", hd->mode );
+
+ (void)aad;
+ (void)aadlen;
+ (void)encryptedlen;
+ (void)taglen;
+
+ return gpg_error (GPG_ERR_INV_CIPHER_MODE);
+}
+
+gcry_error_t
+_gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen)
+{
+ log_fatal ("gcry_cipher_gettag: invalid mode %d\n", hd->mode );
+
+ (void)outtag;
+ (void)taglen;
+
+ return gpg_error (GPG_ERR_INV_CIPHER_MODE);
+}
+
+gcry_error_t
+_gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen)
+{
+ log_fatal ("gcry_cipher_checktag: invalid mode %d\n", hd->mode );
+
+ (void)intag;
+ (void)taglen;
+
+ return gpg_error (GPG_ERR_INV_CIPHER_MODE);
+}
+
gcry_error_t
gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index 473c484..1e5f414 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -1731,6 +1731,10 @@ matches the requirement of the selected algorithm and mode.
This function is also used with the Salsa20 stream cipher to set or
update the required nonce. In this case it needs to be called after
setting the key.
+
+This function is also used with the AEAD cipher modes to set or
+update the required nonce.
+
@end deftypefun
@deftypefun gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t @var{h}, const void *@var{c}, size_t @var{l})
@@ -1750,6 +1754,44 @@ call to gcry_cipher_setkey and clear the initialization vector.
Note that gcry_cipher_reset is implemented as a macro.
@end deftypefun
+Authenticated Encryption with Associated Data (AEAD) block cipher
+modes require the handling of the authentication tag and the additional
+authenticated data, which can be done by using the following
+functions:
+
+ at deftypefun gcry_error_t gcry_cipher_setaad (gcry_cipher_hd_t @var{h}, const void *@var{aad}, size_t @var{aadlen}, size_t @var{enclen}, size_t @var{taglen})
+
+Process the buffer @var{aad} of length @var{aadlen} as the additional
+authenticated data (AAD) for AEAD cipher modes.
+
+Some modes require more information at the beginning of operation; such
+as the length of the data to be encrypted/decrypted or the length of
+authentication tag. The length of encrypted data can be passed through
+ at var{enclen} and the length of authentication tag through @var{taglen}.
+If currently used cipher mode does not require such information at the
+early stages of the operation, these fields may be set to zero.
+
+ at end deftypefun
+
+ at deftypefun gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t @var{h}, void *@var{tag}, size_t @var{taglen})
+
+This function is used to read the authentication tag after encryption.
+The function finalizes and outputs theauthentication tag to the buffer
+ at var{tag} of length @var{taglen} bytes.
+
+ at end deftypefun
+
+ at deftypefun gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t @var{h}, const void *@var{tag}, size_t @var{taglen})
+
+Check the authentication tag after decryption. The authentication
+tag is passed as the buffer @var{tag} of length @var{taglen} bytes
+and compared to internal authentication tag computed during
+decryption. Error code @code{GPG_ERR_CHECKSUM} is returned if
+the authentication tag in the buffer @var{tag} does not match
+the authentication tag calculated during decryption.
+
+ at end deftypefun
+
The actual encryption and decryption is done by using one of the
following functions. They may be used as often as required to process
all the data.
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 64cc0e4..6132868 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -953,6 +953,20 @@ gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd,
gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
const void *iv, size_t ivlen);
+/* Provide additional authentication data for AEAD modes/ciphers. Also
+ provides the length of encrypted data and authentication tag for modes that
+ require this information at early stage. */
+gcry_error_t gcry_cipher_setaad (gcry_cipher_hd_t hd, const void *aad,
+ size_t aadlen, size_t encryptedlen,
+ size_t taglen);
+
+/* Get authentication tag for AEAD modes/ciphers. */
+gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag,
+ size_t taglen);
+
+/* Check authentication tag for AEAD modes/ciphers. */
+gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag,
+ size_t taglen);
/* Reset the handle to the state after open. */
#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
diff --git a/src/libgcrypt.def b/src/libgcrypt.def
index ec0c1e3..ac2dfb8 100644
--- a/src/libgcrypt.def
+++ b/src/libgcrypt.def
@@ -255,6 +255,9 @@ EXPORTS
gcry_sexp_extract_param @225
+ gcry_cipher_setaad @226
+ gcry_cipher_gettag @227
+ gcry_cipher_checktag @228
;; end of file with public symbols for Windows.
diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers
index be72aad..0990ff2 100644
--- a/src/libgcrypt.vers
+++ b/src/libgcrypt.vers
@@ -51,6 +51,7 @@ GCRYPT_1.6 {
gcry_cipher_info; gcry_cipher_map_name;
gcry_cipher_mode_from_oid; gcry_cipher_open;
gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr;
+ gcry_cipher_setaad; gcry_cipher_gettag; gcry_cipher_checktag;
gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl;
gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey;
diff --git a/src/visibility.c b/src/visibility.c
index 848925e..5daf2ea 100644
--- a/src/visibility.c
+++ b/src/visibility.c
@@ -713,6 +713,34 @@ gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
return _gcry_cipher_setctr (hd, ctr, ctrlen);
}
+gcry_error_t
+gcry_cipher_setaad (gcry_cipher_hd_t hd, const void *aad, size_t aadlen,
+ size_t encryptedlen, size_t taglen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_setaad (hd, aad, aadlen, encryptedlen, taglen);
+}
+
+gcry_error_t
+gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_gettag (hd, outtag, taglen);
+}
+
+gcry_error_t
+gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_checktag (hd, intag, taglen);
+}
+
gcry_error_t
gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
diff --git a/src/visibility.h b/src/visibility.h
index 1c8f047..e406d7d 100644
--- a/src/visibility.h
+++ b/src/visibility.h
@@ -81,6 +81,9 @@
#define gcry_cipher_setkey _gcry_cipher_setkey
#define gcry_cipher_setiv _gcry_cipher_setiv
#define gcry_cipher_setctr _gcry_cipher_setctr
+#define gcry_cipher_setaad _gcry_cipher_setaad
+#define gcry_cipher_checktag _gcry_cipher_checktag
+#define gcry_cipher_gettag _gcry_cipher_gettag
#define gcry_cipher_ctl _gcry_cipher_ctl
#define gcry_cipher_decrypt _gcry_cipher_decrypt
#define gcry_cipher_encrypt _gcry_cipher_encrypt
@@ -297,6 +300,9 @@ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
#undef gcry_cipher_setkey
#undef gcry_cipher_setiv
#undef gcry_cipher_setctr
+#undef gcry_cipher_setaad
+#undef gcry_cipher_checktag
+#undef gcry_cipher_gettag
#undef gcry_cipher_ctl
#undef gcry_cipher_decrypt
#undef gcry_cipher_encrypt
@@ -474,6 +480,9 @@ MARK_VISIBLE (gcry_cipher_close)
MARK_VISIBLE (gcry_cipher_setkey)
MARK_VISIBLE (gcry_cipher_setiv)
MARK_VISIBLE (gcry_cipher_setctr)
+MARK_VISIBLE (gcry_cipher_setaad)
+MARK_VISIBLE (gcry_cipher_checktag)
+MARK_VISIBLE (gcry_cipher_gettag)
MARK_VISIBLE (gcry_cipher_ctl)
MARK_VISIBLE (gcry_cipher_decrypt)
MARK_VISIBLE (gcry_cipher_encrypt)
More information about the Gcrypt-devel
mailing list