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