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