#define RPMB_ERR_CNT_EXPIRED 0x80
#define RPMB_ERR_MSK 0x7
-/* Sizes of RPMB data frame */
-#define RPMB_SZ_STUFF 196
-#define RPMB_SZ_MAC 32
-#define RPMB_SZ_DATA 256
-#define RPMB_SZ_NONCE 16
-
#define SHA256_BLOCK_SIZE 64
/* Error messages */
"Authentication key not yet programmed",
};
-
-/* Structure of RPMB data frame. */
-struct s_rpmb {
- unsigned char stuff[RPMB_SZ_STUFF];
- unsigned char mac[RPMB_SZ_MAC];
- unsigned char data[RPMB_SZ_DATA];
- unsigned char nonce[RPMB_SZ_NONCE];
- unsigned int write_counter;
- unsigned short address;
- unsigned short block_count;
- unsigned short result;
- unsigned short request;
-};
-
static int mmc_set_blockcount(struct mmc *mmc, unsigned int blockcount,
bool is_rel_write)
{
return mmc_send_cmd(mmc, &cmd, NULL);
}
-static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s,
+int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s,
unsigned int count, bool is_rel_write)
{
struct mmc_cmd cmd = {0};
cmd.resp_type = MMC_RSP_R1b;
data.src = (const char *)s;
- data.blocks = 1;
+ data.blocks = count;
data.blocksize = MMC_MAX_BLOCK_LEN;
data.flags = MMC_DATA_WRITE;
}
return 0;
}
-static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s,
- unsigned short expected)
+int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s,
+ unsigned int count, unsigned short expected)
{
struct mmc_cmd cmd = {0};
struct mmc_data data;
int ret;
- ret = mmc_set_blockcount(mmc, 1, false);
+ ret = mmc_set_blockcount(mmc, count, false);
if (ret) {
#ifdef CONFIG_MMC_RPMB_TRACE
printf("%s:mmc_set_blockcount-> %d\n", __func__, ret);
cmd.resp_type = MMC_RSP_R1;
data.dest = (char *)s;
- data.blocks = 1;
+ data.blocks = count;
data.blocksize = MMC_MAX_BLOCK_LEN;
data.flags = MMC_DATA_READ;
return -1;
}
/* Check the response and the status */
- if (be16_to_cpu(s->request) != expected) {
+ if (expected && be16_to_cpu(s->request) != expected) {
#ifdef CONFIG_MMC_RPMB_TRACE
printf("%s:response= %x\n", __func__,
be16_to_cpu(s->request));
return -1;
/* Read the result */
- return mmc_rpmb_response(mmc, rpmb_frame, expected);
+ return mmc_rpmb_response(mmc, rpmb_frame, 1, expected);
}
static void rpmb_hmac(unsigned char *key, unsigned char *buff, int len,
unsigned char *output)
return -1;
/* Read the result */
- ret = mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_WCOUNTER);
+ ret = mmc_rpmb_response(mmc, rpmb_frame, 1, RPMB_RESP_WCOUNTER);
if (ret)
return ret;
break;
/* Read the result */
- if (mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_READ_DATA))
+ if (mmc_rpmb_response(mmc, rpmb_frame, 1, RPMB_RESP_READ_DATA))
break;
/* Check the HMAC if key is provided */
/* Function to modify the RST_n_FUNCTION field of EXT_CSD */
int mmc_set_rst_n_function(struct mmc *mmc, u8 enable);
/* Functions to read / write the RPMB partition */
+/* Sizes of RPMB data frame */
+#define RPMB_SZ_STUFF 196
+#define RPMB_SZ_MAC 32
+#define RPMB_SZ_DATA 256
+#define RPMB_SZ_NONCE 16
+
+/* Structure of RPMB data frame. */
+struct s_rpmb {
+ unsigned char stuff[RPMB_SZ_STUFF];
+ unsigned char mac[RPMB_SZ_MAC];
+ unsigned char data[RPMB_SZ_DATA];
+ unsigned char nonce[RPMB_SZ_NONCE];
+ unsigned long write_counter;
+ unsigned short address;
+ unsigned short block_count;
+ unsigned short result;
+ unsigned short request;
+};
int mmc_rpmb_set_key(struct mmc *mmc, void *key);
int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *counter);
int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk,
int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen,
void *rsp, unsigned long rsplen);
+int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s,
+ unsigned int count, bool is_rel_write);
+int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s,
+ unsigned int count, unsigned short expected);
+
#ifdef CONFIG_CMD_BKOPS_ENABLE
int mmc_set_bkops_enable(struct mmc *mmc);
#endif