2020-09-20 18:38:06

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v2 0/7] crypto: sun4i-ss: prevent always fallback for ciphers

Hello

For help testing on "crypto: sun4i-ss - Fix sparse endianness markers",
I have added "stats" support like other allwinner's crypto drivers.
Seeing stats showed a clear problem, the ciphers function were not used
at all.
This is due to the not-inialized need_fallback which is "init" as true
everytime.
So basicly, since the patch introduced it, this probem hidden some bugs.

This serie fixes all hidden problems, then fix the initialization of
"need_fallback" and then add the stats like other allwinner drivers.

Regards

Changes since v1:
- patch #4 is sufficient to fix BE problem (removed todo)

Corentin Labbe (7):
crypto: sun4i-ss: linearize buffers content must be kept
crypto: sun4i-ss: checking sg length is not sufficient
crypto: sun4i-ss: IV register does not work on A10 and A13
crypto: sun4i-ss: handle BigEndian for cipher
crypto: sun4i-ss: initialize need_fallback
crypto: sun4i-ss: enabled stats via debugfs
crypto: sun4i-ss: add SPDX header and remove blank lines

drivers/crypto/allwinner/Kconfig | 9 ++
.../allwinner/sun4i-ss/sun4i-ss-cipher.c | 82 ++++++++++++++-----
.../crypto/allwinner/sun4i-ss/sun4i-ss-core.c | 54 ++++++++++++
.../crypto/allwinner/sun4i-ss/sun4i-ss-hash.c | 8 ++
.../crypto/allwinner/sun4i-ss/sun4i-ss-prng.c | 6 ++
drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h | 11 +++
6 files changed, 148 insertions(+), 22 deletions(-)

--
2.26.2


2020-09-20 18:38:07

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v2 6/7] crypto: sun4i-ss: enabled stats via debugfs

This patch enable to access usage stats for each algorithm.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/allwinner/Kconfig | 9 ++++
.../allwinner/sun4i-ss/sun4i-ss-cipher.c | 21 ++++++++
.../crypto/allwinner/sun4i-ss/sun4i-ss-core.c | 54 +++++++++++++++++++
.../crypto/allwinner/sun4i-ss/sun4i-ss-hash.c | 8 +++
.../crypto/allwinner/sun4i-ss/sun4i-ss-prng.c | 5 ++
drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h | 11 ++++
6 files changed, 108 insertions(+)

diff --git a/drivers/crypto/allwinner/Kconfig b/drivers/crypto/allwinner/Kconfig
index 0e72543ad1f1..e9b7f7e3d307 100644
--- a/drivers/crypto/allwinner/Kconfig
+++ b/drivers/crypto/allwinner/Kconfig
@@ -51,6 +51,15 @@ config CRYPTO_DEV_SUN4I_SS_PRNG
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_SUN4I_SS_DEBUG
+ bool "Enable sun4i-ss stats"
+ depends on CRYPTO_DEV_SUN4I_SS
+ depends on DEBUG_FS
+ help
+ Say y to enable sun4i-ss debug stats.
+ This will create /sys/kernel/debug/sun4i-ss/stats for displaying
+ the number of requests per algorithm.
+
config CRYPTO_DEV_SUN8I_CE
tristate "Support for Allwinner Crypto Engine cryptographic offloader"
select CRYPTO_SKCIPHER
diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
index f3bdf465b02e..2ec359eaa4cf 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
@@ -34,6 +34,10 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
struct sg_mapping_iter mi, mo;
unsigned int oi, oo; /* offset for in and out */
unsigned long flags;
+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct sun4i_ss_alg_template *algt;
+#endif

if (!areq->cryptlen)
return 0;
@@ -50,6 +54,12 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
}

+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);
+ algt->stat_opti++;
+ algt->stat_bytes += areq->cryptlen;
+#endif
+
spin_lock_irqsave(&ss->slock, flags);

for (i = 0; i < op->keylen / 4; i++)
@@ -134,7 +144,13 @@ static int noinline_for_stack sun4i_ss_cipher_poll_fallback(struct skcipher_requ
struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);
int err;
+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct sun4i_ss_alg_template *algt;

+ algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);
+ algt->stat_fb++;
+#endif
skcipher_request_set_tfm(&ctx->fallback_req, op->fallback_tfm);
skcipher_request_set_callback(&ctx->fallback_req, areq->base.flags,
areq->base.complete, areq->base.data);
@@ -223,6 +239,11 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
}

+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ algt->stat_req++;
+ algt->stat_bytes += areq->cryptlen;
+#endif
+
spin_lock_irqsave(&ss->slock, flags);

for (i = 0; i < op->keylen / 4; i++)
diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
index a2b67f7f8a81..d044eb8f88b6 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
@@ -234,6 +234,53 @@ static struct sun4i_ss_alg_template ss_algs[] = {
#endif
};

+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+static int sun4i_ss_dbgfs_read(struct seq_file *seq, void *v)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
+ if (!ss_algs[i].ss)
+ continue;
+ switch (ss_algs[i].type) {
+ case CRYPTO_ALG_TYPE_SKCIPHER:
+ seq_printf(seq, "%s %s reqs=%lu opti=%lu fallback=%lu tsize=%lu\n",
+ ss_algs[i].alg.crypto.base.cra_driver_name,
+ ss_algs[i].alg.crypto.base.cra_name,
+ ss_algs[i].stat_req, ss_algs[i].stat_opti, ss_algs[i].stat_fb,
+ ss_algs[i].stat_bytes);
+ break;
+ case CRYPTO_ALG_TYPE_RNG:
+ 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 reqs=%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);
+ break;
+ }
+ }
+ return 0;
+}
+
+static int sun4i_ss_dbgfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, sun4i_ss_dbgfs_read, inode->i_private);
+}
+
+static const struct file_operations sun4i_ss_debugfs_fops = {
+ .owner = THIS_MODULE,
+ .open = sun4i_ss_dbgfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#endif
+
/*
* Power management strategy: The device is suspended unless a TFM exists for
* one of the algorithms proposed by this driver.
@@ -454,6 +501,13 @@ static int sun4i_ss_probe(struct platform_device *pdev)
break;
}
}
+
+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ /* Ignore error of debugfs */
+ ss->dbgfs_dir = debugfs_create_dir("sun4i-ss", NULL);
+ ss->dbgfs_stats = debugfs_create_file("stats", 0444, ss->dbgfs_dir, ss,
+ &sun4i_ss_debugfs_fops);
+#endif
return 0;
error_alg:
i--;
diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
index dc35edd90034..3da60256f498 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
@@ -197,6 +197,10 @@ static int sun4i_hash(struct ahash_request *areq)
int in_r, err = 0;
size_t copied = 0;
__le32 wb = 0;
+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
+ struct sun4i_ss_alg_template *algt;
+#endif

dev_dbg(ss->dev, "%s %s bc=%llu len=%u mode=%x wl=%u h0=%0x",
__func__, crypto_tfm_alg_name(areq->base.tfm),
@@ -397,6 +401,10 @@ static int sun4i_hash(struct ahash_request *areq)
*/

hash_final:
+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ algt = container_of(alg, struct sun4i_ss_alg_template, alg.hash);
+ algt->stat_req++;
+#endif

/* write the remaining words of the wait buffer */
if (op->len) {
diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
index 729aafdbea84..102f8a90ce0f 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
@@ -32,6 +32,11 @@ int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
if (err < 0)
return err;

+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ algt->stat_req++;
+ algt->stat_bytes += todo;
+#endif
+
spin_lock_bh(&ss->slock);

writel(mode, ss->base + SS_CTL);
diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
index 163962f9e284..a98a2c05089b 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
@@ -13,6 +13,7 @@

#include <linux/clk.h>
#include <linux/crypto.h>
+#include <linux/debugfs.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -152,6 +153,10 @@ struct sun4i_ss_ctx {
#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
u32 seed[SS_SEED_LEN / BITS_PER_LONG];
#endif
+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ struct dentry *dbgfs_dir;
+ struct dentry *dbgfs_stats;
+#endif
};

struct sun4i_ss_alg_template {
@@ -163,6 +168,12 @@ struct sun4i_ss_alg_template {
struct rng_alg rng;
} alg;
struct sun4i_ss_ctx *ss;
+#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
+ unsigned long stat_req;
+ unsigned long stat_fb;
+ unsigned long stat_bytes;
+ unsigned long stat_opti;
+#endif
};

struct sun4i_tfm_ctx {
--
2.26.2

2020-09-20 18:38:26

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v2 7/7] crypto: sun4i-ss: add SPDX header and remove blank lines

This patchs fixes some remaining style issue.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c | 3 ---
drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c | 1 +
2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
index 2ec359eaa4cf..3f19c00f1b0b 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
@@ -137,7 +137,6 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
return err;
}

-
static int noinline_for_stack sun4i_ss_cipher_poll_fallback(struct skcipher_request *areq)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
@@ -544,7 +543,6 @@ int sun4i_ss_cipher_init(struct crypto_tfm *tfm)
sizeof(struct sun4i_cipher_req_ctx) +
crypto_skcipher_reqsize(op->fallback_tfm));

-
err = pm_runtime_get_sync(op->ss->dev);
if (err < 0)
goto error_pm;
@@ -631,5 +629,4 @@ int sun4i_ss_des3_setkey(struct crypto_skcipher *tfm, const u8 *key,
crypto_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);

return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
-
}
diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
index 102f8a90ce0f..4d1610952e90 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
#include "sun4i-ss.h"

int sun4i_ss_prng_seed(struct crypto_rng *tfm, const u8 *seed,
--
2.26.2

2020-09-20 18:38:30

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v2 5/7] crypto: sun4i-ss: initialize need_fallback

The need_fallback is never initialized and seem to be always true at runtime.
So all hardware operations are always bypassed.

Fixes: 0ae1f46c55f87 ("crypto: sun4i-ss - fallback when length is not multiple of blocksize")
Cc: <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
index a05889745097..f3bdf465b02e 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
@@ -181,7 +181,7 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
unsigned int obo = 0; /* offset in bufo*/
unsigned int obl = 0; /* length of data in bufo */
unsigned long flags;
- bool need_fallback;
+ bool need_fallback = false;

if (!areq->cryptlen)
return 0;
--
2.26.2

2020-09-20 18:38:33

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v2 1/7] crypto: sun4i-ss: linearize buffers content must be kept

When running the non-optimized cipher function, SS produce partial random
output.
This is due to linearize buffers being reseted after each loop.

Fixes: 8d3bcb9900ca ("crypto: sun4i-ss - reduce stack usage")
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
index b72de8939497..b92d175b5d2a 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
@@ -163,6 +163,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
unsigned int todo;
struct sg_mapping_iter mi, mo;
unsigned int oi, oo; /* offset for in and out */
+ char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */
+ char bufo[4 * SS_TX_MAX]; /* buffer for linearize SG dst */
unsigned int ob = 0; /* offset in buf */
unsigned int obo = 0; /* offset in bufo*/
unsigned int obl = 0; /* length of data in bufo */
@@ -233,8 +235,6 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)

while (oleft) {
if (ileft) {
- char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */
-
/*
* todo is the number of consecutive 4byte word that we
* can read from current SG
@@ -295,8 +295,6 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
oo = 0;
}
} else {
- char bufo[4 * SS_TX_MAX]; /* buffer for linearize SG dst */
-
/*
* read obl bytes in bufo, we read at maximum for
* emptying the device
--
2.26.2

2020-09-20 18:41:16

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v2 3/7] crypto: sun4i-ss: IV register does not work on A10 and A13

Allwinner A10 and A13 SoC have a version of the SS which produce
invalid IV in IVx register.

Instead of adding a variant for those, let's convert SS to produce IV
directly from data.
Fixes: 6298e948215f2 ("crypto: sunxi-ss - Add Allwinner Security System crypto accelerator")
Cc: <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
.../allwinner/sun4i-ss/sun4i-ss-cipher.c | 34 +++++++++++++++----
1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
index 2614640231dc..c6c25204780d 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
@@ -20,6 +20,7 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
unsigned int ivsize = crypto_skcipher_ivsize(tfm);
struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);
u32 mode = ctx->mode;
+ void *backup_iv = NULL;
/* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */
u32 rx_cnt = SS_RX_DEFAULT;
u32 tx_cnt = 0;
@@ -42,6 +43,13 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
return -EINVAL;
}

+ if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {
+ backup_iv = kzalloc(ivsize, GFP_KERNEL);
+ if (!backup_iv)
+ return -ENOMEM;
+ scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
+ }
+
spin_lock_irqsave(&ss->slock, flags);

for (i = 0; i < op->keylen; i += 4)
@@ -102,9 +110,12 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
} while (oleft);

if (areq->iv) {
- for (i = 0; i < 4 && i < ivsize / 4; i++) {
- v = readl(ss->base + SS_IV0 + i * 4);
- *(u32 *)(areq->iv + i * 4) = v;
+ if (mode & SS_DECRYPTION) {
+ memcpy(areq->iv, backup_iv, ivsize);
+ kfree_sensitive(backup_iv);
+ } else {
+ scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,
+ ivsize, 0);
}
}

@@ -161,6 +172,7 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
unsigned int ileft = areq->cryptlen;
unsigned int oleft = areq->cryptlen;
unsigned int todo;
+ void *backup_iv = NULL;
struct sg_mapping_iter mi, mo;
unsigned int oi, oo; /* offset for in and out */
char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */
@@ -204,6 +216,13 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
if (need_fallback)
return sun4i_ss_cipher_poll_fallback(areq);

+ if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {
+ backup_iv = kzalloc(ivsize, GFP_KERNEL);
+ if (!backup_iv)
+ return -ENOMEM;
+ scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
+ }
+
spin_lock_irqsave(&ss->slock, flags);

for (i = 0; i < op->keylen; i += 4)
@@ -324,9 +343,12 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
}
}
if (areq->iv) {
- for (i = 0; i < 4 && i < ivsize / 4; i++) {
- v = readl(ss->base + SS_IV0 + i * 4);
- *(u32 *)(areq->iv + i * 4) = v;
+ if (mode & SS_DECRYPTION) {
+ memcpy(areq->iv, backup_iv, ivsize);
+ kfree_sensitive(backup_iv);
+ } else {
+ scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,
+ ivsize, 0);
}
}

--
2.26.2

2020-09-25 07:32:08

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] crypto: sun4i-ss: linearize buffers content must be kept

On Sun, Sep 20, 2020 at 06:37:12PM +0000, Corentin Labbe wrote:
> When running the non-optimized cipher function, SS produce partial random
> output.
> This is due to linearize buffers being reseted after each loop.
>
> Fixes: 8d3bcb9900ca ("crypto: sun4i-ss - reduce stack usage")
> Signed-off-by: Corentin Labbe <[email protected]>
> ---
> drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
> index b72de8939497..b92d175b5d2a 100644
> --- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
> +++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
> @@ -163,6 +163,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
> unsigned int todo;
> struct sg_mapping_iter mi, mo;
> unsigned int oi, oo; /* offset for in and out */
> + char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */
> + char bufo[4 * SS_TX_MAX]; /* buffer for linearize SG dst */
> unsigned int ob = 0; /* offset in buf */
> unsigned int obo = 0; /* offset in bufo*/
> unsigned int obl = 0; /* length of data in bufo */
> @@ -233,8 +235,6 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
>
> while (oleft) {
> if (ileft) {
> - char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */
> -
> /*
> * todo is the number of consecutive 4byte word that we
> * can read from current SG

Ouch. So this is obviously correct but I wonder if the stack
usage would be an issue again?

How about moving this code into another function so that it sits
at the same level as the fallback function, which would mean that
the buffers do not double up with the one for the fallback?

Cheers,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2020-09-25 07:37:16

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH v2 6/7] crypto: sun4i-ss: enabled stats via debugfs

On Sun, Sep 20, 2020 at 06:37:17PM +0000, Corentin Labbe wrote:
>
> diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
> index f3bdf465b02e..2ec359eaa4cf 100644
> --- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
> +++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
> @@ -34,6 +34,10 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
> struct sg_mapping_iter mi, mo;
> unsigned int oi, oo; /* offset for in and out */
> unsigned long flags;
> +#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
> + struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
> + struct sun4i_ss_alg_template *algt;
> +#endif
>
> if (!areq->cryptlen)
> return 0;
> @@ -50,6 +54,12 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
> scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
> }
>
> +#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
> + algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);
> + algt->stat_opti++;
> + algt->stat_bytes += areq->cryptlen;
> +#endif

Please do

if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
...
}

instead so this always gets compiled.

> +#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
> + /* Ignore error of debugfs */
> + ss->dbgfs_dir = debugfs_create_dir("sun4i-ss", NULL);
> + ss->dbgfs_stats = debugfs_create_file("stats", 0444, ss->dbgfs_dir, ss,
> + &sun4i_ss_debugfs_fops);
> +#endif

The calls too be done under an if statement. Only the assignments
need to use the ifdef.

> diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
> index 163962f9e284..a98a2c05089b 100644
> --- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
> +++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
> @@ -13,6 +13,7 @@
>
> #include <linux/clk.h>
> #include <linux/crypto.h>
> +#include <linux/debugfs.h>

Please add this into the c files that actually use debugfs, and
not here.

> #include <linux/io.h>
> #include <linux/module.h>
> #include <linux/of.h>
> @@ -152,6 +153,10 @@ struct sun4i_ss_ctx {
> #ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
> u32 seed[SS_SEED_LEN / BITS_PER_LONG];
> #endif
> +#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG
> + struct dentry *dbgfs_dir;
> + struct dentry *dbgfs_stats;
> +#endif

You just need to add forward declarations for struct dentry.

Thanks,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt