qat: fix AES-GCM decryption
authorJohn Griffin <john.griffin@intel.com>
Tue, 8 Mar 2016 16:22:15 +0000 (16:22 +0000)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Fri, 11 Mar 2016 00:31:55 +0000 (01:31 +0100)
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@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
doc/guides/cryptodevs/qat.rst
doc/guides/rel_notes/release_16_04.rst
drivers/crypto/qat/qat_crypto.c

index 8f09d32..a3090f5 100644 (file)
@@ -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:
 
index 8b82492..e978efe 100644 (file)
@@ -122,6 +122,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
 ~~~~~~~~~
index 9ddd333..f267da5 100644 (file)
@@ -553,11 +553,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;