From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id C8BFF2B84 for ; Tue, 11 Oct 2016 11:50:44 +0200 (CEST) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga103.jf.intel.com with ESMTP; 11 Oct 2016 02:50:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,476,1473145200"; d="scan'208";a="18815179" Received: from irsmsx110.ger.corp.intel.com ([163.33.3.25]) by orsmga004.jf.intel.com with ESMTP; 11 Oct 2016 02:50:42 -0700 Received: from irsmsx103.ger.corp.intel.com ([169.254.3.91]) by irsmsx110.ger.corp.intel.com ([163.33.3.25]) with mapi id 14.03.0248.002; Tue, 11 Oct 2016 10:50:41 +0100 From: "Mrozowicz, SlawomirX" To: "Jastrzebski, MichalX K" , Akhil Goyal , "Azarewicz, PiotrX T" , "Doherty, Declan" , "dev@dpdk.org" CC: "Kerlin, MarcinX" , "Kobylinski, MichalX" , "Kulasek, TomaszX" , "Mrzyglod, DanielX T" Thread-Topic: [dpdk-dev] [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device Thread-Index: AQHR/2rzTKpSFeLw4Eqwp21wdyJy7aB1vrqAgAL7KICAKoq6sA== Date: Tue, 11 Oct 2016 09:50:40 +0000 Message-ID: <158888A50F43E34AAE179517F56C9745613AE1@IRSMSX103.ger.corp.intel.com> References: <1472196117-21750-1-git-send-email-piotrx.t.azarewicz@intel.com> <1472196117-21750-2-git-send-email-piotrx.t.azarewicz@intel.com> <4d920e7a-cebc-4ece-e5a2-dccfc3e66a3b@nxp.com> <60ABE07DBB3A454EB7FAD707B4BB158213AEEE33@IRSMSX109.ger.corp.intel.com> In-Reply-To: <60ABE07DBB3A454EB7FAD707B4BB158213AEEE33@IRSMSX109.ger.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [163.33.239.181] Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 09:50:45 -0000 >-----Original Message----- >From: Jastrzebski, MichalX K >Sent: Wednesday, September 14, 2016 10:48 AM >To: Akhil Goyal ; Azarewicz, PiotrX T >; Doherty, Declan >; dev@dpdk.org >Cc: Kerlin, MarcinX ; Mrozowicz, SlawomirX >; Kobylinski, MichalX >; Kulasek, TomaszX >; Mrzyglod, DanielX T > >Subject: RE: [dpdk-dev] [PATCH 1/4] libcrypto_pmd: initial implementation = of >SW crypto device > >> -----Original Message----- >> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal >> Sent: Monday, September 12, 2016 1:17 PM >> To: Azarewicz, PiotrX T ; Doherty, >> Declan ; dev@dpdk.org >> Cc: Kerlin, MarcinX ; Mrozowicz, SlawomirX >> ; Kobylinski, MichalX >> ; Kulasek, TomaszX >> ; Mrzyglod, DanielX T >> >> Subject: Re: [dpdk-dev] [PATCH 1/4] libcrypto_pmd: initial >> implementation of SW crypto device >> >> On 8/26/2016 12:51 PM, Piotr Azarewicz wrote: >> >> > +/** Provide session for operation */ static struct >> > +libcrypto_session * get_session(struct libcrypto_qp *qp, struct >> > +rte_crypto_op *op) { >> > + struct libcrypto_session *sess =3D NULL; >> > + >> > + if (op->sym->sess_type =3D=3D RTE_CRYPTO_SYM_OP_WITH_SESSION) { >> > + /* get existing session */ >> > + if (!unlikely(op->sym->session =3D=3D NULL || >> > + op->sym->session->dev_type !=3D >> > + RTE_CRYPTODEV_LIBCRYPTO_PMD)) >> > + sess =3D (struct libcrypto_session *) >> > + op->sym->session->_private; >> > + } else { >> > + /* provide internal session */ >> > + void *_sess =3D NULL; >> > + >> > + if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) { >> > + sess =3D (struct libcrypto_session *) >> > + ((struct rte_cryptodev_sym_session *)_sess) >> > + ->_private; >> > + >> > + if (unlikely(libcrypto_set_session_parameters( >> > + sess, op->sym->xform) !=3D 0)) { >> > + rte_mempool_put(qp->sess_mp, _sess); >> > + sess =3D NULL; >> > + } else >> > + op->sym->session =3D _sess; >> > + } >> > + } >> > + >> > + if (sess =3D=3D NULL) >> > + op->status =3D RTE_CRYPTO_OP_STATUS_INVALID_SESSION; >> > + >> > + return sess; >> > +} >> > + >> > +/* >> > + >> > +*------------------------------------------------------------------ >> > +------------ >> > + * Process Operations >> > + >> > +*------------------------------------------------------------------ >> > +------------ >> > + */ >> > + >> > +/** Process standard libcrypto cipher encryption */ static int >> > +process_libcrypto_cipher_encrypt(uint8_t *src, uint8_t *dst, >> > + uint8_t *iv, uint8_t *key, int srclen, >> > + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) { >> > + int dstlen, totlen; >> > + >> > + if (EVP_EncryptInit_ex(ctx, algo, NULL, key, iv) <=3D 0) >> > + goto process_cipher_encrypt_err; >> [Akhil] this EVP_EncryptInit_ex() can be done for each session instead >> of each packet. This will improve the performance. Also if there is >> some change in the parameters later then it can be called again here >> with the updated parameters only. >> Same comment is for all cases (hmac, auth, etc) > >Hi Akhil, >Thank You for this comment. We will check if this is possible. > >Michal > [S=B3awomir] We have done some investigation: - At first glance it is valuable to call this kind of function only once per session. - We done test: just remove the functions like EVP_XXXInitXXX and we reduce packet processing time between 1% to 10% depending of processed algorithm. - We analyzed calling only once per session also functions=20 like EVP_XXXFinalXXX but it is not possible because=20 this kind of functions finalize cipher or authenticate process=20 and return result. - The functions like EVP_XXXFinalXXX change context and It is not possible to proper continue processing without reinitialize the context. So after call functions EVP_XXXFinalXXX we need to call EVP_XXXInitXXX for next operation. In sum we can't do the proposed performance improvement. >> > + >> > + if (EVP_EncryptUpdate(ctx, dst, &dstlen, src, srclen) <=3D 0) >> > + goto process_cipher_encrypt_err; >> > + >> > + if (EVP_EncryptFinal_ex(ctx, dst + dstlen, &totlen) <=3D 0) >> > + goto process_cipher_encrypt_err; >> > + >> > + return 0; >> > + >> > +process_cipher_encrypt_err: >> > + LIBCRYPTO_LOG_ERR("Process libcrypto cipher encrypt failed"); >> > + return -EINVAL; >> > +} >> > + >> > +/** Process standard libcrypto cipher decryption */ static int >> > +process_libcrypto_cipher_decrypt(uint8_t *src, uint8_t *dst, >> > + uint8_t *iv, uint8_t *key, int srclen, >> > + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) { >> > + int dstlen, totlen; >> > + >> > + if (EVP_DecryptInit_ex(ctx, algo, NULL, key, iv) <=3D 0) >> > + goto process_cipher_decrypt_err; >> > + >> > + if (EVP_CIPHER_CTX_set_padding(ctx, 0) <=3D 0) >> > + goto process_cipher_decrypt_err; >> > + >> > + if (EVP_DecryptUpdate(ctx, dst, &dstlen, src, srclen) <=3D 0) >> > + goto process_cipher_decrypt_err; >> > + >> > + if (EVP_DecryptFinal_ex(ctx, dst + dstlen, &totlen) <=3D 0) >> > + goto process_cipher_decrypt_err; >> > + >> > + return 0; >> > + >> > +process_cipher_decrypt_err: >> > + LIBCRYPTO_LOG_ERR("Process libcrypto cipher decrypt failed"); >> > + return -EINVAL; >> > +} >> > + >> > +/** Process cipher des 3 ctr encryption, decryption algorithm */ >> > +static int process_libcrypto_cipher_des3ctr(uint8_t *src, uint8_t >> > +*dst, >> > + uint8_t *iv, uint8_t *key, int srclen, EVP_CIPHER_CTX *ctx) { >> > + uint8_t ebuf[8], ctr[8]; >> > + int unused, n; >> > + >> > + /* We use 3DES encryption also for decryption. >> > + * IV is not important for 3DES ecb >> > + */ >> > + if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) >> > +<=3D >> 0) >> > + goto process_cipher_des3ctr_err; >> > + >> > + memcpy(ctr, iv, 8); >> > + n =3D 0; >> > + >> > + while (n < srclen) { >> > + if (n % 8 =3D=3D 0) { >> > + if (EVP_EncryptUpdate(ctx, (unsigned char *)&ebuf, >> &unused, >> > + (const unsigned char *)&ctr, 8) <=3D 0) >> > + goto process_cipher_des3ctr_err; >> > + ctr_inc(ctr); >> > + } >> > + dst[n] =3D src[n] ^ ebuf[n % 8]; >> > + n++; >> > + } >> > + >> > + return 0; >> > + >> > +process_cipher_des3ctr_err: >> > + LIBCRYPTO_LOG_ERR("Process libcrypto cipher des 3 ede ctr failed"); >> > + return -EINVAL; >> > +} >> > + >> > +/** Process auth gmac algorithm */ >> > +static int >> > +process_libcrypto_auth_gmac(uint8_t *src, uint8_t *dst, >> > + uint8_t *iv, uint8_t *key, int srclen, int ivlen, >> > + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) { >> > + int unused; >> > + >> > + if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <=3D 0) >> > + goto process_auth_gmac_err; >> > + >> > + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, >> NULL) <=3D 0) >> > + goto process_auth_gmac_err; >> > + >> > + if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <=3D 0) >> > + goto process_auth_gmac_err; >> > + >> > + if (EVP_EncryptUpdate(ctx, NULL, &unused, src, srclen) <=3D 0) >> > + goto process_auth_gmac_err; >> > + >> > + if (EVP_EncryptFinal_ex(ctx, NULL, &unused) <=3D 0) >> > + goto process_auth_gmac_err; >> > + >> > + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, dst) <=3D >> 0) >> > + goto process_auth_gmac_err; >> > + >> > + return 0; >> > + >> > +process_auth_gmac_err: >> > + LIBCRYPTO_LOG_ERR("Process libcrypto auth gmac failed"); >> > + return -EINVAL; >> > +} >> > + >> > +/** Process standard libcrypto auth algorithms */ static int >> > +process_libcrypto_auth(uint8_t *src, uint8_t *dst, >> > + __rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey, >> > + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) { >> > + size_t dstlen; >> > + >> > + if (EVP_DigestInit_ex(ctx, algo, NULL) <=3D 0) >> > + goto process_auth_err; >> > + >> > + if (EVP_DigestUpdate(ctx, (char *)src, srclen) <=3D 0) >> > + goto process_auth_err; >> > + >> > + if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <=3D 0) >> > + goto process_auth_err; >> > + >> > + return 0; >> > + >> > +process_auth_err: >> > + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); >> > + return -EINVAL; >> > +} >> > + >> > +/** Process standard libcrypto auth algorithms with hmac */ static >> > +int process_libcrypto_auth_hmac(uint8_t *src, uint8_t *dst, >> > + __rte_unused uint8_t *iv, EVP_PKEY *pkey, >> > + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) >> > +{ >> > + size_t dstlen; >> > + >> > + if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <=3D 0) >> > + goto process_auth_err; >> > + >> > + if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <=3D 0) >> > + goto process_auth_err; >> > + >> > + if (EVP_DigestSignFinal(ctx, dst, &dstlen) <=3D 0) >> > + goto process_auth_err; >> > + >> > + return 0; >> > + >> > +process_auth_err: >> > + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); >> > + return -EINVAL; >> > +} >> > + >> > +/*----------------------------------------------------------------- >> > +-----------*/ >> > + >> >>