The SDM firmware is able to verify a certificate in the proprietary certificate format against the programmed root key.
Add a wrapper function for the MBOX_VAB_SRC_CERT mailbox command to be able to verify a certificate more easily. Note that the certificate has to be passed in a slighly different format than what is produced by the signing tools provided by Altera. Signed-off-by: Michael Tretter <[email protected]> --- arch/arm/mach-socfpga/mailbox_s10.c | 53 +++++++++++++++++++++++++++++++++++++ include/mach/socfpga/mailbox_s10.h | 2 ++ 2 files changed, 55 insertions(+) diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c index 1cf92813b5a7..11804969c29f 100644 --- a/arch/arm/mach-socfpga/mailbox_s10.c +++ b/arch/arm/mach-socfpga/mailbox_s10.c @@ -287,6 +287,59 @@ int socfpga_mailbox_s10_init(void) return 0; } +/* + * The SDM firmware apparently has an off-by-one error when verifying the + * certificate. The passed address must be one word before the actual start of + * the certificate, otherwise the firmware reports a 0x80 error with response + * set to 0x2. If the first word in the buffer isn't 0, the firmware reports a + * 0x3ff error code. + * + * Therefore, data has to start with a zero word and the actual certificate has + * to start with a 32 bit offset. + * + * The downstream U-Boot and TF-A allocate a temporary buffer, and copy the + * certificate with a start offset of -1 in the source buffer. The + * documentation in U-Boot and the TF-A seems to be wrong. + */ +int mbox_vab_src_cert(void *data, size_t size) +{ + int ret; + u32 *buf = (u32 *)data; + u32 buf_len = size / sizeof(*buf); + u32 resp_buf; + u32 resp_buf_len = 1; + + ret = mbox_send_cmd(MBOX_ID_BAREBOX, + MBOX_VAB_SRC_CERT, + MBOX_CMD_DIRECT, + buf_len, buf, 0, + &resp_buf_len, &resp_buf); + switch (ret) { + case MBOX_RESP_STATOK: + ret = 0; + break; + case MBOX_RESP_NOT_ALLOWED_UNDER_SECURITY_SETTINGS: + pr_warn("Authentication bypass\n"); + ret = 0; + break; + case MBOX_RESP_AUTH_FAIL: + pr_err("Authentication failed\n"); + break; + case MBOX_RESP_UNKNOWN: + pr_err("Authentication not supported\n"); + break; + case 0x80: + pr_err("Authentication command specific error: 0x%x (0x%x)\n", + ret, resp_buf & 0x1ff); + break; + default: + pr_err("VAB_SRC_CERT failed: 0x%x (0x%x)\n", ret, resp_buf); + break; + } + + return ret; +} + int socfpga_mailbox_s10_qspi_close(void) { return mbox_send_cmd(MBOX_ID_BAREBOX, MBOX_QSPI_CLOSE, MBOX_CMD_DIRECT, diff --git a/include/mach/socfpga/mailbox_s10.h b/include/mach/socfpga/mailbox_s10.h index bc0fd97ff0fc..abe770b8128f 100644 --- a/include/mach/socfpga/mailbox_s10.h +++ b/include/mach/socfpga/mailbox_s10.h @@ -186,6 +186,8 @@ enum ALT_SDM_MBOX_RESP_CODE { int socfpga_mailbox_s10_init(void); +int mbox_vab_src_cert(void *data, size_t size); + int socfpga_mailbox_s10_qspi_close(void); int socfpga_mailbox_s10_qspi_open(unsigned long *master_ref_clk); int socfpga_mailbox_s10_qspi_get_device_info(u32 *resp_buf, u32 resp_buf_len); -- 2.47.3
