Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1320209imu; Wed, 23 Jan 2019 14:54:54 -0800 (PST) X-Google-Smtp-Source: ALg8bN4/itqYKCM+toBOo2UwxiAo8tvhp1mUitiMTY6ni2VTs4MW0YNFQh/W9q/GQc/8XkDqb1cQ X-Received: by 2002:a62:8096:: with SMTP id j144mr3997277pfd.140.1548284094694; Wed, 23 Jan 2019 14:54:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548284094; cv=none; d=google.com; s=arc-20160816; b=u5dIPON8ORUvoj/A60AIVN7eQl6KOqv9kuNgrHON4esSe1+fp67710+IOCBjUL7zoK bUgWU40XH7GXlZmv87ZeoXrPUZ72wykYOTG44xOMNA5AaLA7zB/d5lUWh6O4cnWJIr86 ZUM8US9sxQ6vzkTNe5+mUe/FDheWTtPx6bNgypH8o3MOmgwHXbFLl2Y/e0VvFYpUWTIG c9iYVs4vZqsPckVJiCPmQ7ahj8wtZ12llCHHDqXBkkTi9yICy4NPio0SkXjpL67PBPrg 9RKSgXcTOLbkxPint9ubgwZzHjXWOZRlLP0TiK1TNbKB8mYfUXWCuXYxqRJDInSmgldP +m+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=3gs7ig2SJySpST9N45v1olQN210WJoQJzflay4StCr4=; b=JJHhQ2sTIdwQkPNkA9vSZJGr2hIaU3KbtvrOGZbwDyB/zOWGW+OZMNnzpB9xRmCEfv PQg9QVWcsRGHtxjigWGur7rD2QDJm5wnu5OV26v9DZPOoMRH6o3dUisNHtpkWM6Ecpfr yTiSTEBfp0lnyVNar5jsWypXLEuabQ9enYrSXKOJD596EJNk8z5PaX3l8s1nc2veMz9x 5tfQxULZmyEZiAnd0M2AQVihRq2/m3hcl82lRl5zBw/10TU7pHKc9m+w2WZXo1HyS2El Je0ZloDEkav1ARtzIc30OlkDu5lf4gtWV9GQYXml74Fwsg1EuNjzba08UxALTlf4NAdk giBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=iy7kTFLL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j11si20209761pgk.265.2019.01.23.14.54.39; Wed, 23 Jan 2019 14:54:54 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=iy7kTFLL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727114AbfAWWwh (ORCPT + 99 others); Wed, 23 Jan 2019 17:52:37 -0500 Received: from mail.kernel.org ([198.145.29.99]:50122 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726473AbfAWWwd (ORCPT ); Wed, 23 Jan 2019 17:52:33 -0500 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 560E6218A4; Wed, 23 Jan 2019 22:52:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1548283952; bh=0m28rRGt+dyf2pFnm8cDXy/meEEYN6bA88EXthRWW7s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iy7kTFLL9AL1eU6MrHhB24uUoidhVgQi65eJqRx5g3mnZIhd+Qc+IGoMI8GHwwHYS PVyNkxbINJt/TKLYrUUXCGX12HMPPZ768kGLbB2A/bU0nb5a4Z7IdyVelhBiHWYobd x32W/BnNIC5zYygs+q9EE0W7UhZ2HA+xLCdpIXJ8= From: Eric Biggers To: linux-crypto@vger.kernel.org, Herbert Xu Cc: linux-kernel@vger.kernel.org, "Jason A . Donenfeld" , stable@vger.kernel.org, Ondrej Mosnacek Subject: [RFC/RFT PATCH 04/15] crypto: x86/morus - fix handling chunked inputs and MAY_SLEEP Date: Wed, 23 Jan 2019 14:49:15 -0800 Message-Id: <20190123224926.250525-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog In-Reply-To: <20190123224926.250525-1-ebiggers@kernel.org> References: <20190123224926.250525-1-ebiggers@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Biggers The x86 MORUS implementations all fail the improved AEAD tests because they produce the wrong result with some data layouts. Also, when the MAY_SLEEP flag is given, they can sleep in the skcipher_walk_*() functions while preemption is disabled by kernel_fpu_begin(). Fix these bugs. Fixes: 56e8e57fc3a7 ("crypto: morus - Add common SIMD glue code for MORUS") Cc: # v4.18+ Cc: Ondrej Mosnacek Signed-off-by: Eric Biggers --- arch/x86/crypto/morus1280_glue.c | 40 +++++++++++++------------------- arch/x86/crypto/morus640_glue.c | 39 ++++++++++++------------------- 2 files changed, 31 insertions(+), 48 deletions(-) diff --git a/arch/x86/crypto/morus1280_glue.c b/arch/x86/crypto/morus1280_glue.c index 0dccdda1eb3a..7e600f8bcdad 100644 --- a/arch/x86/crypto/morus1280_glue.c +++ b/arch/x86/crypto/morus1280_glue.c @@ -85,31 +85,20 @@ static void crypto_morus1280_glue_process_ad( static void crypto_morus1280_glue_process_crypt(struct morus1280_state *state, struct morus1280_ops ops, - struct aead_request *req) + struct skcipher_walk *walk) { - struct skcipher_walk walk; - u8 *cursor_src, *cursor_dst; - unsigned int chunksize, base; - - ops.skcipher_walk_init(&walk, req, false); - - while (walk.nbytes) { - cursor_src = walk.src.virt.addr; - cursor_dst = walk.dst.virt.addr; - chunksize = walk.nbytes; - - ops.crypt_blocks(state, cursor_src, cursor_dst, chunksize); - - base = chunksize & ~(MORUS1280_BLOCK_SIZE - 1); - cursor_src += base; - cursor_dst += base; - chunksize &= MORUS1280_BLOCK_SIZE - 1; - - if (chunksize > 0) - ops.crypt_tail(state, cursor_src, cursor_dst, - chunksize); + while (walk->nbytes >= MORUS1280_BLOCK_SIZE) { + ops.crypt_blocks(state, walk->src.virt.addr, + walk->dst.virt.addr, + round_down(walk->nbytes, + MORUS1280_BLOCK_SIZE)); + skcipher_walk_done(walk, walk->nbytes % MORUS1280_BLOCK_SIZE); + } - skcipher_walk_done(&walk, 0); + if (walk->nbytes) { + ops.crypt_tail(state, walk->src.virt.addr, walk->dst.virt.addr, + walk->nbytes); + skcipher_walk_done(walk, 0); } } @@ -147,12 +136,15 @@ static void crypto_morus1280_glue_crypt(struct aead_request *req, struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct morus1280_ctx *ctx = crypto_aead_ctx(tfm); struct morus1280_state state; + struct skcipher_walk walk; + + ops.skcipher_walk_init(&walk, req, true); kernel_fpu_begin(); ctx->ops->init(&state, &ctx->key, req->iv); crypto_morus1280_glue_process_ad(&state, ctx->ops, req->src, req->assoclen); - crypto_morus1280_glue_process_crypt(&state, ops, req); + crypto_morus1280_glue_process_crypt(&state, ops, &walk); ctx->ops->final(&state, tag_xor, req->assoclen, cryptlen); kernel_fpu_end(); diff --git a/arch/x86/crypto/morus640_glue.c b/arch/x86/crypto/morus640_glue.c index 7b58fe4d9bd1..cb3a81732016 100644 --- a/arch/x86/crypto/morus640_glue.c +++ b/arch/x86/crypto/morus640_glue.c @@ -85,31 +85,19 @@ static void crypto_morus640_glue_process_ad( static void crypto_morus640_glue_process_crypt(struct morus640_state *state, struct morus640_ops ops, - struct aead_request *req) + struct skcipher_walk *walk) { - struct skcipher_walk walk; - u8 *cursor_src, *cursor_dst; - unsigned int chunksize, base; - - ops.skcipher_walk_init(&walk, req, false); - - while (walk.nbytes) { - cursor_src = walk.src.virt.addr; - cursor_dst = walk.dst.virt.addr; - chunksize = walk.nbytes; - - ops.crypt_blocks(state, cursor_src, cursor_dst, chunksize); - - base = chunksize & ~(MORUS640_BLOCK_SIZE - 1); - cursor_src += base; - cursor_dst += base; - chunksize &= MORUS640_BLOCK_SIZE - 1; - - if (chunksize > 0) - ops.crypt_tail(state, cursor_src, cursor_dst, - chunksize); + while (walk->nbytes >= MORUS640_BLOCK_SIZE) { + ops.crypt_blocks(state, walk->src.virt.addr, + walk->dst.virt.addr, + round_down(walk->nbytes, MORUS640_BLOCK_SIZE)); + skcipher_walk_done(walk, walk->nbytes % MORUS640_BLOCK_SIZE); + } - skcipher_walk_done(&walk, 0); + if (walk->nbytes) { + ops.crypt_tail(state, walk->src.virt.addr, walk->dst.virt.addr, + walk->nbytes); + skcipher_walk_done(walk, 0); } } @@ -143,12 +131,15 @@ static void crypto_morus640_glue_crypt(struct aead_request *req, struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct morus640_ctx *ctx = crypto_aead_ctx(tfm); struct morus640_state state; + struct skcipher_walk walk; + + ops.skcipher_walk_init(&walk, req, true); kernel_fpu_begin(); ctx->ops->init(&state, &ctx->key, req->iv); crypto_morus640_glue_process_ad(&state, ctx->ops, req->src, req->assoclen); - crypto_morus640_glue_process_crypt(&state, ops, req); + crypto_morus640_glue_process_crypt(&state, ops, &walk); ctx->ops->final(&state, tag_xor, req->assoclen, cryptlen); kernel_fpu_end(); -- 2.20.1.321.g9e740568ce-goog