From 711529cc7b8743ae8c9c0db4980ac15f7acb8618 Mon Sep 17 00:00:00 2001 From: Alex Porosanu Date: Tue, 12 Jan 2016 14:51:00 +0200 Subject: [PATCH 36/38] add compat for CIOCHASH operation This patch adds the necessary ioctl for using the CIOCHASH operation for different userspace & kernel (i.e. 32b userspace and 64b kernel). Signed-off-by: Alex Porosanu --- cryptodev_int.h | 14 +++++++++++++- ioctl.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/cryptodev_int.h b/cryptodev_int.h index 74c295a..6dcfd69 100644 --- a/cryptodev_int.h +++ b/cryptodev_int.h @@ -129,6 +129,18 @@ struct compat_crypt_auth_op { uint32_t iv_len; }; +struct compat_hash_op_data { + compat_uptr_t ses; + uint32_t mac_op; /* cryptodev_crypto_op_t */ + compat_uptr_t mackey; + uint32_t mackeylen; + + uint16_t flags; /* see COP_FLAG_* */ + uint32_t len; /* length of source data */ + compat_uptr_t src; /* source data */ + compat_uptr_t mac_result; +}; + /* 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) @@ -139,7 +151,7 @@ struct compat_crypt_auth_op { #define COMPAT_CIOCASYMASYNCRYPT _IOW('c', 110, struct compat_crypt_kop) #define COMPAT_CIOCASYMFETCHCOOKIE _IOR('c', 111, \ struct compat_pkc_cookie_list_s) - +#define COMPAT_CIOCHASH _IOWR('c', 114, struct compat_hash_op_data) #endif /* CONFIG_COMPAT */ /* kernel-internal extension to struct crypt_kop */ diff --git a/ioctl.c b/ioctl.c index a052614..ff3de44 100644 --- a/ioctl.c +++ b/ioctl.c @@ -1435,8 +1435,11 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) struct fcrypt *fcr; struct session_op sop; struct compat_session_op compat_sop; + struct kernel_hash_op khop; struct kernel_crypt_op kcop; struct kernel_crypt_auth_op kcaop; + struct compat_hash_op_data compat_hash_op_data; + int ret; if (unlikely(!pcr)) @@ -1499,6 +1502,53 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) return compat_kcop_to_user(&kcop, fcr, arg); + case COMPAT_CIOCHASH: + /* get session */ + if (unlikely(copy_from_user(&compat_hash_op_data, arg, + sizeof(struct compat_hash_op_data)))) { + pr_err("copy from user fault\n"); + return -EFAULT; + } + + khop.task = current; + khop.mm = current->mm; + + khop.hash_op.mac_op = compat_hash_op_data.mac_op; + khop.hash_op.mackey = compat_ptr(compat_hash_op_data.mackey); + khop.hash_op.mackeylen = compat_hash_op_data.mackeylen; + khop.hash_op.flags = compat_hash_op_data.flags; + khop.hash_op.len = compat_hash_op_data.len; + khop.hash_op.src = compat_ptr(compat_hash_op_data.src); + khop.hash_op.mac_result = + compat_ptr(compat_hash_op_data.mac_result); + + ret = hash_create_session(&khop.hash_op); + if (unlikely(ret)) { + pr_err("can't get session\n"); + return ret; + } + + /* do hashing */ + ret = hash_run(&khop); + if (unlikely(ret)) { + dwarning(1, "Error in hash run"); + return ret; + } + + ret = copy_to_user(khop.hash_op.mac_result, khop.hash_output, + khop.digestsize); + if (unlikely(ret)) { + dwarning(1, "Error in copy to user"); + return ret; + } + + copy_to_user(arg, &compat_hash_op_data, + sizeof(struct compat_hash_op_data)); + + /* put session */ + hash_destroy_session(khop.hash_op.ses); + return 0; + case COMPAT_CIOCAUTHCRYPT: if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) { dprintk(1, KERN_WARNING, "Error copying from user\n"); -- 2.7.0