Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp431412pxb; Wed, 3 Mar 2021 06:56:45 -0800 (PST) X-Google-Smtp-Source: ABdhPJyquUO/DAXmdO8Q1nP0e5TO1Ysl/oPhFQ/gcqk0+iimzdrAzMlkmrfp1dDer1LllNWgQWMS X-Received: by 2002:a05:6402:4313:: with SMTP id m19mr26020987edc.124.1614783405027; Wed, 03 Mar 2021 06:56:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614783405; cv=none; d=google.com; s=arc-20160816; b=I/+3oYEXp5EIkWF1HuX0BvyUgb7neQX/rLdmwxgYqD1T4W6LA8lvzXUTT61xVqDoa3 5nZ7rcLp/NU+b1eJUvAC6pjvqgEMtFYb5XFA59OPm1OVYOiWOIfGmtvQTW/HR/ilP70c VjV1nJ/qK51D2YR5WWMt1L7X95J55re+YIiLyrnRnEWTGVXAZX1BNGK8UAJF+wNqzrC2 zgtVeeDIsXt1C5pg7O49ijDBBcCqef04+rw5eAHyGdOxkIen9f/iEtnX1CVVJpbEdi4V vGySxQpnXyo1f+FKQoPs/LggCX3BC70gOxd7yRdfF/zT241rCxuUYx/ONyTJIV2eaEsN H82Q== 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=8eF9VgGBmu0pOaOllVIdVwdIr0zRi3lKF9nF7pLxdsM=; b=m/Ftc/wfyFt18W6PB4zuAMzhAnOTLXQYAjXhw7jbZfhiiz/i6iC/IOQuLIy8Wxaggd 06Vnv6RjDKyAbQ4K3l1EiydYo9KfA595YRcFSEsRBEttPyq25tlBBhh4lxEAwB6+wrTK 5B5d4p9NiGMG/7xv5C+UiqliVPHDkUoIHSGPnf+w0IbKb/cibUFHk/6MNA3+vj0O0Oga 1wwksfu3A+L2AwkXTDZCahCK5luQNlOIl+r/Eg6180IN/VNLLcWnO5fL6WFCFVvkbKuo /vbwY2nv2JaICvjsHZ9Q7TbjsmbZAYaqnh95s5i3dAqcDvgi31/RuhOUqlFZSq5pSK/w cHcg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="io/DvFpB"; 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 s26si16446542edr.515.2021.03.03.06.55.28; Wed, 03 Mar 2021 06:56:45 -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="io/DvFpB"; 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 S232186AbhCAWKV (ORCPT + 99 others); Mon, 1 Mar 2021 17:10:21 -0500 Received: from mail.kernel.org ([198.145.29.99]:54264 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232328AbhCAR3u (ORCPT ); Mon, 1 Mar 2021 12:29:50 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id C8A8164FAA; Mon, 1 Mar 2021 16:52:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1614617525; bh=uOr/pal+EAvjgJQuUFSGE56lUbDijpldKkbxEcaGn0I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=io/DvFpBlxSUKTCYqra1PzUAltWmnbcTDBQ+U/hXd1BmpwIV/oM0FfDHWG8Xh2kCo zVAZaK3rgf/CkXAfHY5Hzwb7rS8MBjRUmJ+QasQXA8ZRsVOo1aIscTV3sfl3cs00CL S9s7QxXVf1+EdZiFBBHWOhvDSPEd3pkdNU/k7gDI= 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 5.4 105/340] crypto: talitos - Work around SEC6 ERRATA (AES-CTR mode data size error) Date: Mon, 1 Mar 2021 17:10:49 +0100 Message-Id: <20210301161053.498588303@linuxfoundation.org> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210301161048.294656001@linuxfoundation.org> References: <20210301161048.294656001@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 b7c66fc0ae0c2..8ef6e93e43f3c 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1097,11 +1097,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); @@ -1125,7 +1126,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; @@ -1148,10 +1149,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); @@ -1159,22 +1161,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; @@ -1186,7 +1188,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); } /* @@ -1255,7 +1257,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; @@ -1275,7 +1277,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; if (!encrypt && is_ipsec_esp) { @@ -1583,6 +1585,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 */ @@ -1603,8 +1607,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 1469b956948ab..32825119e8805 100644 --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h @@ -344,6 +344,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