Lines Matching +full:mmc +full:-
1 // SPDX-License-Identifier: GPL-2.0+
6 * eMMC- Replay Protected Memory Block
7 * According to JEDEC Standard No. 84-A441
13 #include <mmc.h>
14 #include <u-boot/sha256.h>
76 static int mmc_set_blockcount(struct mmc *mmc, unsigned int blockcount, in mmc_set_blockcount() argument
87 return mmc_send_cmd(mmc, &cmd, NULL); in mmc_set_blockcount()
89 static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s, in mmc_rpmb_request() argument
96 ret = mmc_set_blockcount(mmc, count, is_rel_write); in mmc_rpmb_request()
99 printf("%s:mmc_set_blockcount-> %d\n", __func__, ret); in mmc_rpmb_request()
113 ret = mmc_send_cmd(mmc, &cmd, &data); in mmc_rpmb_request()
116 printf("%s:mmc_send_cmd-> %d\n", __func__, ret); in mmc_rpmb_request()
122 static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s, in mmc_rpmb_response() argument
129 ret = mmc_set_blockcount(mmc, 1, false); in mmc_rpmb_response()
132 printf("%s:mmc_set_blockcount-> %d\n", __func__, ret); in mmc_rpmb_response()
134 return -1; in mmc_rpmb_response()
145 ret = mmc_send_cmd(mmc, &cmd, &data); in mmc_rpmb_response()
148 printf("%s:mmc_send_cmd-> %d\n", __func__, ret); in mmc_rpmb_response()
150 return -1; in mmc_rpmb_response()
153 if (be16_to_cpu(s->request) != expected) { in mmc_rpmb_response()
156 be16_to_cpu(s->request)); in mmc_rpmb_response()
158 return -1; in mmc_rpmb_response()
160 ret = be16_to_cpu(s->result); in mmc_rpmb_response()
170 static int mmc_rpmb_status(struct mmc *mmc, unsigned short expected) in mmc_rpmb_status() argument
175 rpmb_frame->request = cpu_to_be16(RPMB_REQ_STATUS); in mmc_rpmb_status()
176 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false)) in mmc_rpmb_status()
177 return -1; in mmc_rpmb_status()
180 return mmc_rpmb_response(mmc, rpmb_frame, expected); in mmc_rpmb_status()
226 int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *pcounter) in mmc_rpmb_get_counter() argument
233 rpmb_frame->request = cpu_to_be16(RPMB_REQ_WCOUNTER); in mmc_rpmb_get_counter()
234 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false)) in mmc_rpmb_get_counter()
235 return -1; in mmc_rpmb_get_counter()
238 ret = mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_WCOUNTER); in mmc_rpmb_get_counter()
242 *pcounter = be32_to_cpu(rpmb_frame->write_counter); in mmc_rpmb_get_counter()
245 int mmc_rpmb_set_key(struct mmc *mmc, void *key) in mmc_rpmb_set_key() argument
250 rpmb_frame->request = cpu_to_be16(RPMB_REQ_KEY); in mmc_rpmb_set_key()
251 memcpy(rpmb_frame->mac, key, RPMB_SZ_MAC); in mmc_rpmb_set_key()
253 if (mmc_rpmb_request(mmc, rpmb_frame, 1, true)) in mmc_rpmb_set_key()
254 return -1; in mmc_rpmb_set_key()
257 return mmc_rpmb_status(mmc, RPMB_RESP_KEY); in mmc_rpmb_set_key()
259 int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk, in mmc_rpmb_read() argument
268 rpmb_frame->address = cpu_to_be16(blk + i); in mmc_rpmb_read()
269 rpmb_frame->request = cpu_to_be16(RPMB_REQ_READ_DATA); in mmc_rpmb_read()
270 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false)) in mmc_rpmb_read()
274 if (mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_READ_DATA)) in mmc_rpmb_read()
281 rpmb_hmac(key, rpmb_frame->data, 284, ret_hmac); in mmc_rpmb_read()
282 if (memcmp(ret_hmac, rpmb_frame->mac, RPMB_SZ_MAC)) { in mmc_rpmb_read()
288 memcpy(addr + i * RPMB_SZ_DATA, rpmb_frame->data, RPMB_SZ_DATA); in mmc_rpmb_read()
292 int mmc_rpmb_write(struct mmc *mmc, void *addr, unsigned short blk, in mmc_rpmb_write() argument
300 if (mmc_rpmb_get_counter(mmc, &wcount)) { in mmc_rpmb_write()
307 memcpy(rpmb_frame->data, addr + i * RPMB_SZ_DATA, RPMB_SZ_DATA); in mmc_rpmb_write()
308 rpmb_frame->address = cpu_to_be16(blk + i); in mmc_rpmb_write()
309 rpmb_frame->block_count = cpu_to_be16(1); in mmc_rpmb_write()
310 rpmb_frame->write_counter = cpu_to_be32(wcount); in mmc_rpmb_write()
311 rpmb_frame->request = cpu_to_be16(RPMB_REQ_WRITE_DATA); in mmc_rpmb_write()
313 rpmb_hmac(key, rpmb_frame->data, 284, rpmb_frame->mac); in mmc_rpmb_write()
315 if (mmc_rpmb_request(mmc, rpmb_frame, 1, true)) in mmc_rpmb_write()
319 if (mmc_rpmb_status(mmc, RPMB_RESP_WRITE_DATA)) in mmc_rpmb_write()
325 static int send_write_mult_block(struct mmc *mmc, const struct s_rpmb *frm, in send_write_mult_block() argument
339 return mmc_send_cmd(mmc, &cmd, &data); in send_write_mult_block()
342 static int send_read_mult_block(struct mmc *mmc, struct s_rpmb *frm, in send_read_mult_block() argument
356 return mmc_send_cmd(mmc, &cmd, &data); in send_read_mult_block()
359 static int rpmb_route_write_req(struct mmc *mmc, struct s_rpmb *req, in rpmb_route_write_req() argument
368 ret = mmc_set_blockcount(mmc, req_cnt, true); in rpmb_route_write_req()
372 ret = send_write_mult_block(mmc, req, req_cnt); in rpmb_route_write_req()
379 ret = mmc_set_blockcount(mmc, 1, false); in rpmb_route_write_req()
384 rsp->request = cpu_to_be16(RPMB_REQ_STATUS); in rpmb_route_write_req()
385 ret = send_write_mult_block(mmc, rsp, 1); in rpmb_route_write_req()
389 ret = mmc_set_blockcount(mmc, 1, false); in rpmb_route_write_req()
393 return send_read_mult_block(mmc, rsp, 1); in rpmb_route_write_req()
396 static int rpmb_route_read_req(struct mmc *mmc, struct s_rpmb *req, in rpmb_route_read_req() argument
405 ret = mmc_set_blockcount(mmc, 1, false); in rpmb_route_read_req()
409 ret = send_write_mult_block(mmc, req, 1); in rpmb_route_read_req()
417 ret = mmc_set_blockcount(mmc, rsp_cnt, false); in rpmb_route_read_req()
421 return send_read_mult_block(mmc, rsp, rsp_cnt); in rpmb_route_read_req()
424 static int rpmb_route_frames(struct mmc *mmc, struct s_rpmb *req, in rpmb_route_frames() argument
435 if (req[n].request != req->request) in rpmb_route_frames()
436 return -EINVAL; in rpmb_route_frames()
438 switch (be16_to_cpu(req->request)) { in rpmb_route_frames()
441 return -EINVAL; in rpmb_route_frames()
442 return rpmb_route_write_req(mmc, req, req_cnt, rsp, rsp_cnt); in rpmb_route_frames()
446 return -EINVAL; in rpmb_route_frames()
447 return rpmb_route_write_req(mmc, req, req_cnt, rsp, rsp_cnt); in rpmb_route_frames()
451 return -EINVAL; in rpmb_route_frames()
452 return rpmb_route_read_req(mmc, req, req_cnt, rsp, rsp_cnt); in rpmb_route_frames()
456 return -EINVAL; in rpmb_route_frames()
457 return rpmb_route_read_req(mmc, req, req_cnt, rsp, rsp_cnt); in rpmb_route_frames()
461 be16_to_cpu(req->request)); in rpmb_route_frames()
462 return -EINVAL; in rpmb_route_frames()
466 int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen, in mmc_rpmb_route_frames() argument
479 return -EINVAL; in mmc_rpmb_route_frames()
481 return rpmb_route_frames(mmc, req, reqlen / sizeof(struct s_rpmb), in mmc_rpmb_route_frames()