Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: qat - add GEN6 firmware loader

Add support for the QAT GEN6 devices in the firmware loader.
This includes handling firmware images signed with the RSA 3K and the
XMSS algorithms.

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>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Jack Xu and committed by
Herbert Xu
e7b73261 98943958

+176 -7
+2
drivers/crypto/intel/qat/qat_common/adf_accel_devices.h
··· 34 34 #define PCI_DEVICE_ID_INTEL_QAT_402XXIOV 0x4945 35 35 #define PCI_DEVICE_ID_INTEL_QAT_420XX 0x4946 36 36 #define PCI_DEVICE_ID_INTEL_QAT_420XXIOV 0x4947 37 + #define PCI_DEVICE_ID_INTEL_QAT_6XXX 0x4948 38 + 37 39 #define ADF_DEVICE_FUSECTL_OFFSET 0x40 38 40 #define ADF_DEVICE_LEGFUSE_OFFSET 0x4C 39 41 #define ADF_DEVICE_FUSECTL_MASK 0x80000000
+1
drivers/crypto/intel/qat/qat_common/icp_qat_fw_loader_handle.h
··· 35 35 u32 wakeup_event_val; 36 36 bool fw_auth; 37 37 bool css_3k; 38 + bool dual_sign; 38 39 bool tgroup_share_ustore; 39 40 u32 fcu_ctl_csr; 40 41 u32 fcu_sts_csr;
+23
drivers/crypto/intel/qat/qat_common/icp_qat_uclo.h
··· 7 7 #define ICP_QAT_AC_C62X_DEV_TYPE 0x01000000 8 8 #define ICP_QAT_AC_C3XXX_DEV_TYPE 0x02000000 9 9 #define ICP_QAT_AC_4XXX_A_DEV_TYPE 0x08000000 10 + #define ICP_QAT_AC_6XXX_DEV_TYPE 0x80000000 10 11 #define ICP_QAT_UCLO_MAX_AE 17 11 12 #define ICP_QAT_UCLO_MAX_CTX 8 12 13 #define ICP_QAT_UCLO_MAX_UIMAGE (ICP_QAT_UCLO_MAX_AE * ICP_QAT_UCLO_MAX_CTX) ··· 81 80 ICP_QAT_CSS_SIGNATURE_LEN(handle)) 82 81 #define ICP_QAT_CSS_RSA4K_MAX_IMAGE_LEN 0x40000 83 82 #define ICP_QAT_CSS_RSA3K_MAX_IMAGE_LEN 0x30000 83 + 84 + /* All lengths below are in bytes */ 85 + #define ICP_QAT_DUALSIGN_OPAQUE_HDR_LEN 12 86 + #define ICP_QAT_DUALSIGN_OPAQUE_HDR_ALIGN_LEN 16 87 + #define ICP_QAT_DUALSIGN_OPAQUE_DATA_LEN 3540 88 + #define ICP_QAT_DUALSIGN_XMSS_PUBKEY_LEN 64 89 + #define ICP_QAT_DUALSIGN_XMSS_SIG_LEN 2692 90 + #define ICP_QAT_DUALSIGN_XMSS_SIG_ALIGN_LEN 2696 91 + #define ICP_QAT_DUALSIGN_MISC_INFO_LEN 16 92 + #define ICP_QAT_DUALSIGN_FW_TYPE_LEN 7 93 + #define ICP_QAT_DUALSIGN_MODULE_TYPE 0x14 94 + #define ICP_QAT_DUALSIGN_HDR_LEN 0x375 95 + #define ICP_QAT_DUALSIGN_HDR_VER 0x40001 96 + #define ICP_QAT_DUALSIGN_HDR_LEN_OFFSET 4 97 + #define ICP_QAT_DUALSIGN_HDR_VER_OFFSET 8 84 98 85 99 #define ICP_QAT_CTX_MODE(ae_mode) ((ae_mode) & 0xf) 86 100 #define ICP_QAT_NN_MODE(ae_mode) (((ae_mode) >> 0x4) & 0xf) ··· 456 440 unsigned int img_ae_init_data_low; 457 441 unsigned int img_ae_insts_high; 458 442 unsigned int img_ae_insts_low; 443 + unsigned int cpp_mask; 444 + unsigned int reserved; 445 + unsigned int xmss_pubkey_high; 446 + unsigned int xmss_pubkey_low; 447 + unsigned int xmss_sig_high; 448 + unsigned int xmss_sig_low; 449 + unsigned int reserved2[2]; 459 450 }; 460 451 461 452 struct icp_qat_auth_chunk {
+3
drivers/crypto/intel/qat/qat_common/qat_hal.c
··· 698 698 case PCI_DEVICE_ID_INTEL_QAT_401XX: 699 699 case PCI_DEVICE_ID_INTEL_QAT_402XX: 700 700 case PCI_DEVICE_ID_INTEL_QAT_420XX: 701 + case PCI_DEVICE_ID_INTEL_QAT_6XXX: 701 702 handle->chip_info->mmp_sram_size = 0; 702 703 handle->chip_info->nn = false; 703 704 handle->chip_info->lm2lm3 = true; ··· 713 712 handle->chip_info->wakeup_event_val = 0x80000000; 714 713 handle->chip_info->fw_auth = true; 715 714 handle->chip_info->css_3k = true; 715 + if (handle->pci_dev->device == PCI_DEVICE_ID_INTEL_QAT_6XXX) 716 + handle->chip_info->dual_sign = true; 716 717 handle->chip_info->tgroup_share_ustore = true; 717 718 handle->chip_info->fcu_ctl_csr = FCU_CONTROL_4XXX; 718 719 handle->chip_info->fcu_sts_csr = FCU_STATUS_4XXX;
+147 -7
drivers/crypto/intel/qat/qat_common/qat_uclo.c
··· 10 10 #include <linux/kernel.h> 11 11 #include <linux/delay.h> 12 12 #include <linux/pci_ids.h> 13 + #include <linux/wordpart.h> 13 14 #include "adf_accel_devices.h" 14 15 #include "adf_common_drv.h" 15 16 #include "icp_qat_uclo.h" ··· 738 737 case PCI_DEVICE_ID_INTEL_QAT_402XX: 739 738 case PCI_DEVICE_ID_INTEL_QAT_420XX: 740 739 return ICP_QAT_AC_4XXX_A_DEV_TYPE; 740 + case PCI_DEVICE_ID_INTEL_QAT_6XXX: 741 + return ICP_QAT_AC_6XXX_DEV_TYPE; 741 742 default: 742 743 pr_err("unsupported device 0x%x\n", handle->pci_dev->device); 743 744 return 0; ··· 1038 1035 1039 1036 static unsigned int qat_uclo_simg_hdr2sign_len(struct icp_qat_fw_loader_handle *handle) 1040 1037 { 1038 + if (handle->chip_info->dual_sign) 1039 + return ICP_QAT_DUALSIGN_OPAQUE_DATA_LEN; 1040 + 1041 1041 return ICP_QAT_AE_IMG_OFFSET(handle); 1042 1042 } 1043 1043 1044 1044 static unsigned int qat_uclo_simg_hdr2cont_len(struct icp_qat_fw_loader_handle *handle) 1045 1045 { 1046 + if (handle->chip_info->dual_sign) 1047 + return ICP_QAT_DUALSIGN_OPAQUE_DATA_LEN + ICP_QAT_DUALSIGN_MISC_INFO_LEN; 1048 + 1046 1049 return ICP_QAT_AE_IMG_OFFSET(handle); 1047 1050 } 1048 1051 1049 1052 static unsigned int qat_uclo_simg_fw_type(struct icp_qat_fw_loader_handle *handle, void *img_ptr) 1050 1053 { 1051 1054 struct icp_qat_css_hdr *hdr = img_ptr; 1055 + char *fw_hdr = img_ptr; 1056 + unsigned int offset; 1057 + 1058 + if (handle->chip_info->dual_sign) { 1059 + offset = qat_uclo_simg_hdr2sign_len(handle) + ICP_QAT_DUALSIGN_FW_TYPE_LEN; 1060 + return *(fw_hdr + offset); 1061 + } 1052 1062 1053 1063 return hdr->fw_type; 1054 1064 } ··· 1406 1390 if (handle->chip_info->fw_auth) { 1407 1391 header_len = qat_uclo_simg_hdr2sign_len(handle); 1408 1392 simg_type = qat_uclo_simg_fw_type(handle, image); 1409 - 1410 1393 css_hdr = image; 1411 - if ((css_hdr->header_len * css_dword_size) != header_len) 1412 - goto err; 1413 - if ((css_hdr->size * css_dword_size) != size) 1414 - goto err; 1394 + 1395 + if (handle->chip_info->dual_sign) { 1396 + if (css_hdr->module_type != ICP_QAT_DUALSIGN_MODULE_TYPE) 1397 + goto err; 1398 + if (css_hdr->header_len != ICP_QAT_DUALSIGN_HDR_LEN) 1399 + goto err; 1400 + if (css_hdr->header_ver != ICP_QAT_DUALSIGN_HDR_VER) 1401 + goto err; 1402 + } else { 1403 + if (css_hdr->header_len * css_dword_size != header_len) 1404 + goto err; 1405 + if (css_hdr->size * css_dword_size != size) 1406 + goto err; 1407 + if (size <= header_len) 1408 + goto err; 1409 + } 1410 + 1415 1411 if (fw_type != simg_type) 1416 1412 goto err; 1417 - if (size <= header_len) 1418 - goto err; 1413 + 1419 1414 size -= header_len; 1420 1415 } 1421 1416 ··· 1542 1515 return 0; 1543 1516 } 1544 1517 1518 + static int qat_uclo_build_auth_desc_dualsign(struct icp_qat_fw_loader_handle *handle, 1519 + char *image, unsigned int size, 1520 + struct icp_firml_dram_desc *dram_desc, 1521 + unsigned int fw_type, 1522 + struct icp_qat_fw_auth_desc **desc) 1523 + { 1524 + struct icp_qat_simg_ae_mode *simg_ae_mode; 1525 + struct icp_qat_fw_auth_desc *auth_desc; 1526 + unsigned int chunk_offset, img_offset; 1527 + u64 bus_addr, addr; 1528 + char *virt_addr; 1529 + 1530 + virt_addr = dram_desc->dram_base_addr_v; 1531 + virt_addr += sizeof(struct icp_qat_auth_chunk); 1532 + bus_addr = dram_desc->dram_bus_addr + sizeof(struct icp_qat_auth_chunk); 1533 + 1534 + auth_desc = dram_desc->dram_base_addr_v; 1535 + auth_desc->img_len = size - qat_uclo_simg_hdr2sign_len(handle); 1536 + auth_desc->css_hdr_high = upper_32_bits(bus_addr); 1537 + auth_desc->css_hdr_low = lower_32_bits(bus_addr); 1538 + memcpy(virt_addr, image, ICP_QAT_DUALSIGN_OPAQUE_HDR_LEN); 1539 + 1540 + img_offset = ICP_QAT_DUALSIGN_OPAQUE_HDR_LEN; 1541 + chunk_offset = ICP_QAT_DUALSIGN_OPAQUE_HDR_ALIGN_LEN; 1542 + 1543 + /* RSA pub key */ 1544 + addr = bus_addr + chunk_offset; 1545 + auth_desc->fwsk_pub_high = upper_32_bits(addr); 1546 + auth_desc->fwsk_pub_low = lower_32_bits(addr); 1547 + memcpy(virt_addr + chunk_offset, image + img_offset, ICP_QAT_CSS_FWSK_MODULUS_LEN(handle)); 1548 + 1549 + img_offset += ICP_QAT_CSS_FWSK_MODULUS_LEN(handle); 1550 + chunk_offset += ICP_QAT_CSS_FWSK_MODULUS_LEN(handle); 1551 + /* RSA padding */ 1552 + memset(virt_addr + chunk_offset, 0, ICP_QAT_CSS_FWSK_PAD_LEN(handle)); 1553 + 1554 + chunk_offset += ICP_QAT_CSS_FWSK_PAD_LEN(handle); 1555 + /* RSA exponent */ 1556 + memcpy(virt_addr + chunk_offset, image + img_offset, ICP_QAT_CSS_FWSK_EXPONENT_LEN(handle)); 1557 + 1558 + img_offset += ICP_QAT_CSS_FWSK_EXPONENT_LEN(handle); 1559 + chunk_offset += ICP_QAT_CSS_FWSK_EXPONENT_LEN(handle); 1560 + /* RSA signature */ 1561 + addr = bus_addr + chunk_offset; 1562 + auth_desc->signature_high = upper_32_bits(addr); 1563 + auth_desc->signature_low = lower_32_bits(addr); 1564 + memcpy(virt_addr + chunk_offset, image + img_offset, ICP_QAT_CSS_SIGNATURE_LEN(handle)); 1565 + 1566 + img_offset += ICP_QAT_CSS_SIGNATURE_LEN(handle); 1567 + chunk_offset += ICP_QAT_CSS_SIGNATURE_LEN(handle); 1568 + /* XMSS pubkey */ 1569 + addr = bus_addr + chunk_offset; 1570 + auth_desc->xmss_pubkey_high = upper_32_bits(addr); 1571 + auth_desc->xmss_pubkey_low = lower_32_bits(addr); 1572 + memcpy(virt_addr + chunk_offset, image + img_offset, ICP_QAT_DUALSIGN_XMSS_PUBKEY_LEN); 1573 + 1574 + img_offset += ICP_QAT_DUALSIGN_XMSS_PUBKEY_LEN; 1575 + chunk_offset += ICP_QAT_DUALSIGN_XMSS_PUBKEY_LEN; 1576 + /* XMSS signature */ 1577 + addr = bus_addr + chunk_offset; 1578 + auth_desc->xmss_sig_high = upper_32_bits(addr); 1579 + auth_desc->xmss_sig_low = lower_32_bits(addr); 1580 + memcpy(virt_addr + chunk_offset, image + img_offset, ICP_QAT_DUALSIGN_XMSS_SIG_LEN); 1581 + 1582 + img_offset += ICP_QAT_DUALSIGN_XMSS_SIG_LEN; 1583 + chunk_offset += ICP_QAT_DUALSIGN_XMSS_SIG_ALIGN_LEN; 1584 + 1585 + if (dram_desc->dram_size < (chunk_offset + auth_desc->img_len)) { 1586 + pr_err("auth chunk memory size is not enough to store data\n"); 1587 + return -ENOMEM; 1588 + } 1589 + 1590 + /* Signed data */ 1591 + addr = bus_addr + chunk_offset; 1592 + auth_desc->img_high = upper_32_bits(addr); 1593 + auth_desc->img_low = lower_32_bits(addr); 1594 + memcpy(virt_addr + chunk_offset, image + img_offset, auth_desc->img_len); 1595 + 1596 + chunk_offset += ICP_QAT_DUALSIGN_MISC_INFO_LEN; 1597 + /* AE firmware */ 1598 + if (fw_type == CSS_AE_FIRMWARE) { 1599 + /* AE mode data */ 1600 + addr = bus_addr + chunk_offset; 1601 + auth_desc->img_ae_mode_data_high = upper_32_bits(addr); 1602 + auth_desc->img_ae_mode_data_low = lower_32_bits(addr); 1603 + simg_ae_mode = 1604 + (struct icp_qat_simg_ae_mode *)(virt_addr + chunk_offset); 1605 + auth_desc->ae_mask = simg_ae_mode->ae_mask & handle->cfg_ae_mask; 1606 + 1607 + chunk_offset += sizeof(struct icp_qat_simg_ae_mode); 1608 + /* AE init seq */ 1609 + addr = bus_addr + chunk_offset; 1610 + auth_desc->img_ae_init_data_high = upper_32_bits(addr); 1611 + auth_desc->img_ae_init_data_low = lower_32_bits(addr); 1612 + 1613 + chunk_offset += ICP_QAT_SIMG_AE_INIT_SEQ_LEN; 1614 + /* AE instructions */ 1615 + addr = bus_addr + chunk_offset; 1616 + auth_desc->img_ae_insts_high = upper_32_bits(addr); 1617 + auth_desc->img_ae_insts_low = lower_32_bits(addr); 1618 + } else { 1619 + addr = bus_addr + chunk_offset; 1620 + auth_desc->img_ae_insts_high = upper_32_bits(addr); 1621 + auth_desc->img_ae_insts_low = lower_32_bits(addr); 1622 + } 1623 + *desc = auth_desc; 1624 + return 0; 1625 + } 1626 + 1545 1627 static int qat_uclo_map_auth_fw(struct icp_qat_fw_loader_handle *handle, 1546 1628 char *image, unsigned int size, 1547 1629 struct icp_qat_fw_auth_desc **desc) ··· 1668 1532 auth_chunk = img_desc.dram_base_addr_v; 1669 1533 auth_chunk->chunk_size = img_desc.dram_size; 1670 1534 auth_chunk->chunk_bus_addr = img_desc.dram_bus_addr; 1535 + 1536 + if (handle->chip_info->dual_sign) 1537 + return qat_uclo_build_auth_desc_dualsign(handle, image, size, &img_desc, 1538 + simg_fw_type, desc); 1671 1539 1672 1540 return qat_uclo_build_auth_desc_RSA(handle, image, size, &img_desc, 1673 1541 simg_fw_type, desc);