Signed-off-by: Cristian Stoica <cristian.sto...@nxp.com> --- crypto/cryptodev.h | 16 ++++++++++++++++ ioctl.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+)
diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h index 7fb9c7d..20ae8ba 100644 --- a/crypto/cryptodev.h +++ b/crypto/cryptodev.h @@ -156,6 +156,19 @@ struct crypt_auth_op { __u32 iv_len; }; +/* data container for CIOCHASH operations */ +struct hash_op_data { + __u32 ses; /* session identifier */ + __u32 mac_op; /* cryptodev_crypto_op_t */ + __u8 *mackey; + __u32 mackeylen; + + __u16 flags; /* see COP_FLAG_* */ + __u32 len; /* length of source data */ + __u8 *src; /* source data */ + __u8 *mac_result; +}; + /* In plain AEAD mode the following are required: * flags : 0 * iv : the initialization vector (12 bytes) @@ -289,4 +302,7 @@ enum cryptodev_crk_op_t { #define CIOCASYNCCRYPT _IOW('c', 110, struct crypt_op) #define CIOCASYNCFETCH _IOR('c', 111, struct crypt_op) + +#define CIOCHASH _IOWR('c', 114, struct hash_op_data) + #endif /* L_CRYPTODEV_H */ diff --git a/ioctl.c b/ioctl.c index 8649e95..53bac35 100644 --- a/ioctl.c +++ b/ioctl.c @@ -808,6 +808,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) void __user *arg = (void __user *)arg_; int __user *p = arg; struct session_op sop; + struct hash_op_data hash_op; struct kernel_crypt_op kcop; struct kernel_crypt_auth_op kcaop; struct crypt_priv *pcr = filp->private_data; @@ -872,6 +873,54 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) } return kcop_to_user(&kcop, fcr, arg); + case CIOCHASH: + /* get session */ + if (unlikely(copy_from_user(&hash_op, arg, sizeof(struct hash_op_data)))) { + pr_err("copy from user fault\n"); + return -EFAULT; + } + + sop.cipher = 0; + sop.mac = hash_op.mac_op; + sop.mackey = hash_op.mackey; + sop.mackeylen = hash_op.mackeylen; + + /* writes sop.ses as a side-effect */ + ret = crypto_create_session(fcr, &sop); + if (unlikely(ret)) { + pr_err("can't get session\n"); + return ret; + } + + /* do hashing */ + kcop.cop.ses = sop.ses; + kcop.cop.flags = hash_op.flags; + kcop.cop.len = hash_op.len; + kcop.cop.src = hash_op.src; + kcop.cop.mac = hash_op.mac_result; + kcop.cop.dst = 0; + kcop.cop.op = 0; + kcop.cop.iv = 0; + kcop.ivlen = 0; + kcop.digestsize = 0; /* will be updated during operation */ + kcop.task = current; + kcop.mm = current->mm; + + ret = crypto_run(fcr, &kcop); + if (unlikely(ret)) { + dwarning(1, "Error in hash run"); + return ret; + } + + ret = copy_to_user(kcop.cop.mac, kcop.hash_output, kcop.digestsize); + if (unlikely(ret)) { + dwarning(1, "Error in copy to user"); + return ret; + } + + /* put session */ + ret = crypto_finish_session(fcr, sop.ses); + return 0; case CIOCAUTHCRYPT: if (unlikely(ret = kcaop_from_user(&kcaop, fcr, arg))) { dwarning(1, "Error copying from user"); -- 2.4.10 _______________________________________________ Cryptodev-linux-devel mailing list Cryptodev-linux-devel@gna.org https://mail.gna.org/listinfo/cryptodev-linux-devel