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