AES GCM on the cryptodev API was giving invalid results
in some cases, due to an incorrect IV setting.

Added AES GCM in the QAT supported algorithms,
as encryption/decryption is fully functional.

Fixes: 1703e94ac5ce ("qat: add driver for QuickAssist devices")

Signed-off-by: John Griffin <john.griffin at intel.com>
---
 doc/guides/cryptodevs/qat.rst          |  1 +
 doc/guides/rel_notes/release_16_04.rst |  5 +++++
 drivers/crypto/qat/qat_crypto.c        | 22 +++++++++++++++++++---
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst
index af52047..ec4d6c6 100644
--- a/doc/guides/cryptodevs/qat.rst
+++ b/doc/guides/cryptodevs/qat.rst
@@ -48,6 +48,7 @@ Cipher algorithms:
 * ``RTE_CRYPTO_SYM_CIPHER_AES192_CBC``
 * ``RTE_CRYPTO_SYM_CIPHER_AES256_CBC``
 * ``RTE_CRYPTO_SYM_CIPHER_SNOW3G_UEA2``
+* ``RTE_CRYPTO_CIPHER_AES_GCM``

 Hash algorithms:

diff --git a/doc/guides/rel_notes/release_16_04.rst 
b/doc/guides/rel_notes/release_16_04.rst
index d7a264a..ee8d141 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -99,6 +99,11 @@ Drivers
   This made impossible the creation of more than one aesni_mb device
   from command line.

+* **qat: Fixed AES GCM decryption.**
+
+  Allowed AES GCM on the cryptodev API, but in some cases gave invalid results
+  due to incorrect IV setting.
+

 Libraries
 ~~~~~~~~~
diff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c
index cb16aae..48e810f 100644
--- a/drivers/crypto/qat/qat_crypto.c
+++ b/drivers/crypto/qat/qat_crypto.c
@@ -529,11 +529,27 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t 
*out_msg)
        auth_param->u1.aad_adr = op->sym->auth.aad.phys_addr;
        /* (GCM) aad length(240 max) will be at this location after precompute 
*/
        if (ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128 ||
-               ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64) {
-               auth_param->u2.aad_sz =
-               ALIGN_POW2_ROUNDUP(ctx->cd.hash.sha.state1[
+                       ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64) {
+               struct icp_qat_hw_auth_algo_blk *hash;
+
+               if (ctx->qat_cmd == ICP_QAT_FW_LA_CMD_HASH_CIPHER)
+                       hash = (struct icp_qat_hw_auth_algo_blk *)((char 
*)&ctx->cd);
+               else
+                       hash = (struct icp_qat_hw_auth_algo_blk *)((char 
*)&ctx->cd +
+                               sizeof(struct icp_qat_hw_cipher_algo_blk));
+
+               auth_param->u2.aad_sz = ALIGN_POW2_ROUNDUP(hash->sha.state1[
                                        ICP_QAT_HW_GALOIS_128_STATE1_SZ +
                                        ICP_QAT_HW_GALOIS_H_SZ + 3], 16);
+               if (op->sym->cipher.iv.length == 12) {
+                       /*
+                        * For GCM a 12 bit IV is allowed,
+                        * but we need to inform the f/w
+                        */
+                       ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET(
+                               qat_req->comn_hdr.serv_specif_flags,
+                               ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS);
+               }
        }
        auth_param->hash_state_sz = (auth_param->u2.aad_sz) >> 3;

-- 
2.1.0

Reply via email to