Merge "Add support for RPMB over VirtIO Serial"
This commit is contained in:
commit
2ba61b775a
3 changed files with 117 additions and 40 deletions
|
@ -39,15 +39,29 @@ static const char* trusty_devname;
|
|||
static const char* rpmb_devname;
|
||||
static const char* ss_srv_name = STORAGE_DISK_PROXY_PORT;
|
||||
|
||||
static const char* _sopts = "hp:d:r:";
|
||||
static enum dev_type dev_type = MMC_RPMB;
|
||||
|
||||
static enum dev_type parse_dev_type(const char* dev_type_name) {
|
||||
if (!strcmp(dev_type_name, "mmc")) {
|
||||
return MMC_RPMB;
|
||||
} else if (!strcmp(dev_type_name, "virt")) {
|
||||
return VIRT_RPMB;
|
||||
} else {
|
||||
return UNKNOWN_RPMB;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* _sopts = "hp:d:r:t:";
|
||||
static const struct option _lopts[] = {{"help", no_argument, NULL, 'h'},
|
||||
{"trusty_dev", required_argument, NULL, 'd'},
|
||||
{"data_path", required_argument, NULL, 'p'},
|
||||
{"rpmb_dev", required_argument, NULL, 'r'},
|
||||
{"dev_type", required_argument, NULL, 't'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
static void show_usage_and_exit(int code) {
|
||||
ALOGE("usage: storageproxyd -d <trusty_dev> -p <data_path> -r <rpmb_dev>\n");
|
||||
ALOGE("usage: storageproxyd -d <trusty_dev> -p <data_path> -r <rpmb_dev> -t <dev_type>\n");
|
||||
ALOGE("Available dev types: mmc, virt\n");
|
||||
exit(code);
|
||||
}
|
||||
|
||||
|
@ -195,6 +209,14 @@ static void parse_args(int argc, char* argv[]) {
|
|||
rpmb_devname = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
dev_type = parse_dev_type(optarg);
|
||||
if (dev_type == UNKNOWN_RPMB) {
|
||||
ALOGE("Unrecognized dev type: %s\n", optarg);
|
||||
show_usage_and_exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ALOGE("unrecognized option (%c):\n", opt);
|
||||
show_usage_and_exit(EXIT_FAILURE);
|
||||
|
@ -226,7 +248,7 @@ int main(int argc, char* argv[]) {
|
|||
if (rc < 0) return EXIT_FAILURE;
|
||||
|
||||
/* open rpmb device */
|
||||
rc = rpmb_open(rpmb_devname);
|
||||
rc = rpmb_open(rpmb_devname, dev_type);
|
||||
if (rc < 0) return EXIT_FAILURE;
|
||||
|
||||
/* connect to Trusty secure storage server */
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
static int rpmb_fd = -1;
|
||||
static uint8_t read_buf[4096];
|
||||
static enum dev_type dev_type = UNKNOWN_RPMB;
|
||||
|
||||
#ifdef RPMB_DEBUG
|
||||
|
||||
|
@ -68,36 +69,16 @@ static void print_buf(const char* prefix, const uint8_t* buf, size_t size) {
|
|||
|
||||
#endif
|
||||
|
||||
int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len) {
|
||||
int rc;
|
||||
static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req) {
|
||||
struct {
|
||||
struct mmc_ioc_multi_cmd multi;
|
||||
struct mmc_ioc_cmd cmd_buf[3];
|
||||
} mmc = {};
|
||||
struct mmc_ioc_cmd* cmd = mmc.multi.cmds;
|
||||
const struct storage_rpmb_send_req* req = r;
|
||||
|
||||
if (req_len < sizeof(*req)) {
|
||||
ALOGW("malformed rpmb request: invalid length (%zu < %zu)\n", req_len, sizeof(*req));
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
size_t expected_len = sizeof(*req) + req->reliable_write_size + req->write_size;
|
||||
if (req_len != expected_len) {
|
||||
ALOGW("malformed rpmb request: invalid length (%zu != %zu)\n", req_len, expected_len);
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
int rc;
|
||||
|
||||
const uint8_t* write_buf = req->payload;
|
||||
if (req->reliable_write_size) {
|
||||
if ((req->reliable_write_size % MMC_BLOCK_SIZE) != 0) {
|
||||
ALOGW("invalid reliable write size %u\n", req->reliable_write_size);
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
cmd->write_flag = MMC_WRITE_FLAG_RELW;
|
||||
cmd->opcode = MMC_WRITE_MULTIPLE_BLOCK;
|
||||
cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
|
||||
|
@ -114,12 +95,6 @@ int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len) {
|
|||
}
|
||||
|
||||
if (req->write_size) {
|
||||
if ((req->write_size % MMC_BLOCK_SIZE) != 0) {
|
||||
ALOGW("invalid write size %u\n", req->write_size);
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
cmd->write_flag = MMC_WRITE_FLAG_W;
|
||||
cmd->opcode = MMC_WRITE_MULTIPLE_BLOCK;
|
||||
cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
|
||||
|
@ -136,12 +111,6 @@ int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len) {
|
|||
}
|
||||
|
||||
if (req->read_size) {
|
||||
if (req->read_size % MMC_BLOCK_SIZE != 0 || req->read_size > sizeof(read_buf)) {
|
||||
ALOGE("%s: invalid read size %u\n", __func__, req->read_size);
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
cmd->write_flag = MMC_WRITE_FLAG_R;
|
||||
cmd->opcode = MMC_READ_MULTIPLE_BLOCK;
|
||||
cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC, cmd->blksz = MMC_BLOCK_SIZE;
|
||||
|
@ -154,9 +123,92 @@ int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len) {
|
|||
cmd++;
|
||||
}
|
||||
|
||||
rc = ioctl(rpmb_fd, MMC_IOC_MULTI_CMD, &mmc.multi);
|
||||
rc = ioctl(mmc_fd, MMC_IOC_MULTI_CMD, &mmc.multi);
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: mmc ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int send_virt_rpmb_req(int rpmb_fd, void* read_buf, size_t read_size, const void* payload,
|
||||
size_t payload_size) {
|
||||
int rc;
|
||||
uint16_t res_count = read_size / MMC_BLOCK_SIZE;
|
||||
uint16_t cmd_count = payload_size / MMC_BLOCK_SIZE;
|
||||
rc = write(rpmb_fd, &res_count, sizeof(res_count));
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
rc = write(rpmb_fd, &cmd_count, sizeof(cmd_count));
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
rc = write(rpmb_fd, payload, payload_size);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
rc = read(rpmb_fd, read_buf, read_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len) {
|
||||
int rc;
|
||||
const struct storage_rpmb_send_req* req = r;
|
||||
|
||||
if (req_len < sizeof(*req)) {
|
||||
ALOGW("malformed rpmb request: invalid length (%zu < %zu)\n", req_len, sizeof(*req));
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
size_t expected_len = sizeof(*req) + req->reliable_write_size + req->write_size;
|
||||
if (req_len != expected_len) {
|
||||
ALOGW("malformed rpmb request: invalid length (%zu != %zu)\n", req_len, expected_len);
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
if ((req->reliable_write_size % MMC_BLOCK_SIZE) != 0) {
|
||||
ALOGW("invalid reliable write size %u\n", req->reliable_write_size);
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
if ((req->write_size % MMC_BLOCK_SIZE) != 0) {
|
||||
ALOGW("invalid write size %u\n", req->write_size);
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
if (req->read_size % MMC_BLOCK_SIZE != 0 || req->read_size > sizeof(read_buf)) {
|
||||
ALOGE("%s: invalid read size %u\n", __func__, req->read_size);
|
||||
msg->result = STORAGE_ERR_NOT_VALID;
|
||||
goto err_response;
|
||||
}
|
||||
|
||||
if (dev_type == MMC_RPMB) {
|
||||
rc = send_mmc_rpmb_req(rpmb_fd, req);
|
||||
if (rc < 0) {
|
||||
msg->result = STORAGE_ERR_GENERIC;
|
||||
goto err_response;
|
||||
}
|
||||
} else if (dev_type == VIRT_RPMB) {
|
||||
size_t payload_size = req->reliable_write_size + req->write_size;
|
||||
rc = send_virt_rpmb_req(rpmb_fd, read_buf, req->read_size, req->payload, payload_size);
|
||||
if (rc < 0) {
|
||||
ALOGE("send_virt_rpmb_req failed: %d, %s\n", rc, strerror(errno));
|
||||
msg->result = STORAGE_ERR_GENERIC;
|
||||
goto err_response;
|
||||
}
|
||||
if (rc != req->read_size) {
|
||||
ALOGE("send_virt_rpmb_req got incomplete response: "
|
||||
"(size %d, expected %d)\n",
|
||||
rc, req->read_size);
|
||||
msg->result = STORAGE_ERR_GENERIC;
|
||||
goto err_response;
|
||||
}
|
||||
} else {
|
||||
ALOGE("Unsupported dev_type\n");
|
||||
msg->result = STORAGE_ERR_GENERIC;
|
||||
goto err_response;
|
||||
}
|
||||
|
@ -178,8 +230,9 @@ err_response:
|
|||
return ipc_respond(msg, NULL, 0);
|
||||
}
|
||||
|
||||
int rpmb_open(const char* rpmb_devname) {
|
||||
int rpmb_open(const char* rpmb_devname, enum dev_type open_dev_type) {
|
||||
int rc;
|
||||
dev_type = open_dev_type;
|
||||
|
||||
rc = open(rpmb_devname, O_RDWR, 0);
|
||||
if (rc < 0) {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <stdint.h>
|
||||
#include <trusty/interface/storage.h>
|
||||
|
||||
int rpmb_open(const char* rpmb_devname);
|
||||
enum dev_type { UNKNOWN_RPMB, MMC_RPMB, VIRT_RPMB };
|
||||
|
||||
int rpmb_open(const char* rpmb_devname, enum dev_type dev_type);
|
||||
int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len);
|
||||
void rpmb_close(void);
|
||||
|
|
Loading…
Reference in a new issue