From owner-svn-src-head@freebsd.org Wed Jan 24 20:11:00 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CF092EC2DBB; Wed, 24 Jan 2018 20:11:00 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 80B4475114; Wed, 24 Jan 2018 20:11:00 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7B6312247C; Wed, 24 Jan 2018 20:11:00 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0OKB0Oc033464; Wed, 24 Jan 2018 20:11:00 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0OKB02c033463; Wed, 24 Jan 2018 20:11:00 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201801242011.w0OKB02c033463@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Wed, 24 Jan 2018 20:11:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r328356 - head/sys/dev/cxgbe/crypto X-SVN-Group: head X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: head/sys/dev/cxgbe/crypto X-SVN-Commit-Revision: 328356 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jan 2018 20:11:01 -0000 Author: jhb Date: Wed Jan 24 20:11:00 2018 New Revision: 328356 URL: https://svnweb.freebsd.org/changeset/base/328356 Log: Don't discard AAD and IV output data for AEAD requests. The T6 can hang when processing certain AEAD requests if the request sets a flag asking the crypto engine to discard the input IV and AAD rather than copying them into the output buffer. The existing driver always discards the IV and AAD as we do not need it. As a workaround, allocate a single "dummy" buffer when the ccr driver attaches and change all AEAD requests to write the IV and AAD to this scratch buffer. The contents of the scratch buffer are never used (similar to "bogus_page"), and it is ok for multiple in-flight requests to share this dummy buffer. Submitted by: Harsh Jain @ Chelsio (original version) Sponsored by: Chelsio Communications Modified: head/sys/dev/cxgbe/crypto/t4_crypto.c Modified: head/sys/dev/cxgbe/crypto/t4_crypto.c ============================================================================== --- head/sys/dev/cxgbe/crypto/t4_crypto.c Wed Jan 24 20:08:10 2018 (r328355) +++ head/sys/dev/cxgbe/crypto/t4_crypto.c Wed Jan 24 20:11:00 2018 (r328356) @@ -190,6 +190,13 @@ struct ccr_softc { struct sglist *sg_ulptx; struct sglist *sg_dsgl; + /* + * Pre-allocate a dummy output buffer for the IV and AAD for + * AEAD requests. + */ + char *iv_aad_buf; + struct sglist *sg_iv_aad; + /* Statistics. */ uint64_t stats_blkcipher_encrypt; uint64_t stats_blkcipher_decrypt; @@ -814,15 +821,25 @@ ccr_authenc(struct ccr_softc *sc, uint32_t sid, struct * The output buffer consists of the cipher text followed by * the hash when encrypting. For decryption it only contains * the plain text. + * + * Due to a firmware bug, the output buffer must include a + * dummy output buffer for the IV and AAD prior to the real + * output buffer. */ if (op_type == CHCR_ENCRYPT_OP) { - if (crde->crd_len + hash_size_in_response > MAX_REQUEST_SIZE) + if (s->blkcipher.iv_len + aad_len + crde->crd_len + + hash_size_in_response > MAX_REQUEST_SIZE) return (EFBIG); } else { - if (crde->crd_len > MAX_REQUEST_SIZE) + if (s->blkcipher.iv_len + aad_len + crde->crd_len > + MAX_REQUEST_SIZE) return (EFBIG); } sglist_reset(sc->sg_dsgl); + error = sglist_append_sglist(sc->sg_dsgl, sc->sg_iv_aad, 0, + s->blkcipher.iv_len + aad_len); + if (error) + return (error); error = sglist_append_sglist(sc->sg_dsgl, sc->sg_crp, crde->crd_skip, crde->crd_len); if (error) @@ -977,7 +994,7 @@ ccr_authenc(struct ccr_softc *sc, uint32_t sid, struct crwr->sec_cpl.ivgen_hdrlen = htobe32( V_SCMD_IV_GEN_CTRL(0) | V_SCMD_MORE_FRAGS(0) | V_SCMD_LAST_FRAG(0) | V_SCMD_MAC_ONLY(0) | - V_SCMD_AADIVDROP(1) | V_SCMD_HDR_LEN(dsgl_len)); + V_SCMD_AADIVDROP(0) | V_SCMD_HDR_LEN(dsgl_len)); crwr->key_ctx.ctx_hdr = s->blkcipher.key_ctx_hdr; switch (crde->crd_alg) { @@ -1143,15 +1160,24 @@ ccr_gcm(struct ccr_softc *sc, uint32_t sid, struct ccr * The output buffer consists of the cipher text followed by * the tag when encrypting. For decryption it only contains * the plain text. + * + * Due to a firmware bug, the output buffer must include a + * dummy output buffer for the IV and AAD prior to the real + * output buffer. */ if (op_type == CHCR_ENCRYPT_OP) { - if (crde->crd_len + hash_size_in_response > MAX_REQUEST_SIZE) + if (iv_len + crda->crd_len + crde->crd_len + + hash_size_in_response > MAX_REQUEST_SIZE) return (EFBIG); } else { - if (crde->crd_len > MAX_REQUEST_SIZE) + if (iv_len + crda->crd_len + crde->crd_len > MAX_REQUEST_SIZE) return (EFBIG); } sglist_reset(sc->sg_dsgl); + error = sglist_append_sglist(sc->sg_dsgl, sc->sg_iv_aad, 0, iv_len + + crda->crd_len); + if (error) + return (error); error = sglist_append_sglist(sc->sg_dsgl, sc->sg_crp, crde->crd_skip, crde->crd_len); if (error) @@ -1287,7 +1313,7 @@ ccr_gcm(struct ccr_softc *sc, uint32_t sid, struct ccr crwr->sec_cpl.ivgen_hdrlen = htobe32( V_SCMD_IV_GEN_CTRL(0) | V_SCMD_MORE_FRAGS(0) | V_SCMD_LAST_FRAG(0) | V_SCMD_MAC_ONLY(0) | - V_SCMD_AADIVDROP(1) | V_SCMD_HDR_LEN(dsgl_len)); + V_SCMD_AADIVDROP(0) | V_SCMD_HDR_LEN(dsgl_len)); crwr->key_ctx.ctx_hdr = s->blkcipher.key_ctx_hdr; memcpy(crwr->key_ctx.key, s->blkcipher.enckey, s->blkcipher.key_len); @@ -1511,6 +1537,8 @@ ccr_attach(device_t dev) sc->sg_crp = sglist_alloc(TX_SGL_SEGS, M_WAITOK); sc->sg_ulptx = sglist_alloc(TX_SGL_SEGS, M_WAITOK); sc->sg_dsgl = sglist_alloc(MAX_RX_PHYS_DSGL_SGE, M_WAITOK); + sc->iv_aad_buf = malloc(MAX_AAD_LEN, M_CCR, M_WAITOK); + sc->sg_iv_aad = sglist_build(sc->iv_aad_buf, MAX_AAD_LEN, M_WAITOK); ccr_sysctls(sc); crypto_register(cid, CRYPTO_SHA1_HMAC, 0, 0); @@ -1548,6 +1576,8 @@ ccr_detach(device_t dev) crypto_unregister_all(sc->cid); free(sc->sessions, M_CCR); mtx_destroy(&sc->lock); + sglist_free(sc->sg_iv_aad); + free(sc->iv_aad_buf, M_CCR); sglist_free(sc->sg_dsgl); sglist_free(sc->sg_ulptx); sglist_free(sc->sg_crp);