Re: [PATCH] crypto: aes_ti - fix comment for MixColumns step
On 10 May 2017 at 01:20, Eric Biggers wrote: > From: Eric Biggers > > mix_columns() contains a comment which shows the matrix used by the > MixColumns step of AES, but the last entry in this matrix was incorrect > --- and did not match the code, which is correct. Fix the comment. > > Signed-off-by: Eric Biggers > --- > crypto/aes_ti.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/crypto/aes_ti.c b/crypto/aes_ti.c > index 92644fd1ac19..03023b2290e8 100644 > --- a/crypto/aes_ti.c > +++ b/crypto/aes_ti.c > @@ -114,7 +114,7 @@ static u32 mix_columns(u32 x) > * | 0x2 0x3 0x1 0x1 | | x[0] | > * | 0x1 0x2 0x3 0x1 | | x[1] | > * | 0x1 0x1 0x2 0x3 | x | x[2] | > -* | 0x3 0x1 0x1 0x3 | | x[3] | > +* | 0x3 0x1 0x1 0x2 | | x[3] | > */ > u32 y = mul_by_x(x) ^ ror32(x, 16); > Acked-by: Ard Biesheuvel
[PATCH 0/4] clean some ecc functions
ecc software implementation works with chunks of u64 data. There were some unnecessary casts to u8 and then back to u64 for the ecc keys. Remove the unncessary casts. Tudor Ambarus (4): crypto: ecc - remove unused function arguments crypto: ecc - remove casts in ecdh_make_pub_key crypto: ecc - remove casts in crypto_ecdh_shared_secret crypto: ecc - remove casts in ecc_is_key_valid crypto/ecc.c | 30 +- crypto/ecc.h | 15 --- crypto/ecdh.c | 12 +--- 3 files changed, 22 insertions(+), 35 deletions(-) -- 2.7.4
[PATCH 3/4] crypto: ecc - remove casts in crypto_ecdh_shared_secret
ecc software implementation works with chunks of u64 data. There were some unnecessary casts to u8 and then back to u64 for the ecc keys. This patch removes the unncessary casts. Signed-off-by: Tudor Ambarus --- crypto/ecc.c | 12 ++-- crypto/ecc.h | 4 ++-- crypto/ecdh.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/crypto/ecc.c b/crypto/ecc.c index 0d88cec..e6f2725 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -964,8 +964,8 @@ int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits, } int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, const u8 *public_key, - u8 *secret) + const u64 *private_key, const u64 *public_key, + u64 *secret) { int ret = 0; struct ecc_point *product, *pk; @@ -995,13 +995,13 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, goto err_alloc_product; } - ecc_swap_digits((const u64 *)public_key, pk->x, ndigits); - ecc_swap_digits((const u64 *)&public_key[nbytes], pk->y, ndigits); - ecc_swap_digits((const u64 *)private_key, priv, ndigits); + ecc_swap_digits(public_key, pk->x, ndigits); + ecc_swap_digits(&public_key[ndigits], pk->y, ndigits); + ecc_swap_digits(private_key, priv, ndigits); ecc_point_mult(product, pk, priv, rand_z, curve->p, ndigits); - ecc_swap_digits(product->x, (u64 *)secret, ndigits); + ecc_swap_digits(product->x, secret, ndigits); if (ecc_point_is_zero(product)) ret = -EFAULT; diff --git a/crypto/ecc.h b/crypto/ecc.h index f4ee837..28b623bb 100644 --- a/crypto/ecc.h +++ b/crypto/ecc.h @@ -71,6 +71,6 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits, * if an error occurred. */ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, const u8 *public_key, - u8 *secret); + const u64 *private_key, const u64 *public_key, + u64 *secret); #endif diff --git a/crypto/ecdh.c b/crypto/ecdh.c index 23e3a2a..4b219a8 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -81,9 +81,9 @@ static int ecdh_compute_value(struct kpp_request *req) return -EINVAL; ret = crypto_ecdh_shared_secret(ctx->curve_id, ctx->ndigits, - (const u8 *)ctx->private_key, - (const u8 *)ctx->public_key, - (u8 *)ctx->shared_secret); + ctx->private_key, + ctx->public_key, + ctx->shared_secret); buf = ctx->shared_secret; } else { -- 2.7.4
[PATCH 2/4] crypto: ecc - remove casts in ecdh_make_pub_key
ecc software implementation works with chunks of u64 data. There were some unnecessary casts to u8 and then back to u64 for the ecc keys. This patch removes the unncessary casts. Signed-off-by: Tudor Ambarus --- crypto/ecc.c | 10 -- crypto/ecc.h | 2 +- crypto/ecdh.c | 3 +-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/crypto/ecc.c b/crypto/ecc.c index 69b4cc4..0d88cec 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -928,12 +928,11 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, } int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, u8 *public_key) + const u64 *private_key, u64 *public_key) { int ret = 0; struct ecc_point *pk; u64 priv[ndigits]; - unsigned int nbytes; const struct ecc_curve *curve = ecc_get_curve(curve_id); if (!private_key || !curve) { @@ -941,7 +940,7 @@ int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits, goto out; } - ecc_swap_digits((const u64 *)private_key, priv, ndigits); + ecc_swap_digits(private_key, priv, ndigits); pk = ecc_alloc_point(ndigits); if (!pk) { @@ -955,9 +954,8 @@ int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits, goto err_free_point; } - nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; - ecc_swap_digits(pk->x, (u64 *)public_key, ndigits); - ecc_swap_digits(pk->y, (u64 *)&public_key[nbytes], ndigits); + ecc_swap_digits(pk->x, public_key, ndigits); + ecc_swap_digits(pk->y, &public_key[ndigits], ndigits); err_free_point: ecc_free_point(pk); diff --git a/crypto/ecc.h b/crypto/ecc.h index b01e07c..f4ee837 100644 --- a/crypto/ecc.h +++ b/crypto/ecc.h @@ -54,7 +54,7 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, * if an error occurred. */ int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, u8 *public_key); + const u64 *private_key, u64 *public_key); /** * crypto_ecdh_shared_secret() - Compute a shared secret diff --git a/crypto/ecdh.c b/crypto/ecdh.c index b737ff0..23e3a2a 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -88,8 +88,7 @@ static int ecdh_compute_value(struct kpp_request *req) buf = ctx->shared_secret; } else { ret = ecdh_make_pub_key(ctx->curve_id, ctx->ndigits, - (const u8 *)ctx->private_key, - (u8 *)ctx->public_key); + ctx->private_key, ctx->public_key); buf = ctx->public_key; /* Public part is a point thus it has both coordinates */ nbytes *= 2; -- 2.7.4
[PATCH 4/4] crypto: ecc - remove casts in ecc_is_key_valid
ecc software implementation works with chunks of u64 data. There were some unnecessary casts to u8 and then back to u64 for the ecc keys. This patch removes the unncessary casts. Signed-off-by: Tudor Ambarus --- crypto/ecc.c | 6 +++--- crypto/ecc.h | 2 +- crypto/ecdh.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto/ecc.c b/crypto/ecc.c index e6f2725..e3a2b8f 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -904,7 +904,7 @@ static inline void ecc_swap_digits(const u64 *in, u64 *out, } int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, -const u8 *private_key, unsigned int private_key_len) +const u64 *private_key, unsigned int private_key_len) { int nbytes; const struct ecc_curve *curve = ecc_get_curve(curve_id); @@ -917,11 +917,11 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, if (private_key_len != nbytes) return -EINVAL; - if (vli_is_zero((const u64 *)&private_key[0], ndigits)) + if (vli_is_zero(private_key, ndigits)) return -EINVAL; /* Make sure the private key is in the range [1, n-1]. */ - if (vli_cmp(curve->n, (const u64 *)&private_key[0], ndigits) != 1) + if (vli_cmp(curve->n, private_key, ndigits) != 1) return -EINVAL; return 0; diff --git a/crypto/ecc.h b/crypto/ecc.h index 28b623bb..37bf7d6 100644 --- a/crypto/ecc.h +++ b/crypto/ecc.h @@ -41,7 +41,7 @@ * Returns 0 if the key is acceptable, a negative value otherwise */ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, -const u8 *private_key, unsigned int private_key_len); +const u64 *private_key, unsigned int private_key_len); /** * ecdh_make_pub_key() - Compute an ECC public key diff --git a/crypto/ecdh.c b/crypto/ecdh.c index 4b219a8..f1cc9f4 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -56,7 +56,7 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, ctx->ndigits = ndigits; if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits, -(const u8 *)params.key, params.key_size) < 0) +(const u64 *)params.key, params.key_size) < 0) return -EINVAL; memcpy(ctx->private_key, params.key, params.key_size); -- 2.7.4
[PATCH 1/4] crypto: ecc - remove unused function arguments
Signed-off-by: Tudor Ambarus --- crypto/ecc.c | 8 +++- crypto/ecc.h | 13 +++-- crypto/ecdh.c | 11 +-- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/crypto/ecc.c b/crypto/ecc.c index 414c78a..69b4cc4 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -928,8 +928,7 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, } int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, unsigned int private_key_len, - u8 *public_key, unsigned int public_key_len) + const u8 *private_key, u8 *public_key) { int ret = 0; struct ecc_point *pk; @@ -967,9 +966,8 @@ int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits, } int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, unsigned int private_key_len, - const u8 *public_key, unsigned int public_key_len, - u8 *secret, unsigned int secret_len) + const u8 *private_key, const u8 *public_key, + u8 *secret) { int ret = 0; struct ecc_point *product, *pk; diff --git a/crypto/ecc.h b/crypto/ecc.h index 663d598..b01e07c 100644 --- a/crypto/ecc.h +++ b/crypto/ecc.h @@ -48,27 +48,21 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, * * @curve_id: id representing the curve to use * @private_key: pregenerated private key for the given curve - * @private_key_len: length of private_key * @public_key:buffer for storing the public key generated - * @public_key_len:length of the public_key buffer * * Returns 0 if the public key was generated successfully, a negative value * if an error occurred. */ int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, unsigned int private_key_len, - u8 *public_key, unsigned int public_key_len); + const u8 *private_key, u8 *public_key); /** * crypto_ecdh_shared_secret() - Compute a shared secret * * @curve_id: id representing the curve to use * @private_key: private key of part A - * @private_key_len: length of private_key * @public_key:public key of counterpart B - * @public_key_len:length of public_key * @secret:buffer for storing the calculated shared secret - * @secret_len:length of the secret buffer * * Note: It is recommended that you hash the result of crypto_ecdh_shared_secret * before using it for symmetric encryption or HMAC. @@ -77,7 +71,6 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits, * if an error occurred. */ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, unsigned int private_key_len, - const u8 *public_key, unsigned int public_key_len, - u8 *secret, unsigned int secret_len); + const u8 *private_key, const u8 *public_key, + u8 *secret); #endif diff --git a/crypto/ecdh.c b/crypto/ecdh.c index 63ca337..b737ff0 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -81,16 +81,15 @@ static int ecdh_compute_value(struct kpp_request *req) return -EINVAL; ret = crypto_ecdh_shared_secret(ctx->curve_id, ctx->ndigits, -(const u8 *)ctx->private_key, nbytes, -(const u8 *)ctx->public_key, 2 * nbytes, -(u8 *)ctx->shared_secret, nbytes); + (const u8 *)ctx->private_key, + (const u8 *)ctx->public_key, + (u8 *)ctx->shared_secret); buf = ctx->shared_secret; } else { ret = ecdh_make_pub_key(ctx->curve_id, ctx->ndigits, - (const u8 *)ctx->private_key, nbytes, - (u8 *)ctx->public_key, - sizeof(ctx->public_key)); + (const u8 *)ctx->private_key, + (u8 *)ctx->public_key); buf = ctx->public_key; /* Public part is a point thus it has both coordinates */ nbytes *= 2; -- 2.7.4
[PATCH 2/2] crypto: ecdh - fix ecdh_max_size
The function should return minimum size for output buffer or error code if key hasn't been set. Signed-off-by: Tudor Ambarus --- crypto/ecdh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto/ecdh.c b/crypto/ecdh.c index 63ca337..01bfd13 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -109,10 +109,10 @@ static int ecdh_compute_value(struct kpp_request *req) static int ecdh_max_size(struct crypto_kpp *tfm) { struct ecdh_ctx *ctx = ecdh_get_ctx(tfm); - int nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT; - /* Public key is made of two coordinates */ - return 2 * nbytes; + /* Public key is made of two coordinates, add one to the left shift */ + return ctx->ndigits ? ctx->ndigits << (ECC_DIGITS_TO_BYTES_SHIFT + 1) : + -EINVAL; } static void no_exit_tfm(struct crypto_kpp *tfm) -- 2.7.4
[PATCH 1/2] crypto: dh - fix dh_max_size
The function should return minimum size for output buffer or error code if key hasn't been set. Signed-off-by: Tudor Ambarus --- crypto/dh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/dh.c b/crypto/dh.c index 87e3542..53d17ff 100644 --- a/crypto/dh.c +++ b/crypto/dh.c @@ -148,7 +148,7 @@ static int dh_max_size(struct crypto_kpp *tfm) { struct dh_ctx *ctx = dh_get_ctx(tfm); - return mpi_get_size(ctx->p); + return ctx->p ? mpi_get_size(ctx->p) : -EINVAL; } static void dh_exit_tfm(struct crypto_kpp *tfm) -- 2.7.4
[PATCH] crypto: glue_helper: remove redundant check on nbytes < bsize
From: Colin Ian King There is a check to see if nbytes < bsize (and a jump to label 'done' if it is true) inside the proceeding do-while loop so it is impossible for the second nbytes < bsize check to be true, hence is it redundant and can be removed. Remove it. Detected by CoverityScan, CID#712347 ("Logically dead code") Signed-off-by: Colin Ian King --- arch/x86/crypto/glue_helper.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/crypto/glue_helper.c b/arch/x86/crypto/glue_helper.c index 24ac9fad832d..d61e57960fe0 100644 --- a/arch/x86/crypto/glue_helper.c +++ b/arch/x86/crypto/glue_helper.c @@ -176,9 +176,6 @@ __glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, src -= 1; dst -= 1; } while (nbytes >= func_bytes); - - if (nbytes < bsize) - goto done; } } -- 2.11.0
[PATCH v1 0/3] Add support for Cavium CNN55XX crypto adapters.
Hi Herbert, This series adds support for Cavium CNN55XX crypto adapters. CNN55XX crypto adapters belongs to Cavium NITROX family series, able to accelerates both Symmetric and Asymmetric crypto workloads. These adapters have crypto cores for Symmetric and Asymmetric crypto operations, and needs to load firmware to become operational. Patches are generated on top of kernel/git/herbert/crypto-2.6 'commit 929562b14478 ("crypto: stm32 - Fix OF module alias information")' I will send the firmware to linux-firmware. The series was tested with dm-crypt for in kernel cryptographic offload operations. Please provide the feeback. Srikanth Jampala (3): crypto: cavium - Add support for CNN55XX adapters. crypto: cavium - Add debugfs support in CNN55XX driver crypto: cavium - Register the CNN55XX supported crypto algorithms. drivers/crypto/Kconfig |1 + drivers/crypto/Makefile |1 + drivers/crypto/cavium/nitrox/Kconfig | 21 + drivers/crypto/cavium/nitrox/Makefile|8 + drivers/crypto/cavium/nitrox/nitrox_algs.c | 584 ++ drivers/crypto/cavium/nitrox/nitrox_common.h | 36 + drivers/crypto/cavium/nitrox/nitrox_csr.h| 1085 ++ drivers/crypto/cavium/nitrox/nitrox_dev.h| 184 + drivers/crypto/cavium/nitrox/nitrox_hal.c| 404 ++ drivers/crypto/cavium/nitrox/nitrox_isr.c| 449 +++ drivers/crypto/cavium/nitrox/nitrox_lib.c| 208 + drivers/crypto/cavium/nitrox/nitrox_main.c | 639 +++ drivers/crypto/cavium/nitrox/nitrox_req.h| 438 +++ drivers/crypto/cavium/nitrox/nitrox_reqmgr.c | 572 ++ 14 files changed, 4630 insertions(+) create mode 100644 drivers/crypto/cavium/nitrox/Kconfig create mode 100644 drivers/crypto/cavium/nitrox/Makefile create mode 100644 drivers/crypto/cavium/nitrox/nitrox_algs.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_common.h create mode 100644 drivers/crypto/cavium/nitrox/nitrox_csr.h create mode 100644 drivers/crypto/cavium/nitrox/nitrox_dev.h create mode 100644 drivers/crypto/cavium/nitrox/nitrox_hal.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_isr.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_lib.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_main.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_req.h create mode 100644 drivers/crypto/cavium/nitrox/nitrox_reqmgr.c -- 2.9.3
[PATCH v1 2/3] crypto: cavium - Add debugfs support in CNN55XX driver
Add debugfs support in CNN55XX Physical Function driver. Provides hardware counters and firmware information. Signed-off-by: Srikanth Jampala --- drivers/crypto/cavium/nitrox/nitrox_csr.h | 5 ++ drivers/crypto/cavium/nitrox/nitrox_dev.h | 3 + drivers/crypto/cavium/nitrox/nitrox_main.c | 139 + 3 files changed, 147 insertions(+) diff --git a/drivers/crypto/cavium/nitrox/nitrox_csr.h b/drivers/crypto/cavium/nitrox/nitrox_csr.h index 988a85d..32ebdeb 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_csr.h +++ b/drivers/crypto/cavium/nitrox/nitrox_csr.h @@ -42,6 +42,8 @@ #define NPS_CORE_INT_ACTIVE0x180 #define NPS_CORE_INT 0x1A0 #define NPS_CORE_INT_ENA_W1S 0x1B8 +#define NPS_STATS_PKT_DMA_RD_CNT 0x1000180 +#define NPS_STATS_PKT_DMA_WR_CNT 0x1000190 /* NPS packet registers */ #define NPS_PKT_INT0x1040018 @@ -73,11 +75,13 @@ #define POM_GRP_EXECMASKX(_i) (0x11C1100 | ((_i) * 8)) #define POM_INT0x11C #define POM_PERF_CTL 0x11CC400 +#define POM_PERF_CNT 0x11CC408 /* BMI registers */ #define BMI_INT0x114 #define BMI_CTL0x1140020 #define BMI_INT_ENA_W1S0x1140018 +#define BMI_NPS_PKT_CNT0x1140070 /* EFL registers */ #define EFL_CORE_INT_ENA_W1SX(_i) (0x1240018 + ((_i) * 0x400)) @@ -91,6 +95,7 @@ /* BMO registers */ #define BMO_CTL2 0x1180028 +#define BMO_NPS_SLC_PKT_CNT0x1180078 /* LBC registers */ #define LBC_INT0x120 diff --git a/drivers/crypto/cavium/nitrox/nitrox_dev.h b/drivers/crypto/cavium/nitrox/nitrox_dev.h index ff6bb09..84c2341 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_dev.h +++ b/drivers/crypto/cavium/nitrox/nitrox_dev.h @@ -134,6 +134,9 @@ struct nitrox_device { struct nitrox_bh bh; struct nitrox_hw hw; +#if IS_ENABLED(CONFIG_DEBUG_FS) + struct dentry *debugfs_dir; +#endif }; static inline u8 __iomem *nitrox_csr_addr(struct nitrox_device *ndev, diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c index ac3e9b3..432a21b 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_main.c +++ b/drivers/crypto/cavium/nitrox/nitrox_main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -303,6 +304,139 @@ static int nitrox_pf_hw_init(struct nitrox_device *ndev) return 0; } +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int registers_show(struct seq_file *s, void *v) +{ + struct nitrox_device *ndev = s->private; + u64 offset; + + /* NPS DMA stats */ + offset = NPS_STATS_PKT_DMA_RD_CNT; + seq_printf(s, "NPS_STATS_PKT_DMA_RD_CNT 0x%016llx\n", + nitrox_read_csr(ndev, offset)); + offset = NPS_STATS_PKT_DMA_WR_CNT; + seq_printf(s, "NPS_STATS_PKT_DMA_WR_CNT 0x%016llx\n", + nitrox_read_csr(ndev, offset)); + + /* BMI/BMO stats */ + offset = BMI_NPS_PKT_CNT; + seq_printf(s, "BMI_NPS_PKT_CNT 0x%016llx\n", + nitrox_read_csr(ndev, offset)); + offset = BMO_NPS_SLC_PKT_CNT; + seq_printf(s, "BMO_NPS_PKT_CNT 0x%016llx\n", + nitrox_read_csr(ndev, offset)); + + offset = POM_PERF_CNT; + seq_printf(s, "POM_PERF_CNT 0x%016llx\n", + nitrox_read_csr(ndev, offset)); + + return 0; +} + +static int registers_open(struct inode *inode, struct file *file) +{ + return single_open(file, registers_show, inode->i_private); +} + +static const struct file_operations register_fops = { + .owner = THIS_MODULE, + .open = registers_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int firmware_show(struct seq_file *s, void *v) +{ + struct nitrox_device *ndev = s->private; + + seq_printf(s, "Version: %s\n", ndev->hw.fw_name); + return 0; +} + +static int firmware_open(struct inode *inode, struct file *file) +{ + return single_open(file, firmware_show, inode->i_private); +} + +static const struct file_operations firmware_fops = { + .owner = THIS_MODULE, + .open = firmware_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int nitrox_show(struct seq_file *s, void *v) +{ + struct nitrox_device *ndev = s->private; + + seq_printf(s, "NITROX-5 [idx: %d]\n", ndev->idx); + seq_printf(s, " Revsion ID: 0x%0x\n", ndev->hw.revision_id); + seq_printf(s, " Cores [AE: %u SE: %u]\n", + ndev->hw.ae_cores, ndev->hw.se_cores); + seq_printf(s, " Number of Queues: %u\n", ndev->nr_queues); + seq_printf(s, " Queue length: %u\n", ndev->qlen); + seq_printf(s, " Node: %u\n", ndev->node); + + return 0; +} + +static int nitrox_open(struct inode *inode, struct file *file) +{ +
[PATCH v1 1/3] crypto: cavium - Add support for CNN55XX adapters.
Add Physical Function driver support for CNN55XX crypto adapters. CNN55XX adapters belongs to Cavium NITROX family series, which accelerate both Symmetric and Asymmetric crypto workloads. These adapters have crypto engines that need firmware to become operational. Signed-off-by: Srikanth Jampala --- drivers/crypto/Kconfig |1 + drivers/crypto/Makefile |1 + drivers/crypto/cavium/nitrox/Kconfig | 21 + drivers/crypto/cavium/nitrox/Makefile|7 + drivers/crypto/cavium/nitrox/nitrox_common.h | 29 + drivers/crypto/cavium/nitrox/nitrox_csr.h| 1080 ++ drivers/crypto/cavium/nitrox/nitrox_dev.h| 181 + drivers/crypto/cavium/nitrox/nitrox_hal.c| 404 ++ drivers/crypto/cavium/nitrox/nitrox_isr.c| 449 +++ drivers/crypto/cavium/nitrox/nitrox_lib.c| 170 drivers/crypto/cavium/nitrox/nitrox_main.c | 460 +++ drivers/crypto/cavium/nitrox/nitrox_req.h| 438 +++ drivers/crypto/cavium/nitrox/nitrox_reqmgr.c | 572 ++ 13 files changed, 3813 insertions(+) create mode 100644 drivers/crypto/cavium/nitrox/Kconfig create mode 100644 drivers/crypto/cavium/nitrox/Makefile create mode 100644 drivers/crypto/cavium/nitrox/nitrox_common.h create mode 100644 drivers/crypto/cavium/nitrox/nitrox_csr.h create mode 100644 drivers/crypto/cavium/nitrox/nitrox_dev.h create mode 100644 drivers/crypto/cavium/nitrox/nitrox_hal.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_isr.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_lib.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_main.c create mode 100644 drivers/crypto/cavium/nitrox/nitrox_req.h create mode 100644 drivers/crypto/cavium/nitrox/nitrox_reqmgr.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index fb1e60f..235554e 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -529,6 +529,7 @@ config CRYPTO_DEV_MXS_DCP source "drivers/crypto/qat/Kconfig" source "drivers/crypto/cavium/cpt/Kconfig" +source "drivers/crypto/cavium/nitrox/Kconfig" config CRYPTO_DEV_CAVIUM_ZIP tristate "Cavium ZIP driver" diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 463f335..14209b9 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_CRYPTO_DEV_CAVIUM_ZIP) += cavium/ obj-$(CONFIG_CRYPTO_DEV_CCP) += ccp/ obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chelsio/ obj-$(CONFIG_CRYPTO_DEV_CPT) += cavium/cpt/ +obj-$(CONFIG_CRYPTO_DEV_NITROX) += cavium/nitrox/ obj-$(CONFIG_CRYPTO_DEV_EXYNOS_RNG) += exynos-rng.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/ obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o diff --git a/drivers/crypto/cavium/nitrox/Kconfig b/drivers/crypto/cavium/nitrox/Kconfig new file mode 100644 index 000..d8b979f --- /dev/null +++ b/drivers/crypto/cavium/nitrox/Kconfig @@ -0,0 +1,21 @@ +# +# Cavium NITROX Crypto Device configuration +# +config CRYPTO_DEV_NITROX + tristate + select CRYPTO_BLKCIPHER + select CRYPTO_AES + select CRYPTO_DES + select FW_LOADER + +config CRYPTO_DEV_NITROX_CNN55XX + tristate "Support for Cavium CNN55XX driver" + depends on PCI_MSI + select CRYPTO_DEV_NITROX + default m + help + Support for Cavium NITROX family CNN55XX driver + for accelerating crypto workloads. + + To compile this as a module, choose M here: the module + will be called n5pf. diff --git a/drivers/crypto/cavium/nitrox/Makefile b/drivers/crypto/cavium/nitrox/Makefile new file mode 100644 index 000..ef457f6 --- /dev/null +++ b/drivers/crypto/cavium/nitrox/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_CRYPTO_DEV_NITROX_CNN55XX) += n5pf.o + +n5pf-objs := nitrox_main.o \ + nitrox_isr.o \ + nitrox_lib.o \ + nitrox_hal.o \ + nitrox_reqmgr.o diff --git a/drivers/crypto/cavium/nitrox/nitrox_common.h b/drivers/crypto/cavium/nitrox/nitrox_common.h new file mode 100644 index 000..f79be7d --- /dev/null +++ b/drivers/crypto/cavium/nitrox/nitrox_common.h @@ -0,0 +1,29 @@ +#ifndef __NITROX_COMMON_H +#define __NITROX_COMMON_H + +#include "nitrox_dev.h" +#include "nitrox_req.h" + +void nitrox_pf_cleanup_isr(struct nitrox_device *ndev); +int nitrox_pf_init_isr(struct nitrox_device *ndev); + +int nitrox_common_sw_init(struct nitrox_device *ndev); +void nitrox_common_sw_cleanup(struct nitrox_device *ndev); + +void pkt_slc_resp_handler(unsigned long data); +int nitrox_se_request(struct nitrox_device *ndev, struct crypto_request *req); + +void nitrox_config_emu_unit(struct nitrox_device *ndev); +void nitrox_config_pkt_input_rings(struct nitrox_device *ndev); +void nitrox_config_pkt_solicit_ports(struct nitrox_device *ndev); +void nitrox_config_vfmode(struct nitrox_device *ndev, int mode); +void nitrox_config_nps_unit(struct nitrox_device *ndev); +void nitrox_config_pom_unit(struct nitrox_device *
[PATCH v1 3/3] crypto: cavium - Register the CNN55XX supported crypto algorithms.
Register the Symmetric crypto algorithms supported by CNN55XX driver with crypto subsystem. The following Symmetric crypto algorithms are supported, - aes with cbc, ecb, cfb, xts, ctr and cts modes - des3_ede with cbc and ecb modes Signed-off-by: Srikanth Jampala --- drivers/crypto/cavium/nitrox/Makefile| 3 +- drivers/crypto/cavium/nitrox/nitrox_algs.c | 584 +++ drivers/crypto/cavium/nitrox/nitrox_common.h | 7 + drivers/crypto/cavium/nitrox/nitrox_lib.c| 38 ++ drivers/crypto/cavium/nitrox/nitrox_main.c | 40 ++ 5 files changed, 671 insertions(+), 1 deletion(-) create mode 100644 drivers/crypto/cavium/nitrox/nitrox_algs.c diff --git a/drivers/crypto/cavium/nitrox/Makefile b/drivers/crypto/cavium/nitrox/Makefile index ef457f6..5af2e43 100644 --- a/drivers/crypto/cavium/nitrox/Makefile +++ b/drivers/crypto/cavium/nitrox/Makefile @@ -4,4 +4,5 @@ n5pf-objs := nitrox_main.o \ nitrox_isr.o \ nitrox_lib.o \ nitrox_hal.o \ - nitrox_reqmgr.o + nitrox_reqmgr.o \ + nitrox_algs.o diff --git a/drivers/crypto/cavium/nitrox/nitrox_algs.c b/drivers/crypto/cavium/nitrox/nitrox_algs.c new file mode 100644 index 000..aa9df1c --- /dev/null +++ b/drivers/crypto/cavium/nitrox/nitrox_algs.c @@ -0,0 +1,584 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "nitrox_dev.h" +#include "nitrox_common.h" +#include "nitrox_req.h" + +struct nitrox_cipher { + const char *name; + enum flexi_cipher value; +}; + +/** + * supported cipher list + */ +static const struct nitrox_cipher flexi_cipher_table[] = { + { "null", CIPHER_NULL }, + { "cbc(des3_ede)", CIPHER_3DES_CBC }, + { "ecb(des3_ede)", CIPHER_3DES_ECB }, + { "cbc(aes)", CIPHER_AES_CBC }, + { "ecb(aes)", CIPHER_AES_ECB }, + { "cfb(aes)", CIPHER_AES_CFB }, + { "rfc3686(ctr(aes))", CIPHER_AES_CTR }, + { "xts(aes)", CIPHER_AES_XTS }, + { "cts(cbc(aes))", CIPHER_AES_CBC_CTS }, + { NULL, CIPHER_INVALID } +}; + +static enum flexi_cipher flexi_cipher_type(const char *name) +{ + const struct nitrox_cipher *cipher = flexi_cipher_table; + + while (cipher->name) { + if (!strcmp(cipher->name, name)) + break; + cipher++; + } + return cipher->value; +} + +static int flexi_aes_keylen(int keylen) +{ + int aes_keylen; + + switch (keylen) { + case AES_KEYSIZE_128: + aes_keylen = 1; + break; + case AES_KEYSIZE_192: + aes_keylen = 2; + break; + case AES_KEYSIZE_256: + aes_keylen = 3; + break; + default: + aes_keylen = -EINVAL; + break; + } + return aes_keylen; +} + +static inline void create_io_list(struct scatterlist *src, + struct io_sglist *io) +{ + struct scatterlist *sg; + int cnt, sgcount, i; + + cnt = io->cnt; + sgcount = sg_nents(src); + + for_each_sg(src, sg, sgcount, i) { + if (!sg->length) + continue; + io->bufs[cnt].addr = sg_virt(sg); + io->bufs[cnt].len = sg->length; + cnt++; + } + io->cnt = cnt; +} + +static int nitrox_ablkcipher_init(struct crypto_tfm *tfm) +{ + struct nitrox_crypto_instance *inst = crypto_tfm_ctx(tfm); + void *ctx; + + tfm->crt_ablkcipher.reqsize = sizeof(struct nitrox_crypto_request); + /* get the first device */ + inst->ndev = nitrox_get_first_device(); + if (!inst->ndev) + return -ENODEV; + + /* allocate crypto context */ + ctx = crypto_alloc_context(inst->ndev); + if (!ctx) { + nitrox_put_device(inst->ndev); + return -ENOMEM; + } + inst->u.ctx_handle = (uintptr_t)ctx; + + return 0; +} + +static void nitrox_ablkcipher_exit(struct crypto_tfm *tfm) +{ + struct nitrox_crypto_instance *inst = crypto_tfm_ctx(tfm); + + /* free the crypto context */ + if (inst->u.ctx_handle) + crypto_free_context((void *)inst->u.ctx_handle); + + nitrox_put_device(inst->ndev); + + inst->u.ctx_handle = 0; + inst->ndev = NULL; +} + +static inline int nitrox_ablkcipher_setkey(struct crypto_ablkcipher *cipher, + int aes_keylen, const u8 *key, + unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct nitrox_crypto_instance *inst = crypto_tfm_ctx(tfm); + struct flexi_crypto_context *fctx; + enum flexi_cipher cipher_type; + const char *name; + + name = crypto_tfm_alg_name(tfm); + c
Re: [PATCH v1 3/3] crypto: cavium - Register the CNN55XX supported crypto algorithms.
Am Mittwoch, 10. Mai 2017, 15:06:40 CEST schrieb Srikanth Jampala: Hi Srikanth, In general: you are using the ablkcipher API. I think it is on its way out and being replaced with skcipher. Maybe it makes sense to replace it here too. It could be as simple as s/ ablkcipher/skcipher/g > +static inline int nitrox_ablkcipher_setkey(struct crypto_ablkcipher > *cipher, > + int aes_keylen, const u8 *key, > + unsigned int keylen) > +{ > + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); > + struct nitrox_crypto_instance *inst = crypto_tfm_ctx(tfm); > + struct flexi_crypto_context *fctx; > + enum flexi_cipher cipher_type; > + const char *name; > + > + name = crypto_tfm_alg_name(tfm); > + cipher_type = flexi_cipher_type(name); > + if (cipher_type == CIPHER_INVALID) { > + pr_err("unsupported cipher: %s\n", name); > + return -EINVAL; > + } > + > + /* fill crypto context */ > + fctx = inst->u.fctx; > + fctx->flags = 0; > + fctx->w0.cipher_type = cipher_type; > + fctx->w0.aes_keylen = aes_keylen; > + fctx->w0.iv_source = IV_FROM_DPTR; > + fctx->flags = cpu_to_be64(*(u64 *)&fctx->w0); > + /* copy the key to context */ > + memcpy(fctx->crypto.u.key, key, keylen); Could you help me finding the location where this memory is zeroized upon release? > + > + return 0; > +} > + > +static int nitrox_3des_setkey(struct crypto_ablkcipher *cipher, const u8 > *key, + unsigned int keylen) > +{ > + if (keylen != DES3_EDE_KEY_SIZE) { > + crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); > + return -EINVAL; > + } Please import the check from __des3_ede_setkey (or better, extract that key check into a generic function like xts_check_key). Ciao Stephan
Re: [PATCH v1 1/3] crypto: cavium - Add support for CNN55XX adapters.
Hi Srikanth, [auto build test ERROR on cryptodev/master] [also build test ERROR on next-20170510] [cannot apply to v4.11] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Srikanth-Jampala/crypto-cavium-Add-support-for-CNN55XX-adapters/20170510-211638 base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master config: i386-defconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): In file included from drivers/crypto/cavium/nitrox/nitrox_main.c:10:0: drivers/crypto/cavium/nitrox/nitrox_dev.h: In function 'nitrox_read_csr': >> drivers/crypto/cavium/nitrox/nitrox_dev.h:156:9: error: implicit declaration >> of function 'readq' [-Werror=implicit-function-declaration] return readq(ndev->bar_addr + offset); ^ drivers/crypto/cavium/nitrox/nitrox_dev.h: In function 'nitrox_write_csr': >> drivers/crypto/cavium/nitrox/nitrox_dev.h:168:2: error: implicit declaration >> of function 'writeq' [-Werror=implicit-function-declaration] writeq(value, (ndev->bar_addr + offset)); ^~ cc1: some warnings being treated as errors -- In file included from drivers/crypto/cavium/nitrox/nitrox_hal.c:3:0: drivers/crypto/cavium/nitrox/nitrox_dev.h: In function 'nitrox_read_csr': >> drivers/crypto/cavium/nitrox/nitrox_dev.h:156:9: error: implicit declaration >> of function 'readq' [-Werror=implicit-function-declaration] return readq(ndev->bar_addr + offset); ^ drivers/crypto/cavium/nitrox/nitrox_dev.h: In function 'nitrox_write_csr': >> drivers/crypto/cavium/nitrox/nitrox_dev.h:168:2: error: implicit declaration >> of function 'writeq' [-Werror=implicit-function-declaration] writeq(value, (ndev->bar_addr + offset)); ^~ drivers/crypto/cavium/nitrox/nitrox_hal.c: In function 'nitrox_config_pkt_input_rings': drivers/crypto/cavium/nitrox/nitrox_hal.c:120:23: warning: unused variable 'cmdq' [-Wunused-variable] struct nitrox_cmdq *cmdq = &ndev->pkt_cmdqs[i]; ^~~~ cc1: some warnings being treated as errors vim +/readq +156 drivers/crypto/cavium/nitrox/nitrox_dev.h 150 * @offset: offset of the register to read 151 * 152 * Returns: value read 153 */ 154 static inline u64 nitrox_read_csr(struct nitrox_device *ndev, u64 offset) 155 { > 156 return readq(ndev->bar_addr + offset); 157 } 158 159 /** 160 * nitrox_write_csr - Write to device register 161 * @ndev: NITROX device 162 * @offset: offset of the register to write 163 * @value: value to write 164 */ 165 static inline void nitrox_write_csr(struct nitrox_device *ndev, u64 offset, 166 u64 value) 167 { > 168 writeq(value, (ndev->bar_addr + offset)); 169 } 170 171 static inline int nitrox_in_use(struct nitrox_device *ndev) --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v1 3/3] crypto: cavium - Register the CNN55XX supported crypto algorithms.
Hi Srikanth, [auto build test WARNING on cryptodev/master] [also build test WARNING on next-20170510] [cannot apply to v4.11] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Srikanth-Jampala/crypto-cavium-Add-support-for-CNN55XX-adapters/20170510-211638 base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master config: i386-defconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): In file included from drivers/crypto/cavium/nitrox/nitrox_algs.c:12:0: drivers/crypto/cavium/nitrox/nitrox_dev.h: In function 'nitrox_read_csr': drivers/crypto/cavium/nitrox/nitrox_dev.h:159:9: error: implicit declaration of function 'readq' [-Werror=implicit-function-declaration] return readq(ndev->bar_addr + offset); ^ drivers/crypto/cavium/nitrox/nitrox_dev.h: In function 'nitrox_write_csr': drivers/crypto/cavium/nitrox/nitrox_dev.h:171:2: error: implicit declaration of function 'writeq' [-Werror=implicit-function-declaration] writeq(value, (ndev->bar_addr + offset)); ^~ drivers/crypto/cavium/nitrox/nitrox_algs.c: In function 'nitrox_ablkcipher_exit': >> drivers/crypto/cavium/nitrox/nitrox_algs.c:117:23: warning: cast to pointer >> from integer of different size [-Wint-to-pointer-cast] crypto_free_context((void *)inst->u.ctx_handle); ^ cc1: some warnings being treated as errors vim +117 drivers/crypto/cavium/nitrox/nitrox_algs.c 101 ctx = crypto_alloc_context(inst->ndev); 102 if (!ctx) { 103 nitrox_put_device(inst->ndev); 104 return -ENOMEM; 105 } 106 inst->u.ctx_handle = (uintptr_t)ctx; 107 108 return 0; 109 } 110 111 static void nitrox_ablkcipher_exit(struct crypto_tfm *tfm) 112 { 113 struct nitrox_crypto_instance *inst = crypto_tfm_ctx(tfm); 114 115 /* free the crypto context */ 116 if (inst->u.ctx_handle) > 117 crypto_free_context((void *)inst->u.ctx_handle); 118 119 nitrox_put_device(inst->ndev); 120 121 inst->u.ctx_handle = 0; 122 inst->ndev = NULL; 123 } 124 125 static inline int nitrox_ablkcipher_setkey(struct crypto_ablkcipher *cipher, --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
need to pick a solution for dm-crypt IV generation and do it! [was: Re: dm: submit stacked requests in irq enabled context]
On Wed, May 10 2017 at 9:37am -0400, Gilad Ben-Yossef wrote: > On Wed, May 10, 2017 at 11:49 AM, Neeraj Soni wrote: > > Hi Keith, > > > > Request based dm (dm-req-crypt) is being used for Disk Encryption solution > > in Android used by Google. Also as i mentioned reverting this fix improves > > the RR/RW numbers so this proves the request based dm is coming into path > > and is being used. > > Sadly, that is an out of tree module. > > Does it still use Qcom specific APIs in its implementation (qcrypto_* funcs)? > It did the last time I've checked - and the driver that implements > those is not upstream either... > > It makes it difficult to help - which is a shame since I am interested > in enabling higher performance > of dm-crypt when using HW based crypto transformation myself. I have absolutely no interest in request-based dm-crypt. It is a hack to work-around limitations in crypto IV generation. If "google" is foolish enough to deploy out-of-tree request-based dm-crypt in their android kernel then they are easily capable of reverting the commit in question to prop up their short-cited decision. The correct way forward is to follow through with the crypto work discussed here (pick a solution to implement and make it happen): https://www.redhat.com/archives/dm-devel/2017-March/msg00044.html and here: https://www.redhat.com/archives/dm-devel/2017-March/msg00053.html and here: https://www.redhat.com/archives/dm-devel/2017-April/msg00132.html Mike
Re: need to pick a solution for dm-crypt IV generation and do it! [was: Re: dm: submit stacked requests in irq enabled context]
On Wed, May 10, 2017 at 5:45 PM, Mike Snitzer wrote: > On Wed, May 10 2017 at 9:37am -0400, > Gilad Ben-Yossef wrote: > >> On Wed, May 10, 2017 at 11:49 AM, Neeraj Soni >> wrote: >> > Hi Keith, >> > >> > Request based dm (dm-req-crypt) is being used for Disk Encryption solution >> > in Android used by Google. Also as i mentioned reverting this fix improves >> > the RR/RW numbers so this proves the request based dm is coming into path >> > and is being used. >> >> Sadly, that is an out of tree module. >> >> Does it still use Qcom specific APIs in its implementation (qcrypto_* funcs)? >> It did the last time I've checked - and the driver that implements >> those is not upstream either... >> >> It makes it difficult to help - which is a shame since I am interested >> in enabling higher performance >> of dm-crypt when using HW based crypto transformation myself. > > I have absolutely no interest in request-based dm-crypt. It is a hack > to work-around limitations in crypto IV generation. I agree. This is why I've said I'm interested in a high performance dm-crypt, not "request based dm-crypt". They are trying to solve the same problem but with the wrong solution and doing so out of upstream. As the parlance of our time seems to go... sad. :-) Cheers, Gilad -- Gilad Ben-Yossef Chief Coffee Drinker "If you take a class in large-scale robotics, can you end up in a situation where the homework eats your dog?" -- Jean-Baptiste Queru
Re: [RFC 09/10] ima: move to generic async completion
On Sat, 2017-05-06 at 15:59 +0300, Gilad Ben-Yossef wrote: > ima starts several async. crypto ops and waits for their completions. > Move it over to generic code doing the same. > > Signed-off-by: Gilad Ben-Yossef Acked-by: Mimi Zohar > --- > security/integrity/ima/ima_crypto.c | 56 > +++-- > 1 file changed, 17 insertions(+), 39 deletions(-) > > diff --git a/security/integrity/ima/ima_crypto.c > b/security/integrity/ima/ima_crypto.c > index 802d5d2..0e4db1fe 100644 > --- a/security/integrity/ima/ima_crypto.c > +++ b/security/integrity/ima/ima_crypto.c > @@ -27,11 +27,6 @@ > > #include "ima.h" > > -struct ahash_completion { > - struct completion completion; > - int err; > -}; > - > /* minimum file size for ahash use */ > static unsigned long ima_ahash_minsize; > module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644); > @@ -196,30 +191,13 @@ static void ima_free_atfm(struct crypto_ahash *tfm) > crypto_free_ahash(tfm); > } > > -static void ahash_complete(struct crypto_async_request *req, int err) > +static inline int ahash_wait(int err, struct crypto_wait *wait) > { > - struct ahash_completion *res = req->data; > > - if (err == -EINPROGRESS) > - return; > - res->err = err; > - complete(&res->completion); > -} > + err = crypto_wait_req(err, wait); > > -static int ahash_wait(int err, struct ahash_completion *res) > -{ > - switch (err) { > - case 0: > - break; > - case -EINPROGRESS: > - case -EBUSY: > - wait_for_completion(&res->completion); > - reinit_completion(&res->completion); > - err = res->err; > - /* fall through */ > - default: > + if (err) > pr_crit_ratelimited("ahash calculation failed: err: %d\n", err); > - } > > return err; > } > @@ -233,7 +211,7 @@ static int ima_calc_file_hash_atfm(struct file *file, > int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0; > struct ahash_request *req; > struct scatterlist sg[1]; > - struct ahash_completion res; > + struct crypto_wait wait; > size_t rbuf_size[2]; > > hash->length = crypto_ahash_digestsize(tfm); > @@ -242,12 +220,12 @@ static int ima_calc_file_hash_atfm(struct file *file, > if (!req) > return -ENOMEM; > > - init_completion(&res.completion); > + crypto_init_wait(&wait); > ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | > CRYPTO_TFM_REQ_MAY_SLEEP, > -ahash_complete, &res); > +crypto_req_done, &wait); > > - rc = ahash_wait(crypto_ahash_init(req), &res); > + rc = ahash_wait(crypto_ahash_init(req), &wait); > if (rc) > goto out1; > > @@ -288,7 +266,7 @@ static int ima_calc_file_hash_atfm(struct file *file, >* read/request, wait for the completion of the >* previous ahash_update() request. >*/ > - rc = ahash_wait(ahash_rc, &res); > + rc = ahash_wait(ahash_rc, &wait); > if (rc) > goto out3; > } > @@ -304,7 +282,7 @@ static int ima_calc_file_hash_atfm(struct file *file, >* read/request, wait for the completion of the >* previous ahash_update() request. >*/ > - rc = ahash_wait(ahash_rc, &res); > + rc = ahash_wait(ahash_rc, &wait); > if (rc) > goto out3; > } > @@ -318,7 +296,7 @@ static int ima_calc_file_hash_atfm(struct file *file, > active = !active; /* swap buffers, if we use two */ > } > /* wait for the last update request to complete */ > - rc = ahash_wait(ahash_rc, &res); > + rc = ahash_wait(ahash_rc, &wait); > out3: > if (read) > file->f_mode &= ~FMODE_READ; > @@ -327,7 +305,7 @@ static int ima_calc_file_hash_atfm(struct file *file, > out2: > if (!rc) { > ahash_request_set_crypt(req, NULL, hash->digest, 0); > - rc = ahash_wait(crypto_ahash_final(req), &res); > + rc = ahash_wait(crypto_ahash_final(req), &wait); > } > out1: > ahash_request_free(req); > @@ -527,7 +505,7 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t > len, > { > struct ahash_request *req; > struct scatterlist sg; > - struct ahash_completion res; > + struct crypto_wait wait; > int rc, ahash_rc = 0; > > hash->length = crypto_ahash_digestsize(tfm); > @@ -536,12 +514,12 @@ static int calc_buffer_ahash_atfm(const void *buf, > loff_t len, > if (!req) > return -ENOMEM; > > - init_completion(&res.completion); > + crypt
Re: [RFC 01/10] crypto: factor async completion for general use
Hi Gilad, On Sat, May 06, 2017 at 03:59:50PM +0300, Gilad Ben-Yossef wrote: > Invoking a possibly async. crypto op and waiting for completion > while correctly handling backlog processing is a common task > in the crypto API implementation and outside users of it. > > This patch re-factors one of the in crypto API implementation in > preparation for using it across the board instead of hand > rolled versions. Thanks for doing this! It annoyed me too that there wasn't a helper function for this. Just a few comments below: > diff --git a/crypto/af_alg.c b/crypto/af_alg.c > index 3556d8e..bf4acaf 100644 > --- a/crypto/af_alg.c > +++ b/crypto/af_alg.c > @@ -480,33 +480,6 @@ int af_alg_cmsg_send(struct msghdr *msg, struct > af_alg_control *con) > } > EXPORT_SYMBOL_GPL(af_alg_cmsg_send); > > -int af_alg_wait_for_completion(int err, struct af_alg_completion *completion) > -{ > - switch (err) { > - case -EINPROGRESS: > - case -EBUSY: > - wait_for_completion(&completion->completion); > - reinit_completion(&completion->completion); > - err = completion->err; > - break; > - }; > - > - return err; > -} > -EXPORT_SYMBOL_GPL(af_alg_wait_for_completion); > - > -void af_alg_complete(struct crypto_async_request *req, int err) > -{ > - struct af_alg_completion *completion = req->data; > - > - if (err == -EINPROGRESS) > - return; > - > - completion->err = err; > - complete(&completion->completion); > -} > -EXPORT_SYMBOL_GPL(af_alg_complete); > - I think it would be cleaner to switch af_alg and algif_* over to the new interface in its own patch, rather than in the same patch that introduces the new interface. > @@ -88,8 +88,8 @@ static int hash_sendmsg(struct socket *sock, struct msghdr > *msg, > if ((msg->msg_flags & MSG_MORE)) > hash_free_result(sk, ctx); > > - err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req), > - &ctx->completion); > + err = crypto_wait_req(crypto_ahash_init(&ctx->req), > + &ctx->wait); > if (err) > goto unlock; > } In general can you try to keep the argument lists indented sanely? (This applies throughout the patch series.) e.g. here I'd have expected: err = crypto_wait_req(crypto_ahash_init(&ctx->req), &ctx->wait); > > diff --git a/crypto/api.c b/crypto/api.c > index 941cd4c..1c6e9cd 100644 > --- a/crypto/api.c > +++ b/crypto/api.c > @@ -24,6 +24,7 @@ > #include > #include > #include > +#include > #include "internal.h" > > LIST_HEAD(crypto_alg_list); > @@ -595,5 +596,32 @@ int crypto_has_alg(const char *name, u32 type, u32 mask) > } > EXPORT_SYMBOL_GPL(crypto_has_alg); > > +int crypto_wait_req(int err, struct crypto_wait *wait) > +{ > + switch (err) { > + case -EINPROGRESS: > + case -EBUSY: > + wait_for_completion(&wait->completion); > + reinit_completion(&wait->completion); > + err = wait->err; > + break; > + }; > + > + return err; > +} > +EXPORT_SYMBOL_GPL(crypto_wait_req); crypto_wait_req() maybe should be inlined, since it doesn't do much (note that reinit_completion is actually just a variable assignment), and the common case is that 'err' will be 0, so there will be nothing to wait for. Also drop the unnecessary semicolon at the end of the switch block. With regards to the wait being uninterruptible, I agree that this should be the default behavior, because I think users waiting for specific crypto requests are generally not prepared to handle the wait actually being interrupted. After interruption the crypto operation will still proceed in the background, and it will use buffers which the caller has in many cases already freed. However, I'd suggest taking a close look at anything that was actually doing an interruptible wait before, to see whether it was a bug or intentional (or "doesn't matter"). And yes there could always be a crypto_wait_req_interruptible() introduced if some users need it. > > #define CRYPTO_MINALIGN_ATTR __attribute__ ((__aligned__(CRYPTO_MINALIGN))) > > +/* > + * Macro for declaring a crypto op async wait object on stack > + */ > +#define DECLARE_CRYPTO_WAIT(_wait) \ > + struct crypto_wait _wait = { \ > + COMPLETION_INITIALIZER_ONSTACK((_wait).completion), 0 } > + Move this definition down below, so it's next to crypto_wait? > > /* > * Algorithm registration interface. > */ > @@ -1604,5 +1631,6 @@ static inline int crypto_comp_decompress(struct > crypto_comp *tfm, > src, slen, dst, dlen); > } > > + Don't add unrelated blank lines. - Eric
Re: [RFC 07/10] fscrypt: move to generic async completion
Hi Gilad, On Sat, May 06, 2017 at 03:59:56PM +0300, Gilad Ben-Yossef wrote: > int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw, > u64 lblk_num, struct page *src_page, > struct page *dest_page, unsigned int len, > @@ -150,7 +135,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, > fscrypt_direction_t rw, > u8 padding[FS_XTS_TWEAK_SIZE - sizeof(__le64)]; > } xts_tweak; > struct skcipher_request *req = NULL; > - DECLARE_FS_COMPLETION_RESULT(ecr); > + DECLARE_CRYPTO_WAIT(ecr); > struct scatterlist dst, src; > struct fscrypt_info *ci = inode->i_crypt_info; > struct crypto_skcipher *tfm = ci->ci_ctfm; > @@ -168,7 +153,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, > fscrypt_direction_t rw, [...] This patch looks good --- thanks for doing this! I suggest also renaming 'ecr' to 'wait' in the places being updated to use crypto_wait, since the name is obsolete (and was already; it originally stood for "ext4 completion result"). - Eric
Re: need to pick a solution for dm-crypt IV generation and do it! [was: Re: dm: submit stacked requests in irq enabled context]
Thanks for inputs folks. So shall i conclude that there is no remedy available that can be applied on 4.4 and reverting this patch is only way forward to solve the degradation? Neeraj On 5/10/2017 8:25 PM, Gilad Ben-Yossef wrote: On Wed, May 10, 2017 at 5:45 PM, Mike Snitzer wrote: On Wed, May 10 2017 at 9:37am -0400, Gilad Ben-Yossef wrote: On Wed, May 10, 2017 at 11:49 AM, Neeraj Soni wrote: Hi Keith, Request based dm (dm-req-crypt) is being used for Disk Encryption solution in Android used by Google. Also as i mentioned reverting this fix improves the RR/RW numbers so this proves the request based dm is coming into path and is being used. Sadly, that is an out of tree module. Does it still use Qcom specific APIs in its implementation (qcrypto_* funcs)? It did the last time I've checked - and the driver that implements those is not upstream either... It makes it difficult to help - which is a shame since I am interested in enabling higher performance of dm-crypt when using HW based crypto transformation myself. I have absolutely no interest in request-based dm-crypt. It is a hack to work-around limitations in crypto IV generation. I agree. This is why I've said I'm interested in a high performance dm-crypt, not "request based dm-crypt". They are trying to solve the same problem but with the wrong solution and doing so out of upstream. As the parlance of our time seems to go... sad. :-) Cheers, Gilad
Re: need to pick a solution for dm-crypt IV generation and do it! [was: Re: dm: submit stacked requests in irq enabled context]
Until we move to some latest stable kernel as Keith mentioned. On 5/11/2017 11:22 AM, Neeraj Soni wrote: Thanks for inputs folks. So shall i conclude that there is no remedy available that can be applied on 4.4 and reverting this patch is only way forward to solve the degradation? Neeraj On 5/10/2017 8:25 PM, Gilad Ben-Yossef wrote: On Wed, May 10, 2017 at 5:45 PM, Mike Snitzer wrote: On Wed, May 10 2017 at 9:37am -0400, Gilad Ben-Yossef wrote: On Wed, May 10, 2017 at 11:49 AM, Neeraj Soni wrote: Hi Keith, Request based dm (dm-req-crypt) is being used for Disk Encryption solution in Android used by Google. Also as i mentioned reverting this fix improves the RR/RW numbers so this proves the request based dm is coming into path and is being used. Sadly, that is an out of tree module. Does it still use Qcom specific APIs in its implementation (qcrypto_* funcs)? It did the last time I've checked - and the driver that implements those is not upstream either... It makes it difficult to help - which is a shame since I am interested in enabling higher performance of dm-crypt when using HW based crypto transformation myself. I have absolutely no interest in request-based dm-crypt. It is a hack to work-around limitations in crypto IV generation. I agree. This is why I've said I'm interested in a high performance dm-crypt, not "request based dm-crypt". They are trying to solve the same problem but with the wrong solution and doing so out of upstream. As the parlance of our time seems to go... sad. :-) Cheers, Gilad