From patchwork Tue Oct 18 12:34:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corentin Labbe X-Patchwork-Id: 9382095 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2780A607D0 for ; Tue, 18 Oct 2016 12:38:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 17160295D7 for ; Tue, 18 Oct 2016 12:38:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0B8BF295D9; Tue, 18 Oct 2016 12:38:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9E14E295D7 for ; Tue, 18 Oct 2016 12:38:49 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bwTdh-0007xO-2a; Tue, 18 Oct 2016 12:37:05 +0000 Received: from mail-qk0-x242.google.com ([2607:f8b0:400d:c09::242]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bwTdd-0007vG-Mo for linux-arm-kernel@lists.infradead.org; Tue, 18 Oct 2016 12:37:02 +0000 Received: by mail-qk0-x242.google.com with SMTP id n189so16688670qke.1 for ; Tue, 18 Oct 2016 05:36:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=NsffKMJWnuy1wg9564fc4LVPUxjBzGs5FDQvSlumRR4=; b=wm74CFqrxT/0b6LAVEB/gD89FMlR/gvwvwtwhIvKn9gN4tOYC1XjvSR7Eno0ecgK9M RX1nO/OHcnlWrFUZ+r1BqoTyvuCGFDe64dz7OTsz8u7rTujvc1+nngCHrIXvHpOTo5sQ YZbxtdthQwHt4w5x9ENHaaynNvGJmYGPf43hgPP9OKVq6feFPrVM4YQsvUfVcEsqRzqX G1Poe77NumxmfivCBLPj0I7Bj7BtktorgGOxCyd6aPqD5Krg6FR4uDbNRikmCoMEjm8V MHs9+JdHavj0OB0eytfOLuIG4POFeVuW44B9baB4WoFTrfS9N5tM/DjmMbg74aGIQsB5 1cgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=NsffKMJWnuy1wg9564fc4LVPUxjBzGs5FDQvSlumRR4=; b=M3sDonPaiwPK3dgIon3GZ6r7boJt2cjELwlomRMkAAp67ULQjf9+P6XL3wBh772OC8 RJdW1Pg9vTrb5HPWphuM2+GQ6yzcvjR0dJCGTPYa/xMyaYDg/quoZq5MMcuRPvm7Rq3O 66cqgfiALDUMTX1VjotreKfK8ZO1+dbhQV5IvYhmTkc7ttjNgYfzEDVpmTaxqc7++wvf wLlOXGKBSqyBzk1cOdCRDhktUjBBaiB6pkW+MZZOazuVJx8g7HoXjDELRIEmbKOzC6/E CdsmeJ9wCG4CITL2v8LP4+BWT/mKjz7mAdyR7iLE4uZrffmMhGQhbvgZ4QDeqjR5pR2v pofg== X-Gm-Message-State: AA6/9RmdVwGVFBYSqDbLqMSvPliMmx2oUsUpbHmV2GxcjSiI/PE/xklDEtUQvB5pGAbsig== X-Received: by 10.194.179.193 with SMTP id di1mr139279wjc.72.1476794199644; Tue, 18 Oct 2016 05:36:39 -0700 (PDT) Received: from Red.local (LFbn-1-7035-57.w90-116.abo.wanadoo.fr. [90.116.208.57]) by smtp.googlemail.com with ESMTPSA id r1sm62532320wjc.43.2016.10.18.05.36.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Oct 2016 05:36:38 -0700 (PDT) From: Corentin Labbe To: herbert@gondor.apana.org.au, davem@davemloft.net, maxime.ripard@free-electrons.com, wens@csie.org Subject: [PATCH] crypto: sun4i-ss: support the Security System PRNG Date: Tue, 18 Oct 2016 14:34:27 +0200 Message-Id: <1476794067-28563-1-git-send-email-clabbe.montjoie@gmail.com> X-Mailer: git-send-email 2.7.3 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161018_053701_860299_96394ECB X-CRM114-Status: GOOD ( 22.65 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: LABBE Corentin , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: LABBE Corentin The Security System have a PRNG. This patch add support for it as an hwrng. Signed-off-by: Corentin Labbe --- drivers/crypto/Kconfig | 8 ++++ drivers/crypto/sunxi-ss/Makefile | 1 + drivers/crypto/sunxi-ss/sun4i-ss-core.c | 14 +++++++ drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c | 70 ++++++++++++++++++++++++++++++++ drivers/crypto/sunxi-ss/sun4i-ss.h | 8 ++++ 5 files changed, 101 insertions(+) create mode 100644 drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 4d2b81f..38f7aca 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -538,6 +538,14 @@ config CRYPTO_DEV_SUN4I_SS To compile this driver as a module, choose M here: the module will be called sun4i-ss. +config CRYPTO_DEV_SUN4I_SS_PRNG + bool "Support for Allwinner Security System PRNG" + depends on CRYPTO_DEV_SUN4I_SS + select HW_RANDOM + help + This driver provides kernel-side support for the Pseudo-Random + Number Generator found in the Security System. + config CRYPTO_DEV_ROCKCHIP tristate "Rockchip's Cryptographic Engine driver" depends on OF && ARCH_ROCKCHIP diff --git a/drivers/crypto/sunxi-ss/Makefile b/drivers/crypto/sunxi-ss/Makefile index 8f4c7a2..ca049ee 100644 --- a/drivers/crypto/sunxi-ss/Makefile +++ b/drivers/crypto/sunxi-ss/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sun4i-ss.o sun4i-ss-y += sun4i-ss-core.o sun4i-ss-hash.o sun4i-ss-cipher.o +sun4i-ss-$(CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG) += sun4i-ss-hwrng.o diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c index 3ac6c6c..fa739de 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c @@ -359,6 +359,16 @@ static int sun4i_ss_probe(struct platform_device *pdev) } } platform_set_drvdata(pdev, ss); + +#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG + /* Voluntarily made the PRNG optional */ + err = sun4i_ss_hwrng_register(&ss->hwrng); + if (!err) + dev_info(ss->dev, "sun4i-ss PRNG loaded"); + else + dev_err(ss->dev, "sun4i-ss PRNG failed"); +#endif + return 0; error_alg: i--; @@ -386,6 +396,10 @@ static int sun4i_ss_remove(struct platform_device *pdev) int i; struct sun4i_ss_ctx *ss = platform_get_drvdata(pdev); +#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG + sun4i_ss_hwrng_remove(&ss->hwrng); +#endif + for (i = 0; i < ARRAY_SIZE(ss_algs); i++) { switch (ss_algs[i].type) { case CRYPTO_ALG_TYPE_ABLKCIPHER: diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c b/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c new file mode 100644 index 0000000..95fadb7 --- /dev/null +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c @@ -0,0 +1,70 @@ +#include "sun4i-ss.h" + +static int sun4i_ss_hwrng_init(struct hwrng *hwrng) +{ + struct sun4i_ss_ctx *ss; + + ss = container_of(hwrng, struct sun4i_ss_ctx, hwrng); + get_random_bytes(ss->seed, SS_SEED_LEN); + + return 0; +} + +static int sun4i_ss_hwrng_read(struct hwrng *hwrng, void *buf, + size_t max, bool wait) +{ + int i; + u32 v; + u32 *data = buf; + const u32 mode = SS_OP_PRNG | SS_PRNG_CONTINUE | SS_ENABLED; + size_t len; + struct sun4i_ss_ctx *ss; + + ss = container_of(hwrng, struct sun4i_ss_ctx, hwrng); + len = min_t(size_t, SS_DATA_LEN, max); + + spin_lock_bh(&ss->slock); + + writel(mode, ss->base + SS_CTL); + + /* write the seed */ + for (i = 0; i < SS_SEED_LEN / 4; i++) + writel(ss->seed[i], ss->base + SS_KEY0 + i * 4); + writel(mode | SS_PRNG_START, ss->base + SS_CTL); + + /* Read the random data */ + readsl(ss->base + SS_TXFIFO, data, len / 4); + + if (len % 4 > 0) { + v = readl(ss->base + SS_TXFIFO); + memcpy(data + len / 4, &v, len % 4); + } + + /* Update the seed */ + for (i = 0; i < SS_SEED_LEN / 4; i++) { + v = readl(ss->base + SS_KEY0 + i * 4); + ss->seed[i] = v; + } + + writel(0, ss->base + SS_CTL); + spin_unlock_bh(&ss->slock); + return len; +} + +int sun4i_ss_hwrng_register(struct hwrng *hwrng) +{ + hwrng->name = "sun4i Security System PRNG"; + hwrng->init = sun4i_ss_hwrng_init; + hwrng->read = sun4i_ss_hwrng_read; + hwrng->quality = 1000; + + /* Cannot use devm_hwrng_register() since we need to hwrng_unregister + * before stopping clocks/regulator + */ + return hwrng_register(hwrng); +} + +void sun4i_ss_hwrng_remove(struct hwrng *hwrng) +{ + hwrng_unregister(hwrng); +} diff --git a/drivers/crypto/sunxi-ss/sun4i-ss.h b/drivers/crypto/sunxi-ss/sun4i-ss.h index f04c0f8..1297510 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss.h +++ b/drivers/crypto/sunxi-ss/sun4i-ss.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -125,6 +126,9 @@ #define SS_RXFIFO_EMP_INT_ENABLE (1 << 2) #define SS_TXFIFO_AVA_INT_ENABLE (1 << 0) +#define SS_SEED_LEN (192 / 8) +#define SS_DATA_LEN (160 / 8) + struct sun4i_ss_ctx { void __iomem *base; int irq; @@ -134,6 +138,8 @@ struct sun4i_ss_ctx { struct device *dev; struct resource *res; spinlock_t slock; /* control the use of the device */ + struct hwrng hwrng; + u32 seed[SS_SEED_LEN / 4]; }; struct sun4i_ss_alg_template { @@ -199,3 +205,5 @@ int sun4i_ss_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen); int sun4i_ss_des3_setkey(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen); +int sun4i_ss_hwrng_register(struct hwrng *hwrng); +void sun4i_ss_hwrng_remove(struct hwrng *hwrng);