From patchwork Thu Aug 17 18:25:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: PrasannaKumar Muralidharan X-Patchwork-Id: 9906893 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 345F960244 for ; Thu, 17 Aug 2017 18:26:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2C8DA28B7A for ; Thu, 17 Aug 2017 18:26:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2160528B82; Thu, 17 Aug 2017 18:26:31 +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=-1.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_HI, RCVD_IN_SBL_CSS, RCVD_IN_SORBS_SPAM autolearn=no 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 9A29928B7A for ; Thu, 17 Aug 2017 18:26:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753469AbdHQS01 (ORCPT ); Thu, 17 Aug 2017 14:26:27 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:34599 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753386AbdHQS0V (ORCPT ); Thu, 17 Aug 2017 14:26:21 -0400 Received: by mail-pg0-f68.google.com with SMTP id y192so11081452pgd.1 for ; Thu, 17 Aug 2017 11:26:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=e0OY/eN/tx1Py9r6w4CgrpElQaigNc2aqwnwsVqs1A8=; b=QW9VtcHhs2uNmQHdaLJwW6010rIyf0doSH1Rm+QTnvKgMOqlfpFy+P8Ro2s5r6npgM Qpx4GuXpHMHDRBVbccTRU1sC/ENXfvHMDDaQWkLFb9jAIGuCYDiXIpGE36HZXB+azGtM +g7lb0fORy8WWOg7Jg7plTKZKPV98tU7FHoftv+Oz0SJB9i9x/ar8J8xPLpezHnLQtpT dvjgNPaIFsjTi1zyOFK6BhLEp57h8MNzVqpub+AgWKsRxKGzbvsTYVfEBgX8QYKBm949 qWFN3GelP/pDOBTmKyYh75jzAFWuey00d7LLMFusKLrDE3EehgZtyZ/KoCV/hJb2BPrI e7yw== 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=e0OY/eN/tx1Py9r6w4CgrpElQaigNc2aqwnwsVqs1A8=; b=Iw1ELc43u+fLumJJ9k8jbwPyVsvkTotEIoypVcqxHtISYcbcAlPANPwE94b8T86QV/ zZo9hElTp5gsNTzpaO0fSrHgoiH7dnLzN+SZ2Gtzb3i/nFCQJUZDmYcrVxHBijVq5EGj JpmIrCkH+4yEzVCPW+vC+NIfmjhiFARynPkWeSGAQc9ndeuogV8b+IQ0RgKhFD+OIYuD HwRqmhtsDTPaP93pz5zTKeFNvKPmOU13UZFMZN+hfl0BrsdPcam+BAkXsjcOQN9JCKTI /aQHNfwU7kZDILe7HxC2qiij6L2HkS7QsJVunFXrViSfSjOXw/z83egyxxeTrXXcnxPf GzQA== X-Gm-Message-State: AHYfb5hV1z5tlLy51QefJwy9mxWOV65vAubsrUzKQVPGmnwxAJlyAOSi RqRMn5bH0oBB3w== X-Received: by 10.98.205.202 with SMTP id o193mr6086257pfg.313.1502994381018; Thu, 17 Aug 2017 11:26:21 -0700 (PDT) Received: from linux.local ([42.109.133.212]) by smtp.gmail.com with ESMTPSA id a86sm8882565pfe.181.2017.08.17.11.26.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 17 Aug 2017 11:26:20 -0700 (PDT) From: PrasannaKumar Muralidharan To: herbert@gondor.apana.org.au, robh+dt@kernel.org, mark.rutland@arm.com, ralf@linux-mips.org, mturquette@baylibre.com, sboyd@codeaurora.org, davem@davemloft.net, paul@crapouillou.net, linux-crypto@vger.kernel.org, linux-mips@linux-mips.org Cc: PrasannaKumar Muralidharan Subject: [PATCH 3/6] crypto: jz4780-rng: Add Ingenic JZ4780 hardware PRNG driver Date: Thu, 17 Aug 2017 23:55:17 +0530 Message-Id: <20170817182520.20102-4-prasannatsmkumar@gmail.com> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20170817182520.20102-1-prasannatsmkumar@gmail.com> References: <20170817182520.20102-1-prasannatsmkumar@gmail.com> 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 JZ4780 SoC pseudo random number generator driver using crypto framework. Adding a delay before reading RNG data and disabling RNG after reading data was suggested by Jeffery Walton. Tested-by: Mathieu Malaterre Suggested-by: Jeffrey Walton Signed-off-by: PrasannaKumar Muralidharan --- drivers/crypto/Kconfig | 19 +++++ drivers/crypto/Makefile | 1 + drivers/crypto/jz4780-rng.c | 173 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/crypto/jz4780-rng.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 8fa7e72..8263622 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -614,6 +614,25 @@ config CRYPTO_DEV_IMGTEC_HASH hardware hash accelerator. Supporting MD5/SHA1/SHA224/SHA256 hashing algorithms. +config CRYPTO_DEV_JZ4780_RNG + tristate "JZ4780 HW pseudo random number generator support" + depends on MACH_JZ4780 || COMPILE_TEST + depends on HAS_IOMEM + select CRYPTO_RNG + select REGMAP + select SYSCON + select MFD_SYSCON + ---help--- + This driver provides kernel-side support through the + cryptographic API for the pseudo random number generator + hardware found in ingenic JZ4780 and X1000 SoC. MIPS + Creator CI20 uses JZ4780 SoC. + + To compile this driver as a module, choose M here: the + module will be called jz4780-rng. + + If unsure, say Y. + config CRYPTO_DEV_SUN4I_SS tristate "Support for Allwinner Security System cryptographic accelerator" depends on ARCH_SUNXI && !64BIT diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index b12eb3c..3a3d970 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o +obj-$(CONFIG_CRYPTO_DEV_JZ4780_RNG) += jz4780-rng.o obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o obj-$(CONFIG_CRYPTO_DEV_MARVELL_CESA) += marvell/ obj-$(CONFIG_CRYPTO_DEV_MEDIATEK) += mediatek/ diff --git a/drivers/crypto/jz4780-rng.c b/drivers/crypto/jz4780-rng.c new file mode 100644 index 0000000..a03f2a0 --- /dev/null +++ b/drivers/crypto/jz4780-rng.c @@ -0,0 +1,173 @@ +/* + * jz4780-rng.c - Random Number Generator driver for the jz4780 + * + * Copyright (c) 2017 PrasannaKumar Muralidharan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define REG_RNG_CTRL 0xD8 +#define REG_RNG_DATA 0xDC + +/* Context for crypto */ +struct jz4780_rng_ctx { + struct jz4780_rng *rng; +}; + +/* Device associated memory */ +struct jz4780_rng { + struct device *dev; + struct regmap *regmap; +}; + +static struct jz4780_rng *jz4780_rng; + +static int jz4780_rng_readl(struct jz4780_rng *rng, u32 offset) +{ + u32 val = 0; + int ret; + + ret = regmap_read(rng->regmap, offset, &val); + if (!ret) + return val; + + return ret; +} + +static int jz4780_rng_writel(struct jz4780_rng *rng, u32 val, u32 offset) +{ + return regmap_write(rng->regmap, offset, val); +} + +static int jz4780_rng_generate(struct crypto_rng *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int dlen) +{ + struct jz4780_rng_ctx *ctx = crypto_rng_ctx(tfm); + struct jz4780_rng *rng = ctx->rng; + u32 data; + + /* + * JZ4780 Programmers manual says the RNG should not run continuously + * for more than 1s. So enable RNG, read data and disable it. + * NOTE: No issue was observed with MIPS creator CI20 board even when + * RNG ran continuously for longer periods. This is just a precaution. + * + * A delay is required so that the current RNG data is not bit shifted + * version of previous RNG data which could happen if random data is + * read continuously from this device. + */ + jz4780_rng_writel(rng, 1, REG_RNG_CTRL); + do { + data = jz4780_rng_readl(rng, REG_RNG_DATA); + memcpy((void *)dst, (void *)&data, 4); + dlen -= 4; + dst += 4; + udelay(20); + } while (dlen >= 4); + + if (dlen > 0) { + data = jz4780_rng_readl(rng, REG_RNG_DATA); + memcpy((void *)dst, (void *)&data, dlen); + } + jz4780_rng_writel(rng, 0, REG_RNG_CTRL); + + return 0; +} + +static int jz4780_rng_kcapi_init(struct crypto_tfm *tfm) +{ + struct jz4780_rng_ctx *ctx = crypto_tfm_ctx(tfm); + + ctx->rng = jz4780_rng; + + return 0; +} + +static struct rng_alg jz4780_rng_alg = { + .generate = jz4780_rng_generate, + .base = { + .cra_name = "stdrng", + .cra_driver_name = "jz4780_rng", + .cra_priority = 100, + .cra_ctxsize = sizeof(struct jz4780_rng_ctx), + .cra_module = THIS_MODULE, + .cra_init = jz4780_rng_kcapi_init, + } +}; + +static int jz4780_rng_probe(struct platform_device *pdev) +{ + struct jz4780_rng *rng; + struct resource *res; + int ret; + + rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); + if (!rng) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rng->regmap = syscon_node_to_regmap(pdev->dev.parent->of_node); + if (IS_ERR(rng->regmap)) + return PTR_ERR(rng->regmap); + + jz4780_rng = rng; + + ret = crypto_register_rng(&jz4780_rng_alg); + if (ret) { + dev_err(&pdev->dev, + "Couldn't register rng crypto alg: %d\n", ret); + jz4780_rng = NULL; + } + + return ret; +} + +static int jz4780_rng_remove(struct platform_device *pdev) +{ + crypto_unregister_rng(&jz4780_rng_alg); + + jz4780_rng = NULL; + + return 0; +} + +static const struct of_device_id jz4780_rng_dt_match[] = { + { + .compatible = "ingenic,jz4780-rng", + }, + { }, +}; +MODULE_DEVICE_TABLE(of, jz4780_rng_dt_match); + +static struct platform_driver jz4780_rng_driver = { + .driver = { + .name = "jz4780-rng", + .of_match_table = jz4780_rng_dt_match, + }, + .probe = jz4780_rng_probe, + .remove = jz4780_rng_remove, +}; + +module_platform_driver(jz4780_rng_driver); + +MODULE_DESCRIPTION("Ingenic JZ4780 H/W Pseudo Random Number Generator driver"); +MODULE_AUTHOR("PrasannaKumar Muralidharan "); +MODULE_LICENSE("GPL");