Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e683ff9 authored by Matthew Maurer's avatar Matthew Maurer Committed by android-build-merger
Browse files

Merge "Add support for RPMB over VirtIO Serial"

am: 2ba61b77

Change-Id: If61a57f22b1a649cc158448dde205be452477166
parents d7b62eb7 2ba61b77
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -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 */
+89 −36
Original line number Diff line number Diff line
@@ -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) {
+3 −1
Original line number Diff line number Diff line
@@ -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);