From patchwork Wed Aug 23 09:12:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gilad Ben-Yossef X-Patchwork-Id: 110726 Delivered-To: patch@linaro.org Received: by 10.182.109.195 with SMTP id hu3csp5934467obb; Wed, 23 Aug 2017 02:12:14 -0700 (PDT) X-Received: by 10.99.119.15 with SMTP id s15mr1983707pgc.373.1503479534597; Wed, 23 Aug 2017 02:12:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503479534; cv=none; d=google.com; s=arc-20160816; b=J/OypQ8EIwvTqGpL1g8C2GmJvypdyBBEO/PVQjTo98YaMkaZb69/u0VBizPwIA8igX FV5zZ3mC/g/8IP8zcrWk0BFvzDMXKlTAd3NcdlPF3lsYNvOLzl5KamE5ltf9G8YoGzrA 8sgIauP65HJZ82RQwlhvmKjS0XOoZnhzN0yzaBhd134SHuyn/Hhq5W4DyfPaCU2K3YGh P/5E8QdJ7VogvIkTypx9GtnsRnxTQ71lB3EpUXeNMBD0kYOtOS9gs9gTsFDG3Ff74SE9 IRnSuBZLDJQ9R5XiGO5SvbM8RsrtCb8V6nVAVIA6sHf4tx1/u+iGnNJd3Ri5C6Ifv+RE 2djg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=akr8XMVpKmvJiL1IeXcGu+qbdggRtWxBpaQu6b95UAc=; b=a75bfUpleGoB2SIbSzb+J7xBn9/GFxP7BM56Pj/h/Q87mZDqpgDfnAkT216VHJRfi6 KPic4DZqR3egQX7kJChmIbjjva28atFIpc8FE+4UjN0ybExrF7Va3PFFNWGDu5pWCPiF mTN+GfJFnP5PvZRSE/aWBNNGDmQizGC4e/QNLzDgyXuMh5Jbz4phx6S6MwEZj+i2h5RU E1q8kScGSOuTW7+e30C8l+0x0c8x+cqdBpSUu5xtSYCZ/l837g9R3svQyPS9AN2dZhO+ CsPIMljyym0iKZVKksj1MFJquk32bKCem8SqXF8aH2+WasKyhXB1WsYvcF9TkNFO1D1t dnug== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u128si735262pfu.374.2017.08.23.02.12.14; Wed, 23 Aug 2017 02:12:14 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753522AbdHWJMN (ORCPT + 1 other); Wed, 23 Aug 2017 05:12:13 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:53736 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753513AbdHWJMM (ORCPT ); Wed, 23 Aug 2017 05:12:12 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3061580D; Wed, 23 Aug 2017 02:12:12 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 67AB13F577; Wed, 23 Aug 2017 02:12:10 -0700 (PDT) From: Gilad Ben-Yossef To: Greg Kroah-Hartman , linux-crypto@vger.kernel.org, driverdev-devel@linuxdriverproject.org, devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org Cc: Ofir Drang Subject: [BUGFIX PATCH v2] staging: ccree: save ciphertext for CTS IV Date: Wed, 23 Aug 2017 12:12:05 +0300 Message-Id: <1503479525-23947-1-git-send-email-gilad@benyossef.com> X-Mailer: git-send-email 2.1.4 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org The crypto API requires saving the last blocks of ciphertext in req->info for use as IV for CTS mode. The ccree driver was not doing this. This patch fixes that. The bug was manifested with cts(cbc(aes)) mode in tcrypt tests. Fixes: 302ef8ebb4b2 ("Add CryptoCell skcipher support") Signed-off-by: Gilad Ben-Yossef --- Changes from v1: - Free memory on error path, as pointed out by Stephan Mueller. drivers/staging/ccree/ssi_cipher.c | 40 ++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) -- 2.1.4 diff --git a/drivers/staging/ccree/ssi_cipher.c b/drivers/staging/ccree/ssi_cipher.c index af9afea..8d31a93 100644 --- a/drivers/staging/ccree/ssi_cipher.c +++ b/drivers/staging/ccree/ssi_cipher.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "ssi_config.h" #include "ssi_driver.h" @@ -697,6 +698,7 @@ static int ssi_blkcipher_complete(struct device *dev, { int completion_error = 0; u32 inflight_counter; + struct ablkcipher_request *req = (struct ablkcipher_request *)areq; ssi_buffer_mgr_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst); @@ -707,6 +709,22 @@ static int ssi_blkcipher_complete(struct device *dev, ctx_p->drvdata->inflight_counter--; if (areq) { + /* + * The crypto API expects us to set the req->info to the last + * ciphertext block. For encrypt, simply copy from the result. + * For decrypt, we must copy from a saved buffer since this + * could be an in-place decryption operation and the src is + * lost by this point. + */ + if (req_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) { + memcpy(req->info, req_ctx->backup_info, ivsize); + kfree(req_ctx->backup_info); + } else { + scatterwalk_map_and_copy(req->info, req->dst, + (req->nbytes - ivsize), + ivsize, 0); + } + ablkcipher_request_complete(areq, completion_error); return 0; } @@ -739,11 +757,13 @@ static int ssi_blkcipher_process( if (unlikely(validate_data_size(ctx_p, nbytes))) { SSI_LOG_ERR("Unsupported data size %d.\n", nbytes); crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_BLOCK_LEN); - return -EINVAL; + rc = -EINVAL; + goto exit_process; } if (nbytes == 0) { /* No data to process is valid */ - return 0; + rc = 0; + goto exit_process; } /*For CTS in case of data size aligned to 16 use CBC mode*/ if (((nbytes % AES_BLOCK_SIZE) == 0) && (ctx_p->cipher_mode == DRV_CIPHER_CBC_CTS)) { @@ -818,6 +838,9 @@ static int ssi_blkcipher_process( if (cts_restore_flag != 0) ctx_p->cipher_mode = DRV_CIPHER_CBC_CTS; + if (rc != -EINPROGRESS) + kfree(req_ctx->backup_info); + return rc; } @@ -858,7 +881,6 @@ static int ssi_ablkcipher_encrypt(struct ablkcipher_request *req) struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(req); unsigned int ivsize = crypto_ablkcipher_ivsize(ablk_tfm); - req_ctx->backup_info = req->info; req_ctx->is_giv = false; return ssi_blkcipher_process(tfm, req_ctx, req->dst, req->src, req->nbytes, req->info, ivsize, (void *)req, DRV_CRYPTO_DIRECTION_ENCRYPT); @@ -871,8 +893,18 @@ static int ssi_ablkcipher_decrypt(struct ablkcipher_request *req) struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(req); unsigned int ivsize = crypto_ablkcipher_ivsize(ablk_tfm); - req_ctx->backup_info = req->info; + /* + * Allocate and save the last IV sized bytes of the source, which will + * be lost in case of in-place decryption and might be needed for CTS. + */ + req_ctx->backup_info = kmalloc(ivsize, GFP_KERNEL); + if (!req_ctx->backup_info) + return -ENOMEM; + + scatterwalk_map_and_copy(req_ctx->backup_info, req->src, + (req->nbytes - ivsize), ivsize, 0); req_ctx->is_giv = false; + return ssi_blkcipher_process(tfm, req_ctx, req->dst, req->src, req->nbytes, req->info, ivsize, (void *)req, DRV_CRYPTO_DIRECTION_DECRYPT); }