Hi guys,

Let me know what you think about this patch. Short of the TLS dst_len rounding 
fix, it should be just a refactoring. 

Replacing CIOCAUTHCRYPT with another ioctl that takes dst_len is not such a 
good idea in practice. The transition needs a lot of code duplication that has 
to be tested for regressions and compatibility with the old code. I've tried it 
and the patches are not pretty.

Thanks,
Cristian S.


> -----Original Message-----
> From: Cristian Stoica [mailto:cristian.sto...@freescale.com]
> Sent: Thursday, July 10, 2014 1:33 PM
> To: p...@nwl.cc; n...@gnutls.org
> Cc: cryptodev-linux-devel@gna.org; Stoica Cristian-B18196
> Subject: [PATCH] fix tag and dst_len calculation for aead ciphers
> 
> Calculate tag and destination buffer length in a single place to avoid
> code duplication. The TLS case is fixed by rounding the destination
> length to cipher block size.
> 
> Signed-off-by: Cristian Stoica <cristian.sto...@freescale.com>
> ---
>  authenc.c | 54 +++++++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 39 insertions(+), 15 deletions(-)
> 
> diff --git a/authenc.c b/authenc.c
> index a183820..1bd7377 100644
> --- a/authenc.c
> +++ b/authenc.c
> @@ -172,6 +172,42 @@ static int get_userbuf_srtp(struct csession *ses,
> struct kernel_crypt_auth_op *k
>       return 0;
>  }
> 
> +/*
> + * Return tag (digest) length for authenticated encryption
> + * If the cipher and digest are separate, hdata.init is set - just
> return
> + * digest length. Otherwise return digest length for aead ciphers
> + */
> +static int cryptodev_get_tag_len(struct csession *ses_ptr)
> +{
> +     if (ses_ptr->hdata.init)
> +             return ses_ptr->hdata.digestsize;
> +     else
> +             return cryptodev_cipher_get_tag_size(&ses_ptr->cdata);
> +}
> +
> +/*
> + * Calculate destination buffer length for authenticated encryption. The
> + * expectation is that user-space code allocates exactly the same space
> for
> + * destination buffer before calling cryptodev. The result is cipher-
> dependent.
> + */
> +static int cryptodev_get_dst_len(struct crypt_auth_op *caop, struct
> csession *ses_ptr)
> +{
> +     int dst_len = caop->len;
> +     if (caop->op == COP_DECRYPT)
> +             return dst_len;
> +
> +     dst_len += caop->tag_len;
> +
> +     /* for TLS always add some padding so the total length is rounded
> to
> +      * cipher block size */
> +     if (caop->flags & COP_FLAG_AEAD_TLS_TYPE) {
> +             int bs = ses_ptr->cdata.blocksize;
> +             dst_len += bs - (dst_len % bs);
> +     }
> +
> +     return dst_len;
> +}
> +
>  static int fill_kcaop_from_caop(struct kernel_crypt_auth_op *kcaop,
> struct fcrypt *fcr)
>  {
>       struct crypt_auth_op *caop = &kcaop->caop;
> @@ -194,15 +230,10 @@ static int fill_kcaop_from_caop(struct
> kernel_crypt_auth_op *kcaop, struct fcryp
>       }
> 
>       if (caop->tag_len == 0)
> -             caop->tag_len = ses_ptr->hdata.digestsize;
> +             caop->tag_len = cryptodev_get_tag_len(ses_ptr);
> 
>       kcaop->ivlen = caop->iv ? ses_ptr->cdata.ivsize : 0;
> -
> -     if (caop->flags & COP_FLAG_AEAD_TLS_TYPE)
> -             kcaop->dst_len = caop->len + ses_ptr->cdata.blocksize /* pad
> */ + caop->tag_len;
> -     else
> -             kcaop->dst_len = caop->len;
> -
> +     kcaop->dst_len = cryptodev_get_dst_len(caop, ses_ptr);
>       kcaop->task = current;
>       kcaop->mm = current->mm;
> 
> @@ -645,8 +676,6 @@ __crypto_auth_run_zc(struct csession *ses_ptr, struct
> kernel_crypt_auth_op *kcao
>                       ret = tls_auth_n_crypt(ses_ptr, kcaop, auth_sg, caop-
> >auth_len,
>                                  dst_sg, caop->len);
>               } else {
> -                     int dst_len;
> -
>                       if (unlikely(ses_ptr->cdata.init == 0 ||
>                                    (ses_ptr->cdata.stream == 0 &&
>                                     ses_ptr->cdata.aead == 0))) {
> @@ -655,12 +684,7 @@ __crypto_auth_run_zc(struct csession *ses_ptr,
> struct kernel_crypt_auth_op *kcao
>                               goto free_auth_buf;
>                       }
> 
> -                     if (caop->op == COP_ENCRYPT)
> -                             dst_len = caop->len +
> cryptodev_cipher_get_tag_size(&ses_ptr->cdata);
> -                     else
> -                             dst_len = caop->len;
> -
> -                     ret = get_userbuf(ses_ptr, caop->src, caop->len, caop-
> >dst, dst_len,
> +                     ret = get_userbuf(ses_ptr, caop->src, caop->len, caop-
> >dst, kcaop->dst_len,
>                                         kcaop->task, kcaop->mm, &src_sg,
> &dst_sg);
>                       if (unlikely(ret)) {
>                               derr(1, "get_userbuf(): Error getting user
> pages.");
> --
> 1.8.3.1


_______________________________________________
Cryptodev-linux-devel mailing list
Cryptodev-linux-devel@gna.org
https://mail.gna.org/listinfo/cryptodev-linux-devel

Reply via email to