From: Arek Kusztal Date: Tue, 22 Oct 2019 14:04:26 +0000 (+0200) Subject: crypto/qat: support RSA in asym X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=e2c5f4ea994cfcaafeb686bcf7b6884f558cb4ba;p=dpdk.git crypto/qat: support RSA in asym This commit adds RSA algorithm to asymmetric pmd using pair (n, d) private key Signed-off-by: Arek Kusztal Acked-by: Fiona Trahe --- diff --git a/doc/guides/cryptodevs/features/qat.ini b/doc/guides/cryptodevs/features/qat.ini index cef8015ea3..374b523f0e 100644 --- a/doc/guides/cryptodevs/features/qat.ini +++ b/doc/guides/cryptodevs/features/qat.ini @@ -14,6 +14,7 @@ OOP LB In SGL Out = Y OOP LB In LB Out = Y Digest encrypted = Y Asymmetric sessionless = Y +RSA PRIV OP KEY EXP = Y ; ; Supported crypto algorithms of the 'qat' crypto driver. @@ -71,3 +72,4 @@ AES CCM (256) = Y [Asymmetric] Modular Exponentiation = Y Modular Inversion = Y +RSA = Y diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst index ad685a7e54..8630e27132 100644 --- a/doc/guides/cryptodevs/qat.rst +++ b/doc/guides/cryptodevs/qat.rst @@ -134,6 +134,7 @@ Limitations * Big integers longer than 4096 bits are not supported. * Queue pairs are not thread-safe (that is, within a single queue pair, RX and TX from different lcores is not supported). +* RSA-2560, RSA-3584 are not supported .. _building_qat: diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 7bda331fa7..e2a37bd137 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -128,6 +128,7 @@ New Features * **Updated the Intel QuickAssist Technology (QAT) asymmetric crypto PMD.** * Added support for asymmetric session-less operations. + * Added support for RSA algorithm with pair (n, d) private key representation. * **Updated the Intel QuickAssist Technology (QAT) compression PMD.** diff --git a/drivers/common/qat/qat_adf/qat_pke_functionality_arrays.h b/drivers/common/qat/qat_adf/qat_pke_functionality_arrays.h index 8adf20959f..3e40b8680b 100644 --- a/drivers/common/qat/qat_adf/qat_pke_functionality_arrays.h +++ b/drivers/common/qat/qat_adf/qat_pke_functionality_arrays.h @@ -49,4 +49,22 @@ static const uint32_t MOD_INV_IDS_EVEN[][2] = { { 4096, MATHS_MODINV_EVEN_L4096 }, }; +static const uint32_t RSA_ENC_IDS[][2] = { + { 512, PKE_RSA_EP_512 }, + { 1024, PKE_RSA_EP_1024 }, + { 1536, PKE_RSA_EP_1536 }, + { 2048, PKE_RSA_EP_2048 }, + { 3072, PKE_RSA_EP_3072 }, + { 4096, PKE_RSA_EP_4096 }, +}; + +static const uint32_t RSA_DEC_IDS[][2] = { + { 512, PKE_RSA_DP1_512 }, + { 1024, PKE_RSA_DP1_1024 }, + { 1536, PKE_RSA_DP1_1536 }, + { 2048, PKE_RSA_DP1_2048 }, + { 3072, PKE_RSA_DP1_3072 }, + { 4096, PKE_RSA_DP1_4096 }, +}; + #endif diff --git a/drivers/crypto/qat/qat_asym.c b/drivers/crypto/qat/qat_asym.c index 1145425d9a..070feb9163 100644 --- a/drivers/crypto/qat/qat_asym.c +++ b/drivers/crypto/qat/qat_asym.c @@ -228,6 +228,171 @@ qat_asym_fill_arrays(struct rte_crypto_asym_op *asym_op, cookie->input_array[1], alg_size_in_bytes); #endif + } else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_RSA) { + err = qat_asym_check_nonzero(xform->rsa.n); + if (err) { + QAT_LOG(ERR, "Empty modulus in RSA" + " inverse, aborting this operation"); + return err; + } + + alg_size_in_bytes = xform->rsa.n.length; + alg_size = alg_size_in_bytes << 3; + + qat_req->input_param_count = + QAT_ASYM_RSA_NUM_IN_PARAMS; + qat_req->output_param_count = + QAT_ASYM_RSA_NUM_OUT_PARAMS; + + if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT || + asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_VERIFY) { + + if (qat_asym_get_sz_and_func_id(RSA_ENC_IDS, + sizeof(RSA_ENC_IDS)/ + sizeof(*RSA_ENC_IDS), + &alg_size, &func_id)) { + err = -(EINVAL); + QAT_LOG(ERR, + "Not supported RSA parameter size (key)"); + return err; + } + alg_size_in_bytes = alg_size >> 3; + if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) { + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(cookie->input_array[0] + + alg_size_in_bytes - + asym_op->rsa.message.length + , asym_op->rsa.message.data, + asym_op->rsa.message.length); + break; + default: + err = -(EINVAL); + QAT_LOG(ERR, + "Invalid RSA padding (Encryption)"); + return err; + } +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Message", + cookie->input_array[0], + alg_size_in_bytes); +#endif + } else { + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(cookie->input_array[0], + asym_op->rsa.sign.data, + alg_size_in_bytes); + break; + default: + err = -(EINVAL); + QAT_LOG(ERR, + "Invalid RSA padding (Verify)"); + return err; + } + +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, " RSA Signature", + cookie->input_array[0], + alg_size_in_bytes); +#endif + + } + rte_memcpy(cookie->input_array[1] + + alg_size_in_bytes - + xform->rsa.e.length + , xform->rsa.e.data, + xform->rsa.e.length); + rte_memcpy(cookie->input_array[2] + + alg_size_in_bytes - + xform->rsa.n.length, + xform->rsa.n.data, + xform->rsa.n.length); + + cookie->alg_size = alg_size; + qat_req->pke_hdr.cd_pars.func_id = func_id; + +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Public Key", + cookie->input_array[1], alg_size_in_bytes); + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Modulus", + cookie->input_array[2], alg_size_in_bytes); +#endif + } else { + if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_DECRYPT) { + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(cookie->input_array[0] + + alg_size_in_bytes - + asym_op->rsa.cipher.length, + asym_op->rsa.cipher.data, + asym_op->rsa.cipher.length); + break; + default: + QAT_LOG(ERR, + "Invalid padding of RSA (Decrypt)"); + return -(EINVAL); + } + + } else if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_SIGN) { + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(cookie->input_array[0] + + alg_size_in_bytes - + asym_op->rsa.message.length, + asym_op->rsa.message.data, + asym_op->rsa.message.length); + break; + default: + QAT_LOG(ERR, + "Invalid padding of RSA (Signature)"); + return -(EINVAL); + } + } + + if (xform->rsa.key_type == RTE_RSA_KET_TYPE_QT) { + QAT_LOG(ERR, "RSA CRT not implemented"); + return -(EINVAL); + } else if (xform->rsa.key_type == + RTE_RSA_KEY_TYPE_EXP) { + if (qat_asym_get_sz_and_func_id( + RSA_DEC_IDS, + sizeof(RSA_DEC_IDS)/ + sizeof(*RSA_DEC_IDS), + &alg_size, &func_id)) { + return -(EINVAL); + } + alg_size_in_bytes = alg_size >> 3; + rte_memcpy(cookie->input_array[1] + + alg_size_in_bytes - + xform->rsa.d.length, + xform->rsa.d.data, + xform->rsa.d.length); + rte_memcpy(cookie->input_array[2] + + alg_size_in_bytes - + xform->rsa.n.length, + xform->rsa.n.data, + xform->rsa.n.length); +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA ciphertext", + cookie->input_array[0], + alg_size_in_bytes); + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA d", cookie->input_array[1], + alg_size_in_bytes); + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA n", cookie->input_array[2], + alg_size_in_bytes); +#endif + + cookie->alg_size = alg_size; + qat_req->pke_hdr.cd_pars.func_id = func_id; + } else { + QAT_LOG(ERR, "Invalid RSA key type"); + return -(EINVAL); + } + } } else { QAT_LOG(ERR, "Invalid asymmetric crypto xform"); return -(EINVAL); @@ -354,6 +519,85 @@ static void qat_asym_collect_response(struct rte_crypto_op *rx_op, alg_size_in_bytes); #endif } + } else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_RSA) { + + alg_size = cookie->alg_size; + alg_size_in_bytes = alg_size >> 3; + if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT || + asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_VERIFY) { + if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_ENCRYPT) { + uint8_t *rsa_result = asym_op->rsa.cipher.data; + + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); + rx_op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Encrypted data", + cookie->output_array[0], + alg_size_in_bytes); +#endif + } else if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_VERIFY) { + uint8_t *rsa_result = asym_op->rsa.cipher.data; + + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); + rx_op->status = + RTE_CRYPTO_OP_STATUS_SUCCESS; +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Signature", + cookie->output_array[0], + alg_size_in_bytes); +#endif + break; + default: + QAT_LOG(ERR, "Padding not supported"); + rx_op->status = + RTE_CRYPTO_OP_STATUS_ERROR; + break; + } + } + } else { + if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_DECRYPT) { + uint8_t *rsa_result = asym_op->rsa.message.data; + + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); + break; + default: + QAT_LOG(ERR, "Padding not supported"); + rx_op->status = + RTE_CRYPTO_OP_STATUS_ERROR; + break; + } +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Decrypted Message", + rsa_result, alg_size_in_bytes); +#endif + } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN) { + uint8_t *rsa_result = asym_op->rsa.sign.data; + + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); + rx_op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Signature", + cookie->output_array[0], + alg_size_in_bytes); +#endif + } + } } qat_clear_arrays_by_alg(cookie, xform->xform_type, alg_size_in_bytes, alg_size_in_bytes); @@ -393,7 +637,7 @@ qat_asym_process_response(void **op, uint8_t *resp, if (rx_op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { ctx = (struct qat_asym_session *)get_asym_session_private_data( - rx_op->asym->session, cryptodev_qat_asym_driver_id); + rx_op->asym->session, cryptodev_qat_asym_driver_id); qat_asym_collect_response(rx_op, cookie, ctx->xform); } else if (rx_op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) { qat_asym_collect_response(rx_op, cookie, rx_op->asym->xform); @@ -436,6 +680,12 @@ qat_asym_session_configure(struct rte_cryptodev *dev, err = -EINVAL; goto error; } + } else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_RSA) { + if (xform->rsa.n.length == 0) { + QAT_LOG(ERR, "Invalid rsa input parameter"); + err = -EINVAL; + goto error; + } } else if (xform->xform_type >= RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END || xform->xform_type <= RTE_CRYPTO_ASYM_XFORM_NONE) { QAT_LOG(ERR, "Invalid asymmetric crypto xform"); diff --git a/drivers/crypto/qat/qat_asym.h b/drivers/crypto/qat/qat_asym.h index 2959b07810..b1dec8f6b9 100644 --- a/drivers/crypto/qat/qat_asym.h +++ b/drivers/crypto/qat/qat_asym.h @@ -22,6 +22,8 @@ typedef uint64_t large_int_ptr; #define QAT_ASYM_MODINV_NUM_OUT_PARAMS 1 #define QAT_ASYM_MODEXP_NUM_IN_PARAMS 3 #define QAT_ASYM_MODEXP_NUM_OUT_PARAMS 1 +#define QAT_ASYM_RSA_NUM_IN_PARAMS 3 +#define QAT_ASYM_RSA_NUM_OUT_PARAMS 1 struct qat_asym_op_cookie { size_t alg_size; diff --git a/drivers/crypto/qat/qat_asym_capabilities.h b/drivers/crypto/qat/qat_asym_capabilities.h index f43c025fc7..523b4da6d3 100644 --- a/drivers/crypto/qat/qat_asym_capabilities.h +++ b/drivers/crypto/qat/qat_asym_capabilities.h @@ -37,6 +37,27 @@ } \ }, \ } \ + }, \ + { /* RSA */ \ + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC, \ + {.asym = { \ + .xform_capa = { \ + .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA, \ + .op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) | \ + (1 << RTE_CRYPTO_ASYM_OP_VERIFY) | \ + (1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) | \ + (1 << RTE_CRYPTO_ASYM_OP_DECRYPT)), \ + { \ + .modlen = { \ + /* min length is based on openssl rsa keygen */ \ + .min = 64, \ + /* value 0 symbolizes no limit on max length */ \ + .max = 512, \ + .increment = 64 \ + }, } \ + } \ + }, \ + } \ } \ #endif /* _QAT_ASYM_CAPABILITIES_H_ */ diff --git a/drivers/crypto/qat/qat_asym_pmd.c b/drivers/crypto/qat/qat_asym_pmd.c index 71fd7090e0..78fc2d723e 100644 --- a/drivers/crypto/qat/qat_asym_pmd.c +++ b/drivers/crypto/qat/qat_asym_pmd.c @@ -271,7 +271,8 @@ qat_asym_dev_create(struct qat_pci_device *qat_pci_dev) cryptodev->feature_flags = RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO | RTE_CRYPTODEV_FF_HW_ACCELERATED | - RTE_CRYPTODEV_FF_ASYM_SESSIONLESS; + RTE_CRYPTODEV_FF_ASYM_SESSIONLESS | + RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP; internals = cryptodev->data->dev_private; internals->qat_dev = qat_pci_dev; qat_pci_dev->asym_dev = internals;