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: 9382091 X-Patchwork-Delegate: herbert@gondor.apana.org.au 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 D0851607D0 for ; Tue, 18 Oct 2016 12:36:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C11B7295D5 for ; Tue, 18 Oct 2016 12:36:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B5819295D7; Tue, 18 Oct 2016 12:36:43 +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=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2730D295D5 for ; Tue, 18 Oct 2016 12:36:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753541AbcJRMgl (ORCPT ); Tue, 18 Oct 2016 08:36:41 -0400 Received: from mail-qk0-f196.google.com ([209.85.220.196]:33949 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753329AbcJRMgk (ORCPT ); Tue, 18 Oct 2016 08:36:40 -0400 Received: by mail-qk0-f196.google.com with SMTP id n189so16688668qke.1; 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=mYap9dIEFAdUwJhMHKAvZ2y6UlOcBPqGa1fU8LpE7FhLSoNUykiHXXyh3StugP+V+i hG22GjJvVt8HbwVQ4U9goGsS2hO5W/xp6rTlryNJsZ4rCVSDDNAJDBgbDXWDoOjpIxXg EoE0IiNA1b/xOPII7pV0D0xPlfgB0zrPqeazmaYXTasAszHcbSlVnmZ07qNQ2zKDG3Fz 0ZyeZaiCPkuo4A3rmgq3vSLDdNE3cYBaiNr9RWMS7ohe0uVQkOGJvAVZhF75uJ53o57G em2q22LELYOaDxanLtjKDFbqKHdkWModfnkjYYxdtsedRNeuSkXS4T8yCRxIejuebSjD JfYg== X-Gm-Message-State: AA6/9RlLdV64fU6VmBKvaqIBAcrxV4nnzr5E0KGuxXkYeNILsYbERnf1HRzH2qJ0V0hi9w== 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 Cc: linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, LABBE Corentin 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 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.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);