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

Reply via email to