[PATCH 1/2] [v3] Add API to support AEAD cipher modes
Jussi Kivilinna
jussi.kivilinna at iki.fi
Tue Oct 22 15:49:23 CEST 2013
Do these look ok to push?
-Jussi
On 22.10.2013 15:32, Jussi Kivilinna wrote:
> * cipher/cipher.c (_gcry_cipher_authenticate, _gcry_cipher_checktag)
> (_gcry_cipher_gettag): New.
> * doc/gcrypt.texi: Add documentation for new API functions.
> * src/visibility.c (gcry_cipher_authenticate, 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.
>
> Changes in v3:
> - Change gcry_cipher_setaad back to gcry_cipher_authenticate. Additional
> parameters (encrypt_len, tag_len, aad_len) for CCM will be given
> through GCRY_CTL_SET_CCM_LENGTHS.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
> ---
> cipher/cipher.c | 34 ++++++++++++++++++++++++++++++++++
> doc/gcrypt.texi | 35 +++++++++++++++++++++++++++++++++++
> src/gcrypt.h.in | 11 +++++++++++
> src/libgcrypt.def | 3 +++
> src/libgcrypt.vers | 1 +
> src/visibility.c | 27 +++++++++++++++++++++++++++
> src/visibility.h | 9 +++++++++
> 7 files changed, 120 insertions(+)
>
> diff --git a/cipher/cipher.c b/cipher/cipher.c
> index 75d42d1..36c79db 100644
> --- a/cipher/cipher.c
> +++ b/cipher/cipher.c
> @@ -910,6 +910,40 @@ _gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
> return 0;
> }
>
> +gcry_error_t
> +_gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
> + size_t abuflen)
> +{
> + log_fatal ("gcry_cipher_authenticate: invalid mode %d\n", hd->mode);
> +
> + (void)abuf;
> + (void)abuflen;
> +
> + 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..0049fa0 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,37 @@ 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_authenticate (gcry_cipher_hd_t @var{h}, const void *@var{abuf}, size_t @var{abuflen})
> +
> +Process the buffer @var{abuf} of length @var{abuflen} as the additional
> +authenticated data (AAD) for AEAD cipher modes.
> +
> + 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 the authentication 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..f0ae927 100644
> --- a/src/gcrypt.h.in
> +++ b/src/gcrypt.h.in
> @@ -953,6 +953,17 @@ 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. */
> +gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
> + size_t abuflen);
> +
> +/* 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..64ba370 100644
> --- a/src/libgcrypt.def
> +++ b/src/libgcrypt.def
> @@ -255,6 +255,9 @@ EXPORTS
>
> gcry_sexp_extract_param @225
>
> + gcry_cipher_authenticate @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..93eaa93 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_authenticate; 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..1f7bb3a 100644
> --- a/src/visibility.c
> +++ b/src/visibility.c
> @@ -713,6 +713,33 @@ 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_authenticate (gcry_cipher_hd_t hd, const void *abuf, size_t abuflen)
> +{
> + if (!fips_is_operational ())
> + return gpg_error (fips_not_operational ());
> +
> + return _gcry_cipher_authenticate (hd, abuf, abuflen);
> +}
> +
> +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..b2fa4c0 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_authenticate _gcry_cipher_authenticate
> +#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_authenticate
> +#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_authenticate)
> +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)
>
>
> _______________________________________________
> Gcrypt-devel mailing list
> Gcrypt-devel at gnupg.org
> http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
>
More information about the Gcrypt-devel
mailing list