[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