1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2014, Staubli Faverges
6 * eMMC- Replay Protected Memory Block
7 * According to JEDEC Standard No. 84-A441
14 #include <u-boot/sha256.h>
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 int 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_R1;
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))
325 static int send_write_mult_block(struct mmc *mmc, const struct s_rpmb *frm,
328 struct mmc_cmd cmd = {
329 .cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK,
330 .resp_type = MMC_RSP_R1,
332 struct mmc_data data = {
333 .src = (const void *)frm,
335 .blocksize = sizeof(*frm),
336 .flags = MMC_DATA_WRITE,
339 return mmc_send_cmd(mmc, &cmd, &data);
342 static int send_read_mult_block(struct mmc *mmc, struct s_rpmb *frm,
345 struct mmc_cmd cmd = {
346 .cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK,
347 .resp_type = MMC_RSP_R1,
349 struct mmc_data data = {
352 .blocksize = sizeof(*frm),
353 .flags = MMC_DATA_READ,
356 return mmc_send_cmd(mmc, &cmd, &data);
359 static int rpmb_route_write_req(struct mmc *mmc, struct s_rpmb *req,
360 unsigned short req_cnt, struct s_rpmb *rsp,
361 unsigned short rsp_cnt)
366 * Send the write request.
368 ret = mmc_set_blockcount(mmc, req_cnt, true);
372 ret = send_write_mult_block(mmc, req, req_cnt);
377 * Read the result of the request.
379 ret = mmc_set_blockcount(mmc, 1, false);
383 memset(rsp, 0, sizeof(*rsp));
384 rsp->request = cpu_to_be16(RPMB_REQ_STATUS);
385 ret = send_write_mult_block(mmc, rsp, 1);
389 ret = mmc_set_blockcount(mmc, 1, false);
393 return send_read_mult_block(mmc, rsp, 1);
396 static int rpmb_route_read_req(struct mmc *mmc, struct s_rpmb *req,
397 unsigned short req_cnt, struct s_rpmb *rsp,
398 unsigned short rsp_cnt)
403 * Send the read request.
405 ret = mmc_set_blockcount(mmc, 1, false);
409 ret = send_write_mult_block(mmc, req, 1);
414 * Read the result of the request.
417 ret = mmc_set_blockcount(mmc, rsp_cnt, false);
421 return send_read_mult_block(mmc, rsp, rsp_cnt);
424 static int rpmb_route_frames(struct mmc *mmc, struct s_rpmb *req,
425 unsigned short req_cnt, struct s_rpmb *rsp,
426 unsigned short rsp_cnt)
431 * If multiple request frames are provided, make sure that all are
434 for (n = 1; n < req_cnt; n++)
435 if (req[n].request != req->request)
438 switch (be16_to_cpu(req->request)) {
440 if (req_cnt != 1 || rsp_cnt != 1)
442 return rpmb_route_write_req(mmc, req, req_cnt, rsp, rsp_cnt);
444 case RPMB_REQ_WRITE_DATA:
445 if (!req_cnt || rsp_cnt != 1)
447 return rpmb_route_write_req(mmc, req, req_cnt, rsp, rsp_cnt);
449 case RPMB_REQ_WCOUNTER:
450 if (req_cnt != 1 || rsp_cnt != 1)
452 return rpmb_route_read_req(mmc, req, req_cnt, rsp, rsp_cnt);
454 case RPMB_REQ_READ_DATA:
455 if (req_cnt != 1 || !req_cnt)
457 return rpmb_route_read_req(mmc, req, req_cnt, rsp, rsp_cnt);
460 debug("Unsupported message type: %d\n",
461 be16_to_cpu(req->request));
466 int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen,
467 void *rsp, unsigned long rsplen)
470 * Whoever crafted the data supplied to this function knows how to
471 * format the PRMB frames and which response is expected. If
472 * there's some unexpected mismatch it's more helpful to report an
473 * error immediately than trying to guess what was the intention
474 * and possibly just delay an eventual error which will be harder
478 if (reqlen % sizeof(struct s_rpmb) || rsplen % sizeof(struct s_rpmb))
481 return rpmb_route_frames(mmc, req, reqlen / sizeof(struct s_rpmb),
482 rsp, rsplen / sizeof(struct s_rpmb));