X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fcrypto%2Fopenssl%2Frte_openssl_pmd.c;h=f584d0d6f14958b9ff0e7b79a8c29b04b5a4d0db;hb=340b7bb8d583661369a9491ade63fe2407e85267;hp=cd80b99551bd8632fa2b9df52bb096896b6d0ed7;hpb=b4b86b09f2c0ecdd00ba87c48b55ef5801ba602d;p=dpdk.git diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index cd80b99551..f584d0d6f1 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -1,41 +1,12 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2016-2017 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation */ #include #include #include #include -#include -#include +#include #include #include @@ -287,6 +258,21 @@ get_aead_algo(enum rte_crypto_aead_algorithm sess_algo, size_t keylen, res = -EINVAL; } break; + case RTE_CRYPTO_AEAD_AES_CCM: + switch (keylen) { + case 16: + *algo = EVP_aes_128_ccm(); + break; + case 24: + *algo = EVP_aes_192_ccm(); + break; + case 32: + *algo = EVP_aes_256_ccm(); + break; + default: + res = -EINVAL; + } + break; default: res = -EINVAL; break; @@ -305,6 +291,7 @@ openssl_set_sess_aead_enc_param(struct openssl_session *sess, uint8_t tag_len, uint8_t *key) { int iv_type = 0; + unsigned int do_ccm; sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_ENCRYPT; sess->auth.operation = RTE_CRYPTO_AUTH_OP_GENERATE; @@ -315,6 +302,14 @@ openssl_set_sess_aead_enc_param(struct openssl_session *sess, iv_type = EVP_CTRL_GCM_SET_IVLEN; if (tag_len != 16) return -EINVAL; + do_ccm = 0; + break; + case RTE_CRYPTO_AEAD_AES_CCM: + iv_type = EVP_CTRL_CCM_SET_IVLEN; + /* Digest size can be 4, 6, 8, 10, 12, 14 or 16 bytes */ + if (tag_len < 4 || tag_len > 16 || (tag_len & 1) == 1) + return -EINVAL; + do_ccm = 1; break; default: return -ENOTSUP; @@ -339,6 +334,10 @@ openssl_set_sess_aead_enc_param(struct openssl_session *sess, NULL) <= 0) return -EINVAL; + if (do_ccm) + EVP_CIPHER_CTX_ctrl(sess->cipher.ctx, EVP_CTRL_CCM_SET_TAG, + tag_len, NULL); + if (EVP_EncryptInit_ex(sess->cipher.ctx, NULL, NULL, key, NULL) <= 0) return -EINVAL; @@ -352,6 +351,7 @@ openssl_set_sess_aead_dec_param(struct openssl_session *sess, uint8_t tag_len, uint8_t *key) { int iv_type = 0; + unsigned int do_ccm = 0; sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_DECRYPT; sess->auth.operation = RTE_CRYPTO_AUTH_OP_VERIFY; @@ -363,6 +363,13 @@ openssl_set_sess_aead_dec_param(struct openssl_session *sess, if (tag_len != 16) return -EINVAL; break; + case RTE_CRYPTO_AEAD_AES_CCM: + iv_type = EVP_CTRL_CCM_SET_IVLEN; + /* Digest size can be 4, 6, 8, 10, 12, 14 or 16 bytes */ + if (tag_len < 4 || tag_len > 16 || (tag_len & 1) == 1) + return -EINVAL; + do_ccm = 1; + break; default: return -ENOTSUP; } @@ -386,6 +393,10 @@ openssl_set_sess_aead_dec_param(struct openssl_session *sess, sess->iv.length, NULL) <= 0) return -EINVAL; + if (do_ccm) + EVP_CIPHER_CTX_ctrl(sess->cipher.ctx, EVP_CTRL_CCM_SET_TAG, + tag_len, NULL); + if (EVP_DecryptInit_ex(sess->cipher.ctx, NULL, NULL, key, NULL) <= 0) return -EINVAL; @@ -600,7 +611,16 @@ openssl_set_session_aead_parameters(struct openssl_session *sess, sess->cipher.key.length = xform->aead.key.length; /* Set IV parameters */ - sess->iv.offset = xform->aead.iv.offset; + if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) + /* + * For AES-CCM, the actual IV is placed + * one byte after the start of the IV field, + * according to the API. + */ + sess->iv.offset = xform->aead.iv.offset + 1; + else + sess->iv.offset = xform->aead.iv.offset; + sess->iv.length = xform->aead.iv.length; sess->auth.aad_length = xform->aead.aad_length; @@ -973,7 +993,7 @@ process_cipher_des3ctr_err: return -EINVAL; } -/** Process auth/encription aes-gcm algorithm */ +/** Process AES-GCM encrypt algorithm */ static int process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset, int srclen, uint8_t *aad, int aadlen, uint8_t *iv, @@ -1011,6 +1031,48 @@ process_auth_encryption_gcm_err: return -EINVAL; } +/** Process AES-CCM encrypt algorithm */ +static int +process_openssl_auth_encryption_ccm(struct rte_mbuf *mbuf_src, int offset, + int srclen, uint8_t *aad, int aadlen, uint8_t *iv, + uint8_t *dst, uint8_t *tag, uint8_t taglen, EVP_CIPHER_CTX *ctx) +{ + int len = 0; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) + goto process_auth_encryption_ccm_err; + + if (EVP_EncryptUpdate(ctx, NULL, &len, NULL, srclen) <= 0) + goto process_auth_encryption_ccm_err; + + if (aadlen > 0) + /* + * For AES-CCM, the actual AAD is placed + * 18 bytes after the start of the AAD field, + * according to the API. + */ + if (EVP_EncryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0) + goto process_auth_encryption_ccm_err; + + if (srclen > 0) + if (process_openssl_encryption_update(mbuf_src, offset, &dst, + srclen, ctx)) + goto process_auth_encryption_ccm_err; + + if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0) + goto process_auth_encryption_ccm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, taglen, tag) <= 0) + goto process_auth_encryption_ccm_err; + + return 0; + +process_auth_encryption_ccm_err: + OPENSSL_LOG_ERR("Process openssl auth encryption ccm failed"); + return -EINVAL; +} + +/** Process AES-GCM decrypt algorithm */ static int process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset, int srclen, uint8_t *aad, int aadlen, uint8_t *iv, @@ -1039,16 +1101,52 @@ process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset, goto process_auth_decryption_gcm_err; if (EVP_DecryptFinal_ex(ctx, dst, &len) <= 0) - goto process_auth_decryption_gcm_final_err; + return -EFAULT; return 0; process_auth_decryption_gcm_err: - OPENSSL_LOG_ERR("Process openssl auth description gcm failed"); + OPENSSL_LOG_ERR("Process openssl auth decryption gcm failed"); return -EINVAL; +} -process_auth_decryption_gcm_final_err: - return -EFAULT; +/** Process AES-CCM decrypt algorithm */ +static int +process_openssl_auth_decryption_ccm(struct rte_mbuf *mbuf_src, int offset, + int srclen, uint8_t *aad, int aadlen, uint8_t *iv, + uint8_t *dst, uint8_t *tag, uint8_t tag_len, + EVP_CIPHER_CTX *ctx) +{ + int len = 0; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_len, tag) <= 0) + goto process_auth_decryption_ccm_err; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) + goto process_auth_decryption_ccm_err; + + if (EVP_DecryptUpdate(ctx, NULL, &len, NULL, srclen) <= 0) + goto process_auth_decryption_ccm_err; + + if (aadlen > 0) + /* + * For AES-CCM, the actual AAD is placed + * 18 bytes after the start of the AAD field, + * according to the API. + */ + if (EVP_DecryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0) + goto process_auth_decryption_ccm_err; + + if (srclen > 0) + if (process_openssl_decryption_update(mbuf_src, offset, &dst, + srclen, ctx)) + return -EFAULT; + + return 0; + +process_auth_decryption_ccm_err: + OPENSSL_LOG_ERR("Process openssl auth decryption ccm failed"); + return -EINVAL; } /** Process standard openssl auth algorithms */ @@ -1169,6 +1267,7 @@ process_openssl_combined_op uint8_t *dst = NULL, *iv, *tag, *aad; int srclen, aadlen, status = -1; uint32_t offset; + uint8_t taglen; /* * Segmented destination buffer is not supported for @@ -1204,16 +1303,34 @@ process_openssl_combined_op offset + srclen); } - if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) - status = process_openssl_auth_encryption_gcm( - mbuf_src, offset, srclen, - aad, aadlen, iv, - dst, tag, sess->cipher.ctx); - else - status = process_openssl_auth_decryption_gcm( - mbuf_src, offset, srclen, - aad, aadlen, iv, - dst, tag, sess->cipher.ctx); + taglen = sess->auth.digest_length; + + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { + if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC || + sess->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) + status = process_openssl_auth_encryption_gcm( + mbuf_src, offset, srclen, + aad, aadlen, iv, + dst, tag, sess->cipher.ctx); + else + status = process_openssl_auth_encryption_ccm( + mbuf_src, offset, srclen, + aad, aadlen, iv, + dst, tag, taglen, sess->cipher.ctx); + + } else { + if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC || + sess->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) + status = process_openssl_auth_decryption_gcm( + mbuf_src, offset, srclen, + aad, aadlen, iv, + dst, tag, sess->cipher.ctx); + else + status = process_openssl_auth_decryption_ccm( + mbuf_src, offset, srclen, + aad, aadlen, iv, + dst, tag, taglen, sess->cipher.ctx); + } if (status != 0) { if (status == (-EFAULT) && @@ -1522,19 +1639,12 @@ openssl_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, static int cryptodev_openssl_create(const char *name, struct rte_vdev_device *vdev, - struct rte_crypto_vdev_init_params *init_params) + struct rte_cryptodev_pmd_init_params *init_params) { struct rte_cryptodev *dev; struct openssl_private *internals; - if (init_params->name[0] == '\0') - snprintf(init_params->name, sizeof(init_params->name), - "%s", name); - - dev = rte_cryptodev_vdev_pmd_init(init_params->name, - sizeof(struct openssl_private), - init_params->socket_id, - vdev); + dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params); if (dev == NULL) { OPENSSL_LOG_ERR("failed to create cryptodev vdev"); goto init_error; @@ -1572,11 +1682,12 @@ init_error: static int cryptodev_openssl_probe(struct rte_vdev_device *vdev) { - struct rte_crypto_vdev_init_params init_params = { - RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS, - RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS, + struct rte_cryptodev_pmd_init_params init_params = { + "", + sizeof(struct openssl_private), rte_socket_id(), - {0} + RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS, + RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS }; const char *name; const char *input_args; @@ -1586,17 +1697,7 @@ cryptodev_openssl_probe(struct rte_vdev_device *vdev) return -EINVAL; input_args = rte_vdev_device_args(vdev); - rte_cryptodev_vdev_parse_init_params(&init_params, input_args); - - RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name, - init_params.socket_id); - if (init_params.name[0] != '\0') - RTE_LOG(INFO, PMD, " User defined name = %s\n", - init_params.name); - RTE_LOG(INFO, PMD, " Max number of queue pairs = %d\n", - init_params.max_nb_queue_pairs); - RTE_LOG(INFO, PMD, " Max number of sessions = %d\n", - init_params.max_nb_sessions); + rte_cryptodev_pmd_parse_input_args(&init_params, input_args); return cryptodev_openssl_create(name, vdev, &init_params); } @@ -1605,17 +1706,18 @@ cryptodev_openssl_probe(struct rte_vdev_device *vdev) static int cryptodev_openssl_remove(struct rte_vdev_device *vdev) { + struct rte_cryptodev *cryptodev; const char *name; name = rte_vdev_device_name(vdev); if (name == NULL) return -EINVAL; - RTE_LOG(INFO, PMD, - "Closing OPENSSL crypto device %s on numa socket %u\n", - name, rte_socket_id()); + cryptodev = rte_cryptodev_pmd_get_named_dev(name); + if (cryptodev == NULL) + return -ENODEV; - return 0; + return rte_cryptodev_pmd_destroy(cryptodev); } static struct rte_vdev_driver cryptodev_openssl_pmd_drv = { @@ -1631,5 +1733,5 @@ RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_OPENSSL_PMD, "max_nb_queue_pairs= " "max_nb_sessions= " "socket_id="); -RTE_PMD_REGISTER_CRYPTO_DRIVER(openssl_crypto_drv, cryptodev_openssl_pmd_drv, - cryptodev_driver_id); +RTE_PMD_REGISTER_CRYPTO_DRIVER(openssl_crypto_drv, + cryptodev_openssl_pmd_drv.driver, cryptodev_driver_id);