crypto: qat - refactor FW signing algorithm
authorJack Xu <jack.xu@intel.com>
Wed, 30 Apr 2025 11:34:46 +0000 (12:34 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Mon, 5 May 2025 10:20:44 +0000 (18:20 +0800)
The current implementation is designed to support single FW signing
authentication only.
Refactor the implementation to support other FW signing methods.

This does not include any functional change.

Co-developed-by: Suman Kumar Chakraborty <suman.kumar.chakraborty@intel.com>
Signed-off-by: Suman Kumar Chakraborty <suman.kumar.chakraborty@intel.com>
Signed-off-by: Jack Xu <jack.xu@intel.com>
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/intel/qat/qat_common/qat_uclo.c

index 9dc26f5d2d0128d215dd4987b062831344d80717..d7f2ceb81f1f54f98b21d45aaf8e39d1a57bf26e 100644 (file)
@@ -1033,6 +1033,23 @@ out_err:
        return -EFAULT;
 }
 
+static unsigned int qat_uclo_simg_hdr2sign_len(struct icp_qat_fw_loader_handle *handle)
+{
+       return ICP_QAT_AE_IMG_OFFSET(handle);
+}
+
+static unsigned int qat_uclo_simg_hdr2cont_len(struct icp_qat_fw_loader_handle *handle)
+{
+       return ICP_QAT_AE_IMG_OFFSET(handle);
+}
+
+static unsigned int qat_uclo_simg_fw_type(struct icp_qat_fw_loader_handle *handle, void *img_ptr)
+{
+       struct icp_qat_css_hdr *hdr = img_ptr;
+
+       return hdr->fw_type;
+}
+
 static int qat_uclo_map_suof_file_hdr(struct icp_qat_fw_loader_handle *handle,
                                      struct icp_qat_suof_filehdr *suof_ptr,
                                      int suof_size)
@@ -1064,9 +1081,9 @@ static void qat_uclo_map_simg(struct icp_qat_fw_loader_handle *handle,
                              struct icp_qat_suof_chunk_hdr *suof_chunk_hdr)
 {
        struct icp_qat_suof_handle *suof_handle = handle->sobj_handle;
-       unsigned int offset = ICP_QAT_AE_IMG_OFFSET(handle);
-       struct icp_qat_simg_ae_mode *ae_mode;
+       unsigned int offset = qat_uclo_simg_hdr2cont_len(handle);
        struct icp_qat_suof_objhdr *suof_objhdr;
+       struct icp_qat_simg_ae_mode *ae_mode;
 
        suof_img_hdr->simg_buf  = (suof_handle->suof_buf +
                                   suof_chunk_hdr->offset +
@@ -1362,21 +1379,24 @@ static void qat_uclo_ummap_auth_fw(struct icp_qat_fw_loader_handle *handle,
 }
 
 static int qat_uclo_check_image(struct icp_qat_fw_loader_handle *handle,
-                               char *image, unsigned int size,
+                               void *image, unsigned int size,
                                unsigned int fw_type)
 {
        char *fw_type_name = fw_type ? "MMP" : "AE";
        unsigned int css_dword_size = sizeof(u32);
+       unsigned int header_len, simg_type;
+       struct icp_qat_css_hdr *css_hdr;
 
        if (handle->chip_info->fw_auth) {
-               struct icp_qat_css_hdr *css_hdr = (struct icp_qat_css_hdr *)image;
-               unsigned int header_len = ICP_QAT_AE_IMG_OFFSET(handle);
+               header_len = qat_uclo_simg_hdr2sign_len(handle);
+               simg_type = qat_uclo_simg_fw_type(handle, image);
 
+               css_hdr = image;
                if ((css_hdr->header_len * css_dword_size) != header_len)
                        goto err;
                if ((css_hdr->size * css_dword_size) != size)
                        goto err;
-               if (fw_type != css_hdr->fw_type)
+               if (fw_type != simg_type)
                        goto err;
                if (size <= header_len)
                        goto err;
@@ -1403,113 +1423,85 @@ err:
        return -EINVAL;
 }
 
-static int qat_uclo_map_auth_fw(struct icp_qat_fw_loader_handle *handle,
-                               char *image, unsigned int size,
-                               struct icp_qat_fw_auth_desc **desc)
+static int qat_uclo_build_auth_desc_RSA(struct icp_qat_fw_loader_handle *handle,
+                                       char *image, unsigned int size,
+                                       struct icp_firml_dram_desc *dram_desc,
+                                       unsigned int fw_type, struct icp_qat_fw_auth_desc **desc)
 {
        struct icp_qat_css_hdr *css_hdr = (struct icp_qat_css_hdr *)image;
-       struct icp_qat_fw_auth_desc *auth_desc;
-       struct icp_qat_auth_chunk *auth_chunk;
-       u64 virt_addr,  bus_addr, virt_base;
-       unsigned int simg_offset = sizeof(*auth_chunk);
        struct icp_qat_simg_ae_mode *simg_ae_mode;
-       struct icp_firml_dram_desc img_desc;
-       int ret;
-
-       ret = qat_uclo_simg_alloc(handle, &img_desc, ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN);
-       if (ret) {
-               pr_err("error, allocate continuous dram fail\n");
-               return ret;
-       }
-
-       if (!IS_ALIGNED(img_desc.dram_size, 8) || !img_desc.dram_bus_addr) {
-               pr_debug("invalid address\n");
-               qat_uclo_simg_free(handle, &img_desc);
-               return -EINVAL;
-       }
+       struct icp_qat_fw_auth_desc *auth_desc;
+       char *virt_addr, *virt_base;
+       u64 bus_addr;
 
-       auth_chunk = img_desc.dram_base_addr_v;
-       auth_chunk->chunk_size = img_desc.dram_size;
-       auth_chunk->chunk_bus_addr = img_desc.dram_bus_addr;
-       virt_base = (uintptr_t)img_desc.dram_base_addr_v + simg_offset;
-       bus_addr  = img_desc.dram_bus_addr + simg_offset;
-       auth_desc = img_desc.dram_base_addr_v;
-       auth_desc->css_hdr_high = (unsigned int)(bus_addr >> BITS_PER_TYPE(u32));
-       auth_desc->css_hdr_low = (unsigned int)bus_addr;
+       virt_base = dram_desc->dram_base_addr_v;
+       virt_base += sizeof(struct icp_qat_auth_chunk);
+       bus_addr  = dram_desc->dram_bus_addr + sizeof(struct icp_qat_auth_chunk);
+       auth_desc = dram_desc->dram_base_addr_v;
+       auth_desc->css_hdr_high = upper_32_bits(bus_addr);
+       auth_desc->css_hdr_low = lower_32_bits(bus_addr);
        virt_addr = virt_base;
 
-       memcpy((void *)(uintptr_t)virt_addr, image, sizeof(*css_hdr));
+       memcpy(virt_addr, image, sizeof(*css_hdr));
        /* pub key */
        bus_addr = ADD_ADDR(auth_desc->css_hdr_high, auth_desc->css_hdr_low) +
                           sizeof(*css_hdr);
        virt_addr = virt_addr + sizeof(*css_hdr);
 
-       auth_desc->fwsk_pub_high = (unsigned int)(bus_addr >> BITS_PER_TYPE(u32));
-       auth_desc->fwsk_pub_low = (unsigned int)bus_addr;
+       auth_desc->fwsk_pub_high = upper_32_bits(bus_addr);
+       auth_desc->fwsk_pub_low = lower_32_bits(bus_addr);
 
-       memcpy((void *)(uintptr_t)virt_addr,
-              (void *)(image + sizeof(*css_hdr)),
-              ICP_QAT_CSS_FWSK_MODULUS_LEN(handle));
+       memcpy(virt_addr, image + sizeof(*css_hdr), ICP_QAT_CSS_FWSK_MODULUS_LEN(handle));
        /* padding */
        memset((void *)(uintptr_t)(virt_addr + ICP_QAT_CSS_FWSK_MODULUS_LEN(handle)),
               0, ICP_QAT_CSS_FWSK_PAD_LEN(handle));
 
        /* exponent */
-       memcpy((void *)(uintptr_t)(virt_addr + ICP_QAT_CSS_FWSK_MODULUS_LEN(handle) +
-              ICP_QAT_CSS_FWSK_PAD_LEN(handle)),
-              (void *)(image + sizeof(*css_hdr) +
-                       ICP_QAT_CSS_FWSK_MODULUS_LEN(handle)),
-              sizeof(unsigned int));
+       memcpy(virt_addr + ICP_QAT_CSS_FWSK_MODULUS_LEN(handle) +
+              ICP_QAT_CSS_FWSK_PAD_LEN(handle), image + sizeof(*css_hdr) +
+              ICP_QAT_CSS_FWSK_MODULUS_LEN(handle), sizeof(unsigned int));
 
        /* signature */
        bus_addr = ADD_ADDR(auth_desc->fwsk_pub_high,
                            auth_desc->fwsk_pub_low) +
                   ICP_QAT_CSS_FWSK_PUB_LEN(handle);
        virt_addr = virt_addr + ICP_QAT_CSS_FWSK_PUB_LEN(handle);
-       auth_desc->signature_high = (unsigned int)(bus_addr >> BITS_PER_TYPE(u32));
-       auth_desc->signature_low = (unsigned int)bus_addr;
+       auth_desc->signature_high = upper_32_bits(bus_addr);
+       auth_desc->signature_low = lower_32_bits(bus_addr);
 
-       memcpy((void *)(uintptr_t)virt_addr,
-              (void *)(image + sizeof(*css_hdr) +
-              ICP_QAT_CSS_FWSK_MODULUS_LEN(handle) +
-              ICP_QAT_CSS_FWSK_EXPONENT_LEN(handle)),
-              ICP_QAT_CSS_SIGNATURE_LEN(handle));
+       memcpy(virt_addr, image + sizeof(*css_hdr) + ICP_QAT_CSS_FWSK_MODULUS_LEN(handle) +
+              ICP_QAT_CSS_FWSK_EXPONENT_LEN(handle), ICP_QAT_CSS_SIGNATURE_LEN(handle));
 
        bus_addr = ADD_ADDR(auth_desc->signature_high,
                            auth_desc->signature_low) +
                   ICP_QAT_CSS_SIGNATURE_LEN(handle);
        virt_addr += ICP_QAT_CSS_SIGNATURE_LEN(handle);
 
-       auth_desc->img_high = (unsigned int)(bus_addr >> BITS_PER_TYPE(u32));
-       auth_desc->img_low = (unsigned int)bus_addr;
-       auth_desc->img_len = size - ICP_QAT_AE_IMG_OFFSET(handle);
-       if (bus_addr + auth_desc->img_len > img_desc.dram_bus_addr +
-                                           ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN) {
+       auth_desc->img_high = upper_32_bits(bus_addr);
+       auth_desc->img_low = lower_32_bits(bus_addr);
+       auth_desc->img_len = size - qat_uclo_simg_hdr2sign_len(handle);
+       if (bus_addr + auth_desc->img_len >
+           dram_desc->dram_bus_addr + ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN) {
                pr_err("insufficient memory size for authentication data\n");
-               qat_uclo_simg_free(handle, &img_desc);
+               qat_uclo_simg_free(handle, dram_desc);
                return -ENOMEM;
        }
 
-       memcpy((void *)(uintptr_t)virt_addr,
-              (void *)(image + ICP_QAT_AE_IMG_OFFSET(handle)),
-              auth_desc->img_len);
+       memcpy(virt_addr, image + qat_uclo_simg_hdr2sign_len(handle), auth_desc->img_len);
        virt_addr = virt_base;
        /* AE firmware */
-       if (((struct icp_qat_css_hdr *)(uintptr_t)virt_addr)->fw_type ==
-           CSS_AE_FIRMWARE) {
+       if (fw_type == CSS_AE_FIRMWARE) {
                auth_desc->img_ae_mode_data_high = auth_desc->img_high;
                auth_desc->img_ae_mode_data_low = auth_desc->img_low;
                bus_addr = ADD_ADDR(auth_desc->img_ae_mode_data_high,
                                    auth_desc->img_ae_mode_data_low) +
                           sizeof(struct icp_qat_simg_ae_mode);
 
-               auth_desc->img_ae_init_data_high =
-                       (unsigned int)(bus_addr >> BITS_PER_TYPE(u32));
-               auth_desc->img_ae_init_data_low = (unsigned int)bus_addr;
+               auth_desc->img_ae_init_data_high = upper_32_bits(bus_addr);
+               auth_desc->img_ae_init_data_low = lower_32_bits(bus_addr);
                bus_addr += ICP_QAT_SIMG_AE_INIT_SEQ_LEN;
-               auth_desc->img_ae_insts_high =
-                       (unsigned int)(bus_addr >> BITS_PER_TYPE(u32));
-               auth_desc->img_ae_insts_low = (unsigned int)bus_addr;
+               auth_desc->img_ae_insts_high = upper_32_bits(bus_addr);
+               auth_desc->img_ae_insts_low = lower_32_bits(bus_addr);
                virt_addr += sizeof(struct icp_qat_css_hdr);
                virt_addr += ICP_QAT_CSS_FWSK_PUB_LEN(handle);
                virt_addr += ICP_QAT_CSS_SIGNATURE_LEN(handle);
@@ -1523,6 +1515,28 @@ static int qat_uclo_map_auth_fw(struct icp_qat_fw_loader_handle *handle,
        return 0;
 }
 
+static int qat_uclo_map_auth_fw(struct icp_qat_fw_loader_handle *handle,
+                               char *image, unsigned int size,
+                               struct icp_qat_fw_auth_desc **desc)
+{
+       struct icp_qat_auth_chunk *auth_chunk;
+       struct icp_firml_dram_desc img_desc;
+       unsigned int simg_fw_type;
+       int ret;
+
+       ret = qat_uclo_simg_alloc(handle, &img_desc, ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN);
+       if (ret)
+               return ret;
+
+       simg_fw_type = qat_uclo_simg_fw_type(handle, image);
+       auth_chunk = img_desc.dram_base_addr_v;
+       auth_chunk->chunk_size = img_desc.dram_size;
+       auth_chunk->chunk_bus_addr = img_desc.dram_bus_addr;
+
+       return qat_uclo_build_auth_desc_RSA(handle, image, size, &img_desc,
+                                           simg_fw_type, desc);
+}
+
 static int qat_uclo_load_fw(struct icp_qat_fw_loader_handle *handle,
                            struct icp_qat_fw_auth_desc *desc)
 {