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 <u-boot/sha256.h>
16 #include "mmc_private.h"
19 #define RPMB_REQ_KEY 1
20 #define RPMB_REQ_WCOUNTER 2
21 #define RPMB_REQ_WRITE_DATA 3
22 #define RPMB_REQ_READ_DATA 4
23 #define RPMB_REQ_STATUS 5
26 #define RPMB_RESP_KEY 0x0100
27 #define RPMB_RESP_WCOUNTER 0x0200
28 #define RPMB_RESP_WRITE_DATA 0x0300
29 #define RPMB_RESP_READ_DATA 0x0400
33 #define RPMB_ERR_GENERAL 1
34 #define RPMB_ERR_AUTH 2
35 #define RPMB_ERR_COUNTER 3
36 #define RPMB_ERR_ADDRESS 4
37 #define RPMB_ERR_WRITE 5
38 #define RPMB_ERR_READ 6
39 #define RPMB_ERR_KEY 7
40 #define RPMB_ERR_CNT_EXPIRED 0x80
41 #define RPMB_ERR_MSK 0x7
43 /* Sizes of RPMB data frame */
44 #define RPMB_SZ_STUFF 196
45 #define RPMB_SZ_MAC 32
46 #define RPMB_SZ_DATA 256
47 #define RPMB_SZ_NONCE 16
49 #define SHA256_BLOCK_SIZE 64
52 static const char * const rpmb_err_msg[] = {
55 "Authentication failure",
60 "Authentication key not yet programmed",
64 /* Structure of RPMB data frame. */
66 unsigned char stuff[RPMB_SZ_STUFF];
67 unsigned char mac[RPMB_SZ_MAC];
68 unsigned char data[RPMB_SZ_DATA];
69 unsigned char nonce[RPMB_SZ_NONCE];
70 unsigned int write_counter;
71 unsigned short address;
72 unsigned short block_count;
73 unsigned short result;
74 unsigned short request;
77 static int mmc_set_blockcount(struct mmc *mmc, unsigned int blockcount,
80 struct mmc_cmd cmd = {0};
82 cmd.cmdidx = MMC_CMD_SET_BLOCK_COUNT;
83 cmd.cmdarg = blockcount & 0x0000FFFF;
85 cmd.cmdarg |= 1 << 31;
86 cmd.resp_type = MMC_RSP_R1;
88 return mmc_send_cmd(mmc, &cmd, NULL);
90 static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s,
91 unsigned int count, bool is_rel_write)
93 struct mmc_cmd cmd = {0};
97 ret = mmc_set_blockcount(mmc, count, is_rel_write);
99 #ifdef CONFIG_MMC_RPMB_TRACE
100 printf("%s:mmc_set_blockcount-> %d\n", __func__, ret);
105 cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
107 cmd.resp_type = MMC_RSP_R1b;
109 data.src = (const char *)s;
111 data.blocksize = MMC_MAX_BLOCK_LEN;
112 data.flags = MMC_DATA_WRITE;
114 ret = mmc_send_cmd(mmc, &cmd, &data);
116 #ifdef CONFIG_MMC_RPMB_TRACE
117 printf("%s:mmc_send_cmd-> %d\n", __func__, ret);
123 static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s,
124 unsigned short expected)
126 struct mmc_cmd cmd = {0};
127 struct mmc_data data;
130 ret = mmc_set_blockcount(mmc, 1, false);
132 #ifdef CONFIG_MMC_RPMB_TRACE
133 printf("%s:mmc_set_blockcount-> %d\n", __func__, ret);
137 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
139 cmd.resp_type = MMC_RSP_R1;
141 data.dest = (char *)s;
143 data.blocksize = MMC_MAX_BLOCK_LEN;
144 data.flags = MMC_DATA_READ;
146 ret = mmc_send_cmd(mmc, &cmd, &data);
148 #ifdef CONFIG_MMC_RPMB_TRACE
149 printf("%s:mmc_send_cmd-> %d\n", __func__, ret);
153 /* Check the response and the status */
154 if (be16_to_cpu(s->request) != expected) {
155 #ifdef CONFIG_MMC_RPMB_TRACE
156 printf("%s:response= %x\n", __func__,
157 be16_to_cpu(s->request));
161 ret = be16_to_cpu(s->result);
163 printf("%s %s\n", rpmb_err_msg[ret & RPMB_ERR_MSK],
164 (ret & RPMB_ERR_CNT_EXPIRED) ?
165 "Write counter has expired" : "");
168 /* Return the status of the command */
171 static int mmc_rpmb_status(struct mmc *mmc, unsigned short expected)
173 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
175 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
176 rpmb_frame->request = cpu_to_be16(RPMB_REQ_STATUS);
177 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
180 /* Read the result */
181 return mmc_rpmb_response(mmc, rpmb_frame, expected);
183 static void rpmb_hmac(unsigned char *key, unsigned char *buff, int len,
184 unsigned char *output)
188 unsigned char k_ipad[SHA256_BLOCK_SIZE];
189 unsigned char k_opad[SHA256_BLOCK_SIZE];
193 /* According to RFC 4634, the HMAC transform looks like:
194 SHA(K XOR opad, SHA(K XOR ipad, text))
196 where K is an n byte key.
197 ipad is the byte 0x36 repeated blocksize times
198 opad is the byte 0x5c repeated blocksize times
199 and text is the data being protected.
202 for (i = 0; i < RPMB_SZ_MAC; i++) {
203 k_ipad[i] = key[i] ^ 0x36;
204 k_opad[i] = key[i] ^ 0x5c;
206 /* remaining pad bytes are '\0' XOR'd with ipad and opad values */
207 for ( ; i < SHA256_BLOCK_SIZE; i++) {
211 sha256_update(&ctx, k_ipad, SHA256_BLOCK_SIZE);
212 sha256_update(&ctx, buff, len);
213 sha256_finish(&ctx, output);
215 /* Init context for second pass */
218 /* start with outer pad */
219 sha256_update(&ctx, k_opad, SHA256_BLOCK_SIZE);
221 /* then results of 1st hash */
222 sha256_update(&ctx, output, RPMB_SZ_MAC);
224 /* finish up 2nd pass */
225 sha256_finish(&ctx, output);
227 int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *pcounter)
230 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
232 /* Fill the request */
233 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
234 rpmb_frame->request = cpu_to_be16(RPMB_REQ_WCOUNTER);
235 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
238 /* Read the result */
239 ret = mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_WCOUNTER);
243 *pcounter = be32_to_cpu(rpmb_frame->write_counter);
246 int mmc_rpmb_set_key(struct mmc *mmc, void *key)
248 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
249 /* Fill the request */
250 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
251 rpmb_frame->request = cpu_to_be16(RPMB_REQ_KEY);
252 memcpy(rpmb_frame->mac, key, RPMB_SZ_MAC);
254 if (mmc_rpmb_request(mmc, rpmb_frame, 1, true))
257 /* read the operation status */
258 return mmc_rpmb_status(mmc, RPMB_RESP_KEY);
260 int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk,
261 unsigned short cnt, unsigned char *key)
263 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
266 for (i = 0; i < cnt; i++) {
267 /* Fill the request */
268 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
269 rpmb_frame->address = cpu_to_be16(blk + i);
270 rpmb_frame->request = cpu_to_be16(RPMB_REQ_READ_DATA);
271 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
274 /* Read the result */
275 if (mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_READ_DATA))
278 /* Check the HMAC if key is provided */
280 unsigned char ret_hmac[RPMB_SZ_MAC];
282 rpmb_hmac(key, rpmb_frame->data, 284, ret_hmac);
283 if (memcmp(ret_hmac, rpmb_frame->mac, RPMB_SZ_MAC)) {
284 printf("MAC error on block #%d\n", i);
289 memcpy(addr + i * RPMB_SZ_DATA, rpmb_frame->data, RPMB_SZ_DATA);
293 int mmc_rpmb_write(struct mmc *mmc, void *addr, unsigned short blk,
294 unsigned short cnt, unsigned char *key)
296 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
297 unsigned long wcount;
300 for (i = 0; i < cnt; i++) {
301 if (mmc_rpmb_get_counter(mmc, &wcount)) {
302 printf("Cannot read RPMB write counter\n");
306 /* Fill the request */
307 memset(rpmb_frame, 0, sizeof(struct s_rpmb));
308 memcpy(rpmb_frame->data, addr + i * RPMB_SZ_DATA, RPMB_SZ_DATA);
309 rpmb_frame->address = cpu_to_be16(blk + i);
310 rpmb_frame->block_count = cpu_to_be16(1);
311 rpmb_frame->write_counter = cpu_to_be32(wcount);
312 rpmb_frame->request = cpu_to_be16(RPMB_REQ_WRITE_DATA);
314 rpmb_hmac(key, rpmb_frame->data, 284, rpmb_frame->mac);
316 if (mmc_rpmb_request(mmc, rpmb_frame, 1, true))
320 if (mmc_rpmb_status(mmc, RPMB_RESP_WRITE_DATA))