2 * Copyright 2014, Staubli Faverges
5 * eMMC- Replay Protected Memory Block
6 * According to JEDEC Standard No. 84-A441
8 * SPDX-License-Identifier: GPL-2.0+
15 #include "mmc_private.h"
18 #define RPMB_REQ_KEY 1
19 #define RPMB_REQ_WCOUNTER 2
20 #define RPMB_REQ_WRITE_DATA 3
21 #define RPMB_REQ_READ_DATA 4
22 #define RPMB_REQ_STATUS 5
25 #define RPMB_RESP_KEY 0x0100
26 #define RPMB_RESP_WCOUNTER 0x0200
27 #define RPMB_RESP_WRITE_DATA 0x0300
28 #define RPMB_RESP_READ_DATA 0x0400
32 #define RPMB_ERR_GENERAL 1
33 #define RPMB_ERR_AUTH 2
34 #define RPMB_ERR_COUNTER 3
35 #define RPMB_ERR_ADDRESS 4
36 #define RPMB_ERR_WRITE 5
37 #define RPMB_ERR_READ 6
38 #define RPMB_ERR_KEY 7
39 #define RPMB_ERR_CNT_EXPIRED 0x80
40 #define RPMB_ERR_MSK 0x7
42 /* Sizes of RPMB data frame */
43 #define RPMB_SZ_STUFF 196
44 #define RPMB_SZ_MAC 32
45 #define RPMB_SZ_DATA 256
46 #define RPMB_SZ_NONCE 16
48 #define SHA256_BLOCK_SIZE 64
51 static const char * const rpmb_err_msg[] = {
54 "Authentication failure",
59 "Authentication key not yet programmed",
63 /* Structure of RPMB data frame. */
65 unsigned char stuff[RPMB_SZ_STUFF];
66 unsigned char mac[RPMB_SZ_MAC];
67 unsigned char data[RPMB_SZ_DATA];
68 unsigned char nonce[RPMB_SZ_NONCE];
69 unsigned long write_counter;
70 unsigned short address;
71 unsigned short block_count;
72 unsigned short result;
73 unsigned short request;
76 static int mmc_set_blockcount(struct mmc *mmc, unsigned int blockcount,
79 struct mmc_cmd cmd = {0};
81 cmd.cmdidx = MMC_CMD_SET_BLOCK_COUNT;
82 cmd.cmdarg = blockcount & 0x0000FFFF;
84 cmd.cmdarg |= 1 << 31;
85 cmd.resp_type = MMC_RSP_R1;
87 return mmc_send_cmd(mmc, &cmd, NULL);
89 static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s,
90 unsigned int count, bool is_rel_write)
92 struct mmc_cmd cmd = {0};
96 ret = mmc_set_blockcount(mmc, count, is_rel_write);
98 #ifdef CONFIG_MMC_RPMB_TRACE
99 printf("%s:mmc_set_blockcount-> %d\n", __func__, ret);
104 cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
106 cmd.resp_type = MMC_RSP_R1b;
108 data.src = (const char *)s;
110 data.blocksize = MMC_MAX_BLOCK_LEN;
111 data.flags = MMC_DATA_WRITE;
113 ret = mmc_send_cmd(mmc, &cmd, &data);
115 #ifdef CONFIG_MMC_RPMB_TRACE
116 printf("%s:mmc_send_cmd-> %d\n", __func__, ret);
122 static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s,
123 unsigned short expected)
125 struct mmc_cmd cmd = {0};
126 struct mmc_data data;
129 ret = mmc_set_blockcount(mmc, 1, false);
131 #ifdef CONFIG_MMC_RPMB_TRACE
132 printf("%s:mmc_set_blockcount-> %d\n", __func__, ret);
136 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
138 cmd.resp_type = MMC_RSP_R1;
140 data.dest = (char *)s;
142 data.blocksize = MMC_MAX_BLOCK_LEN;
143 data.flags = MMC_DATA_READ;
145 ret = mmc_send_cmd(mmc, &cmd, &data);
147 #ifdef CONFIG_MMC_RPMB_TRACE
148 printf("%s:mmc_send_cmd-> %d\n", __func__, ret);
152 /* Check the response and the status */
153 if (be16_to_cpu(s->request) != expected) {
154 #ifdef CONFIG_MMC_RPMB_TRACE
155 printf("%s:response= %x\n", __func__,
156 be16_to_cpu(s->request));
160 ret = be16_to_cpu(s->result);
162 printf("%s %s\n", rpmb_err_msg[ret & RPMB_ERR_MSK],
163 (ret & RPMB_ERR_CNT_EXPIRED) ?
164 "Write counter has expired" : "");
167 /* Return the status of the command */
170 static int mmc_rpmb_status(struct mmc *mmc, unsigned short expected)
172 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
174 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
175 rpmb_frame->request = cpu_to_be16(RPMB_REQ_STATUS);
176 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
179 /* Read the result */
180 return mmc_rpmb_response(mmc, rpmb_frame, expected);
182 static void rpmb_hmac(unsigned char *key, unsigned char *buff, int len,
183 unsigned char *output)
187 unsigned char k_ipad[SHA256_BLOCK_SIZE];
188 unsigned char k_opad[SHA256_BLOCK_SIZE];
192 /* According to RFC 4634, the HMAC transform looks like:
193 SHA(K XOR opad, SHA(K XOR ipad, text))
195 where K is an n byte key.
196 ipad is the byte 0x36 repeated blocksize times
197 opad is the byte 0x5c repeated blocksize times
198 and text is the data being protected.
201 for (i = 0; i < RPMB_SZ_MAC; i++) {
202 k_ipad[i] = key[i] ^ 0x36;
203 k_opad[i] = key[i] ^ 0x5c;
205 /* remaining pad bytes are '\0' XOR'd with ipad and opad values */
206 for ( ; i < SHA256_BLOCK_SIZE; i++) {
210 sha256_update(&ctx, k_ipad, SHA256_BLOCK_SIZE);
211 sha256_update(&ctx, buff, len);
212 sha256_finish(&ctx, output);
214 /* Init context for second pass */
217 /* start with outer pad */
218 sha256_update(&ctx, k_opad, SHA256_BLOCK_SIZE);
220 /* then results of 1st hash */
221 sha256_update(&ctx, output, RPMB_SZ_MAC);
223 /* finish up 2nd pass */
224 sha256_finish(&ctx, output);
226 int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *pcounter)
229 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
231 /* Fill the request */
232 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
233 rpmb_frame->request = cpu_to_be16(RPMB_REQ_WCOUNTER);
234 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
237 /* Read the result */
238 ret = mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_WCOUNTER);
242 *pcounter = be32_to_cpu(rpmb_frame->write_counter);
245 int mmc_rpmb_set_key(struct mmc *mmc, void *key)
247 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
248 /* Fill the request */
249 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
250 rpmb_frame->request = cpu_to_be16(RPMB_REQ_KEY);
251 memcpy(rpmb_frame->mac, key, RPMB_SZ_MAC);
253 if (mmc_rpmb_request(mmc, rpmb_frame, 1, true))
256 /* read the operation status */
257 return mmc_rpmb_status(mmc, RPMB_RESP_KEY);
259 int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk,
260 unsigned short cnt, unsigned char *key)
262 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
265 for (i = 0; i < cnt; i++) {
266 /* Fill the request */
267 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
268 rpmb_frame->address = cpu_to_be16(blk + i);
269 rpmb_frame->request = cpu_to_be16(RPMB_REQ_READ_DATA);
270 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
273 /* Read the result */
274 if (mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_READ_DATA))
277 /* Check the HMAC if key is provided */
279 unsigned char ret_hmac[RPMB_SZ_MAC];
281 rpmb_hmac(key, rpmb_frame->data, 284, ret_hmac);
282 if (memcmp(ret_hmac, rpmb_frame->mac, RPMB_SZ_MAC)) {
283 printf("MAC error on block #%d\n", i);
288 memcpy(addr + i * RPMB_SZ_DATA, rpmb_frame->data, RPMB_SZ_DATA);
292 int mmc_rpmb_write(struct mmc *mmc, void *addr, unsigned short blk,
293 unsigned short cnt, unsigned char *key)
295 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
296 unsigned long wcount;
299 for (i = 0; i < cnt; i++) {
300 if (mmc_rpmb_get_counter(mmc, &wcount)) {
301 printf("Cannot read RPMB write counter\n");
305 /* Fill the request */
306 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
307 memcpy(rpmb_frame->data, addr + i * RPMB_SZ_DATA, RPMB_SZ_DATA);
308 rpmb_frame->address = cpu_to_be16(blk + i);
309 rpmb_frame->block_count = cpu_to_be16(1);
310 rpmb_frame->write_counter = cpu_to_be32(wcount);
311 rpmb_frame->request = cpu_to_be16(RPMB_REQ_WRITE_DATA);
313 rpmb_hmac(key, rpmb_frame->data, 284, rpmb_frame->mac);
315 if (mmc_rpmb_request(mmc, rpmb_frame, 1, true))
319 if (mmc_rpmb_status(mmc, RPMB_RESP_WRITE_DATA))