forked from clearlinux-pkgs/linux-iot-lts2018
-
Notifications
You must be signed in to change notification settings - Fork 0
/
0027-rpmb-add-nvme-rpmb-frame-type.patch
164 lines (150 loc) · 5.64 KB
/
0027-rpmb-add-nvme-rpmb-frame-type.patch
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
From 32ae91528785c048190fc4bdfc75459634507e5f Mon Sep 17 00:00:00 2001
From: Tomas Winkler <[email protected]>
Date: Sat, 28 Apr 2018 22:01:32 +0300
Subject: [PATCH 12/22] rpmb: add nvme rpmb frame type
The NVMe RPMB frame differs in layout and endianity
from the one defined by JDEC.
Change-Id: Ifae77454e1bc8733eb1e5bcb2146dc198f94151d
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/char/rpmb/cdev.c | 26 ++++++++++++++++++-------
include/uapi/linux/rpmb.h | 41 +++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/drivers/char/rpmb/cdev.c b/drivers/char/rpmb/cdev.c
index bdac3894b111..028c7ecd2ac7 100644
--- a/drivers/char/rpmb/cdev.c
+++ b/drivers/char/rpmb/cdev.c
@@ -67,18 +67,28 @@ static int rpmb_release(struct inode *inode, struct file *fp)
return 0;
}
+static size_t rpmb_ioc_frames_len(struct rpmb_dev *rdev, size_t nframes)
+{
+ if (rdev->ops->type == RPMB_TYPE_NVME)
+ return rpmb_ioc_frames_len_nvme(nframes);
+ else
+ return rpmb_ioc_frames_len_jdec(nframes);
+}
+
/**
* rpmb_cmd_copy_from_user - copy rpmb command from the user space
*
+ * @rdev: rpmb device
* @cmd: internal cmd structure
* @ucmd: user space cmd structure
*
* Return: 0 on success, <0 on error
*/
-static int rpmb_cmd_copy_from_user(struct rpmb_cmd *cmd,
+static int rpmb_cmd_copy_from_user(struct rpmb_dev *rdev,
+ struct rpmb_cmd *cmd,
struct rpmb_ioc_cmd __user *ucmd)
{
- struct rpmb_frame *frames;
+ void *frames;
u64 frames_ptr;
if (get_user(cmd->flags, &ucmd->flags))
@@ -95,7 +105,7 @@ static int rpmb_cmd_copy_from_user(struct rpmb_cmd *cmd,
return -EFAULT;
frames = memdup_user(u64_to_user_ptr(frames_ptr),
- rpmb_ioc_frames_len_jdec(cmd->nframes));
+ rpmb_ioc_frames_len(rdev, cmd->nframes));
if (IS_ERR(frames))
return PTR_ERR(frames);
@@ -106,12 +116,14 @@ static int rpmb_cmd_copy_from_user(struct rpmb_cmd *cmd,
/**
* rpmb_cmd_copy_to_user - copy rpmb command to the user space
*
+ * @rdev: rpmb device
* @ucmd: user space cmd structure
* @cmd: internal cmd structure
*
* Return: 0 on success, <0 on error
*/
-static int rpmb_cmd_copy_to_user(struct rpmb_ioc_cmd __user *ucmd,
+static int rpmb_cmd_copy_to_user(struct rpmb_dev *rdev,
+ struct rpmb_ioc_cmd __user *ucmd,
struct rpmb_cmd *cmd)
{
u64 frames_ptr;
@@ -121,7 +133,7 @@ static int rpmb_cmd_copy_to_user(struct rpmb_ioc_cmd __user *ucmd,
/* some archs have issues with 64bit get_user */
if (copy_to_user(u64_to_user_ptr(frames_ptr), cmd->frames,
- rpmb_ioc_frames_len_jdec(cmd->nframes)))
+ rpmb_ioc_frames_len(rdev, cmd->nframes)))
return -EFAULT;
return 0;
@@ -167,7 +179,7 @@ static long rpmb_ioctl_seq_cmd(struct rpmb_dev *rdev,
ucmds = (struct rpmb_ioc_cmd __user *)ptr->cmds;
for (i = 0; i < ncmds; i++) {
- ret = rpmb_cmd_copy_from_user(&cmds[i], &ucmds[i]);
+ ret = rpmb_cmd_copy_from_user(rdev, &cmds[i], &ucmds[i]);
if (ret)
goto out;
}
@@ -177,7 +189,7 @@ static long rpmb_ioctl_seq_cmd(struct rpmb_dev *rdev,
goto out;
for (i = 0; i < ncmds; i++) {
- ret = rpmb_cmd_copy_to_user(&ucmds[i], &cmds[i]);
+ ret = rpmb_cmd_copy_to_user(rdev, &ucmds[i], &cmds[i]);
if (ret)
goto out;
}
diff --git a/include/uapi/linux/rpmb.h b/include/uapi/linux/rpmb.h
index d304701cd258..f41a28ea9765 100644
--- a/include/uapi/linux/rpmb.h
+++ b/include/uapi/linux/rpmb.h
@@ -68,6 +68,44 @@ struct rpmb_frame_jdec {
(sizeof(struct rpmb_frame_jdec) - \
offsetof(struct rpmb_frame_jdec, data))
+/**
+ * struct rpmb_frame_nvme - rpmb frame as defined by specs
+ *
+ * @key_mac : The authentication key or the message authentication
+ * code (MAC) depending on the request/response type.
+ * The MAC will be delivered in the last (or the only)
+ * block of data.
+ * @rpmb_target : RPMB target to access.
+ * @nonce : Random number generated by the host for the requests
+ * and copied to the response by the RPMB engine.
+ * @write_counter: Counter value for the total amount of the successful
+ * authenticated data write requests made by the host.
+ * @addr : Address of the data to be programmed to or read
+ * from the RPMB. Address is the serial number of
+ * the accessed block (half sector 256B).
+ * @block_count : Number of sctors (sectors, 512B) requested to be
+ * read/programmed. (In spec this field is named sector_count).
+ * @result : Includes information about the status of the write counter
+ * (valid, expired) and result of the access made to the RPMB.
+ * @req_resp : Defines the type of request and response to/from the memory.
+ * @data : variable sized payload 512 * block_count
+ */
+struct rpmb_frame_nvme {
+ __u8 key_mac[223];
+ __u8 rpmb_target;
+ __u8 nonce[16];
+ __le32 write_counter;
+ __le32 addr;
+ __le32 block_count;
+ __le16 result;
+ __le16 req_resp;
+ __u8 data[0];
+} __attribute__((packed));
+
+#define rpmb_nvme_hmac_data_len \
+ (sizeof(struct rpmb_frame_nvme) - \
+ offsetof(struct rpmb_frame_nvme, rpmb_target))
+
#define RPMB_PROGRAM_KEY 0x0001 /* Program RPMB Authentication Key */
#define RPMB_GET_WRITE_COUNTER 0x0002 /* Read RPMB write counter */
#define RPMB_WRITE_DATA 0x0003 /* Write data to RPMB partition */
@@ -142,6 +180,9 @@ struct rpmb_ioc_cmd {
#define rpmb_ioc_frames_len_jdec(_n) \
(((_n) ?: 1) * sizeof(struct rpmb_frame_jdec))
+#define rpmb_ioc_frames_len_nvme(_n) \
+ (sizeof(struct rpmb_frame_nvme) + (_n) * 512)
+
/**
* struct rpmb_ioc_seq_cmd - rpmb command sequence
*
--
2.19.1