Needed for 64b kernel with 32b user space.
Signed-off-by: Horia Geanta <[email protected]>
Reviewed-by: Mircea Pop <[email protected]>
Reviewed-by: Cristian Stoica <[email protected]>
Tested-by: Cristian Stoica <[email protected]>
---
authenc.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
cryptodev_int.h | 41 ++++++++++++++++++++++++++++
ioctl.c | 16 +++++++++++
3 files changed, 137 insertions(+), 0 deletions(-)
diff --git a/authenc.c b/authenc.c
index 759a67d..277baed 100644
--- a/authenc.c
+++ b/authenc.c
@@ -246,6 +246,86 @@ static int fill_caop_from_kcaop(struct
kernel_crypt_auth_op *kcaop, struct fcryp
return 0;
}
+/* compatibility code for 32bit userlands */
+#ifdef CONFIG_COMPAT
+
+static inline void
+compat_to_crypt_auth_op(struct compat_crypt_auth_op *compat,
+ struct crypt_auth_op *caop)
+{
+ caop->ses = compat->ses;
+ caop->op = compat->op;
+ caop->flags = compat->flags;
+ caop->len = compat->len;
+ caop->dst_len = compat->dst_len;
+ caop->auth_len = compat->auth_len;
+ caop->tag_len = compat->tag_len;
+ caop->iv_len = compat->iv_len;
+
+ caop->auth_src = compat_ptr(compat->auth_src);
+ caop->src = compat_ptr(compat->src);
+ caop->dst = compat_ptr(compat->dst);
+ caop->tag = compat_ptr(compat->tag);
+ caop->iv = compat_ptr(compat->iv);
+}
+
+static inline void
+crypt_auth_op_to_compat(struct crypt_auth_op *caop,
+ struct compat_crypt_auth_op *compat)
+{
+ compat->ses = caop->ses;
+ compat->op = caop->op;
+ compat->flags = caop->flags;
+ compat->len = caop->len;
+ compat->dst_len = caop->dst_len;
+ compat->auth_len = caop->auth_len;
+ compat->tag_len = caop->tag_len;
+ compat->iv_len = caop->iv_len;
+
+ compat->auth_src = ptr_to_compat(caop->auth_src);
+ compat->src = ptr_to_compat(caop->src);
+ compat->dst = ptr_to_compat(caop->dst);
+ compat->tag = ptr_to_compat(caop->tag);
+ compat->iv = ptr_to_compat(caop->iv);
+}
+
+int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
+ struct fcrypt *fcr, void __user *arg)
+{
+ struct compat_crypt_auth_op compat_caop;
+
+ if (unlikely(copy_from_user(&compat_caop, arg, sizeof(compat_caop)))) {
+ dprintk(1, KERN_ERR, "Error in copying from userspace\n");
+ return -EFAULT;
+ }
+
+ compat_to_crypt_auth_op(&compat_caop, &kcaop->caop);
+
+ return fill_kcaop_from_caop(kcaop, fcr);
+}
+
+int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
+ struct fcrypt *fcr, void __user *arg)
+{
+ int ret;
+ struct compat_crypt_auth_op compat_caop;
+
+ ret = fill_caop_from_kcaop(kcaop, fcr);
+ if (unlikely(ret)) {
+ dprintk(1, KERN_ERR, "fill_caop_from_kcaop\n");
+ return ret;
+ }
+
+ crypt_auth_op_to_compat(&kcaop->caop, &compat_caop);
+
+ if (unlikely(copy_to_user(arg, &compat_caop, sizeof(compat_caop)))) {
+ dprintk(1, KERN_ERR, "Error in copying to userspace\n");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+#endif /* CONFIG_COMPAT */
int kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
struct fcrypt *fcr, void __user *arg)
diff --git a/cryptodev_int.h b/cryptodev_int.h
index e3e3e10..29d1113 100644
--- a/cryptodev_int.h
+++ b/cryptodev_int.h
@@ -62,11 +62,43 @@ struct compat_session_op {
compat_uptr_t iv;/* initialization vector for encryption operations */
};
+ /* input of CIOCAUTHCRYPT */
+struct compat_crypt_auth_op {
+ uint32_t ses; /* session identifier */
+ uint16_t op; /* COP_ENCRYPT or COP_DECRYPT */
+ uint16_t flags; /* see COP_FLAG_AEAD_* */
+ uint32_t len; /* length of source data */
+ uint32_t dst_len; /* length of result data */
+ uint32_t auth_len; /* length of auth data */
+ compat_uptr_t auth_src; /* authenticated-only data */
+
+ /* The current implementation is more efficient if data are
+ * encrypted in-place (src==dst). */
+ compat_uptr_t src; /* data to be encrypted and
+ authenticated */
+ compat_uptr_t dst; /* pointer to output data. Must have
+ * space for tag. For TLS this should be
+ * at least len + tag_size + block_size
+ * for padding */
+
+ compat_uptr_t tag; /* where the tag will be copied to. TLS
+ * mode doesn't use that as tag is
+ * copied to dst.
+ * SRTP mode copies tag there. */
+ uint32_t tag_len; /* the length of the tag. Use zero for
+ * digest size or max tag. */
+
+ /* initialization vector for encryption operations */
+ compat_uptr_t iv;
+ uint32_t iv_len;
+};
+
/* compat ioctls, defined for the above structs */
#define COMPAT_CIOCGSESSION _IOWR('c', 102, struct compat_session_op)
#define COMPAT_CIOCCRYPT _IOWR('c', 104, struct compat_crypt_op)
#define COMPAT_CIOCASYNCCRYPT _IOW('c', 107, struct compat_crypt_op)
#define COMPAT_CIOCASYNCFETCH _IOR('c', 108, struct compat_crypt_op)
+#define COMPAT_CIOCAUTHCRYPT _IOWR('c', 109, struct compat_crypt_auth_op)
#endif /* CONFIG_COMPAT */
@@ -97,6 +129,15 @@ struct kernel_crypt_auth_op {
/* auth */
+#ifdef CONFIG_COMPAT
+int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop,
+ struct fcrypt *fcr, void __user *arg);
+
+int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
+ struct fcrypt *fcr, void __user *arg);
+#endif /* CONFIG_COMPAT */
+
+
int kcaop_from_user(struct kernel_crypt_auth_op *kcop,
struct fcrypt *fcr, void __user *arg);
int kcaop_to_user(struct kernel_crypt_auth_op *kcaop,
diff --git a/ioctl.c b/ioctl.c
index 0ee447a..ae27293 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -998,6 +998,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg_)
struct session_op sop;
struct compat_session_op compat_sop;
struct kernel_crypt_op kcop;
+ struct kernel_crypt_auth_op kcaop;
int ret;
if (unlikely(!pcr))
@@ -1040,6 +1041,21 @@ cryptodev_compat_ioctl(struct file *file, unsigned int
cmd, unsigned long arg_)
return ret;
return compat_kcop_to_user(&kcop, fcr, arg);
+
+ case COMPAT_CIOCAUTHCRYPT:
+ if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) {
+ dprintk(1, KERN_WARNING, "Error copying from user\n");
+ return ret;
+ }
+
+ ret = crypto_auth_run(fcr, &kcaop);
+ if (unlikely(ret)) {
+ dprintk(1, KERN_WARNING, "Error in crypto_auth_run\n");
+ return ret;
+ }
+
+ return compat_kcaop_to_user(&kcaop, fcr, arg);
+
#ifdef ENABLE_ASYNC
case COMPAT_CIOCASYNCCRYPT:
if (unlikely(ret = compat_kcop_from_user(&kcop, fcr, arg)))
--
1.7.7.6
_______________________________________________
Cryptodev-linux-devel mailing list
[email protected]
https://mail.gna.org/listinfo/cryptodev-linux-devel