Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp396015pxb; Wed, 3 Mar 2021 06:08:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJzAmDZWmAACA4RW5pLtYEzyjQd0N6I/ApH2W1xG09cCTfkY1u0O8QXy9pDv8Mrzb5VDML8a X-Received: by 2002:a17:907:94d4:: with SMTP id dn20mr26143680ejc.397.1614780528141; Wed, 03 Mar 2021 06:08:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614780528; cv=none; d=google.com; s=arc-20160816; b=l3nGXEbNKwJm1sG1zFrt/Qe7gXlz4UAGAGgouvMrLwNEUYjuFAfLe0ymUFwKCopIxC PUl3xBuoHiMCAQT73I+lrOL7U23CxoszE87UIRfACuhm8/0g29bFlrphrMRPiZvMR0Fz DU78gThzJgTVKk8ribV8454WX+wNJR2KebMIvGmwUy0ZK43iGghblrH85EFHOCMVE4UL p8OZExgn/hv4DLgZmMnO72KCmWFX9O7sUVdli6inj/RPy840FSKH5ofYmuxhOvoconsY XPd9hKM5HMb0Do5ZCLYjsrsn4mwZOu/KdBZg+mw5taKJO1KN4KW2uGcBjZlKFJhLzUFM U+uQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Ci+BaH56IWmUb9KfGxjdi8FsL05IMEqK6tUi6ukRa0c=; b=vfxK6z36HP5H5oGXNJzrcoxyruFaxcvBCkG2tBbYBPGhXsbyOFOXIRHTrR9CCwM8BJ 8Nshw1IF/ahyq8ek7lySeNxsEggY+x+eDbyFHE+QjvlTA7oqD7oy0xXhMcFeyklvT2Te YKuq0g5rUEPOM68xsVFJxXMj7rt0cLn1HhWGrYXnu9GDm7XrkM0L3uxaz5A5s8zkjg/Y zIWXpbQ80tR25SviJHTjzvU+3VuRgkh2e1m9uoE1I1+8u8cWGcRu3BB7RGub3sMJnG6I FH/eq4WI5AXk5pijsR8ITMUEE96CvXJ9fNrsanyAsowLs5Aqdqm12iqiwjWyBGy5yixz pHmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=TQIlrpkP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z15si15914001ejr.160.2021.03.03.06.07.33; Wed, 03 Mar 2021 06:08:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=TQIlrpkP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243710AbhCAUjJ (ORCPT + 99 others); Mon, 1 Mar 2021 15:39:09 -0500 Received: from mail.kernel.org ([198.145.29.99]:35322 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237512AbhCARIV (ORCPT ); Mon, 1 Mar 2021 12:08:21 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id AD2CC64F86; Mon, 1 Mar 2021 16:41:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1614616872; bh=Uddgtl8x7+3nKSqAHufwvjSoGX0FLguNWqtf3aCL8qk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TQIlrpkPB/5AJelXjHVE9h7xsxuKrdBS/YCIdijutRHpHNHJySQpXtkea8C4aoVnL 2HgZT0qWjG8J0rgXcy0h6OP7R6sMgtlHE+I+tkpbO06008eEJT5NTfW0tQk6DzSvb0 at1D9JdinNPf/FK0eKTD1tnnUOIqV3YCT1rtqm50= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Christophe Leroy , Herbert Xu , Sasha Levin Subject: [PATCH 4.19 094/247] crypto: talitos - Work around SEC6 ERRATA (AES-CTR mode data size error) Date: Mon, 1 Mar 2021 17:11:54 +0100 Message-Id: <20210301161036.276142439@linuxfoundation.org> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210301161031.684018251@linuxfoundation.org> References: <20210301161031.684018251@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Christophe Leroy [ Upstream commit 416b846757bcea20006a9197e67ba3a8b5b2a680 ] Talitos Security Engine AESU considers any input data size that is not a multiple of 16 bytes to be an error. This is not a problem in general, except for Counter mode that is a stream cipher and can have an input of any size. Test Manager for ctr(aes) fails on 4th test vector which has a length of 499 while all previous vectors which have a 16 bytes multiple length succeed. As suggested by Freescale, round up the input data length to the nearest 16 bytes. Fixes: 5e75ae1b3cef ("crypto: talitos - add new crypto modes") Signed-off-by: Christophe Leroy Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/talitos.c | 28 ++++++++++++++++------------ drivers/crypto/talitos.h | 1 + 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index c70a7c4f5b739..7a55baa861e58 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1066,11 +1066,12 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev, */ static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count, unsigned int offset, int datalen, int elen, - struct talitos_ptr *link_tbl_ptr) + struct talitos_ptr *link_tbl_ptr, int align) { int n_sg = elen ? sg_count + 1 : sg_count; int count = 0; int cryptlen = datalen + elen; + int padding = ALIGN(cryptlen, align) - cryptlen; while (cryptlen && sg && n_sg--) { unsigned int len = sg_dma_len(sg); @@ -1094,7 +1095,7 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count, offset += datalen; } to_talitos_ptr(link_tbl_ptr + count, - sg_dma_address(sg) + offset, len, 0); + sg_dma_address(sg) + offset, sg_next(sg) ? len : len + padding, 0); to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0); count++; cryptlen -= len; @@ -1117,10 +1118,11 @@ static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src, unsigned int len, struct talitos_edesc *edesc, struct talitos_ptr *ptr, int sg_count, unsigned int offset, int tbl_off, int elen, - bool force) + bool force, int align) { struct talitos_private *priv = dev_get_drvdata(dev); bool is_sec1 = has_ftr_sec1(priv); + int aligned_len = ALIGN(len, align); if (!src) { to_talitos_ptr(ptr, 0, 0, is_sec1); @@ -1128,22 +1130,22 @@ static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src, } to_talitos_ptr_ext_set(ptr, elen, is_sec1); if (sg_count == 1 && !force) { - to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1); + to_talitos_ptr(ptr, sg_dma_address(src) + offset, aligned_len, is_sec1); return sg_count; } if (is_sec1) { - to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1); + to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, aligned_len, is_sec1); return sg_count; } sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len, elen, - &edesc->link_tbl[tbl_off]); + &edesc->link_tbl[tbl_off], align); if (sg_count == 1 && !force) { /* Only one segment now, so no link tbl needed*/ copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1); return sg_count; } to_talitos_ptr(ptr, edesc->dma_link_tbl + - tbl_off * sizeof(struct talitos_ptr), len, is_sec1); + tbl_off * sizeof(struct talitos_ptr), aligned_len, is_sec1); to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1); return sg_count; @@ -1155,7 +1157,7 @@ static int talitos_sg_map(struct device *dev, struct scatterlist *src, unsigned int offset, int tbl_off) { return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset, - tbl_off, 0, false); + tbl_off, 0, false, 1); } /* @@ -1224,7 +1226,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4], sg_count, areq->assoclen, tbl_off, elen, - false); + false, 1); if (ret > 1) { tbl_off += ret; @@ -1244,7 +1246,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, elen = 0; ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc, &desc->ptr[5], sg_count, areq->assoclen, tbl_off, elen, - is_ipsec_esp && !encrypt); + is_ipsec_esp && !encrypt, 1); tbl_off += ret; /* ICV data */ @@ -1554,6 +1556,8 @@ static int common_nonsnoop(struct talitos_edesc *edesc, bool sync_needed = false; struct talitos_private *priv = dev_get_drvdata(dev); bool is_sec1 = has_ftr_sec1(priv); + bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU && + (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR; /* first DWORD empty */ @@ -1574,8 +1578,8 @@ static int common_nonsnoop(struct talitos_edesc *edesc, /* * cipher in */ - sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc, - &desc->ptr[3], sg_count, 0, 0); + sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3], + sg_count, 0, 0, 0, false, is_ctr ? 16 : 1); if (sg_count > 1) sync_needed = true; diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h index cb0137e131cc8..16f96c57de341 100644 --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h @@ -377,6 +377,7 @@ static inline bool has_ftr_sec1(struct talitos_private *priv) /* primary execution unit mode (MODE0) and derivatives */ #define DESC_HDR_MODE0_ENCRYPT cpu_to_be32(0x00100000) +#define DESC_HDR_MODE0_AESU_MASK cpu_to_be32(0x00600000) #define DESC_HDR_MODE0_AESU_CBC cpu_to_be32(0x00200000) #define DESC_HDR_MODE0_AESU_CTR cpu_to_be32(0x00600000) #define DESC_HDR_MODE0_DEU_CBC cpu_to_be32(0x00400000) -- 2.27.0