From patchwork Fri Apr 24 14:02:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corentin Labbe X-Patchwork-Id: 197837 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7AF0FC55194 for ; Fri, 24 Apr 2020 14:02:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5BDDE21582 for ; Fri, 24 Apr 2020 14:02:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="cA4XqStY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726717AbgDXOC0 (ORCPT ); Fri, 24 Apr 2020 10:02:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38164 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727082AbgDXOC0 (ORCPT ); Fri, 24 Apr 2020 10:02:26 -0400 Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B5D1FC09B045 for ; Fri, 24 Apr 2020 07:02:25 -0700 (PDT) Received: by mail-wm1-x343.google.com with SMTP id z6so10874535wml.2 for ; Fri, 24 Apr 2020 07:02:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LFDRXwTitCs1nrRc2jOX6sWRaTpGwdnr5FsLJM6PpMw=; b=cA4XqStYQ3bJdc/z0XtvsleabRXRTvKKpGNZXfAxCX/J4R/VlS1P2nRctqDhYN9uL6 hA2YNT9vS+RusmqhGcnw6UYAyyjSiXRvqiayiQ9336ybq5F86jrE1LigdDmvO94775Zq XCFX1a6iT7SxxQIlDlmf0D2WspHCYl+NATRjv9SPxzCGKYcOIB2zun6fmLqT/KS9nBEo VuEE33Bv6CK7A7p0hZOa2PZyEsdOA64WDIWpuGwahdB+RURUS8C+JTUP4NT+/mar1Mbo 2cZ1DyAtdkF/RrPfpKJrf7nI0UCnzZRL2GgoKIRtyGGJe8MswS4KBW1ZPXReZYKaE8xR EYag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LFDRXwTitCs1nrRc2jOX6sWRaTpGwdnr5FsLJM6PpMw=; b=LfHC/ErOkBNpPKVmTgABQdcDTPk9C+vNMmFWQZtcX+nj3hU4PXvXIJcpmYCdQ5GTvJ q23NGaoHwA2odVAtV3LG9I8r7ep0Rk8+a49voZEXyID72DPRyEy/KxScdQCYn/E1q54g 3ElQHM0VibxDc2L3DJtS0c9UW0+dODzPUkLk7sg8dYRBNsEkDm9UUAjGCqQbsDRA3EwT X0zfk4fRSRVGaV46tQazQZaKOdWgkygACikUYOQEjGwsFmwTd8YNNVIVnYXQkEccZ8ag eIMZyT50ie5c8FIf6VgwtgjpxlXpE0zAVAzfNc4NjKkBSDCM58gjYYhjB9+vyxqDQPTO MydQ== X-Gm-Message-State: AGi0PuY5LuSdOieiMYURSmOWFWtOahknn+ELPlxUdbpSVgP/zVtPj7nM AafmjOi3RL2vCJtle/zFClNjDQ== X-Google-Smtp-Source: APiQypI7FP3oDj+Ga1cJJbsF1kwlbSAYMlbf8X/KovxXObcFQAoCwc5XUxK3qZl570o61YXVEbKfzQ== X-Received: by 2002:a05:600c:290f:: with SMTP id i15mr9772059wmd.167.1587736944462; Fri, 24 Apr 2020 07:02:24 -0700 (PDT) Received: from localhost.localdomain ([51.15.160.169]) by smtp.googlemail.com with ESMTPSA id v131sm3061051wmb.19.2020.04.24.07.02.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2020 07:02:23 -0700 (PDT) From: Corentin Labbe To: davem@davemloft.net, herbert@gondor.apana.org.au, mripard@kernel.org, wens@csie.org Cc: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Corentin Labbe Subject: [PATCH v2 01/14] crypto: sun8i-ss: Add SS_START define Date: Fri, 24 Apr 2020 14:02:01 +0000 Message-Id: <1587736934-22801-2-git-send-email-clabbe@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> References: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Instead of using an hardcoded value, let's use a defined value for SS_START. Signed-off-by: Corentin Labbe --- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 2 +- drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c index 5d9d0fedcb06..81eff935fb5c 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c @@ -61,7 +61,7 @@ int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx const char *name) { int flow = rctx->flow; - u32 v = 1; + u32 v = SS_START; int i; #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h index 29c44f279112..f7a64033fc03 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h @@ -13,6 +13,8 @@ #include #include +#define SS_START 1 + #define SS_ENCRYPTION 0 #define SS_DECRYPTION BIT(6) From patchwork Fri Apr 24 14:02:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corentin Labbe X-Patchwork-Id: 197831 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10859C54FD0 for ; Fri, 24 Apr 2020 14:03:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C39ED2075A for ; Fri, 24 Apr 2020 14:03:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="ra7zgTTK" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728301AbgDXODV (ORCPT ); Fri, 24 Apr 2020 10:03:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1728300AbgDXOCa (ORCPT ); Fri, 24 Apr 2020 10:02:30 -0400 Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3421C09B045 for ; Fri, 24 Apr 2020 07:02:29 -0700 (PDT) Received: by mail-wm1-x343.google.com with SMTP id x25so10578380wmc.0 for ; Fri, 24 Apr 2020 07:02:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Mg4OpuD3OXDiFizBCVZSzB583ncngclW1D4CseSbw7Q=; b=ra7zgTTKF6nHTefUjCmDncwF8TN/Wua4ofDRJkSPsWmsAPjLy5tE1FvtgAlzuC3+Fg KCRGrRYUY3NOoRKBn1CB6xSAv9QY14BgBi86QAct6Y05TNCXA2C8Ibm9g9/lOu4cMhys NaDTMIJgURpzAGEOKHtQ4QyouevAh9yYtSULyoFSsMCNOC98jHgMzJUqBkA0UuFiNyga SSa+gR66PFlXbwBcmlQtRmMpdc1nY9gKqjsutQ0a+t8Nn20EW5hVijhElITlGQ0AXxve 755V8WKPOCDK9tT/Xb12skI12qOIzNh9JjV6dPjY3J3b40ApcsvW7fRa3oiSAH0+tND6 kisg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Mg4OpuD3OXDiFizBCVZSzB583ncngclW1D4CseSbw7Q=; b=LXlHkjW8VcHntgnBZiHmJnb0pAr28V6ufSXO04kjPyv7QwW4pnPAjvLVoj1FKP9nDC B1O80PzPexUlktn8nt81mb9XBomUdNUSjX2WfbLU9H3U+z/1lIvFMMFXeoH6JHm7rXLJ Yz1sQt4ah5JrQ24kDDra+l2ONpKMHjCX6kbzrYzxCpdo3A2rCH7NkjkC5683uE1oIIz2 gls4zeBgcavYlM3w9qJMXi/rSI52lWhWEfPr2gveL6Th+A3Bg45qGzd+KE7dtP6c48j/ uOI3gsdB3Ykh8PH+H4jtFXARw/89Cy5cjf2+uOJbxUDOxrbQS6MXtbz+MTKXmQ4u9te5 wTAw== X-Gm-Message-State: AGi0Pua0UQ3Q3IyVYfoZ+wF1atEIAGZJ2cwXPGosS59gGm5PoUH9h6+S U5+DeNY6MeOLJYKWpxjsK962YA== X-Google-Smtp-Source: APiQypKS/s7Fjgcwo7Mx2BcMMvIE3InP838QPPYKoWjUxEf5s4vx9zMRfoGVQ+3JCV8R3jT8KIowew== X-Received: by 2002:a7b:c772:: with SMTP id x18mr10803151wmk.39.1587736947948; Fri, 24 Apr 2020 07:02:27 -0700 (PDT) Received: from localhost.localdomain ([51.15.160.169]) by smtp.googlemail.com with ESMTPSA id v131sm3061051wmb.19.2020.04.24.07.02.25 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2020 07:02:26 -0700 (PDT) From: Corentin Labbe To: davem@davemloft.net, herbert@gondor.apana.org.au, mripard@kernel.org, wens@csie.org Cc: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Corentin Labbe Subject: [PATCH v2 03/14] crypto: sun8i-ss: support hash algorithms Date: Fri, 24 Apr 2020 14:02:03 +0000 Message-Id: <1587736934-22801-4-git-send-email-clabbe@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> References: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org The SS support multiples hash algorithms, this patch adds support for MD5, SHA1, SHA224 and SHA256. Signed-off-by: Corentin Labbe --- drivers/crypto/allwinner/Kconfig | 9 + drivers/crypto/allwinner/sun8i-ss/Makefile | 1 + .../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 155 ++++++ .../crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 446 ++++++++++++++++++ drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h | 60 +++ 5 files changed, 671 insertions(+) create mode 100644 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c diff --git a/drivers/crypto/allwinner/Kconfig b/drivers/crypto/allwinner/Kconfig index a0bdb26d0fe4..945228b3a8c4 100644 --- a/drivers/crypto/allwinner/Kconfig +++ b/drivers/crypto/allwinner/Kconfig @@ -103,3 +103,12 @@ config CRYPTO_DEV_SUN8I_SS_PRNG help Select this option if you want to provide kernel-side support for the Pseudo-Random Number Generator found in the Security System. + +config CRYPTO_DEV_SUN8I_SS_HASH + bool "Enable support for hash on sun8i-ss" + depends on CRYPTO_DEV_SUN8I_SS + select MD5 + select SHA1 + select SHA256 + help + Say y to enable support for hash algorithms. diff --git a/drivers/crypto/allwinner/sun8i-ss/Makefile b/drivers/crypto/allwinner/sun8i-ss/Makefile index 49f2f912c816..aabfd893c817 100644 --- a/drivers/crypto/allwinner/sun8i-ss/Makefile +++ b/drivers/crypto/allwinner/sun8i-ss/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_CRYPTO_DEV_SUN8I_SS) += sun8i-ss.o sun8i-ss-y += sun8i-ss-core.o sun8i-ss-cipher.o sun8i-ss-$(CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG) += sun8i-ss-prng.o +sun8i-ss-$(CONFIG_CRYPTO_DEV_SUN8I_SS_HASH) += sun8i-ss-hash.o diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c index 592ee35616ba..cd408969bd03 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c @@ -41,6 +41,8 @@ static const struct ss_variant ss_a80_variant = { static const struct ss_variant ss_a83t_variant = { .alg_cipher = { SS_ALG_AES, SS_ALG_DES, SS_ALG_3DES, }, + .alg_hash = { SS_ALG_MD5, SS_ALG_SHA1, SS_ALG_SHA224, SS_ALG_SHA256, + }, .op_mode = { SS_OP_ECB, SS_OP_CBC, }, .ss_clks = { @@ -280,6 +282,128 @@ static struct sun8i_ss_alg_template ss_algs[] = { } }, #endif +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_HASH +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ss_algo_id = SS_ID_HASH_MD5, + .alg.hash = { + .init = sun8i_ss_hash_init, + .update = sun8i_ss_hash_update, + .final = sun8i_ss_hash_final, + .finup = sun8i_ss_hash_finup, + .digest = sun8i_ss_hash_digest, + .export = sun8i_ss_hash_export, + .import = sun8i_ss_hash_import, + .halg = { + .digestsize = MD5_DIGEST_SIZE, + .statesize = sizeof(struct md5_state), + .base = { + .cra_name = "md5", + .cra_driver_name = "md5-sun8i-ss", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ss_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ss_hash_crainit, + .cra_exit = sun8i_ss_hash_craexit, + } + } + } +}, +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ss_algo_id = SS_ID_HASH_SHA1, + .alg.hash = { + .init = sun8i_ss_hash_init, + .update = sun8i_ss_hash_update, + .final = sun8i_ss_hash_final, + .finup = sun8i_ss_hash_finup, + .digest = sun8i_ss_hash_digest, + .export = sun8i_ss_hash_export, + .import = sun8i_ss_hash_import, + .halg = { + .digestsize = SHA1_DIGEST_SIZE, + .statesize = sizeof(struct sha1_state), + .base = { + .cra_name = "sha1", + .cra_driver_name = "sha1-sun8i-ss", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ss_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ss_hash_crainit, + .cra_exit = sun8i_ss_hash_craexit, + } + } + } +}, +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ss_algo_id = SS_ID_HASH_SHA224, + .alg.hash = { + .init = sun8i_ss_hash_init, + .update = sun8i_ss_hash_update, + .final = sun8i_ss_hash_final, + .finup = sun8i_ss_hash_finup, + .digest = sun8i_ss_hash_digest, + .export = sun8i_ss_hash_export, + .import = sun8i_ss_hash_import, + .halg = { + .digestsize = SHA224_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha224", + .cra_driver_name = "sha224-sun8i-ss", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ss_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ss_hash_crainit, + .cra_exit = sun8i_ss_hash_craexit, + } + } + } +}, +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ss_algo_id = SS_ID_HASH_SHA256, + .alg.hash = { + .init = sun8i_ss_hash_init, + .update = sun8i_ss_hash_update, + .final = sun8i_ss_hash_final, + .finup = sun8i_ss_hash_finup, + .digest = sun8i_ss_hash_digest, + .export = sun8i_ss_hash_export, + .import = sun8i_ss_hash_import, + .halg = { + .digestsize = SHA256_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha256", + .cra_driver_name = "sha256-sun8i-ss", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ss_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ss_hash_crainit, + .cra_exit = sun8i_ss_hash_craexit, + } + } + } +}, +#endif }; #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG @@ -307,6 +431,12 @@ static int sun8i_ss_dbgfs_read(struct seq_file *seq, void *v) ss_algs[i].alg.rng.base.cra_name, ss_algs[i].stat_req, ss_algs[i].stat_bytes); break; + case CRYPTO_ALG_TYPE_AHASH: + seq_printf(seq, "%s %s %lu %lu\n", + ss_algs[i].alg.hash.halg.base.cra_driver_name, + ss_algs[i].alg.hash.halg.base.cra_name, + ss_algs[i].stat_req, ss_algs[i].stat_fb); + break; } } return 0; @@ -478,6 +608,26 @@ static int sun8i_ss_register_algs(struct sun8i_ss_dev *ss) ss_algs[i].ss = NULL; } break; + case CRYPTO_ALG_TYPE_AHASH: + id = ss_algs[i].ss_algo_id; + ss_method = ss->variant->alg_hash[id]; + if (ss_method == SS_ID_NOTSUPP) { + dev_info(ss->dev, + "DEBUG: Algo of %s not supported\n", + ss_algs[i].alg.hash.halg.base.cra_name); + ss_algs[i].ss = NULL; + break; + } + dev_info(ss->dev, "Register %s\n", + ss_algs[i].alg.hash.halg.base.cra_name); + err = crypto_register_ahash(&ss_algs[i].alg.hash); + if (err) { + dev_err(ss->dev, "ERROR: Fail to register %s\n", + ss_algs[i].alg.hash.halg.base.cra_name); + ss_algs[i].ss = NULL; + return err; + } + break; default: ss_algs[i].ss = NULL; dev_err(ss->dev, "ERROR: tried to register an unknown algo\n"); @@ -504,6 +654,11 @@ static void sun8i_ss_unregister_algs(struct sun8i_ss_dev *ss) ss_algs[i].alg.rng.base.cra_name); crypto_unregister_rng(&ss_algs[i].alg.rng); break; + case CRYPTO_ALG_TYPE_AHASH: + dev_info(ss->dev, "Unregister %d %s\n", i, + ss_algs[i].alg.hash.halg.base.cra_name); + crypto_unregister_ahash(&ss_algs[i].alg.hash); + break; } } } diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c new file mode 100644 index 000000000000..d89b2ef895f5 --- /dev/null +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * sun8i-ss-hash.c - hardware cryptographic offloader for + * Allwinner A80/A83T SoC + * + * Copyright (C) 2015-2020 Corentin Labbe + * + * This file add support for MD5 and SHA1/SHA224/SHA256. + * + * You could find the datasheet in Documentation/arm/sunxi.rst + */ +#include +#include +#include +#include +#include +#include "sun8i-ss.h" + +int sun8i_ss_hash_crainit(struct crypto_tfm *tfm) +{ + struct sun8i_ss_hash_tfm_ctx *op = crypto_tfm_ctx(tfm); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg); + struct sun8i_ss_alg_template *algt; + int err; + + memset(op, 0, sizeof(struct sun8i_ss_hash_tfm_ctx)); + + algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); + op->ss = algt->ss; + + op->enginectx.op.do_one_request = sun8i_ss_hash_run; + op->enginectx.op.prepare_request = NULL; + op->enginectx.op.unprepare_request = NULL; + + /* FALLBACK */ + op->fallback_tfm = crypto_alloc_ahash(crypto_tfm_alg_name(tfm), 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(op->fallback_tfm)) { + dev_err(algt->ss->dev, "Fallback driver could no be loaded\n"); + return PTR_ERR(op->fallback_tfm); + } + + if (algt->alg.hash.halg.statesize < crypto_ahash_statesize(op->fallback_tfm)) + algt->alg.hash.halg.statesize = crypto_ahash_statesize(op->fallback_tfm); + + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct sun8i_ss_hash_reqctx) + + crypto_ahash_reqsize(op->fallback_tfm)); + + dev_info(op->ss->dev, "Fallback for %s is %s\n", + crypto_tfm_alg_driver_name(tfm), + crypto_tfm_alg_driver_name(&op->fallback_tfm->base)); + err = pm_runtime_get_sync(op->ss->dev); + if (err < 0) + goto error_pm; + return 0; +error_pm: + crypto_free_ahash(op->fallback_tfm); + return err; +} + +void sun8i_ss_hash_craexit(struct crypto_tfm *tfm) +{ + struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_tfm_ctx(tfm); + + crypto_free_ahash(tfmctx->fallback_tfm); + pm_runtime_put_sync_suspend(tfmctx->ss->dev); +} + +int sun8i_ss_hash_init(struct ahash_request *areq) +{ + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ss_alg_template *algt; + + memset(rctx, 0, sizeof(struct sun8i_ss_hash_reqctx)); + + algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_init(&rctx->fallback_req); +} + +int sun8i_ss_hash_export(struct ahash_request *areq, void *out) +{ + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_export(&rctx->fallback_req, out); +} + +int sun8i_ss_hash_import(struct ahash_request *areq, const void *in) +{ + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_import(&rctx->fallback_req, in); +} + +int sun8i_ss_hash_final(struct ahash_request *areq) +{ + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ss_alg_template *algt; +#endif + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->fallback_req.result = areq->result; + +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG + algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); + algt->stat_fb++; +#endif + + return crypto_ahash_final(&rctx->fallback_req); +} + +int sun8i_ss_hash_update(struct ahash_request *areq) +{ + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->fallback_req.nbytes = areq->nbytes; + rctx->fallback_req.src = areq->src; + + return crypto_ahash_update(&rctx->fallback_req); +} + +int sun8i_ss_hash_finup(struct ahash_request *areq) +{ + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ss_alg_template *algt; +#endif + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + + rctx->fallback_req.nbytes = areq->nbytes; + rctx->fallback_req.src = areq->src; + rctx->fallback_req.result = areq->result; +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG + algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); + algt->stat_fb++; +#endif + + return crypto_ahash_finup(&rctx->fallback_req); +} + +int sun8i_ss_hash_digest_fb(struct ahash_request *areq) +{ + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ss_alg_template *algt; +#endif + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + + rctx->fallback_req.nbytes = areq->nbytes; + rctx->fallback_req.src = areq->src; + rctx->fallback_req.result = areq->result; +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG + algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); + algt->stat_fb++; +#endif + + return crypto_ahash_digest(&rctx->fallback_req); +} + +static int sun8i_ss_run_hash_task(struct sun8i_ss_dev *ss, + struct sun8i_ss_hash_reqctx *rctx, + const char *name) +{ + int flow = rctx->flow; + u32 v = SS_START; + int i; + +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG + ss->flows[flow].stat_req++; +#endif + + /* choose between stream0/stream1 */ + if (flow) + v |= SS_FLOW1; + else + v |= SS_FLOW0; + + v |= rctx->method; + + for (i = 0; i < MAX_SG; i++) { + if (!rctx->t_dst[i].addr) + break; + + mutex_lock(&ss->mlock); + if (i > 0) { + v |= BIT(17); + writel(rctx->t_dst[i - 1].addr, ss->base + SS_KEY_ADR_REG); + writel(rctx->t_dst[i - 1].addr, ss->base + SS_IV_ADR_REG); + } + + dev_dbg(ss->dev, + "Processing SG %d on flow %d %s ctl=%x %d to %d method=%x src=%x dst=%x\n", + i, flow, name, v, + rctx->t_src[i].len, rctx->t_dst[i].len, + rctx->method, rctx->t_src[i].addr, rctx->t_dst[i].addr); + + writel(rctx->t_src[i].addr, ss->base + SS_SRC_ADR_REG); + writel(rctx->t_dst[i].addr, ss->base + SS_DST_ADR_REG); + writel(rctx->t_src[i].len, ss->base + SS_LEN_ADR_REG); + writel(BIT(0) | BIT(1), ss->base + SS_INT_CTL_REG); + + reinit_completion(&ss->flows[flow].complete); + ss->flows[flow].status = 0; + wmb(); + + writel(v, ss->base + SS_CTL_REG); + mutex_unlock(&ss->mlock); + wait_for_completion_interruptible_timeout(&ss->flows[flow].complete, + msecs_to_jiffies(2000)); + if (ss->flows[flow].status == 0) { + dev_err(ss->dev, "DMA timeout for %s\n", name); + return -EFAULT; + } + } + + return 0; +} + +static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq) +{ + struct scatterlist *sg; + + if (areq->nbytes == 0) + return true; + /* we need to reserve one SG for the padding one */ + if (sg_nents(areq->src) > MAX_SG - 1) + return true; + sg = areq->src; + while (sg) { + /* SS can operate hash only on full block size + * since SS support only MD5,sha1,sha224 and sha256, blocksize + * is always 64 + * TODO: handle request if last SG is not len%64 + * but this will need to copy data on a new SG of size=64 + */ + if (sg->length % 64 || !IS_ALIGNED(sg->offset, sizeof(u32))) + return true; + sg = sg_next(sg); + } + return false; +} + +int sun8i_ss_hash_digest(struct ahash_request *areq) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct sun8i_ss_alg_template *algt; + struct sun8i_ss_dev *ss; + struct crypto_engine *engine; + struct scatterlist *sg; + int nr_sgs, e, i; + + if (sun8i_ss_hash_need_fallback(areq)) + return sun8i_ss_hash_digest_fb(areq); + + nr_sgs = sg_nents(areq->src); + if (nr_sgs > MAX_SG - 1) + return sun8i_ss_hash_digest_fb(areq); + + for_each_sg(areq->src, sg, nr_sgs, i) { + if (sg->length % 4 || !IS_ALIGNED(sg->offset, sizeof(u32))) + return sun8i_ss_hash_digest_fb(areq); + } + + algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); + ss = algt->ss; + + e = sun8i_ss_get_engine_number(ss); + rctx->flow = e; + engine = ss->flows[e].engine; + + return crypto_transfer_hash_request_to_engine(engine, areq); +} + +/* sun8i_ss_hash_run - run an ahash request + * Send the data of the request to the SS along with an extra SG with padding + */ +int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) +{ + struct ahash_request *areq = container_of(breq, struct ahash_request, base); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); + struct sun8i_ss_alg_template *algt; + struct sun8i_ss_dev *ss; + struct scatterlist *sg; + int nr_sgs, err, digestsize; + unsigned int len; + u64 fill, min_fill, byte_count; + void *pad, *result; + int j, i, todo; + __be64 *bebits; + __le64 *lebits; + dma_addr_t addr_res, addr_pad; + u32 *bf; + + algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); + ss = algt->ss; + + digestsize = algt->alg.hash.halg.digestsize; + if (digestsize == SHA224_DIGEST_SIZE) + digestsize = SHA256_DIGEST_SIZE; + + /* the padding could be up to two block. */ + pad = kzalloc(algt->alg.hash.halg.base.cra_blocksize * 2, GFP_KERNEL | GFP_DMA); + if (!pad) + return -ENOMEM; + bf = (u32 *)pad; + + result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA); + if (!result) + return -ENOMEM; + + for (i = 0; i < MAX_SG; i++) { + rctx->t_dst[i].addr = 0; + rctx->t_dst[i].len = 0; + } + +#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG + algt->stat_req++; +#endif + + rctx->method = cpu_to_le32(ss->variant->alg_hash[algt->ss_algo_id]); + + nr_sgs = dma_map_sg(ss->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); + if (nr_sgs <= 0 || nr_sgs > MAX_SG) { + dev_err(ss->dev, "Invalid sg number %d\n", nr_sgs); + err = -EINVAL; + goto theend; + } + + addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE); + if (dma_mapping_error(ss->dev, addr_res)) { + dev_err(ss->dev, "DMA map dest\n"); + err = -EINVAL; + goto theend; + } + + len = areq->nbytes; + for_each_sg(areq->src, sg, nr_sgs, i) { + rctx->t_src[i].addr = cpu_to_le32(sg_dma_address(sg)); + todo = min(len, sg_dma_len(sg)); + rctx->t_src[i].len = cpu_to_le32(todo / 4); + len -= todo; + rctx->t_dst[i].addr = cpu_to_le32(addr_res); + rctx->t_dst[i].len = cpu_to_le32(digestsize / 4); + } + if (len > 0) { + dev_err(ss->dev, "remaining len %d\n", len); + err = -EINVAL; + goto theend; + } + + byte_count = areq->nbytes; + j = 0; + bf[j++] = le32_to_cpu(1 << 7); + + fill = 64 - (byte_count % 64); + min_fill = 3 * sizeof(u32); + + if (fill < min_fill) + fill += 64; + + j += (fill - min_fill) / sizeof(u32); + + switch (algt->ss_algo_id) { + case SS_ID_HASH_MD5: + lebits = (__le64 *)&bf[j]; + *lebits = cpu_to_le64(byte_count << 3); + j += 2; + break; + case SS_ID_HASH_SHA1: + case SS_ID_HASH_SHA224: + case SS_ID_HASH_SHA256: + bebits = (__be64 *)&bf[j]; + *bebits = cpu_to_be64(byte_count << 3); + j += 2; + break; + } + + addr_pad = dma_map_single(ss->dev, pad, j * 4, DMA_TO_DEVICE); + rctx->t_src[i].addr = cpu_to_le32(addr_pad); + rctx->t_src[i].len = cpu_to_le32(j); + rctx->t_dst[i].addr = cpu_to_le32(addr_res); + rctx->t_dst[i].len = cpu_to_le32(digestsize / 4); + if (dma_mapping_error(ss->dev, addr_pad)) { + dev_err(ss->dev, "DMA error on padding SG\n"); + err = -EINVAL; + goto theend; + } + + err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm)); + + dma_unmap_single(ss->dev, addr_pad, j * 4, DMA_TO_DEVICE); + dma_unmap_sg(ss->dev, areq->src, nr_sgs, DMA_TO_DEVICE); + dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE); + + kfree(pad); + + memcpy(areq->result, result, algt->alg.hash.halg.digestsize); + kfree(result); +theend: + crypto_finalize_hash_request(engine, breq, err); + return 0; +} diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h index 0223e10495ac..350a611b0b9e 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #define SS_START 1 @@ -22,7 +25,11 @@ #define SS_ALG_AES 0 #define SS_ALG_DES (1 << 2) #define SS_ALG_3DES (2 << 2) +#define SS_ALG_MD5 (3 << 2) #define SS_ALG_PRNG (4 << 2) +#define SS_ALG_SHA1 (6 << 2) +#define SS_ALG_SHA224 (7 << 2) +#define SS_ALG_SHA256 (8 << 2) #define SS_CTL_REG 0x00 #define SS_INT_CTL_REG 0x04 @@ -51,6 +58,12 @@ #define SS_OP_ECB 0 #define SS_OP_CBC (1 << 13) +#define SS_ID_HASH_MD5 0 +#define SS_ID_HASH_SHA1 1 +#define SS_ID_HASH_SHA224 2 +#define SS_ID_HASH_SHA256 3 +#define SS_ID_HASH_MAX 4 + #define SS_FLOW0 BIT(30) #define SS_FLOW1 BIT(31) @@ -84,11 +97,14 @@ struct ss_clock { * struct ss_variant - Describe SS capability for each variant hardware * @alg_cipher: list of supported ciphers. for each SS_ID_ this will give the * coresponding SS_ALG_XXX value + * @alg_hash: list of supported hashes. for each SS_ID_ this will give the + * corresponding SS_ALG_XXX value * @op_mode: list of supported block modes * @ss_clks! list of clock needed by this variant */ struct ss_variant { char alg_cipher[SS_ID_CIPHER_MAX]; + char alg_hash[SS_ID_HASH_MAX]; u32 op_mode[SS_ID_OP_MAX]; struct ss_clock ss_clks[SS_MAX_CLOCKS]; }; @@ -196,6 +212,38 @@ struct sun8i_ss_rng_tfm_ctx { unsigned int slen; }; +/* + * struct sun8i_ss_hash_tfm_ctx - context for an ahash TFM + * @enginectx: crypto_engine used by this TFM + * @fallback_tfm: pointer to the fallback TFM + * @ss: pointer to the private data of driver handling this TFM + * + * enginectx must be the first element + */ +struct sun8i_ss_hash_tfm_ctx { + struct crypto_engine_ctx enginectx; + struct crypto_ahash *fallback_tfm; + struct sun8i_ss_dev *ss; +}; + +/* + * struct sun8i_ss_hash_reqctx - context for an ahash request + * @t_src: list of DMA address and size for source SGs + * @t_dst: list of DMA address and size for destination SGs + * @fallback_req: pre-allocated fallback request + * @method: the register value for the algorithm used by this request + * @flow: the flow to use for this request + * + * t_src, t_dst and method must be in LE32 + */ +struct sun8i_ss_hash_reqctx { + struct sginfo t_src[MAX_SG]; + struct sginfo t_dst[MAX_SG]; + struct ahash_request fallback_req; + u32 method; + int flow; +}; + /* * struct sun8i_ss_alg_template - crypto_alg template * @type: the CRYPTO_ALG_TYPE for this template @@ -216,6 +264,7 @@ struct sun8i_ss_alg_template { union { struct skcipher_alg skcipher; struct rng_alg rng; + struct ahash_alg hash; } alg; #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG unsigned long stat_req; @@ -243,3 +292,14 @@ int sun8i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src, int sun8i_ss_prng_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); int sun8i_ss_prng_init(struct crypto_tfm *tfm); void sun8i_ss_prng_exit(struct crypto_tfm *tfm); + +int sun8i_ss_hash_crainit(struct crypto_tfm *tfm); +void sun8i_ss_hash_craexit(struct crypto_tfm *tfm); +int sun8i_ss_hash_init(struct ahash_request *areq); +int sun8i_ss_hash_export(struct ahash_request *areq, void *out); +int sun8i_ss_hash_import(struct ahash_request *areq, const void *in); +int sun8i_ss_hash_final(struct ahash_request *areq); +int sun8i_ss_hash_update(struct ahash_request *areq); +int sun8i_ss_hash_finup(struct ahash_request *areq); +int sun8i_ss_hash_digest(struct ahash_request *areq); +int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq); From patchwork Fri Apr 24 14:02:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corentin Labbe X-Patchwork-Id: 197832 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 925D9C55194 for ; Fri, 24 Apr 2020 14:03:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6B66721569 for ; Fri, 24 Apr 2020 14:03:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="FuoPfzJU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728071AbgDXOCj (ORCPT ); Fri, 24 Apr 2020 10:02:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38212 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1728373AbgDXOCi (ORCPT ); Fri, 24 Apr 2020 10:02:38 -0400 Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 04F2CC09B045 for ; Fri, 24 Apr 2020 07:02:37 -0700 (PDT) Received: by mail-wm1-x341.google.com with SMTP id h2so10571495wmb.4 for ; Fri, 24 Apr 2020 07:02:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SU0E9luozURTZ9TC+AsIeijArTCKSbuhSsq3JPq3G+Q=; b=FuoPfzJUK/ct5OaBTFDq9xyu8VZKYeQiFwCDQAeXPwGBBmcCFdiZLenmH3KNChIAjM c+Zax04FMpjAF11s0LW7x4jKqmzTHMzPYvIXkBqY5XF3YXiPsqRxXPmNQm0Q6/520H++ HPxrRjWNsHr/lqXPWUKY8XQjN0VB3QUzRfJuPw3zgfd15dEIGQ57jpSRi7fE3p6cXdkx 6NLzXSr4vNC9bN937sTzCCxJHmkGQLUwwcDJnpVBdpT9/yDiGxyps94d2eKaYsXjW8nI magVDUKbL+sJZKEDdI3RHiVbTHBQEFwb5y4azCLqdR1LABFCY4rDHAA0MYDddOaimcrL qdyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SU0E9luozURTZ9TC+AsIeijArTCKSbuhSsq3JPq3G+Q=; b=ktgVCneJq4BqZWcncTZrLte9BC5fH/rW5OXyGlzqkaktvc355uFqhNSVc7ij4bHK0f rQp1kOjbUZcvmsfa5PJdtgg8exDQCO9fd6YCf6nn7+mx18h4dBeMfflrS64nK0YfakeF bMp0o60f7Xx0fE2JWh7pGGzcq6vqUVgVVhSglzLefKujiFzObvrgs6sQL3jNkiYFZKIv 7AJA2i8sm46jlOpT22ZnvSqkChW0U/o1Of+DLGZbjC5J1MHoiYJ7TL80hE4x0ix5U+3p /jlxSzk2zTbwojrsL85f3GmNGshO2hzxubL+gFh1mEsSVUNKk9Zz2OXY/3vkMR6ES4oR ynFA== X-Gm-Message-State: AGi0PuZD5P1brsKq+1er9Fo7KTyU6SY6dQW8KarRbAN0zWrofeOHnver EdHOAAdzeqp8wdlFVz6pi8YMgw== X-Google-Smtp-Source: APiQypI0A8PJKVgaS0meuPVlaPvfocGUfiVkxmyRS+dPjkui9z0Cj6/x2YMQuD8fNlV3vVje8fNMtQ== X-Received: by 2002:a1c:4304:: with SMTP id q4mr11080546wma.152.1587736955755; Fri, 24 Apr 2020 07:02:35 -0700 (PDT) Received: from localhost.localdomain ([51.15.160.169]) by smtp.googlemail.com with ESMTPSA id v131sm3061051wmb.19.2020.04.24.07.02.33 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2020 07:02:34 -0700 (PDT) From: Corentin Labbe To: davem@davemloft.net, herbert@gondor.apana.org.au, mripard@kernel.org, wens@csie.org Cc: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Corentin Labbe Subject: [PATCH v2 06/14] crypto: sun8i-ss: better debug printing Date: Fri, 24 Apr 2020 14:02:06 +0000 Message-Id: <1587736934-22801-7-git-send-email-clabbe@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> References: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org This patch reworks the way debug info are printed. Instead of printing raw numbers, let's add a bit of context. Signed-off-by: Corentin Labbe --- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c index cd408969bd03..8ab154842c9e 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c @@ -420,19 +420,19 @@ static int sun8i_ss_dbgfs_read(struct seq_file *seq, void *v) continue; switch (ss_algs[i].type) { case CRYPTO_ALG_TYPE_SKCIPHER: - seq_printf(seq, "%s %s %lu %lu\n", + seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", ss_algs[i].alg.skcipher.base.cra_driver_name, ss_algs[i].alg.skcipher.base.cra_name, ss_algs[i].stat_req, ss_algs[i].stat_fb); break; case CRYPTO_ALG_TYPE_RNG: - seq_printf(seq, "%s %s %lu %lu\n", + seq_printf(seq, "%s %s reqs=%lu tsize=%lu\n", ss_algs[i].alg.rng.base.cra_driver_name, ss_algs[i].alg.rng.base.cra_name, ss_algs[i].stat_req, ss_algs[i].stat_bytes); break; case CRYPTO_ALG_TYPE_AHASH: - seq_printf(seq, "%s %s %lu %lu\n", + seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", ss_algs[i].alg.hash.halg.base.cra_driver_name, ss_algs[i].alg.hash.halg.base.cra_name, ss_algs[i].stat_req, ss_algs[i].stat_fb); From patchwork Fri Apr 24 14:02:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corentin Labbe X-Patchwork-Id: 197835 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A565C54FD0 for ; Fri, 24 Apr 2020 14:02:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 046002075A for ; Fri, 24 Apr 2020 14:02:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="onhrFneX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728471AbgDXOCq (ORCPT ); Fri, 24 Apr 2020 10:02:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38236 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1728430AbgDXOCp (ORCPT ); Fri, 24 Apr 2020 10:02:45 -0400 Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D0C6C09B045 for ; Fri, 24 Apr 2020 07:02:43 -0700 (PDT) Received: by mail-wm1-x344.google.com with SMTP id g12so10838163wmh.3 for ; Fri, 24 Apr 2020 07:02:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+xIdR6ROlQQsYyBm9HmTjwcK2nY5CHq9LE79wf8WO1A=; b=onhrFneXL+HREqFhDlDzl3KWmCFWaBJqBVFW2Wx9GKFBxdLZbfU8tmLbthreOxb5HE vkfvOp8sNqUSe+w766rQlCOaZ2zALdAxikhXyZArCvh6pd0GuQZOCgu6po1AyM+ok/J6 rVfASAgPx5q7yFJyZwTgIqfAmyfJ9TjI4pJCWS1YkdWtuuSDTR0BEXOTTcJm+VCYSvVJ +tZmz69k1o94h2FeAvIdGiGQq/dw8H+pgnhZB8zVvvJwByKGDt3uzqdmOQ5Vfta2R/Gw Tv3uTeojtFw7697xTun3MDsSZVmFurAohxpPxP6M9exlkUcaXhw84tv3EQ+nFFo6botG jWKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+xIdR6ROlQQsYyBm9HmTjwcK2nY5CHq9LE79wf8WO1A=; b=IcHHHQpJMH9Y8nAxoVimrMJ3+X0YMbH1olC4WTR1hYaDV6BjceN4X7G3C7TVNDaToI 9ui/w0fToVI51kxjNdZWSKyUjQFQ5AEy2j93msmFfe2j7VLtPDjjDJBHp78JkNB8Wcc7 LJQZAzHRN6Z77CsM+ov0bK4d/5PBiWyJVuvlO7/yPFr8chv73/HhMdaNg2c/FDAXF1jT A9ePKSnFlL7mcVA3CYpTKzcEWDE3Ac7kf/1G6tPklT5vG58PQsuWdumX+yt4k7/4sbED qjgfnSCnm0fBzDrlCtOwD6/xtftsdFdBTXbOQeHWwI1fiMi/ydxYapIQsjbOG0An9Nsi Q8fg== X-Gm-Message-State: AGi0PubAM+De1zKC/KC8u+RD4BLOsRaE7wLWcFTxJA1C1/BINA9oNQkB K9RnQApkPS4M+85h+m+fmBD5ow== X-Google-Smtp-Source: APiQypIeAx7J/vofT7s3q7EIA9lQ9CwvbzNGpuRn9789QH0+F4q5Fblu7FRr8fgCCWYi3y094ePzZg== X-Received: by 2002:a1c:bc09:: with SMTP id m9mr9927322wmf.145.1587736962269; Fri, 24 Apr 2020 07:02:42 -0700 (PDT) Received: from localhost.localdomain ([51.15.160.169]) by smtp.googlemail.com with ESMTPSA id v131sm3061051wmb.19.2020.04.24.07.02.38 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2020 07:02:40 -0700 (PDT) From: Corentin Labbe To: davem@davemloft.net, herbert@gondor.apana.org.au, mripard@kernel.org, wens@csie.org Cc: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Corentin Labbe Subject: [PATCH v2 08/14] crypto: sun8i-ce: split into prepare/run/unprepare Date: Fri, 24 Apr 2020 14:02:08 +0000 Message-Id: <1587736934-22801-9-git-send-email-clabbe@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> References: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org This patch split the do_one_request into three. Prepare will handle all DMA mapping and initialisation of the task structure. Unprepare will clean all DMA mapping. And the do_one_request will be limited to just executing the task. Signed-off-by: Corentin Labbe --- .../allwinner/sun8i-ce/sun8i-ce-cipher.c | 70 ++++++++++++++++--- drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h | 4 ++ 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c index 7716fa2d3250..d662dac83361 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c @@ -78,8 +78,9 @@ static int sun8i_ce_cipher_fallback(struct skcipher_request *areq) return err; } -static int sun8i_ce_cipher(struct skcipher_request *areq) +static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req) { + struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base); struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); struct sun8i_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm); struct sun8i_ce_dev *ce = op->ce; @@ -237,7 +238,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq) } chan->timeout = areq->cryptlen; - err = sun8i_ce_run_task(ce, flow, crypto_tfm_alg_name(areq->base.tfm)); + rctx->nr_sgs = nr_sgs; + rctx->nr_sgd = nr_sgd; + return 0; theend_sgs: if (areq->src == areq->dst) { @@ -271,13 +274,64 @@ static int sun8i_ce_cipher(struct skcipher_request *areq) return err; } -static int sun8i_ce_handle_cipher_request(struct crypto_engine *engine, void *areq) +int sun8i_ce_cipher_run(struct crypto_engine *engine, void *areq) { - int err; struct skcipher_request *breq = container_of(areq, struct skcipher_request, base); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(breq); + struct sun8i_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm); + struct sun8i_ce_dev *ce = op->ce; + struct sun8i_cipher_req_ctx *rctx = skcipher_request_ctx(breq); + int flow, err; - err = sun8i_ce_cipher(breq); + flow = rctx->flow; + err = sun8i_ce_run_task(ce, flow, crypto_tfm_alg_name(breq->base.tfm)); crypto_finalize_skcipher_request(engine, breq, err); + return 0; +} + +static int sun8i_ce_cipher_unprepare(struct crypto_engine *engine, void *async_req) +{ + struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); + struct sun8i_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm); + struct sun8i_ce_dev *ce = op->ce; + struct sun8i_cipher_req_ctx *rctx = skcipher_request_ctx(areq); + struct sun8i_ce_flow *chan; + struct ce_task *cet; + unsigned int ivsize, offset; + int nr_sgs = rctx->nr_sgs; + int nr_sgd = rctx->nr_sgd; + int flow; + + flow = rctx->flow; + chan = &ce->chanlist[flow]; + cet = chan->tl; + ivsize = crypto_skcipher_ivsize(tfm); + + if (areq->src == areq->dst) { + dma_unmap_sg(ce->dev, areq->src, nr_sgs, DMA_BIDIRECTIONAL); + } else { + if (nr_sgs > 0) + dma_unmap_sg(ce->dev, areq->src, nr_sgs, DMA_TO_DEVICE); + dma_unmap_sg(ce->dev, areq->dst, nr_sgd, DMA_FROM_DEVICE); + } + + if (areq->iv && ivsize > 0) { + if (cet->t_iv) + dma_unmap_single(ce->dev, cet->t_iv, rctx->ivlen, + DMA_TO_DEVICE); + offset = areq->cryptlen - ivsize; + if (rctx->op_dir & CE_DECRYPTION) { + memcpy(areq->iv, rctx->backup_iv, ivsize); + kzfree(rctx->backup_iv); + } else { + scatterwalk_map_and_copy(areq->iv, areq->dst, offset, + ivsize, 0); + } + kfree(rctx->bounce_iv); + } + + dma_unmap_single(ce->dev, cet->t_key, op->keylen, DMA_TO_DEVICE); return 0; } @@ -347,9 +401,9 @@ int sun8i_ce_cipher_init(struct crypto_tfm *tfm) crypto_tfm_alg_driver_name(&sktfm->base), crypto_tfm_alg_driver_name(crypto_skcipher_tfm(&op->fallback_tfm->base))); - op->enginectx.op.do_one_request = sun8i_ce_handle_cipher_request; - op->enginectx.op.prepare_request = NULL; - op->enginectx.op.unprepare_request = NULL; + op->enginectx.op.do_one_request = sun8i_ce_cipher_run; + op->enginectx.op.prepare_request = sun8i_ce_cipher_prepare; + op->enginectx.op.unprepare_request = sun8i_ce_cipher_unprepare; err = pm_runtime_get_sync(op->ce->dev); if (err < 0) diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h index c9c7ef8299e2..fe97fee74e47 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h @@ -182,6 +182,8 @@ struct sun8i_ce_dev { * @backup_iv: buffer which contain the next IV to store * @bounce_iv: buffer which contain a copy of IV * @ivlen: size of bounce_iv + * @nr_sgs: The number of source SG (as given by dma_map_sg()) + * @nr_sgd: The number of destination SG (as given by dma_map_sg()) */ struct sun8i_cipher_req_ctx { u32 op_dir; @@ -189,6 +191,8 @@ struct sun8i_cipher_req_ctx { void *backup_iv; void *bounce_iv; unsigned int ivlen; + int nr_sgs; + int nr_sgd; }; /* From patchwork Fri Apr 24 14:02:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corentin Labbe X-Patchwork-Id: 197836 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F6B5C55194 for ; Fri, 24 Apr 2020 14:02:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0CB4221569 for ; Fri, 24 Apr 2020 14:02:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="DvyaBcQJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728486AbgDXOCs (ORCPT ); Fri, 24 Apr 2020 10:02:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1728463AbgDXOCs (ORCPT ); Fri, 24 Apr 2020 10:02:48 -0400 Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D5C39C09B046 for ; Fri, 24 Apr 2020 07:02:47 -0700 (PDT) Received: by mail-wr1-x442.google.com with SMTP id k1so10980466wrx.4 for ; Fri, 24 Apr 2020 07:02:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=g8U0XNbBq8ssolXmS0TLiEjhDwf6nz3yMHXDCMAD7sc=; b=DvyaBcQJNGWVZFD/KC3yEryBXIDwQgzX41kqbDE1JtzMJeRsGTiVE4RWEsUE2jKI4d WfDzZKJ+X8l2lVeS4suyru8mstxkQJUBzRsPR2D2bUZsWxsmfnuNRDPJyxTpUggfQIx6 NODPu6tDNArn+nEEPr+O+0cBOsAzVuw1C4uGje7mWI9Z9J8WROFtBgOnMjS9N65wsNrW CtZIA5Q5x7bH+Jlpq00ngCzFugkIVG+kXL3DpgsRkNA7BE8qkrntot8y6mARKJXaE0EC N5F3X/CI5wuyMldZo4zqKO6yXtXKuc5cYn1zmUrW8CelFcfYh3c3gJbPtZtdW2y8D0Yi gtDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=g8U0XNbBq8ssolXmS0TLiEjhDwf6nz3yMHXDCMAD7sc=; b=h0U4tZ80ADTJuZcSbHYedJyXfiTK1Dcd0RfIVbNueF5odIEkkYfgBA0mil6tt48aFA qBy0G9NfyzqRTDN+sEPeYXIz8Mj0BJpUZNu1gBPcsEQSNI2VZO+BcpUkFgORSp+WDLcH 74ktIkcRYf9+CnhWmGBH99alnD1I/UU1uVqufMKmrhuUVPu+6L4mRtPhSQ8pJIEQBHcS qtQ80pthBCec5TCJRHUOukTI3FJD2cGGsG//pbC4wLA5LhkSxER0KnGdkK2LolHhVe9l vNXCfSD/XMTLHEgUgHk1eFOYeWmLyIw8+NAUCk2Rq6JjPFLZOR+jGckMAenGeITsVy16 D9eQ== X-Gm-Message-State: AGi0PuYtorOpBXIyJh3KuQmJXhGtBClaVFuj6k0j2F6rYg0B3dWcIuBI BzITdepM5tMni1Kh6Mtqy8mKGA== X-Google-Smtp-Source: APiQypKpesTpZF+Cl8O0C7Cg5hyDE+qe5ZCnpiV8wq9RtKMvRqWamf8VuzxeA/XldX6c4hfQW95pXg== X-Received: by 2002:a5d:5745:: with SMTP id q5mr12047098wrw.351.1587736966051; Fri, 24 Apr 2020 07:02:46 -0700 (PDT) Received: from localhost.localdomain ([51.15.160.169]) by smtp.googlemail.com with ESMTPSA id v131sm3061051wmb.19.2020.04.24.07.02.44 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2020 07:02:44 -0700 (PDT) From: Corentin Labbe To: davem@davemloft.net, herbert@gondor.apana.org.au, mripard@kernel.org, wens@csie.org Cc: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Corentin Labbe Subject: [PATCH v2 10/14] crypto: sun8i-ce: rename has_t_dlen_in_bytes to cipher_t_dlen_in_bytes Date: Fri, 24 Apr 2020 14:02:10 +0000 Message-Id: <1587736934-22801-11-git-send-email-clabbe@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> References: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Hash algorithms will need also a spetial t_dlen handling, but since the meaning will be different, rename the current flag to specify it apply only on ciphers algorithms. Signed-off-by: Corentin Labbe --- drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c | 2 +- drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 2 +- drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c index d662dac83361..ee7add582e90 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c @@ -122,7 +122,7 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req common |= rctx->op_dir | CE_COMM_INT; cet->t_common_ctl = cpu_to_le32(common); /* CTS and recent CE (H6) need length in bytes, in word otherwise */ - if (ce->variant->has_t_dlen_in_bytes) + if (ce->variant->cipher_t_dlen_in_bytes) cet->t_dlen = cpu_to_le32(areq->cryptlen); else cet->t_dlen = cpu_to_le32(areq->cryptlen / 4); diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c index 80f7918fbea8..8bc669f18010 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c @@ -61,7 +61,7 @@ static const struct ce_variant ce_h6_variant = { }, .op_mode = { CE_OP_ECB, CE_OP_CBC }, - .has_t_dlen_in_bytes = true, + .cipher_t_dlen_in_bytes = true, .ce_clks = { { "bus", 0, 200000000 }, { "mod", 300000000, 0 }, diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h index ed1a91da967b..0a70fcc102f1 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h @@ -97,7 +97,7 @@ struct ce_clock { * @alg_cipher: list of supported ciphers. for each CE_ID_ this will give the * coresponding CE_ALG_XXX value * @op_mode: list of supported block modes - * @has_t_dlen_in_bytes: Does the request size for cipher is in + * @cipher_t_dlen_in_bytes: Does the request size for cipher is in * bytes or words * @ce_clks: list of clocks needed by this variant * @esr: The type of error register @@ -105,7 +105,7 @@ struct ce_clock { struct ce_variant { char alg_cipher[CE_ID_CIPHER_MAX]; u32 op_mode[CE_ID_OP_MAX]; - bool has_t_dlen_in_bytes; + bool cipher_t_dlen_in_bytes; struct ce_clock ce_clks[CE_MAX_CLOCKS]; int esr; }; From patchwork Fri Apr 24 14:02:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corentin Labbe X-Patchwork-Id: 197833 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5DA13C54FCB for ; Fri, 24 Apr 2020 14:03:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 18A4921569 for ; Fri, 24 Apr 2020 14:03:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="GC57ZLdu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728555AbgDXODG (ORCPT ); Fri, 24 Apr 2020 10:03:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1728492AbgDXOCv (ORCPT ); Fri, 24 Apr 2020 10:02:51 -0400 Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6973AC09B045 for ; Fri, 24 Apr 2020 07:02:51 -0700 (PDT) Received: by mail-wr1-x442.google.com with SMTP id k1so10980769wrx.4 for ; Fri, 24 Apr 2020 07:02:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4L8RaV53HvYLYFl9LgcjNOhNScjozccPppJgb6DSmMU=; b=GC57ZLdu7fcu6Djp5kYG1a7kFBGlpoMpX91In08gUuSyKN6MV+tTGefY8az98gDkbW 5eoyh+gi8JjnARmhQgrNJHSQT9AlC7g4CHLe57Q+FmS14idMF0fYNkPZuKkk4wlUn/IW RGoA5F+CRKQQ1nTOYL5ky+w+SEho7H88+K4pIe7hUjz5SPy3A1bmG7lo9dvq3WZdfTWw iHXnsl8duOub4lIxSpLeFZqRwrf+xBL28WASvlIQBrGjJa8W51MAnjt4/vTxFL+0ZNiw Il8nM9KdrnMkm6sixfGF+P516bdDX2lx5/q20OgMYRviOnfFiHMhuBqQyzq+XXN4+yUJ OPjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4L8RaV53HvYLYFl9LgcjNOhNScjozccPppJgb6DSmMU=; b=qUfNJJrC6appB4yXCCN1z9ZF6VmtcusKmDaOMVdSBLWyDsEUrmORT1RcKG4Hme6o8e dwK0xr0l8vTWlwYKKR9hs9lq7ZDR4mA1MbzBnfc/tLU4gLMWS5M/5VjUoV27a2Pj1wGE i5fOzJ0uycK3bu0iWJAvN/2/eCUh6+zhGVy+TkAWbYhuFhF3Dos49fK1m2xPEdDgMFaR R/4N+ta/mKzgXzia6jxO6ctUI3NSW9JXjN+2p8rq3ZGQaEkxCVko6KLvdkCTbfiFv0Az UcjgfFCSxOBXsJD3fOQtOh/sBwhewsvzjlC9uhKz4XOtJ6tQtrMTl5Gj+g6my8IJGdzN 45xw== X-Gm-Message-State: AGi0Pua1OW9WVaVFSHVyEd/nJcDBcNqHyxXsfDZuT5/FqqbNBPIDvvj0 jo9IxodqbLPwJW3t3BaoaayuwA== X-Google-Smtp-Source: APiQypJvjNpDhaQPozlSC4YSALovMJYpkwcRKwfFfyv8i330OLbaPVZCppZ6JCNkySRILENXTi/VkQ== X-Received: by 2002:a5d:6503:: with SMTP id x3mr12351444wru.153.1587736969545; Fri, 24 Apr 2020 07:02:49 -0700 (PDT) Received: from localhost.localdomain ([51.15.160.169]) by smtp.googlemail.com with ESMTPSA id v131sm3061051wmb.19.2020.04.24.07.02.46 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2020 07:02:48 -0700 (PDT) From: Corentin Labbe To: davem@davemloft.net, herbert@gondor.apana.org.au, mripard@kernel.org, wens@csie.org Cc: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Corentin Labbe Subject: [PATCH v2 11/14] crypto: sun8i-ce: support hash algorithms Date: Fri, 24 Apr 2020 14:02:11 +0000 Message-Id: <1587736934-22801-12-git-send-email-clabbe@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> References: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org The CE support multiples hash algorithms, this patch adds support for MD5, SHA1, SHA224, SHA256, SHA384 and SHA512. Signed-off-by: Corentin Labbe --- drivers/crypto/allwinner/Kconfig | 10 + drivers/crypto/allwinner/sun8i-ce/Makefile | 1 + .../crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 229 ++++++++++ .../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 415 ++++++++++++++++++ drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h | 58 +++ 5 files changed, 713 insertions(+) create mode 100644 drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c diff --git a/drivers/crypto/allwinner/Kconfig b/drivers/crypto/allwinner/Kconfig index 945228b3a8c4..93cc67adb1ed 100644 --- a/drivers/crypto/allwinner/Kconfig +++ b/drivers/crypto/allwinner/Kconfig @@ -69,6 +69,16 @@ config CRYPTO_DEV_SUN8I_CE_DEBUG This will create /sys/kernel/debug/sun8i-ce/stats for displaying the number of requests per flow and per algorithm. +config CRYPTO_DEV_SUN8I_CE_HASH + bool "Enable support for hash on sun8i-ce" + depends on CRYPTO_DEV_SUN8I_CE + select MD5 + select SHA1 + select SHA256 + select SHA512 + help + Say y to enable support for hash algorithms. + config CRYPTO_DEV_SUN8I_SS tristate "Support for Allwinner Security System cryptographic offloader" select CRYPTO_SKCIPHER diff --git a/drivers/crypto/allwinner/sun8i-ce/Makefile b/drivers/crypto/allwinner/sun8i-ce/Makefile index 08b68c3c1ca9..d1b1f0e86c79 100644 --- a/drivers/crypto/allwinner/sun8i-ce/Makefile +++ b/drivers/crypto/allwinner/sun8i-ce/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_CRYPTO_DEV_SUN8I_CE) += sun8i-ce.o sun8i-ce-y += sun8i-ce-core.o sun8i-ce-cipher.o +sun8i-ce-$(CONFIG_CRYPTO_DEV_SUN8I_CE_HASH) += sun8i-ce-hash.o diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c index 8bc669f18010..8c94ffe1efd0 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c @@ -35,6 +35,9 @@ static const struct ce_variant ce_h3_variant = { .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, }, + .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256, + CE_ALG_SHA384, CE_ALG_SHA512 + }, .op_mode = { CE_OP_ECB, CE_OP_CBC }, .ce_clks = { @@ -47,6 +50,9 @@ static const struct ce_variant ce_h3_variant = { static const struct ce_variant ce_h5_variant = { .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, }, + .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256, + CE_ID_NOTSUPP, CE_ID_NOTSUPP + }, .op_mode = { CE_OP_ECB, CE_OP_CBC }, .ce_clks = { @@ -59,9 +65,13 @@ static const struct ce_variant ce_h5_variant = { static const struct ce_variant ce_h6_variant = { .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, }, + .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256, + CE_ALG_SHA384, CE_ALG_SHA512 + }, .op_mode = { CE_OP_ECB, CE_OP_CBC }, .cipher_t_dlen_in_bytes = true, + .hash_t_dlen_in_bits = true, .ce_clks = { { "bus", 0, 200000000 }, { "mod", 300000000, 0 }, @@ -73,6 +83,9 @@ static const struct ce_variant ce_h6_variant = { static const struct ce_variant ce_a64_variant = { .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, }, + .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256, + CE_ID_NOTSUPP, CE_ID_NOTSUPP + }, .op_mode = { CE_OP_ECB, CE_OP_CBC }, .ce_clks = { @@ -85,6 +98,9 @@ static const struct ce_variant ce_a64_variant = { static const struct ce_variant ce_r40_variant = { .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, }, + .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256, + CE_ID_NOTSUPP, CE_ID_NOTSUPP + }, .op_mode = { CE_OP_ECB, CE_OP_CBC }, .ce_clks = { @@ -318,6 +334,188 @@ static struct sun8i_ce_alg_template ce_algs[] = { .decrypt = sun8i_ce_skdecrypt, } }, +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_HASH +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ce_algo_id = CE_ID_HASH_MD5, + .alg.hash = { + .init = sun8i_ce_hash_init, + .update = sun8i_ce_hash_update, + .final = sun8i_ce_hash_final, + .finup = sun8i_ce_hash_finup, + .digest = sun8i_ce_hash_digest, + .export = sun8i_ce_hash_export, + .import = sun8i_ce_hash_import, + .halg = { + .digestsize = MD5_DIGEST_SIZE, + .statesize = sizeof(struct md5_state), + .base = { + .cra_name = "md5", + .cra_driver_name = "md5-sun8i-ce", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ce_hash_crainit, + .cra_exit = sun8i_ce_hash_craexit, + } + } + } +}, +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ce_algo_id = CE_ID_HASH_SHA1, + .alg.hash = { + .init = sun8i_ce_hash_init, + .update = sun8i_ce_hash_update, + .final = sun8i_ce_hash_final, + .finup = sun8i_ce_hash_finup, + .digest = sun8i_ce_hash_digest, + .export = sun8i_ce_hash_export, + .import = sun8i_ce_hash_import, + .halg = { + .digestsize = SHA1_DIGEST_SIZE, + .statesize = sizeof(struct sha1_state), + .base = { + .cra_name = "sha1", + .cra_driver_name = "sha1-sun8i-ce", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ce_hash_crainit, + .cra_exit = sun8i_ce_hash_craexit, + } + } + } +}, +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ce_algo_id = CE_ID_HASH_SHA224, + .alg.hash = { + .init = sun8i_ce_hash_init, + .update = sun8i_ce_hash_update, + .final = sun8i_ce_hash_final, + .finup = sun8i_ce_hash_finup, + .digest = sun8i_ce_hash_digest, + .export = sun8i_ce_hash_export, + .import = sun8i_ce_hash_import, + .halg = { + .digestsize = SHA224_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha224", + .cra_driver_name = "sha224-sun8i-ce", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ce_hash_crainit, + .cra_exit = sun8i_ce_hash_craexit, + } + } + } +}, +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ce_algo_id = CE_ID_HASH_SHA256, + .alg.hash = { + .init = sun8i_ce_hash_init, + .update = sun8i_ce_hash_update, + .final = sun8i_ce_hash_final, + .finup = sun8i_ce_hash_finup, + .digest = sun8i_ce_hash_digest, + .export = sun8i_ce_hash_export, + .import = sun8i_ce_hash_import, + .halg = { + .digestsize = SHA256_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha256", + .cra_driver_name = "sha256-sun8i-ce", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ce_hash_crainit, + .cra_exit = sun8i_ce_hash_craexit, + } + } + } +}, +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ce_algo_id = CE_ID_HASH_SHA384, + .alg.hash = { + .init = sun8i_ce_hash_init, + .update = sun8i_ce_hash_update, + .final = sun8i_ce_hash_final, + .finup = sun8i_ce_hash_finup, + .digest = sun8i_ce_hash_digest, + .export = sun8i_ce_hash_export, + .import = sun8i_ce_hash_import, + .halg = { + .digestsize = SHA384_DIGEST_SIZE, + .statesize = sizeof(struct sha512_state), + .base = { + .cra_name = "sha384", + .cra_driver_name = "sha384-sun8i-ce", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ce_hash_crainit, + .cra_exit = sun8i_ce_hash_craexit, + } + } + } +}, +{ .type = CRYPTO_ALG_TYPE_AHASH, + .ce_algo_id = CE_ID_HASH_SHA512, + .alg.hash = { + .init = sun8i_ce_hash_init, + .update = sun8i_ce_hash_update, + .final = sun8i_ce_hash_final, + .finup = sun8i_ce_hash_finup, + .digest = sun8i_ce_hash_digest, + .export = sun8i_ce_hash_export, + .import = sun8i_ce_hash_import, + .halg = { + .digestsize = SHA512_DIGEST_SIZE, + .statesize = sizeof(struct sha512_state), + .base = { + .cra_name = "sha512", + .cra_driver_name = "sha512-sun8i-ce", + .cra_priority = 300, + .cra_alignmask = 3, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_init = sun8i_ce_hash_crainit, + .cra_exit = sun8i_ce_hash_craexit, + } + } + } +}, +#endif }; #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG @@ -339,6 +537,12 @@ static int sun8i_ce_dbgfs_read(struct seq_file *seq, void *v) ce_algs[i].alg.skcipher.base.cra_name, ce_algs[i].stat_req, ce_algs[i].stat_fb); break; + case CRYPTO_ALG_TYPE_AHASH: + seq_printf(seq, "%s %s %lu %lu\n", + ce_algs[i].alg.hash.halg.base.cra_driver_name, + ce_algs[i].alg.hash.halg.base.cra_name, + ce_algs[i].stat_req, ce_algs[i].stat_fb); + break; } } return 0; @@ -553,6 +757,26 @@ static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce) return err; } break; + case CRYPTO_ALG_TYPE_AHASH: + id = ce_algs[i].ce_algo_id; + ce_method = ce->variant->alg_hash[id]; + if (ce_method == CE_ID_NOTSUPP) { + dev_info(ce->dev, + "DEBUG: Algo of %s not supported\n", + ce_algs[i].alg.hash.halg.base.cra_name); + ce_algs[i].ce = NULL; + break; + } + dev_info(ce->dev, "Register %s\n", + ce_algs[i].alg.hash.halg.base.cra_name); + err = crypto_register_ahash(&ce_algs[i].alg.hash); + if (err) { + dev_err(ce->dev, "ERROR: Fail to register %s\n", + ce_algs[i].alg.hash.halg.base.cra_name); + ce_algs[i].ce = NULL; + return err; + } + break; default: ce_algs[i].ce = NULL; dev_err(ce->dev, "ERROR: tried to register an unknown algo\n"); @@ -574,6 +798,11 @@ static void sun8i_ce_unregister_algs(struct sun8i_ce_dev *ce) ce_algs[i].alg.skcipher.base.cra_name); crypto_unregister_skcipher(&ce_algs[i].alg.skcipher); break; + case CRYPTO_ALG_TYPE_AHASH: + dev_info(ce->dev, "Unregister %d %s\n", i, + ce_algs[i].alg.hash.halg.base.cra_name); + crypto_unregister_ahash(&ce_algs[i].alg.hash); + break; } } } diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c new file mode 100644 index 000000000000..b227fc990ac7 --- /dev/null +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c @@ -0,0 +1,415 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * sun8i-ce-hash.c - hardware cryptographic offloader for + * Allwinner H3/A64/H5/H2+/H6/R40 SoC + * + * Copyright (C) 2015-2020 Corentin Labbe + * + * This file add support for MD5 and SHA1/SHA224/SHA256/SHA384/SHA512. + * + * You could find the datasheet in Documentation/arm/sunxi/README + */ +#include +#include +#include +#include +#include +#include "sun8i-ce.h" + +int sun8i_ce_hash_crainit(struct crypto_tfm *tfm) +{ + struct sun8i_ce_hash_tfm_ctx *op = crypto_tfm_ctx(tfm); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg); + struct sun8i_ce_alg_template *algt; + int err; + + memset(op, 0, sizeof(struct sun8i_ce_hash_tfm_ctx)); + + algt = container_of(alg, struct sun8i_ce_alg_template, alg.hash); + op->ce = algt->ce; + + op->enginectx.op.do_one_request = sun8i_ce_hash_run; + op->enginectx.op.prepare_request = NULL; + op->enginectx.op.unprepare_request = NULL; + + /* FALLBACK */ + op->fallback_tfm = crypto_alloc_ahash(crypto_tfm_alg_name(tfm), 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(op->fallback_tfm)) { + dev_err(algt->ce->dev, "Fallback driver could no be loaded\n"); + return PTR_ERR(op->fallback_tfm); + } + + if (algt->alg.hash.halg.statesize < crypto_ahash_statesize(op->fallback_tfm)) + algt->alg.hash.halg.statesize = crypto_ahash_statesize(op->fallback_tfm); + + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct sun8i_ce_hash_reqctx) + + crypto_ahash_reqsize(op->fallback_tfm)); + + dev_info(op->ce->dev, "Fallback for %s is %s\n", + crypto_tfm_alg_driver_name(tfm), + crypto_tfm_alg_driver_name(&op->fallback_tfm->base)); + err = pm_runtime_get_sync(op->ce->dev); + if (err < 0) + goto error_pm; + return 0; +error_pm: + crypto_free_ahash(op->fallback_tfm); + return err; +} + +void sun8i_ce_hash_craexit(struct crypto_tfm *tfm) +{ + struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_tfm_ctx(tfm); + + crypto_free_ahash(tfmctx->fallback_tfm); + pm_runtime_put_sync_suspend(tfmctx->ce->dev); +} + +int sun8i_ce_hash_init(struct ahash_request *areq) +{ + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ce_alg_template *algt; + + memset(rctx, 0, sizeof(struct sun8i_ce_hash_reqctx)); + + algt = container_of(alg, struct sun8i_ce_alg_template, alg.hash); + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_init(&rctx->fallback_req); +} + +int sun8i_ce_hash_export(struct ahash_request *areq, void *out) +{ + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_export(&rctx->fallback_req, out); +} + +int sun8i_ce_hash_import(struct ahash_request *areq, const void *in) +{ + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_import(&rctx->fallback_req, in); +} + +int sun8i_ce_hash_final(struct ahash_request *areq) +{ + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ce_alg_template *algt; +#endif + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->fallback_req.result = areq->result; + +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + algt = container_of(alg, struct sun8i_ce_alg_template, alg.hash); + algt->stat_fb++; +#endif + + return crypto_ahash_final(&rctx->fallback_req); +} + +int sun8i_ce_hash_update(struct ahash_request *areq) +{ + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->fallback_req.nbytes = areq->nbytes; + rctx->fallback_req.src = areq->src; + + return crypto_ahash_update(&rctx->fallback_req); +} + +int sun8i_ce_hash_finup(struct ahash_request *areq) +{ + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ce_alg_template *algt; +#endif + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + + rctx->fallback_req.nbytes = areq->nbytes; + rctx->fallback_req.src = areq->src; + rctx->fallback_req.result = areq->result; +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + algt = container_of(alg, struct sun8i_ce_alg_template, alg.hash); + algt->stat_fb++; +#endif + + return crypto_ahash_finup(&rctx->fallback_req); +} + +int sun8i_ce_hash_digest_fb(struct ahash_request *areq) +{ + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct sun8i_ce_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ce_alg_template *algt; +#endif + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + + rctx->fallback_req.nbytes = areq->nbytes; + rctx->fallback_req.src = areq->src; + rctx->fallback_req.result = areq->result; +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + algt = container_of(alg, struct sun8i_ce_alg_template, alg.hash); + algt->stat_fb++; +#endif + + return crypto_ahash_digest(&rctx->fallback_req); +} + +static bool sun8i_ce_hash_need_fallback(struct ahash_request *areq) +{ + struct scatterlist *sg; + + if (areq->nbytes == 0) + return true; + /* we need to reserve one SG for padding one */ + if (sg_nents(areq->src) > MAX_SG - 1) + return true; + sg = areq->src; + while (sg) { + if (sg->length % 4 || !IS_ALIGNED(sg->offset, sizeof(u32))) + return true; + sg = sg_next(sg); + } + return false; +} + +int sun8i_ce_hash_digest(struct ahash_request *areq) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct sun8i_ce_alg_template *algt; + struct sun8i_ce_dev *ce; + struct crypto_engine *engine; + struct scatterlist *sg; + int nr_sgs, e, i; + + if (sun8i_ce_hash_need_fallback(areq)) + return sun8i_ce_hash_digest_fb(areq); + + nr_sgs = sg_nents(areq->src); + if (nr_sgs > MAX_SG - 1) + return sun8i_ce_hash_digest_fb(areq); + + for_each_sg(areq->src, sg, nr_sgs, i) { + if (sg->length % 4 || !IS_ALIGNED(sg->offset, sizeof(u32))) + return sun8i_ce_hash_digest_fb(areq); + } + + algt = container_of(alg, struct sun8i_ce_alg_template, alg.hash); + ce = algt->ce; + + e = sun8i_ce_get_engine_number(ce); + rctx->flow = e; + engine = ce->chanlist[e].engine; + + return crypto_transfer_hash_request_to_engine(engine, areq); +} + +int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq) +{ + struct ahash_request *areq = container_of(breq, struct ahash_request, base); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx(areq); + struct sun8i_ce_alg_template *algt; + struct sun8i_ce_dev *ce; + struct sun8i_ce_flow *chan; + struct ce_task *cet; + struct scatterlist *sg; + int nr_sgs, flow, err; + unsigned int len; + u32 common; + u64 byte_count; + u32 *bf; + void *buf; + int j, i, todo; + int nbw = 0; + u64 fill, min_fill; + __be64 *bebits; + __le64 *lebits; + void *result; + u64 bs; + int digestsize; + dma_addr_t addr_res, addr_pad; + + algt = container_of(alg, struct sun8i_ce_alg_template, alg.hash); + ce = algt->ce; + + bs = algt->alg.hash.halg.base.cra_blocksize; + digestsize = algt->alg.hash.halg.digestsize; + if (digestsize == SHA224_DIGEST_SIZE) + digestsize = SHA256_DIGEST_SIZE; + if (digestsize == SHA384_DIGEST_SIZE) + digestsize = SHA512_DIGEST_SIZE; + + /* the padding could be up to two block. */ + buf = kzalloc(bs * 2, GFP_KERNEL | GFP_DMA); + if (!buf) + return -ENOMEM; + bf = (u32 *)buf; + + result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA); + if (!result) + return -ENOMEM; + + flow = rctx->flow; + chan = &ce->chanlist[flow]; + +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + algt->stat_req++; +#endif + dev_dbg(ce->dev, "%s %s len=%d\n", __func__, crypto_tfm_alg_name(areq->base.tfm), areq->nbytes); + + cet = chan->tl; + memset(cet, 0, sizeof(struct ce_task)); + + cet->t_id = cpu_to_le32(flow); + common = ce->variant->alg_hash[algt->ce_algo_id]; + common |= CE_COMM_INT; + cet->t_common_ctl = cpu_to_le32(common); + + cet->t_sym_ctl = 0; + cet->t_asym_ctl = 0; + + nr_sgs = dma_map_sg(ce->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); + if (nr_sgs <= 0 || nr_sgs > MAX_SG) { + dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs); + err = -EINVAL; + goto theend; + } + + len = areq->nbytes; + for_each_sg(areq->src, sg, nr_sgs, i) { + cet->t_src[i].addr = cpu_to_le32(sg_dma_address(sg)); + todo = min(len, sg_dma_len(sg)); + cet->t_src[i].len = cpu_to_le32(todo / 4); + len -= todo; + } + if (len > 0) { + dev_err(ce->dev, "remaining len %d\n", len); + err = -EINVAL; + goto theend; + } + addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE); + cet->t_dst[0].addr = cpu_to_le32(addr_res); + cet->t_dst[0].len = cpu_to_le32(digestsize / 4); + if (dma_mapping_error(ce->dev, addr_res)) { + dev_err(ce->dev, "DMA map dest\n"); + err = -EINVAL; + goto theend; + } + + byte_count = areq->nbytes; + j = 0; + bf[j++] = le32_to_cpu(1 << 7); + + if (bs == 64) { + fill = 64 - (byte_count % 64); + min_fill = 2 * sizeof(u32) + (nbw ? 0 : sizeof(u32)); + } else { + fill = 128 - (byte_count % 128); + min_fill = 4 * sizeof(u32) + (nbw ? 0 : sizeof(u32)); + } + + if (fill < min_fill) + fill += bs; + + j += (fill - min_fill) / sizeof(u32); + + switch (algt->ce_algo_id) { + case CE_ID_HASH_MD5: + lebits = (__le64 *)&bf[j]; + *lebits = cpu_to_le64(byte_count << 3); + j += 2; + break; + case CE_ID_HASH_SHA1: + case CE_ID_HASH_SHA224: + case CE_ID_HASH_SHA256: + bebits = (__be64 *)&bf[j]; + *bebits = cpu_to_be64(byte_count << 3); + j += 2; + break; + case CE_ID_HASH_SHA384: + case CE_ID_HASH_SHA512: + bebits = (__be64 *)&bf[j]; + *bebits = cpu_to_be64(byte_count >> 61); + j += 2; + bebits = (__be64 *)&bf[j]; + *bebits = cpu_to_be64(byte_count << 3); + j += 2; + break; + } + + addr_pad = dma_map_single(ce->dev, buf, j * 4, DMA_TO_DEVICE); + cet->t_src[i].addr = cpu_to_le32(addr_pad); + cet->t_src[i].len = cpu_to_le32(j); + if (dma_mapping_error(ce->dev, addr_pad)) { + dev_err(ce->dev, "DMA error on padding SG\n"); + err = -EINVAL; + goto theend; + } + + if (ce->variant->hash_t_dlen_in_bits) + cet->t_dlen = cpu_to_le32((areq->nbytes + j * 4) * 8); + else + cet->t_dlen = cpu_to_le32(areq->nbytes / 4 + j); + + chan->timeout = areq->nbytes; + + err = sun8i_ce_run_task(ce, flow, crypto_tfm_alg_name(areq->base.tfm)); + + dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE); + dma_unmap_sg(ce->dev, areq->src, nr_sgs, DMA_TO_DEVICE); + dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE); + + kfree(buf); + + memcpy(areq->result, result, algt->alg.hash.halg.digestsize); + kfree(result); +theend: + crypto_finalize_hash_request(engine, breq, err); + return 0; +} diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h index 0a70fcc102f1..19ced8b1cd89 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include /* CE Registers */ #define CE_TDQ 0x00 @@ -45,6 +48,12 @@ #define CE_ALG_AES 0 #define CE_ALG_DES 1 #define CE_ALG_3DES 2 +#define CE_ALG_MD5 16 +#define CE_ALG_SHA1 17 +#define CE_ALG_SHA224 18 +#define CE_ALG_SHA256 19 +#define CE_ALG_SHA384 20 +#define CE_ALG_SHA512 21 /* Used in ce_variant */ #define CE_ID_NOTSUPP 0xFF @@ -54,6 +63,14 @@ #define CE_ID_CIPHER_DES3 2 #define CE_ID_CIPHER_MAX 3 +#define CE_ID_HASH_MD5 0 +#define CE_ID_HASH_SHA1 1 +#define CE_ID_HASH_SHA224 2 +#define CE_ID_HASH_SHA256 3 +#define CE_ID_HASH_SHA384 4 +#define CE_ID_HASH_SHA512 5 +#define CE_ID_HASH_MAX 6 + #define CE_ID_OP_ECB 0 #define CE_ID_OP_CBC 1 #define CE_ID_OP_MAX 2 @@ -96,16 +113,22 @@ struct ce_clock { * struct ce_variant - Describe CE capability for each variant hardware * @alg_cipher: list of supported ciphers. for each CE_ID_ this will give the * coresponding CE_ALG_XXX value + * @alg_hash: list of supported hashes. for each CE_ID_ this will give the + * corresponding CE_ALG_XXX value * @op_mode: list of supported block modes * @cipher_t_dlen_in_bytes: Does the request size for cipher is in * bytes or words + * @hash_t_dlen_in_bytes: Does the request size for hash is in + * bits or words * @ce_clks: list of clocks needed by this variant * @esr: The type of error register */ struct ce_variant { char alg_cipher[CE_ID_CIPHER_MAX]; + char alg_hash[CE_ID_HASH_MAX]; u32 op_mode[CE_ID_OP_MAX]; bool cipher_t_dlen_in_bytes; + bool hash_t_dlen_in_bits; struct ce_clock ce_clks[CE_MAX_CLOCKS]; int esr; }; @@ -219,6 +242,28 @@ struct sun8i_cipher_tfm_ctx { struct crypto_sync_skcipher *fallback_tfm; }; +/* + * struct sun8i_ce_hash_tfm_ctx - context for an ahash TFM + * @enginectx: crypto_engine used by this TFM + * @ce: pointer to the private data of driver handling this TFM + * @fallback_tfm: pointer to the fallback TFM + */ +struct sun8i_ce_hash_tfm_ctx { + struct crypto_engine_ctx enginectx; + struct sun8i_ce_dev *ce; + struct crypto_ahash *fallback_tfm; +}; + +/* + * struct sun8i_ce_hash_reqctx - context for an ahash request + * @fallback_req: pre-allocated fallback request + * @flow: the flow to use for this request + */ +struct sun8i_ce_hash_reqctx { + struct ahash_request fallback_req; + int flow; +}; + /* * struct sun8i_ce_alg_template - crypto_alg template * @type: the CRYPTO_ALG_TYPE for this template @@ -237,6 +282,7 @@ struct sun8i_ce_alg_template { struct sun8i_ce_dev *ce; union { struct skcipher_alg skcipher; + struct ahash_alg hash; } alg; #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG unsigned long stat_req; @@ -258,3 +304,15 @@ int sun8i_ce_skencrypt(struct skcipher_request *areq); int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce); int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name); + +int sun8i_ce_hash_crainit(struct crypto_tfm *tfm); +void sun8i_ce_hash_craexit(struct crypto_tfm *tfm); +int sun8i_ce_hash_init(struct ahash_request *areq); +int sun8i_ce_hash_export(struct ahash_request *areq, void *out); +int sun8i_ce_hash_import(struct ahash_request *areq, const void *in); +int sun8i_ce_hash(struct ahash_request *areq); +int sun8i_ce_hash_final(struct ahash_request *areq); +int sun8i_ce_hash_update(struct ahash_request *areq); +int sun8i_ce_hash_finup(struct ahash_request *areq); +int sun8i_ce_hash_digest(struct ahash_request *areq); +int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq); From patchwork Fri Apr 24 14:02:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corentin Labbe X-Patchwork-Id: 197834 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5B04C55194 for ; Fri, 24 Apr 2020 14:03:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 84D1F2075A for ; Fri, 24 Apr 2020 14:03:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="rrJE4KYh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728540AbgDXODA (ORCPT ); Fri, 24 Apr 2020 10:03:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38296 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1728526AbgDXOC6 (ORCPT ); Fri, 24 Apr 2020 10:02:58 -0400 Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE24EC09B045 for ; Fri, 24 Apr 2020 07:02:57 -0700 (PDT) Received: by mail-wr1-x442.google.com with SMTP id j1so10970316wrt.1 for ; Fri, 24 Apr 2020 07:02:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nbnYkoyW1OBcHw16DoZTSPNKApBT1625WKteYM7+N7Q=; b=rrJE4KYhtKMlWlc5/gm/wdqcMZqqNa2MyDe5J0KUyvFZsq/iEwm/8wZfKmJWwGE/nz Ie2xeaTZqDRCIsBhQpaBcnwlWFhlaihch5SRRJR5EarfN6KCyKsgwJkshdxp9etAuLwP AoQY86fzJEJ0JxeGUCmMcrGFXFY1dowhOFQHQq5iOsj1Hj2J8dCT3xqq3yhjn2/i2z0W s+VJGmCWQRrNavqJhUY4hZXMxDRA3FXntSkvRX2MAATHUqr+2ub0fV4vH8hw9GE+OdhD 9wphZhnbifrR+R0Oe9l670x0MDvR1FN7nXhT8e5ochFGN1mHuxd38+kv/aLwK+IQqq62 gaWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nbnYkoyW1OBcHw16DoZTSPNKApBT1625WKteYM7+N7Q=; b=tOXkv1ERgu+ezu95+ktktU2HnsPyqyT0VHEqHNE8lVzqGVJD/Sq6vja7ydNK55gU5P DF0kVbLvcRwaF2dNOw02uWDpuQ7eqRsSwAT+vRPpaATxlbvub90D0K46yqNP32TxLzER Y/rDbgD+QzKEAbig6t9RPk0pgOj3ZFQ3PXd/IBPpOwkyGVHmtS8YaeLgalySVsmtS2vD +tmhCANrTQ3nhK8I5RMOjN4oPVPtYleB3K2XtIDpD+ZqFBMwoMljwc7wMg0KKwZ0Ba/k REPT2tqEs7qNAnMYFQM+1sHyfb8QbcP+8BZ04p2AEwHF63l0mgZTjD3xqZ/8gzsAGDIM 5ARw== X-Gm-Message-State: AGi0PuZvT4CeRBryM5ordzZG10hlcSjIMwZf7cE702fGsvkGfGd7Za5B qAlQtmg5BvNXaTYYJwMX4YbVJQ== X-Google-Smtp-Source: APiQypL4AvypJe0GUhkJ+y1S9GIL8xeGK4lPCiti1Q/+Px+4sUX50TI3u5WmzC25+UPu/18ilYa99g== X-Received: by 2002:adf:f3cc:: with SMTP id g12mr11044709wrp.82.1587736976444; Fri, 24 Apr 2020 07:02:56 -0700 (PDT) Received: from localhost.localdomain ([51.15.160.169]) by smtp.googlemail.com with ESMTPSA id v131sm3061051wmb.19.2020.04.24.07.02.53 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2020 07:02:55 -0700 (PDT) From: Corentin Labbe To: davem@davemloft.net, herbert@gondor.apana.org.au, mripard@kernel.org, wens@csie.org Cc: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Corentin Labbe Subject: [PATCH v2 14/14] crypto: sun8i-ce: Add support for the TRNG Date: Fri, 24 Apr 2020 14:02:14 +0000 Message-Id: <1587736934-22801-15-git-send-email-clabbe@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> References: <1587736934-22801-1-git-send-email-clabbe@baylibre.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org This patch had support for the TRNG present in the CE. Note that according to the algorithm ID, 2 version of the TRNG exists, the first present in H3/H5/R40/A64 and the second present in H6. This patch adds support for both, but only the second is working reliabily accoridng to rngtest. Signed-off-by: Corentin Labbe --- drivers/crypto/allwinner/Kconfig | 8 ++ drivers/crypto/allwinner/sun8i-ce/Makefile | 1 + .../crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 18 +++ .../crypto/allwinner/sun8i-ce/sun8i-ce-trng.c | 123 ++++++++++++++++++ drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h | 18 +++ 5 files changed, 168 insertions(+) create mode 100644 drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c diff --git a/drivers/crypto/allwinner/Kconfig b/drivers/crypto/allwinner/Kconfig index 223a5823867c..6aec31f7d2be 100644 --- a/drivers/crypto/allwinner/Kconfig +++ b/drivers/crypto/allwinner/Kconfig @@ -87,6 +87,14 @@ config CRYPTO_DEV_SUN8I_CE_PRNG Select this option if you want to provide kernel-side support for the Pseudo-Random Number Generator found in the Crypto Engine. +config CRYPTO_DEV_SUN8I_CE_TRNG + bool "Support for Allwinner Crypto Engine TRNG" + depends on CRYPTO_DEV_SUN8I_CE + select HW_RANDOM + help + Select this option if you want to provide kernel-side support for + the True Random Number Generator found in the Crypto Engine. + config CRYPTO_DEV_SUN8I_SS tristate "Support for Allwinner Security System cryptographic offloader" select CRYPTO_SKCIPHER diff --git a/drivers/crypto/allwinner/sun8i-ce/Makefile b/drivers/crypto/allwinner/sun8i-ce/Makefile index c0ea81da2c7d..0842eb2d9408 100644 --- a/drivers/crypto/allwinner/sun8i-ce/Makefile +++ b/drivers/crypto/allwinner/sun8i-ce/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_CRYPTO_DEV_SUN8I_CE) += sun8i-ce.o sun8i-ce-y += sun8i-ce-core.o sun8i-ce-cipher.o sun8i-ce-$(CONFIG_CRYPTO_DEV_SUN8I_CE_HASH) += sun8i-ce-hash.o sun8i-ce-$(CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG) += sun8i-ce-prng.o +sun8i-ce-$(CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG) += sun8i-ce-trng.o diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c index 23b9fc67d7ea..86d75789811f 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c @@ -47,6 +47,7 @@ static const struct ce_variant ce_h3_variant = { }, .esr = ESR_H3, .prng = CE_ALG_PRNG, + .trng = CE_ID_NOTSUPP, }; static const struct ce_variant ce_h5_variant = { @@ -63,6 +64,7 @@ static const struct ce_variant ce_h5_variant = { }, .esr = ESR_H5, .prng = CE_ALG_PRNG, + .trng = CE_ID_NOTSUPP, }; static const struct ce_variant ce_h6_variant = { @@ -76,6 +78,7 @@ static const struct ce_variant ce_h6_variant = { .cipher_t_dlen_in_bytes = true, .hash_t_dlen_in_bits = true, .prng_t_dlen_in_bytes = true, + .trng_t_dlen_in_bytes = true, .ce_clks = { { "bus", 0, 200000000 }, { "mod", 300000000, 0 }, @@ -83,6 +86,7 @@ static const struct ce_variant ce_h6_variant = { }, .esr = ESR_H6, .prng = CE_ALG_PRNG_V2, + .trng = CE_ALG_TRNG_V2, }; static const struct ce_variant ce_a64_variant = { @@ -99,6 +103,7 @@ static const struct ce_variant ce_a64_variant = { }, .esr = ESR_A64, .prng = CE_ALG_PRNG, + .trng = CE_ID_NOTSUPP, }; static const struct ce_variant ce_r40_variant = { @@ -115,6 +120,7 @@ static const struct ce_variant ce_r40_variant = { }, .esr = ESR_R40, .prng = CE_ALG_PRNG, + .trng = CE_ID_NOTSUPP, }; /* @@ -579,6 +585,10 @@ static int sun8i_ce_dbgfs_read(struct seq_file *seq, void *v) break; } } +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG + seq_printf(seq, "HWRNG %lu %lu\n", + ce->hwrng_stat_req, ce->hwrng_stat_bytes); +#endif return 0; } @@ -928,6 +938,10 @@ static int sun8i_ce_probe(struct platform_device *pdev) if (err < 0) goto error_alg; +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG + sun8i_ce_hwrng_register(ce); +#endif + v = readl(ce->base + CE_CTR); v >>= CE_DIE_ID_SHIFT; v &= CE_DIE_ID_MASK; @@ -957,6 +971,10 @@ static int sun8i_ce_remove(struct platform_device *pdev) { struct sun8i_ce_dev *ce = platform_get_drvdata(pdev); +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG + sun8i_ce_hwrng_unregister(ce); +#endif + sun8i_ce_unregister_algs(ce); #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c new file mode 100644 index 000000000000..5e4effe29ed3 --- /dev/null +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * sun8i-ce-trng.c - hardware cryptographic offloader for + * Allwinner H3/A64/H5/H2+/H6/R40 SoC + * + * Copyright (C) 2015-2020 Corentin Labbe + * + * This file handle the TRNG + * + * You could find a link for the datasheet in Documentation/arm/sunxi/README + */ +#include "sun8i-ce.h" +#include +#include +/* + * Note that according to the algorithm ID, 2 versions of the TRNG exists, + * The first present in H3/H5/R40/A64 and the second present in H6. + * This file adds support for both, but only the second is working + * reliabily according to rngtest. + **/ + +int sun8i_ce_trng_read(struct hwrng *rng, void *data, size_t max, bool wait) +{ + struct sun8i_ce_dev *ce; + dma_addr_t dma_dst; + int err = 0; + int flow = 3; + unsigned int todo; + struct sun8i_ce_flow *chan; + struct ce_task *cet; + u32 common; + void *d; + + ce = container_of(rng, struct sun8i_ce_dev, trng); + + todo = max + 32; + todo -= todo % 32; + + d = kzalloc(todo, GFP_KERNEL | GFP_DMA); + if (!d) + return -ENOMEM; + +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + ce->hwrng_stat_req++; + ce->hwrng_stat_bytes += todo; +#endif + + dma_dst = dma_map_single(ce->dev, d, todo, DMA_FROM_DEVICE); + if (dma_mapping_error(ce->dev, dma_dst)) { + dev_err(ce->dev, "Cannot DMA MAP DST\n"); + err = -EFAULT; + goto err_dst; + } + + err = pm_runtime_get_sync(ce->dev); + if (err < 0) + goto err_pm; + + mutex_lock(&ce->rnglock); + chan = &ce->chanlist[flow]; + + cet = &chan->tl[0]; + memset(cet, 0, sizeof(struct ce_task)); + + cet->t_id = cpu_to_le32(flow); + common = ce->variant->trng | CE_COMM_INT; + cet->t_common_ctl = cpu_to_le32(common); + + /* recent CE (H6) need length in bytes, in word otherwise */ + if (ce->variant->trng_t_dlen_in_bytes) + cet->t_dlen = cpu_to_le32(todo); + else + cet->t_dlen = cpu_to_le32(todo / 4); + + cet->t_sym_ctl = 0; + cet->t_asym_ctl = 0; + + cet->t_dst[0].addr = cpu_to_le32(dma_dst); + cet->t_dst[0].len = cpu_to_le32(todo / 4); + ce->chanlist[flow].timeout = 2000; + + err = sun8i_ce_run_task(ce, 3, "TRNG"); + mutex_unlock(&ce->rnglock); + + pm_runtime_put(ce->dev); + +err_pm: + dma_unmap_single(ce->dev, dma_dst, todo, DMA_FROM_DEVICE); + + if (!err) { + memcpy(data, d, max); + err = max; + } + +err_dst: + kfree(d); + return err; +} + +int sun8i_ce_hwrng_register(struct sun8i_ce_dev *ce) +{ + int ret; + + if (ce->variant->trng == CE_ID_NOTSUPP) { + dev_info(ce->dev, "TRNG not supported\n"); + return 0; + } + ce->trng.name = "sun8i Crypto Engine TRNG"; + ce->trng.read = sun8i_ce_trng_read; + ce->trng.quality = 1000; + + ret = hwrng_register(&ce->trng); + if (ret) + dev_err(ce->dev, "Fail to register the TRNG\n"); + return ret; +} + +void sun8i_ce_hwrng_unregister(struct sun8i_ce_dev *ce) +{ + if (ce->variant->trng == CE_ID_NOTSUPP) + return; + hwrng_unregister(&ce->trng); +} diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h index 2ef0c3814367..746e56c254d4 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +56,9 @@ #define CE_ALG_SHA256 19 #define CE_ALG_SHA384 20 #define CE_ALG_SHA512 21 +#define CE_ALG_TRNG 48 #define CE_ALG_PRNG 49 +#define CE_ALG_TRNG_V2 0x1c #define CE_ALG_PRNG_V2 0x1d /* Used in ce_variant */ @@ -129,9 +132,12 @@ struct ce_clock { * bits or words * @prng_t_dlen_in_bytes: Does the request size for PRNG is in * bytes or words + * @trng_t_dlen_in_bytes: Does the request size for TRNG is in + * bytes or words * @ce_clks: list of clocks needed by this variant * @esr: The type of error register * @prng: The CE_ALG_XXX value for the PRNG + * @trng: The CE_ALG_XXX value for the TRNG */ struct ce_variant { char alg_cipher[CE_ID_CIPHER_MAX]; @@ -140,9 +146,11 @@ struct ce_variant { bool cipher_t_dlen_in_bytes; bool hash_t_dlen_in_bits; bool prng_t_dlen_in_bytes; + bool trng_t_dlen_in_bytes; struct ce_clock ce_clks[CE_MAX_CLOCKS]; int esr; char prng; + char trng; }; struct sginfo { @@ -218,6 +226,13 @@ struct sun8i_ce_dev { struct dentry *dbgfs_dir; struct dentry *dbgfs_stats; #endif +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG + struct hwrng trng; +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + unsigned long hwrng_stat_req; + unsigned long hwrng_stat_bytes; +#endif +#endif }; /* @@ -349,3 +364,6 @@ int sun8i_ce_prng_generate(struct crypto_rng *tfm, const u8 *src, int sun8i_ce_prng_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); void sun8i_ce_prng_exit(struct crypto_tfm *tfm); int sun8i_ce_prng_init(struct crypto_tfm *tfm); + +int sun8i_ce_hwrng_register(struct sun8i_ce_dev *ce); +void sun8i_ce_hwrng_unregister(struct sun8i_ce_dev *ce);