1 From 75e26bf18997488518228cb851585bf8e4c3120f Mon Sep 17 00:00:00 2001
 
   2 From: Horia Geanta <horia.geanta@freescale.com>
 
   3 Date: Wed, 4 Dec 2013 15:43:41 +0200
 
   4 Subject: [[Patch][fsl 07/16] add support for COMPAT_CIOCAUTHCRYPT ioctl()
 
   6 Upstream-status: Pending
 
   8 Needed for 64b kernel with 32b user space.
 
  10 Signed-off-by: Horia Geanta <horia.geanta@freescale.com>
 
  11 Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
 
  13  authenc.c       |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
  14  cryptodev_int.h |   41 ++++++++++++++++++++++++++++
 
  15  ioctl.c         |   16 +++++++++++
 
  16  3 files changed, 137 insertions(+)
 
  18 diff --git a/authenc.c b/authenc.c
 
  19 index 5235973..259a225 100644
 
  22 @@ -241,6 +241,86 @@ static int fill_caop_from_kcaop(struct kernel_crypt_auth_op *kcaop, struct fcryp
 
  26 +/* compatibility code for 32bit userlands */
 
  30 +compat_to_crypt_auth_op(struct compat_crypt_auth_op *compat,
 
  31 +                       struct crypt_auth_op *caop)
 
  33 +       caop->ses = compat->ses;
 
  34 +       caop->op = compat->op;
 
  35 +       caop->flags = compat->flags;
 
  36 +       caop->len = compat->len;
 
  37 +       caop->dst_len = compat->dst_len;
 
  38 +       caop->auth_len = compat->auth_len;
 
  39 +       caop->tag_len = compat->tag_len;
 
  40 +       caop->iv_len = compat->iv_len;
 
  42 +       caop->auth_src = compat_ptr(compat->auth_src);
 
  43 +       caop->src = compat_ptr(compat->src);
 
  44 +       caop->dst = compat_ptr(compat->dst);
 
  45 +       caop->tag = compat_ptr(compat->tag);
 
  46 +       caop->iv = compat_ptr(compat->iv);
 
  50 +crypt_auth_op_to_compat(struct crypt_auth_op *caop,
 
  51 +                       struct compat_crypt_auth_op *compat)
 
  53 +       compat->ses = caop->ses;
 
  54 +       compat->op = caop->op;
 
  55 +       compat->flags = caop->flags;
 
  56 +       compat->len = caop->len;
 
  57 +       compat->dst_len = caop->dst_len;
 
  58 +       compat->auth_len = caop->auth_len;
 
  59 +       compat->tag_len = caop->tag_len;
 
  60 +       compat->iv_len = caop->iv_len;
 
  62 +       compat->auth_src = ptr_to_compat(caop->auth_src);
 
  63 +       compat->src = ptr_to_compat(caop->src);
 
  64 +       compat->dst = ptr_to_compat(caop->dst);
 
  65 +       compat->tag = ptr_to_compat(caop->tag);
 
  66 +       compat->iv = ptr_to_compat(caop->iv);
 
  69 +int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
 
  70 +                               struct fcrypt *fcr, void __user *arg)
 
  72 +       struct compat_crypt_auth_op compat_caop;
 
  74 +       if (unlikely(copy_from_user(&compat_caop, arg, sizeof(compat_caop)))) {
 
  75 +               dprintk(1, KERN_ERR, "Error in copying from userspace\n");
 
  79 +       compat_to_crypt_auth_op(&compat_caop, &kcaop->caop);
 
  81 +       return fill_kcaop_from_caop(kcaop, fcr);
 
  84 +int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
 
  85 +                               struct fcrypt *fcr, void __user *arg)
 
  88 +       struct compat_crypt_auth_op compat_caop;
 
  90 +       ret = fill_caop_from_kcaop(kcaop, fcr);
 
  91 +       if (unlikely(ret)) {
 
  92 +               dprintk(1, KERN_ERR, "fill_caop_from_kcaop\n");
 
  96 +       crypt_auth_op_to_compat(&kcaop->caop, &compat_caop);
 
  98 +       if (unlikely(copy_to_user(arg, &compat_caop, sizeof(compat_caop)))) {
 
  99 +               dprintk(1, KERN_ERR, "Error in copying to userspace\n");
 
 105 +#endif /* CONFIG_COMPAT */
 
 107  int kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
 
 108                         struct fcrypt *fcr, void __user *arg)
 
 109 diff --git a/cryptodev_int.h b/cryptodev_int.h
 
 110 index d7660fa..8d206c9 100644
 
 111 --- a/cryptodev_int.h
 
 112 +++ b/cryptodev_int.h
 
 113 @@ -73,11 +73,43 @@ struct compat_crypt_op {
 
 114         compat_uptr_t   iv;/* initialization vector for encryption operations */
 
 117 + /* input of CIOCAUTHCRYPT */
 
 118 +struct compat_crypt_auth_op {
 
 119 +       uint32_t        ses;            /* session identifier */
 
 120 +       uint16_t        op;             /* COP_ENCRYPT or COP_DECRYPT */
 
 121 +       uint16_t        flags;          /* see COP_FLAG_AEAD_* */
 
 122 +       uint32_t        len;            /* length of source data */
 
 123 +       uint32_t        dst_len;        /* length of result data */
 
 124 +       uint32_t        auth_len;       /* length of auth data */
 
 125 +       compat_uptr_t   auth_src;       /* authenticated-only data */
 
 127 +       /* The current implementation is more efficient if data are
 
 128 +        * encrypted in-place (src==dst). */
 
 129 +       compat_uptr_t   src;            /* data to be encrypted and
 
 131 +       compat_uptr_t   dst;            /* pointer to output data. Must have
 
 132 +                                        * space for tag. For TLS this should be
 
 133 +                                        * at least len + tag_size + block_size
 
 136 +       compat_uptr_t   tag;            /* where the tag will be copied to. TLS
 
 137 +                                        * mode doesn't use that as tag is
 
 139 +                                        * SRTP mode copies tag there. */
 
 140 +       uint32_t        tag_len;        /* the length of the tag. Use zero for
 
 141 +                                        * digest size or max tag. */
 
 143 +       /* initialization vector for encryption operations */
 
 148  /* compat ioctls, defined for the above structs */
 
 149  #define COMPAT_CIOCGSESSION    _IOWR('c', 102, struct compat_session_op)
 
 150  #define COMPAT_CIOCCRYPT       _IOWR('c', 104, struct compat_crypt_op)
 
 151  #define COMPAT_CIOCASYNCCRYPT  _IOW('c', 107, struct compat_crypt_op)
 
 152  #define COMPAT_CIOCASYNCFETCH  _IOR('c', 108, struct compat_crypt_op)
 
 153 +#define COMPAT_CIOCAUTHCRYPT   _IOWR('c', 109, struct compat_crypt_auth_op)
 
 155  #endif /* CONFIG_COMPAT */
 
 157 @@ -108,6 +140,15 @@ struct kernel_crypt_auth_op {
 
 161 +#ifdef CONFIG_COMPAT
 
 162 +int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
 
 163 +                               struct fcrypt *fcr, void __user *arg);
 
 165 +int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
 
 166 +                               struct fcrypt *fcr, void __user *arg);
 
 167 +#endif /* CONFIG_COMPAT */
 
 170  int kcaop_from_user(struct kernel_crypt_auth_op *kcop,
 
 171                         struct fcrypt *fcr, void __user *arg);
 
 172  int kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
 
 173 diff --git a/ioctl.c b/ioctl.c
 
 174 index 3baf195..18874d3 100644
 
 177 @@ -991,6 +991,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
 
 178         struct session_op sop;
 
 179         struct compat_session_op compat_sop;
 
 180         struct kernel_crypt_op kcop;
 
 181 +       struct kernel_crypt_auth_op kcaop;
 
 185 @@ -1033,6 +1034,21 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
 
 188                 return compat_kcop_to_user(&kcop, fcr, arg);
 
 190 +       case COMPAT_CIOCAUTHCRYPT:
 
 191 +               if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) {
 
 192 +                       dprintk(1, KERN_WARNING, "Error copying from user\n");
 
 196 +               ret = crypto_auth_run(fcr, &kcaop);
 
 197 +               if (unlikely(ret)) {
 
 198 +                       dprintk(1, KERN_WARNING, "Error in crypto_auth_run\n");
 
 202 +               return compat_kcaop_to_user(&kcaop, fcr, arg);
 
 205         case COMPAT_CIOCASYNCCRYPT:
 
 206                 if (unlikely(ret = compat_kcop_from_user(&kcop, fcr, arg)))