QATHW and QATSW Co-existence

July 14, 2026 · View on GitHub

Intel® QAT OpenSSL* Engine and Provider support QAT_HW and QAT_SW Co-existence when both QAT_HW flag --with-qat_hw_dir=/path/to/QAT_Driver and QAT_SW flag --enable-qat_sw configured in the build configure option to provide acceleration from both QAT_HW and QAT_SW combined.

If the platform has support for both QAT_HW and QAT_SW, the default behavior is to accelerate asymmetric algorithms and Symmetric chained ciphers using QAT Hardware and Symmetric GCM Ciphers using QAT Software. If the platform doesn't have QAT Hardware support then it will use QAT_SW Acceleration for QAT_SW asymmetric algorithms that are supported in the qatengine.

The default behavior can be changed using corresponding algorithm's enable flags (eg:--enable-qat_sw_rsa) in which case the individual algorithms enabled (either qat_hw or qat_sw) in the build configure will get accelerated.

For the algorithms RSA2K/3K/4K, ECDHP256/P384/X25519 & ECDSAP384 to reach better performance, QATEngine uses both QAT_HW and QAT_SW for acceleration when QAT_HW capacity is reached with co-existence build. The mechanism by which QAT_HW capacity is detected differs between the two driver modes:

OOT (Out-of-Tree) driver: QAT_HW signals capacity via a RETRY status returned from the driver. When a RETRY is received, the request is transparently rerouted to QAT_SW. The control flow for this mode is illustrated below.

flowchart TD
    A([Crypto Request]) --> B[Submit to QAT_HW]
    B --> C{QAT_HW\nResponse?}
    C -- Success  --> D([Return Result])
    C -- RETRY    --> E[Route to QAT_SW]
    E --> F[Process via\nQAT_SW multibuffer]
    F --> D

    style A fill:#dae8fc,stroke:#6c8ebf,color:#000000
    style D fill:#dae8fc,stroke:#6c8ebf,color:#000000
    style B fill:#fff2cc,stroke:#d6b656,color:#000000
    style E fill:#fff2cc,stroke:#d6b656,color:#000000
    style F fill:#fff2cc,stroke:#d6b656,color:#000000
    style C fill:#f8cecc,stroke:#b85450,color:#000000

Intree driver (QAT_HW_INTREE): Instead of relying on RETRY, the icp_sal_AsymGetInflightRequests() API provided by the intree driver is invoked to query the number of in-flight requests currently outstanding on the QAT_HW device. When this count reaches a configured threshold, subsequent requests are offloaded to QAT_SW rather than being submitted to QAT_HW, achieving co-existence without needing to wait for an explicit RETRY response from the hardware. Note that in intree mode a QAT_HW failure is returned as an error to the caller.

flowchart TD
    A([Crypto Request]) --> B[icp_sal_AsymGetInflightRequests]
    B --> C{Inflight count\n< threshold?}
    C -- Yes --> D[Submit to QAT_HW]
    C -- No  --> E[Route to QAT_SW]
    D --> F{QAT_HW\nComplete?}
    F -- Success --> G([Return Result])
    F -- Error   --> I([Return Error])
    E --> H[Process via\nQAT_SW multibuffer]
    H --> G

    style A fill:#dae8fc,stroke:#6c8ebf,color:#000000
    style G fill:#dae8fc,stroke:#6c8ebf,color:#000000
    style I fill:#f8cecc,stroke:#b85450,color:#000000
    style B fill:#fff2cc,stroke:#d6b656,color:#000000
    style D fill:#fff2cc,stroke:#d6b656,color:#000000
    style E fill:#fff2cc,stroke:#d6b656,color:#000000
    style H fill:#fff2cc,stroke:#d6b656,color:#000000
    style C fill:#f8cecc,stroke:#b85450,color:#000000
    style F fill:#f8cecc,stroke:#b85450,color:#000000
  1. For those algorithms that can achieve stronger performance with QAT_SW, we only use QAT_SW by default. These algorithms include:AES-GCM, ECDSA-P256, SM4-CBC(256-1024 bytes).

  2. For those algorithms that can achieve stronger performance with QAT_HW, the request will be offloaded to QAT_HW first, and after QAT_HW capacity is reached, it will be processed through QAT_SW. These algorithms include: RSA-2K/3K/4K, ECDSA-P384, ECDH-P256/P384/X25519, SM4-CBC(2048-16384 bytes).

    Note: SM4-CBC co-existence (HW + SW) is supported with the OOT driver only. It relies on the QAT_HW RETRY mechanism to trigger QAT_SW fallback. SM4-CBC co-existence is not supported with the intree driver (QAT_HW_INTREE).

  3. It is recommended to set "LimitDevAccess" to 0 in QAT_HW driver config file to utilize all the available device per process for Co-existence mode to fully utilize QAT_HW first and then utilize QAT_SW.

  4. For SM4-CBC (OOT driver only), It is recommended to set "CyNumConcurrentSymRequests" to be smaller to trigger QAT HW RETRY. And The number of async jobs should be appropriate, Number of async requests has to be maintained properly to achieve optimal performance. The following is a best known configuration( tested with 1 QAT DEV using OpenSSL speed App on SPR and the "CyNumConcurrentSymRequests" is set to 64):

    Packet Length1 Multi2 Multi4 Multi8-64 Multi
    16 bytes64 async jobs64 async jobs64 async jobs64 async jobs
    64 bytes64 async jobs64 async jobs64 async jobs64 async jobs
    256 bytes96 async jobs96 async jobs96 async jobs96 async jobs
    1024 bytes96 async jobs96 async jobs96 async jobs96 async jobs
    8192 bytes48 async jobs88 async jobs136 async jobs176 async jobs
    16384 bytes48 async jobs88 async jobs152 async jobs176 async jobs

Run time configuration using HW & SW algorithm bitmap

Note: This section is applicable to the QAT Engine (qatengine) module only and does not apply to the QAT Provider (qatprovider).

Intel® QAT OpenSSL* Engine supports a runtime mechanism to dynamically choose the QAT_HW or QAT_SW or both for each algorithm using the ENGINE ctrl commands: HW_ALGO_BITMAP & SW_ALGO_BITMAP, Bitmap of each algorithm is defined below:

AlgorithmBitHW or SW supported(Priority)
RSA0x00001Both (HW > SW)
DSA0x00002HW
DH0x00004HW
ECDSA0x00008Both (SW > HW for P256) (HW > SW for other curves)
ECDH0x00010Both (HW > SW)
ECX255190x00020Both (HW > SW)
ECX4480x00040HW
PRF0x00080HW
HKDF0x00100HW
SM2(ECDSA)0x00200HW > SW
AES-GCM0x00400Both (SW > HW)
AES-CBC-HMAC-SHA0x00800HW
SM4-CBC0x01000Both (HW > SW)
CHACHA-POLY0x02000HW
SHA30x04000HW
SM30x08000SW
SM4-GCM0x10000SW
SM4-CCM0x20000SW
AES-CCM0x40000HW

Note: ECDH-SM2 is included in ECDH SW group.

If one algorithm is expected to be enabled, the preconditions are:

  1. Supported in configuration, e.g., --enable-qat_hw_gcm.
  2. Enabled in [default algorithm] directive, e.g., RSA/EC/DH/DSA/CIPHER/PKEY/DIGEST/ALL.

Algorithms that are enabled in HW_ALGO_BITMAP will be accelerated via QAT_HW method and algorithms that are enabled in SW_ALGO_BITMAP will be accelerated via QAT_SW method. If an algorithm is enabled in both HW_ALGO_BITMAP and SW_ALGO_BITMAP then the one that has highest priority (listed above) will be accelerated. If none is enabled, OpenSSL SW will be used.

Note:

  1. The default HW_ALGO_BITMAP and SW_ALGO_BITMAP value for each algorithm are set to 0xFFFF, which means all algorithms are enabled by default. If both HW&SW bitmap aren't set, QAT_Engine will offload the algorithm depending on the configuration and [default algorithm] setup.
  2. The XX_ALGO_BITMAP commands are only workable when the corresponding offload mode is enabled, e.g. SW_ALGO_BITMAP is supported only if the QAT_SW is enabled.
  3. In case the QAT_HW&QAT_SW are both enabled, it's recommended to set both HW_ALGO_BITMAP and SW_ALGO_BITMAP in the meantime, disabling the unnecessary and enabling the necessary offload mode for each algorithm.
  4. The offload mode with higher priority must be disabled when you want to enable the lower priority one for each algorithm.

Example 1:
Algorithm combination to be enabled: RSA(HW), ECDSA(HW), ECDH(SW), ECX25519(HW), SM2(SW), AES-GCM(SW). Make sure these algorithms are supported in configuration and already set RSA,EC,PKEY,CIPHER or ALL in the [default algorithm].

HW_ALGO_BITMAP: RSA(0x0001) + ECDSA(0x0008) + ECX25519(0x0020) = 0x0029.
SW_ALGO_BITMAP: ECDH(0x0010) + SM2(0x0200) + AES-GCM(0x0400) = 0x0610.
  • openssl.conf
[qatengine_section]
engine_id = qatengine
default_algorithms = ALL
HW_ALGO_BITMAP = 0x0029
SW_ALGO_BITMAP = 0x0610
  • testapp
./testapp -engine qatengine -async_jobs 1 -c 1 -n 1 -nc 1 -v -hw_algo 0x0029 -sw_algo 0x0610 [test_case]

Example 2:
Lower priority Algorithms need to be enabled: RSA(SW), AES-GCM(HW):

HW_ALGO_BITMAP: 0xFFFF - RSA(0x0001) = 0xFFFE. # Disable the RSA HW BITMAP because it has higher priority.
SW_ALGO_BITMAP: 0xFFFF - AES-GCM(0x0400) = 0xFBFF. # Disable the AES-GCM SW BITMAP because it has higher priority.