X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcrypto%2Fopenssl%2Frte_openssl_pmd.c;h=5794ed8159c0b9d64ae742ab81e30c3c1f5ed59b;hb=25d703151d3c1183c29623dad24b54b48ddcfba0;hp=a0ccacb1e482e547530e22dd0bad4230e7bf5bd6;hpb=2680b69c7bd577ac07c799304eb21bc8e72fc4cd;p=dpdk.git diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index a0ccacb1e4..5794ed8159 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -13,7 +13,7 @@ #include #include -#include "rte_openssl_pmd_private.h" +#include "openssl_pmd_private.h" #include "compat.h" #define DES_BLOCK_SIZE 8 @@ -92,14 +92,14 @@ openssl_get_chain_order(const struct rte_crypto_sym_xform *xform) /** Get session cipher key from input cipher key */ static void -get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key) +get_cipher_key(const uint8_t *input_key, int keylen, uint8_t *session_key) { memcpy(session_key, input_key, keylen); } /** Get key ede 24 bytes standard from input key */ static int -get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede) +get_cipher_key_ede(const uint8_t *key, int keylen, uint8_t *key_ede) { int res = 0; @@ -292,7 +292,7 @@ get_aead_algo(enum rte_crypto_aead_algorithm sess_algo, size_t keylen, static int openssl_set_sess_aead_enc_param(struct openssl_session *sess, enum rte_crypto_aead_algorithm algo, - uint8_t tag_len, uint8_t *key) + uint8_t tag_len, const uint8_t *key) { int iv_type = 0; unsigned int do_ccm; @@ -352,7 +352,7 @@ openssl_set_sess_aead_enc_param(struct openssl_session *sess, static int openssl_set_sess_aead_dec_param(struct openssl_session *sess, enum rte_crypto_aead_algorithm algo, - uint8_t tag_len, uint8_t *key) + uint8_t tag_len, const uint8_t *key) { int iv_type = 0; unsigned int do_ccm = 0; @@ -762,13 +762,14 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op) return NULL; /* provide internal session */ - void *_sess = NULL; + void *_sess = rte_cryptodev_sym_session_create(qp->sess_mp); void *_sess_private_data = NULL; - if (rte_mempool_get(qp->sess_mp, (void **)&_sess)) + if (_sess == NULL) return NULL; - if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data)) + if (rte_mempool_get(qp->sess_mp_priv, + (void **)&_sess_private_data)) return NULL; sess = (struct openssl_session *)_sess_private_data; @@ -776,7 +777,7 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op) if (unlikely(openssl_set_session_parameters(sess, op->sym->xform) != 0)) { rte_mempool_put(qp->sess_mp, _sess); - rte_mempool_put(qp->sess_mp, _sess_private_data); + rte_mempool_put(qp->sess_mp_priv, _sess_private_data); sess = NULL; } op->sym->session = (struct rte_cryptodev_sym_session *)_sess; @@ -797,12 +798,12 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op) */ static inline int process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset, - uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx) + uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace) { struct rte_mbuf *m; int dstlen; int l, n = srclen; - uint8_t *src; + uint8_t *src, temp[EVP_CIPHER_CTX_block_size(ctx)]; for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m); m = m->next) @@ -812,6 +813,8 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset, return -1; src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset); + if (inplace) + *dst = src; l = rte_pktmbuf_data_len(m) - offset; if (srclen <= l) { @@ -828,8 +831,24 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset, n -= l; for (m = m->next; (m != NULL) && (n > 0); m = m->next) { + uint8_t diff = l - dstlen, rem; + src = rte_pktmbuf_mtod(m, uint8_t *); - l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n; + l = RTE_MIN(rte_pktmbuf_data_len(m), n); + if (diff && inplace) { + rem = RTE_MIN(l, + (EVP_CIPHER_CTX_block_size(ctx) - diff)); + if (EVP_EncryptUpdate(ctx, temp, + &dstlen, src, rem) <= 0) + return -1; + n -= rem; + rte_memcpy(*dst, temp, diff); + rte_memcpy(src, temp + diff, rem); + src += rem; + l -= rem; + } + if (inplace) + *dst = src; if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0) return -1; *dst += dstlen; @@ -841,12 +860,12 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset, static inline int process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset, - uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx) + uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace) { struct rte_mbuf *m; int dstlen; int l, n = srclen; - uint8_t *src; + uint8_t *src, temp[EVP_CIPHER_CTX_block_size(ctx)]; for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m); m = m->next) @@ -856,6 +875,8 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset, return -1; src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset); + if (inplace) + *dst = src; l = rte_pktmbuf_data_len(m) - offset; if (srclen <= l) { @@ -872,8 +893,24 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset, n -= l; for (m = m->next; (m != NULL) && (n > 0); m = m->next) { + uint8_t diff = l - dstlen, rem; + src = rte_pktmbuf_mtod(m, uint8_t *); - l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n; + l = RTE_MIN(rte_pktmbuf_data_len(m), n); + if (diff && inplace) { + rem = RTE_MIN(l, + (EVP_CIPHER_CTX_block_size(ctx) - diff)); + if (EVP_DecryptUpdate(ctx, temp, + &dstlen, src, rem) <= 0) + return -1; + n -= rem; + rte_memcpy(*dst, temp, diff); + rte_memcpy(src, temp + diff, rem); + src += rem; + l -= rem; + } + if (inplace) + *dst = src; if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0) return -1; *dst += dstlen; @@ -886,7 +923,8 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset, /** Process standard openssl cipher encryption */ static int process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst, - int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx) + int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx, + uint8_t inplace) { int totlen; @@ -896,7 +934,7 @@ process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst, EVP_CIPHER_CTX_set_padding(ctx, 0); if (process_openssl_encryption_update(mbuf_src, offset, &dst, - srclen, ctx)) + srclen, ctx, inplace)) goto process_cipher_encrypt_err; if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0) @@ -935,7 +973,8 @@ process_cipher_encrypt_err: /** Process standard openssl cipher decryption */ static int process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst, - int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx) + int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx, + uint8_t inplace) { int totlen; @@ -945,7 +984,7 @@ process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst, EVP_CIPHER_CTX_set_padding(ctx, 0); if (process_openssl_decryption_update(mbuf_src, offset, &dst, - srclen, ctx)) + srclen, ctx, inplace)) goto process_cipher_decrypt_err; if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0) @@ -1032,7 +1071,7 @@ process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset, if (srclen > 0) if (process_openssl_encryption_update(mbuf_src, offset, &dst, - srclen, ctx)) + srclen, ctx, 0)) goto process_auth_encryption_gcm_err; /* Workaround open ssl bug in version less then 1.0.1f */ @@ -1075,9 +1114,9 @@ process_openssl_auth_encryption_ccm(struct rte_mbuf *mbuf_src, int offset, if (EVP_EncryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0) goto process_auth_encryption_ccm_err; - if (srclen > 0) + if (srclen >= 0) if (process_openssl_encryption_update(mbuf_src, offset, &dst, - srclen, ctx)) + srclen, ctx, 0)) goto process_auth_encryption_ccm_err; if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0) @@ -1114,7 +1153,7 @@ process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset, if (srclen > 0) if (process_openssl_decryption_update(mbuf_src, offset, &dst, - srclen, ctx)) + srclen, ctx, 0)) goto process_auth_decryption_gcm_err; /* Workaround open ssl bug in version less then 1.0.1f */ @@ -1158,9 +1197,9 @@ process_openssl_auth_decryption_ccm(struct rte_mbuf *mbuf_src, int offset, if (EVP_DecryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0) goto process_auth_decryption_ccm_err; - if (srclen > 0) + if (srclen >= 0) if (process_openssl_decryption_update(mbuf_src, offset, &dst, - srclen, ctx)) + srclen, ctx, 0)) return -EFAULT; return 0; @@ -1289,6 +1328,7 @@ process_openssl_combined_op int srclen, aadlen, status = -1; uint32_t offset; uint8_t taglen; + EVP_CIPHER_CTX *ctx_copy; /* * Segmented destination buffer is not supported for @@ -1325,6 +1365,8 @@ process_openssl_combined_op } taglen = sess->auth.digest_length; + ctx_copy = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX_copy(ctx_copy, sess->cipher.ctx); if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC || @@ -1332,12 +1374,12 @@ process_openssl_combined_op status = process_openssl_auth_encryption_gcm( mbuf_src, offset, srclen, aad, aadlen, iv, - dst, tag, sess->cipher.ctx); + dst, tag, ctx_copy); else status = process_openssl_auth_encryption_ccm( mbuf_src, offset, srclen, aad, aadlen, iv, - dst, tag, taglen, sess->cipher.ctx); + dst, tag, taglen, ctx_copy); } else { if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC || @@ -1345,14 +1387,15 @@ process_openssl_combined_op status = process_openssl_auth_decryption_gcm( mbuf_src, offset, srclen, aad, aadlen, iv, - dst, tag, sess->cipher.ctx); + dst, tag, ctx_copy); else status = process_openssl_auth_decryption_ccm( mbuf_src, offset, srclen, aad, aadlen, iv, - dst, tag, taglen, sess->cipher.ctx); + dst, tag, taglen, ctx_copy); } + EVP_CIPHER_CTX_free(ctx_copy); if (status != 0) { if (status == (-EFAULT) && sess->auth.operation == @@ -1371,12 +1414,16 @@ process_openssl_cipher_op { uint8_t *dst, *iv; int srclen, status; + uint8_t inplace = (mbuf_src == mbuf_dst) ? 1 : 0; + EVP_CIPHER_CTX *ctx_copy; /* - * Segmented destination buffer is not supported for - * encryption/decryption + * Segmented OOP destination buffer is not supported for encryption/ + * decryption. In case of des3ctr, even inplace segmented buffers are + * not supported. */ - if (!rte_pktmbuf_is_contiguous(mbuf_dst)) { + if (!rte_pktmbuf_is_contiguous(mbuf_dst) && + (!inplace || sess->cipher.mode != OPENSSL_CIPHER_LIB)) { op->status = RTE_CRYPTO_OP_STATUS_ERROR; return; } @@ -1387,22 +1434,25 @@ process_openssl_cipher_op iv = rte_crypto_op_ctod_offset(op, uint8_t *, sess->iv.offset); + ctx_copy = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX_copy(ctx_copy, sess->cipher.ctx); if (sess->cipher.mode == OPENSSL_CIPHER_LIB) if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) status = process_openssl_cipher_encrypt(mbuf_src, dst, op->sym->cipher.data.offset, iv, - srclen, sess->cipher.ctx); + srclen, ctx_copy, inplace); else status = process_openssl_cipher_decrypt(mbuf_src, dst, op->sym->cipher.data.offset, iv, - srclen, sess->cipher.ctx); + srclen, ctx_copy, inplace); else status = process_openssl_cipher_des3ctr(mbuf_src, dst, op->sym->cipher.data.offset, iv, sess->cipher.key.data, srclen, - sess->cipher.ctx); + ctx_copy); + EVP_CIPHER_CTX_free(ctx_copy); if (status != 0) op->status = RTE_CRYPTO_OP_STATUS_ERROR; } @@ -1440,7 +1490,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op *op, /* Encrypt with the block aligned stream with CBC mode */ status = process_openssl_cipher_encrypt(mbuf_src, dst, op->sym->cipher.data.offset, iv, - srclen, sess->cipher.ctx); + srclen, sess->cipher.ctx, 0); if (last_block_len) { /* Point at last block */ dst += srclen; @@ -1490,7 +1540,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op *op, /* Decrypt with CBC mode */ status |= process_openssl_cipher_decrypt(mbuf_src, dst, op->sym->cipher.data.offset, iv, - srclen, sess->cipher.ctx); + srclen, sess->cipher.ctx, 0); } } @@ -1506,6 +1556,8 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op, { uint8_t *dst; int srclen, status; + EVP_MD_CTX *ctx_a; + HMAC_CTX *ctx_h; srclen = op->sym->auth.data.length; @@ -1513,14 +1565,20 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op, switch (sess->auth.mode) { case OPENSSL_AUTH_AS_AUTH: + ctx_a = EVP_MD_CTX_create(); + EVP_MD_CTX_copy_ex(ctx_a, sess->auth.auth.ctx); status = process_openssl_auth(mbuf_src, dst, op->sym->auth.data.offset, NULL, NULL, srclen, - sess->auth.auth.ctx, sess->auth.auth.evp_algo); + ctx_a, sess->auth.auth.evp_algo); + EVP_MD_CTX_destroy(ctx_a); break; case OPENSSL_AUTH_AS_HMAC: + ctx_h = HMAC_CTX_new(); + HMAC_CTX_copy(ctx_h, sess->auth.hmac.ctx); status = process_openssl_auth_hmac(mbuf_src, dst, op->sym->auth.data.offset, srclen, - sess->auth.hmac.ctx); + ctx_h); + HMAC_CTX_free(ctx_h); break; default: status = -1; @@ -1528,7 +1586,7 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op, } if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { - if (memcmp(dst, op->sym->auth.digest.data, + if (CRYPTO_memcmp(dst, op->sym->auth.digest.data, sess->auth.digest_length) != 0) { op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; } @@ -1789,11 +1847,14 @@ process_openssl_modinv_op(struct rte_crypto_op *cop, if (BN_mod_inverse(res, base, sess->u.m.modulus, sess->u.m.ctx)) { cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; - op->modinv.base.length = BN_bn2bin(res, op->modinv.base.data); + op->modinv.result.length = BN_bn2bin(res, op->modinv.result.data); } else { cop->status = RTE_CRYPTO_OP_STATUS_ERROR; } + BN_clear(res); + BN_clear(base); + return 0; } @@ -1813,17 +1874,20 @@ process_openssl_modexp_op(struct rte_crypto_op *cop, return -1; } - base = BN_bin2bn((const unsigned char *)op->modinv.base.data, - op->modinv.base.length, base); + base = BN_bin2bn((const unsigned char *)op->modex.base.data, + op->modex.base.length, base); if (BN_mod_exp(res, base, sess->u.e.exp, sess->u.e.mod, sess->u.e.ctx)) { - op->modinv.base.length = BN_bn2bin(res, op->modinv.base.data); + op->modex.result.length = BN_bn2bin(res, op->modex.result.data); cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; } else { cop->status = RTE_CRYPTO_OP_STATUS_ERROR; } + BN_clear(res); + BN_clear(base); + return 0; } @@ -1841,9 +1905,7 @@ process_openssl_rsa_op(struct rte_crypto_op *cop, cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; switch (pad) { - case RTE_CRYPTO_RSA_PKCS1_V1_5_BT0: - case RTE_CRYPTO_RSA_PKCS1_V1_5_BT1: - case RTE_CRYPTO_RSA_PKCS1_V1_5_BT2: + case RTE_CRYPTO_RSA_PADDING_PKCS1_5: pad = RSA_PKCS1_PADDING; break; case RTE_CRYPTO_RSA_PADDING_NONE: @@ -1860,19 +1922,19 @@ process_openssl_rsa_op(struct rte_crypto_op *cop, case RTE_CRYPTO_ASYM_OP_ENCRYPT: ret = RSA_public_encrypt(op->rsa.message.length, op->rsa.message.data, - op->rsa.message.data, + op->rsa.cipher.data, rsa, pad); if (ret > 0) - op->rsa.message.length = ret; + op->rsa.cipher.length = ret; OPENSSL_LOG(DEBUG, "length of encrypted text %d\n", ret); break; case RTE_CRYPTO_ASYM_OP_DECRYPT: - ret = RSA_private_decrypt(op->rsa.message.length, - op->rsa.message.data, + ret = RSA_private_decrypt(op->rsa.cipher.length, + op->rsa.cipher.data, op->rsa.message.data, rsa, pad); @@ -1907,7 +1969,7 @@ process_openssl_rsa_op(struct rte_crypto_op *cop, "Length of public_decrypt %d " "length of message %zd\n", ret, op->rsa.message.length); - if ((ret <= 0) || (memcmp(tmp, op->rsa.message.data, + if ((ret <= 0) || (CRYPTO_memcmp(tmp, op->rsa.message.data, op->rsa.message.length))) { OPENSSL_LOG(ERR, "RSA sign Verification failed"); cop->status = RTE_CRYPTO_OP_STATUS_ERROR; @@ -1975,6 +2037,26 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op, return retval; } +static void +copy_plaintext(struct rte_mbuf *m_src, struct rte_mbuf *m_dst, + struct rte_crypto_op *op) +{ + uint8_t *p_src, *p_dst; + + p_src = rte_pktmbuf_mtod(m_src, uint8_t *); + p_dst = rte_pktmbuf_mtod(m_dst, uint8_t *); + + /** + * Copy the content between cipher offset and auth offset + * for generating correct digest. + */ + if (op->sym->cipher.data.offset > op->sym->auth.data.offset) + memcpy(p_dst + op->sym->auth.data.offset, + p_src + op->sym->auth.data.offset, + op->sym->cipher.data.offset - + op->sym->auth.data.offset); +} + /** Process crypto operation for mbuf */ static int process_op(struct openssl_qp *qp, struct rte_crypto_op *op, @@ -1997,6 +2079,9 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op, break; case OPENSSL_CHAIN_CIPHER_AUTH: process_openssl_cipher_op(op, sess, msrc, mdst); + /* OOP */ + if (msrc != mdst) + copy_plaintext(msrc, mdst, op); process_openssl_auth_op(qp, op, sess, mdst, mdst); break; case OPENSSL_CHAIN_AUTH_CIPHER: @@ -2019,8 +2104,9 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op, openssl_reset_session(sess); memset(sess, 0, sizeof(struct openssl_session)); memset(op->sym->session, 0, - rte_cryptodev_sym_get_header_session_size()); - rte_mempool_put(qp->sess_mp, sess); + rte_cryptodev_sym_get_existing_header_session_size( + op->sym->session)); + rte_mempool_put(qp->sess_mp_priv, sess); rte_mempool_put(qp->sess_mp, op->sym->session); op->sym->session = NULL; } @@ -2115,15 +2201,20 @@ cryptodev_openssl_create(const char *name, dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | RTE_CRYPTODEV_FF_CPU_AESNI | + RTE_CRYPTODEV_FF_IN_PLACE_SGL | RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT | RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT | - RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO; + RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO | + RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP | + RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT | + RTE_CRYPTODEV_FF_SYM_SESSIONLESS; - /* Set vector instructions mode supported */ internals = dev->data->dev_private; internals->max_nb_qpairs = init_params->max_nb_queue_pairs; + rte_cryptodev_pmd_probing_finish(dev); + return 0; init_error: @@ -2189,8 +2280,4 @@ RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_OPENSSL_PMD, "socket_id="); RTE_PMD_REGISTER_CRYPTO_DRIVER(openssl_crypto_drv, cryptodev_openssl_pmd_drv.driver, cryptodev_driver_id); - -RTE_INIT(openssl_init_log) -{ - openssl_logtype_driver = rte_log_register("pmd.crypto.openssl"); -} +RTE_LOG_REGISTER_DEFAULT(openssl_logtype_driver, INFO);