]> code.ossystems Code Review - meta-freescale.git/blob
b796f16015279726f48a924e0086243ed928fb74
[meta-freescale.git] /
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()
5
6 Upstream-status: Pending
7
8 Needed for 64b kernel with 32b user space.
9
10 Signed-off-by: Horia Geanta <horia.geanta@freescale.com>
11 Tested-by: Cristian Stoica <cristian.stoica@freescale.com>
12 ---
13  authenc.c       |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
14  cryptodev_int.h |   41 ++++++++++++++++++++++++++++
15  ioctl.c         |   16 +++++++++++
16  3 files changed, 137 insertions(+)
17
18 diff --git a/authenc.c b/authenc.c
19 index 5235973..259a225 100644
20 --- a/authenc.c
21 +++ b/authenc.c
22 @@ -241,6 +241,86 @@ static int fill_caop_from_kcaop(struct kernel_crypt_auth_op *kcaop, struct fcryp
23         return 0;
24  }
25  
26 +/* compatibility code for 32bit userlands */
27 +#ifdef CONFIG_COMPAT
28 +
29 +static inline void
30 +compat_to_crypt_auth_op(struct compat_crypt_auth_op *compat,
31 +                       struct crypt_auth_op *caop)
32 +{
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;
41 +
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);
47 +}
48 +
49 +static inline void
50 +crypt_auth_op_to_compat(struct crypt_auth_op *caop,
51 +                       struct compat_crypt_auth_op *compat)
52 +{
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;
61 +
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);
67 +}
68 +
69 +int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
70 +                               struct fcrypt *fcr, void __user *arg)
71 +{
72 +       struct compat_crypt_auth_op compat_caop;
73 +
74 +       if (unlikely(copy_from_user(&compat_caop, arg, sizeof(compat_caop)))) {
75 +               dprintk(1, KERN_ERR, "Error in copying from userspace\n");
76 +               return -EFAULT;
77 +       }
78 +
79 +       compat_to_crypt_auth_op(&compat_caop, &kcaop->caop);
80 +
81 +       return fill_kcaop_from_caop(kcaop, fcr);
82 +}
83 +
84 +int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
85 +                               struct fcrypt *fcr, void __user *arg)
86 +{
87 +       int ret;
88 +       struct compat_crypt_auth_op compat_caop;
89 +
90 +       ret = fill_caop_from_kcaop(kcaop, fcr);
91 +       if (unlikely(ret)) {
92 +               dprintk(1, KERN_ERR, "fill_caop_from_kcaop\n");
93 +               return ret;
94 +       }
95 +
96 +       crypt_auth_op_to_compat(&kcaop->caop, &compat_caop);
97 +
98 +       if (unlikely(copy_to_user(arg, &compat_caop, sizeof(compat_caop)))) {
99 +               dprintk(1, KERN_ERR, "Error in copying to userspace\n");
100 +               return -EFAULT;
101 +       }
102 +       return 0;
103 +}
104 +
105 +#endif /* CONFIG_COMPAT */
106  
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 */
115  };
116  
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 */
126 +
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
130 +       authenticated */
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
134 +                                        * for padding */
135 +
136 +       compat_uptr_t   tag;            /* where the tag will be copied to. TLS
137 +                                        * mode doesn't use that as tag is
138 +                                        * copied to dst.
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. */
142 +
143 +       /* initialization vector for encryption operations */
144 +       compat_uptr_t   iv;
145 +       uint32_t        iv_len;
146 +};
147 +
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)
154  
155  #endif /* CONFIG_COMPAT */
156  
157 @@ -108,6 +140,15 @@ struct kernel_crypt_auth_op {
158  
159  /* auth */
160  
161 +#ifdef CONFIG_COMPAT
162 +int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
163 +                               struct fcrypt *fcr, void __user *arg);
164 +
165 +int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
166 +                               struct fcrypt *fcr, void __user *arg);
167 +#endif /* CONFIG_COMPAT */
168 +
169 +
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
175 --- a/ioctl.c
176 +++ b/ioctl.c
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;
182         int ret;
183  
184         if (unlikely(!pcr))
185 @@ -1033,6 +1034,21 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
186                         return ret;
187  
188                 return compat_kcop_to_user(&kcop, fcr, arg);
189 +
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");
193 +                       return ret;
194 +               }
195 +
196 +               ret = crypto_auth_run(fcr, &kcaop);
197 +               if (unlikely(ret)) {
198 +                       dprintk(1, KERN_WARNING, "Error in crypto_auth_run\n");
199 +                       return ret;
200 +               }
201 +
202 +               return compat_kcaop_to_user(&kcaop, fcr, arg);
203 +
204  #ifdef ENABLE_ASYNC
205         case COMPAT_CIOCASYNCCRYPT:
206                 if (unlikely(ret = compat_kcop_from_user(&kcop, fcr, arg)))
207 -- 
208 1.7.9.7
209