1 From 4b766c93e4ee19248dd66bbebb61fb5cc9c8a012 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 2/9] add support for COMPAT_CIOCAUTHCRYPT ioctl()
 
   6 Upstream-status: Pending
 
   8 Needed for 64b kernel with 32b user space.
 
  10 Change-Id: I44a999a4164e7ae7122dee6ed0716b2f25cadbc1
 
  11 Signed-off-by: Horia Geanta <horia.geanta@freescale.com>
 
  12 Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
 
  14  authenc.c       | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
  15  cryptodev_int.h | 40 +++++++++++++++++++++++++++++
 
  16  ioctl.c         | 16 ++++++++++++
 
  17  3 files changed, 134 insertions(+)
 
  19 diff --git a/authenc.c b/authenc.c
 
  20 index 1bd7377..ef0d3db 100644
 
  23 @@ -272,6 +272,84 @@ static int fill_caop_from_kcaop(struct kernel_crypt_auth_op *kcaop, struct fcryp
 
  27 +/* compatibility code for 32bit userlands */
 
  31 +compat_to_crypt_auth_op(struct compat_crypt_auth_op *compat,
 
  32 +                       struct crypt_auth_op *caop)
 
  34 +       caop->ses = compat->ses;
 
  35 +       caop->op = compat->op;
 
  36 +       caop->flags = compat->flags;
 
  37 +       caop->len = compat->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->auth_len = caop->auth_len;
 
  58 +       compat->tag_len = caop->tag_len;
 
  59 +       compat->iv_len = caop->iv_len;
 
  61 +       compat->auth_src = ptr_to_compat(caop->auth_src);
 
  62 +       compat->src = ptr_to_compat(caop->src);
 
  63 +       compat->dst = ptr_to_compat(caop->dst);
 
  64 +       compat->tag = ptr_to_compat(caop->tag);
 
  65 +       compat->iv = ptr_to_compat(caop->iv);
 
  68 +int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
 
  69 +                               struct fcrypt *fcr, void __user *arg)
 
  71 +       struct compat_crypt_auth_op compat_caop;
 
  73 +       if (unlikely(copy_from_user(&compat_caop, arg, sizeof(compat_caop)))) {
 
  74 +               dprintk(1, KERN_ERR, "Error in copying from userspace\n");
 
  78 +       compat_to_crypt_auth_op(&compat_caop, &kcaop->caop);
 
  80 +       return fill_kcaop_from_caop(kcaop, fcr);
 
  83 +int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
 
  84 +                               struct fcrypt *fcr, void __user *arg)
 
  87 +       struct compat_crypt_auth_op compat_caop;
 
  89 +       ret = fill_caop_from_kcaop(kcaop, fcr);
 
  90 +       if (unlikely(ret)) {
 
  91 +               dprintk(1, KERN_ERR, "fill_caop_from_kcaop\n");
 
  95 +       crypt_auth_op_to_compat(&kcaop->caop, &compat_caop);
 
  97 +       if (unlikely(copy_to_user(arg, &compat_caop, sizeof(compat_caop)))) {
 
  98 +               dprintk(1, KERN_ERR, "Error in copying to userspace\n");
 
 104 +#endif /* CONFIG_COMPAT */
 
 106  int kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
 
 107                         struct fcrypt *fcr, void __user *arg)
 
 108 diff --git a/cryptodev_int.h b/cryptodev_int.h
 
 109 index d7660fa..8e687e7 100644
 
 110 --- a/cryptodev_int.h
 
 111 +++ b/cryptodev_int.h
 
 112 @@ -73,11 +73,42 @@ struct compat_crypt_op {
 
 113         compat_uptr_t   iv;/* initialization vector for encryption operations */
 
 116 + /* input of CIOCAUTHCRYPT */
 
 117 +struct compat_crypt_auth_op {
 
 118 +       uint32_t        ses;            /* session identifier */
 
 119 +       uint16_t        op;             /* COP_ENCRYPT or COP_DECRYPT */
 
 120 +       uint16_t        flags;          /* see COP_FLAG_AEAD_* */
 
 121 +       uint32_t        len;            /* length of source data */
 
 122 +       uint32_t        auth_len;       /* length of auth data */
 
 123 +       compat_uptr_t   auth_src;       /* authenticated-only data */
 
 125 +       /* The current implementation is more efficient if data are
 
 126 +        * encrypted in-place (src==dst). */
 
 127 +       compat_uptr_t   src;            /* data to be encrypted and
 
 129 +       compat_uptr_t   dst;            /* pointer to output data. Must have
 
 130 +                                        * space for tag. For TLS this should be
 
 131 +                                        * at least len + tag_size + block_size
 
 134 +       compat_uptr_t   tag;            /* where the tag will be copied to. TLS
 
 135 +                                        * mode doesn't use that as tag is
 
 137 +                                        * SRTP mode copies tag there. */
 
 138 +       uint32_t        tag_len;        /* the length of the tag. Use zero for
 
 139 +                                        * digest size or max tag. */
 
 141 +       /* initialization vector for encryption operations */
 
 146  /* compat ioctls, defined for the above structs */
 
 147  #define COMPAT_CIOCGSESSION    _IOWR('c', 102, struct compat_session_op)
 
 148  #define COMPAT_CIOCCRYPT       _IOWR('c', 104, struct compat_crypt_op)
 
 149  #define COMPAT_CIOCASYNCCRYPT  _IOW('c', 107, struct compat_crypt_op)
 
 150  #define COMPAT_CIOCASYNCFETCH  _IOR('c', 108, struct compat_crypt_op)
 
 151 +#define COMPAT_CIOCAUTHCRYPT   _IOWR('c', 109, struct compat_crypt_auth_op)
 
 153  #endif /* CONFIG_COMPAT */
 
 155 @@ -108,6 +139,15 @@ struct kernel_crypt_auth_op {
 
 159 +#ifdef CONFIG_COMPAT
 
 160 +int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
 
 161 +                               struct fcrypt *fcr, void __user *arg);
 
 163 +int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
 
 164 +                               struct fcrypt *fcr, void __user *arg);
 
 165 +#endif /* CONFIG_COMPAT */
 
 168  int kcaop_from_user(struct kernel_crypt_auth_op *kcop,
 
 169                         struct fcrypt *fcr, void __user *arg);
 
 170  int kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
 
 171 diff --git a/ioctl.c b/ioctl.c
 
 172 index f9b9b2e..1563c75 100644
 
 175 @@ -998,6 +998,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
 
 176         struct session_op sop;
 
 177         struct compat_session_op compat_sop;
 
 178         struct kernel_crypt_op kcop;
 
 179 +       struct kernel_crypt_auth_op kcaop;
 
 183 @@ -1040,6 +1041,21 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
 
 186                 return compat_kcop_to_user(&kcop, fcr, arg);
 
 188 +       case COMPAT_CIOCAUTHCRYPT:
 
 189 +               if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) {
 
 190 +                       dprintk(1, KERN_WARNING, "Error copying from user\n");
 
 194 +               ret = crypto_auth_run(fcr, &kcaop);
 
 195 +               if (unlikely(ret)) {
 
 196 +                       dprintk(1, KERN_WARNING, "Error in crypto_auth_run\n");
 
 200 +               return compat_kcaop_to_user(&kcaop, fcr, arg);
 
 203         case COMPAT_CIOCASYNCCRYPT:
 
 204                 if (unlikely(ret = compat_kcop_from_user(&kcop, fcr, arg)))