1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
From c43fa74b9ed11f0183d25b21486b71fe02d84de7 Mon Sep 17 00:00:00 2001
From: Cristian Stoica <cristian.stoica@nxp.com>
Date: Tue, 15 Dec 2015 15:31:47 +0200
Subject: [PATCH 34/38] extend API with CIOCHASH to support direct hash
operations
Signed-off-by: Cristian Stoica <cristian.stoica@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 f6058ca..c6083f7 100644
--- a/crypto/cryptodev.h
+++ b/crypto/cryptodev.h
@@ -167,6 +167,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)
@@ -325,4 +338,7 @@ enum cryptodev_crk_op_t {
/* additional ioctls for asynchronous operation for asymmetric ciphers*/
#define CIOCASYMASYNCRYPT _IOW('c', 112, struct crypt_kop)
#define CIOCASYMFETCHCOOKIE _IOR('c', 113, struct pkc_cookie_list_s)
+
+#define CIOCHASH _IOWR('c', 114, struct hash_op_data)
+
#endif /* L_CRYPTODEV_H */
diff --git a/ioctl.c b/ioctl.c
index 7adde75..3763954 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -960,6 +960,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;
@@ -1049,6 +1050,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.7.0
|