Loading trusty/storage/proxy/proxy.c +25 −3 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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); Loading Loading @@ -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 */ Loading trusty/storage/proxy/rpmb.c +89 −36 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading @@ -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) { Loading trusty/storage/proxy/rpmb.h +3 −1 Original line number Diff line number Diff line Loading @@ -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
trusty/storage/proxy/proxy.c +25 −3 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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); Loading Loading @@ -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 */ Loading
trusty/storage/proxy/rpmb.c +89 −36 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading @@ -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) { Loading
trusty/storage/proxy/rpmb.h +3 −1 Original line number Diff line number Diff line Loading @@ -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);