|
Torsten Duwe |
3a6ee2 |
From 908f24270d9ccbe120b91e7029b372f3dcd18290 Mon Sep 17 00:00:00 2001
|
|
Torsten Duwe |
3a6ee2 |
From: Srinivas Kerekare <srinivas.kerekare@intel.com>
|
|
Torsten Duwe |
3a6ee2 |
Date: Mon, 25 Jul 2022 11:40:09 +0100
|
|
Torsten Duwe |
3a6ee2 |
Subject: [PATCH] crypto: qat - add check to validate firmware images
|
|
Torsten Duwe |
3a6ee2 |
Git-commit: 908f24270d9ccbe120b91e7029b372f3dcd18290
|
|
Torsten Duwe |
3a6ee2 |
Patch-mainline: v6.1-rc1
|
|
Torsten Duwe |
3a6ee2 |
References: jsc#PED-1073
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
The function qat_uclo_check_image() validates the MMP and AE firmware
|
|
Torsten Duwe |
3a6ee2 |
images. If the QAT device supports firmware authentication (indicated
|
|
Torsten Duwe |
3a6ee2 |
by the handle to firmware loader), the input signed binary MMP and AE
|
|
Torsten Duwe |
3a6ee2 |
images are validated by parsing the following information:
|
|
Torsten Duwe |
3a6ee2 |
- Header length
|
|
Torsten Duwe |
3a6ee2 |
- Full size of the binary
|
|
Torsten Duwe |
3a6ee2 |
- Type of binary image (MMP or AE Firmware)
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
Firmware binaries use RSA3K for signing and verification.
|
|
Torsten Duwe |
3a6ee2 |
The header length for the RSA3k is 0x384 bytes.
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
All the size field values in the binary are quantified
|
|
Torsten Duwe |
3a6ee2 |
as DWORDS (1 DWORD = 4bytes).
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
On an invalid value the function prints an error message and returns
|
|
Torsten Duwe |
3a6ee2 |
with an error code "EINVAL".
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
Signed-off-by: Srinivas Kerekare <srinivas.kerekare@intel.com>
|
|
Torsten Duwe |
3a6ee2 |
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
|
|
Torsten Duwe |
3a6ee2 |
Reviewed-by: Wojciech Ziemba <wojciech.ziemba@intel.com>
|
|
Torsten Duwe |
3a6ee2 |
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
|
Torsten Duwe |
3a6ee2 |
Signed-off-by: Torsten Duwe <duwe@suse.de>
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
---
|
|
Torsten Duwe |
3a6ee2 |
drivers/crypto/qat/qat_common/icp_qat_uclo.h | 3 +-
|
|
Torsten Duwe |
3a6ee2 |
drivers/crypto/qat/qat_common/qat_uclo.c | 56 +++++++++++++++++++-
|
|
Torsten Duwe |
3a6ee2 |
2 files changed, 57 insertions(+), 2 deletions(-)
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
diff --git a/drivers/crypto/qat/qat_common/icp_qat_uclo.h b/drivers/crypto/qat/qat_common/icp_qat_uclo.h
|
|
Torsten Duwe |
3a6ee2 |
index 4b36869bf460b..69482abdb8b93 100644
|
|
Torsten Duwe |
3a6ee2 |
--- a/drivers/crypto/qat/qat_common/icp_qat_uclo.h
|
|
Torsten Duwe |
3a6ee2 |
+++ b/drivers/crypto/qat/qat_common/icp_qat_uclo.h
|
|
Torsten Duwe |
3a6ee2 |
@@ -86,7 +86,8 @@
|
|
Torsten Duwe |
3a6ee2 |
ICP_QAT_CSS_FWSK_MODULUS_LEN(handle) + \
|
|
Torsten Duwe |
3a6ee2 |
ICP_QAT_CSS_FWSK_EXPONENT_LEN(handle) + \
|
|
Torsten Duwe |
3a6ee2 |
ICP_QAT_CSS_SIGNATURE_LEN(handle))
|
|
Torsten Duwe |
3a6ee2 |
-#define ICP_QAT_CSS_MAX_IMAGE_LEN 0x40000
|
|
Torsten Duwe |
3a6ee2 |
+#define ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN 0x40000
|
|
Torsten Duwe |
3a6ee2 |
+#define ICP_QAT_CSS_RSA3K_MAX_IMAGE_LEN 0x30000
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
#define ICP_QAT_CTX_MODE(ae_mode) ((ae_mode) & 0xf)
|
|
Torsten Duwe |
3a6ee2 |
#define ICP_QAT_NN_MODE(ae_mode) (((ae_mode) >> 0x4) & 0xf)
|
|
Torsten Duwe |
3a6ee2 |
diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c
|
|
Torsten Duwe |
3a6ee2 |
index 0fe5a474aa452..b7f7869ef8b2f 100644
|
|
Torsten Duwe |
3a6ee2 |
--- a/drivers/crypto/qat/qat_common/qat_uclo.c
|
|
Torsten Duwe |
3a6ee2 |
+++ b/drivers/crypto/qat/qat_common/qat_uclo.c
|
|
Torsten Duwe |
3a6ee2 |
@@ -1367,6 +1367,48 @@ static void qat_uclo_ummap_auth_fw(struct icp_qat_fw_loader_handle *handle,
|
|
Torsten Duwe |
3a6ee2 |
}
|
|
Torsten Duwe |
3a6ee2 |
}
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
+static int qat_uclo_check_image(struct icp_qat_fw_loader_handle *handle,
|
|
Torsten Duwe |
3a6ee2 |
+ char *image, unsigned int size,
|
|
Torsten Duwe |
3a6ee2 |
+ unsigned int fw_type)
|
|
Torsten Duwe |
3a6ee2 |
+{
|
|
Torsten Duwe |
3a6ee2 |
+ char *fw_type_name = fw_type ? "MMP" : "AE";
|
|
Torsten Duwe |
3a6ee2 |
+ unsigned int css_dword_size = sizeof(u32);
|
|
Torsten Duwe |
3a6ee2 |
+
|
|
Torsten Duwe |
3a6ee2 |
+ if (handle->chip_info->fw_auth) {
|
|
Torsten Duwe |
3a6ee2 |
+ struct icp_qat_css_hdr *css_hdr = (struct icp_qat_css_hdr *)image;
|
|
Torsten Duwe |
3a6ee2 |
+ unsigned int header_len = ICP_QAT_AE_IMG_OFFSET(handle);
|
|
Torsten Duwe |
3a6ee2 |
+
|
|
Torsten Duwe |
3a6ee2 |
+ if ((css_hdr->header_len * css_dword_size) != header_len)
|
|
Torsten Duwe |
3a6ee2 |
+ goto err;
|
|
Torsten Duwe |
3a6ee2 |
+ if ((css_hdr->size * css_dword_size) != size)
|
|
Torsten Duwe |
3a6ee2 |
+ goto err;
|
|
Torsten Duwe |
3a6ee2 |
+ if (fw_type != css_hdr->fw_type)
|
|
Torsten Duwe |
3a6ee2 |
+ goto err;
|
|
Torsten Duwe |
3a6ee2 |
+ if (size <= header_len)
|
|
Torsten Duwe |
3a6ee2 |
+ goto err;
|
|
Torsten Duwe |
3a6ee2 |
+ size -= header_len;
|
|
Torsten Duwe |
3a6ee2 |
+ }
|
|
Torsten Duwe |
3a6ee2 |
+
|
|
Torsten Duwe |
3a6ee2 |
+ if (fw_type == CSS_AE_FIRMWARE) {
|
|
Torsten Duwe |
3a6ee2 |
+ if (size < sizeof(struct icp_qat_simg_ae_mode *) +
|
|
Torsten Duwe |
3a6ee2 |
+ ICP_QAT_SIMG_AE_INIT_SEQ_LEN)
|
|
Torsten Duwe |
3a6ee2 |
+ goto err;
|
|
Torsten Duwe |
3a6ee2 |
+ if (size > ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN)
|
|
Torsten Duwe |
3a6ee2 |
+ goto err;
|
|
Torsten Duwe |
3a6ee2 |
+ } else if (fw_type == CSS_MMP_FIRMWARE) {
|
|
Torsten Duwe |
3a6ee2 |
+ if (size > ICP_QAT_CSS_RSA3K_MAX_IMAGE_LEN)
|
|
Torsten Duwe |
3a6ee2 |
+ goto err;
|
|
Torsten Duwe |
3a6ee2 |
+ } else {
|
|
Torsten Duwe |
3a6ee2 |
+ pr_err("QAT: Unsupported firmware type\n");
|
|
Torsten Duwe |
3a6ee2 |
+ return -EINVAL;
|
|
Torsten Duwe |
3a6ee2 |
+ }
|
|
Torsten Duwe |
3a6ee2 |
+ return 0;
|
|
Torsten Duwe |
3a6ee2 |
+
|
|
Torsten Duwe |
3a6ee2 |
+err:
|
|
Torsten Duwe |
3a6ee2 |
+ pr_err("QAT: Invalid %s firmware image\n", fw_type_name);
|
|
Torsten Duwe |
3a6ee2 |
+ return -EINVAL;
|
|
Torsten Duwe |
3a6ee2 |
+}
|
|
Torsten Duwe |
3a6ee2 |
+
|
|
Torsten Duwe |
3a6ee2 |
static int qat_uclo_map_auth_fw(struct icp_qat_fw_loader_handle *handle,
|
|
Torsten Duwe |
3a6ee2 |
char *image, unsigned int size,
|
|
Torsten Duwe |
3a6ee2 |
struct icp_qat_fw_auth_desc **desc)
|
|
Torsten Duwe |
3a6ee2 |
@@ -1379,7 +1421,7 @@ static int qat_uclo_map_auth_fw(struct icp_qat_fw_loader_handle *handle,
|
|
Torsten Duwe |
3a6ee2 |
struct icp_qat_simg_ae_mode *simg_ae_mode;
|
|
Torsten Duwe |
3a6ee2 |
struct icp_firml_dram_desc img_desc;
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
- if (size > (ICP_QAT_AE_IMG_OFFSET(handle) + ICP_QAT_CSS_MAX_IMAGE_LEN)) {
|
|
Torsten Duwe |
3a6ee2 |
+ if (size > (ICP_QAT_AE_IMG_OFFSET(handle) + ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN)) {
|
|
Torsten Duwe |
3a6ee2 |
pr_err("QAT: error, input image size overflow %d\n", size);
|
|
Torsten Duwe |
3a6ee2 |
return -EINVAL;
|
|
Torsten Duwe |
3a6ee2 |
}
|
|
Torsten Duwe |
3a6ee2 |
@@ -1547,6 +1589,11 @@ int qat_uclo_wr_mimage(struct icp_qat_fw_loader_handle *handle,
|
|
Torsten Duwe |
3a6ee2 |
{
|
|
Torsten Duwe |
3a6ee2 |
struct icp_qat_fw_auth_desc *desc = NULL;
|
|
Torsten Duwe |
3a6ee2 |
int status = 0;
|
|
Torsten Duwe |
3a6ee2 |
+ int ret;
|
|
Torsten Duwe |
3a6ee2 |
+
|
|
Torsten Duwe |
3a6ee2 |
+ ret = qat_uclo_check_image(handle, addr_ptr, mem_size, CSS_MMP_FIRMWARE);
|
|
Torsten Duwe |
3a6ee2 |
+ if (ret)
|
|
Torsten Duwe |
3a6ee2 |
+ return ret;
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
if (handle->chip_info->fw_auth) {
|
|
Torsten Duwe |
3a6ee2 |
status = qat_uclo_map_auth_fw(handle, addr_ptr, mem_size, &desc);
|
|
Torsten Duwe |
3a6ee2 |
@@ -2018,8 +2065,15 @@ static int qat_uclo_wr_suof_img(struct icp_qat_fw_loader_handle *handle)
|
|
Torsten Duwe |
3a6ee2 |
struct icp_qat_fw_auth_desc *desc = NULL;
|
|
Torsten Duwe |
3a6ee2 |
struct icp_qat_suof_handle *sobj_handle = handle->sobj_handle;
|
|
Torsten Duwe |
3a6ee2 |
struct icp_qat_suof_img_hdr *simg_hdr = sobj_handle->img_table.simg_hdr;
|
|
Torsten Duwe |
3a6ee2 |
+ int ret;
|
|
Torsten Duwe |
3a6ee2 |
|
|
Torsten Duwe |
3a6ee2 |
for (i = 0; i < sobj_handle->img_table.num_simgs; i++) {
|
|
Torsten Duwe |
3a6ee2 |
+ ret = qat_uclo_check_image(handle, simg_hdr[i].simg_buf,
|
|
Torsten Duwe |
3a6ee2 |
+ simg_hdr[i].simg_len,
|
|
Torsten Duwe |
3a6ee2 |
+ CSS_AE_FIRMWARE);
|
|
Torsten Duwe |
3a6ee2 |
+ if (ret)
|
|
Torsten Duwe |
3a6ee2 |
+ return ret;
|
|
Torsten Duwe |
3a6ee2 |
+
|
|
Torsten Duwe |
3a6ee2 |
if (qat_uclo_map_auth_fw(handle,
|
|
Torsten Duwe |
3a6ee2 |
(char *)simg_hdr[i].simg_buf,
|
|
Torsten Duwe |
3a6ee2 |
(unsigned int)
|
|
Torsten Duwe |
3a6ee2 |
--
|
|
Torsten Duwe |
3a6ee2 |
2.35.3
|
|
Torsten Duwe |
3a6ee2 |
|