Signed-off-by: Cristian Stoica <[email protected]>
---
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
[email protected]
https://mail.gna.org/listinfo/cryptodev-linux-devel