* [PATCH v3 0/2] crypto: hisilicon - fix the authsize and icv problems of aead in sec
@ 2024-11-02 2:55 Chenghai Huang
2024-11-02 2:55 ` [PATCH v3 1/2] crypto: hisilicon/sec2 - fix for aead icv error Chenghai Huang
2024-11-02 2:55 ` [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize Chenghai Huang
0 siblings, 2 replies; 7+ messages in thread
From: Chenghai Huang @ 2024-11-02 2:55 UTC (permalink / raw)
To: herbert, davem
Cc: linux-kernel, linux-crypto, liulongfang, qianweili, linwenkai6,
wangzhou1, huangchenghai2
1. Fix for aead invalid authsize.
2. Fix for aead icv error.
---
Changes in v3:
- Call crypto_aead_authsize to obtain authsize instead of
actx->authsize.
- Link to v2: https://lore.kernel.org/all/20241018105830.169212-1-huangchenghai2@huawei.com/
Changes in v2:
- Restored authsize to the tfm.
- Link to v1: https://lore.kernel.org/all/20240929112630.863282-1-huangchenghai2@huawei.com/
---
Wenkai Lin (2):
crypto: hisilicon/sec2 - fix for aead icv error
crypto: hisilicon/sec2 - fix for aead invalid authsize
drivers/crypto/hisilicon/sec2/sec.h | 1 -
drivers/crypto/hisilicon/sec2/sec_crypto.c | 156 ++++++++++-----------
drivers/crypto/hisilicon/sec2/sec_crypto.h | 11 --
3 files changed, 73 insertions(+), 95 deletions(-)
--
2.33.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 1/2] crypto: hisilicon/sec2 - fix for aead icv error
2024-11-02 2:55 [PATCH v3 0/2] crypto: hisilicon - fix the authsize and icv problems of aead in sec Chenghai Huang
@ 2024-11-02 2:55 ` Chenghai Huang
2024-11-02 2:55 ` [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize Chenghai Huang
1 sibling, 0 replies; 7+ messages in thread
From: Chenghai Huang @ 2024-11-02 2:55 UTC (permalink / raw)
To: herbert, davem
Cc: linux-kernel, linux-crypto, liulongfang, qianweili, linwenkai6,
wangzhou1, huangchenghai2
From: Wenkai Lin <linwenkai6@hisilicon.com>
When the AEAD algorithm is used for encryption or decryption,
the input authentication length varies, the hardware needs to
obtain the input length to pass the integrity check verification.
Currently, the driver uses a fixed authentication length,which
causes decryption failure, so the length configuration is modified.
In addition, the step of setting the auth length is unnecessary,
so it was deleted from the setkey function.
Fixes: 2f072d75d1ab ("crypto: hisilicon - Add aead support on SEC2")
Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com>
Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
---
drivers/crypto/hisilicon/sec2/sec.h | 1 -
drivers/crypto/hisilicon/sec2/sec_crypto.c | 101 +++++++++------------
drivers/crypto/hisilicon/sec2/sec_crypto.h | 11 ---
3 files changed, 44 insertions(+), 69 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h
index 356188bee6fb..70c3bdedb6ba 100644
--- a/drivers/crypto/hisilicon/sec2/sec.h
+++ b/drivers/crypto/hisilicon/sec2/sec.h
@@ -90,7 +90,6 @@ struct sec_auth_ctx {
dma_addr_t a_key_dma;
u8 *a_key;
u8 a_key_len;
- u8 mac_len;
u8 a_alg;
bool fallback;
struct crypto_shash *hash_tfm;
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
index ae9ebbb4103d..8db995279545 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
@@ -948,15 +948,14 @@ static int sec_aead_mac_init(struct sec_aead_req *req)
struct aead_request *aead_req = req->aead_req;
struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req);
size_t authsize = crypto_aead_authsize(tfm);
- u8 *mac_out = req->out_mac;
struct scatterlist *sgl = aead_req->src;
+ u8 *mac_out = req->out_mac;
size_t copy_size;
off_t skip_size;
/* Copy input mac */
skip_size = aead_req->assoclen + aead_req->cryptlen - authsize;
- copy_size = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac_out,
- authsize, skip_size);
+ copy_size = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac_out, authsize, skip_size);
if (unlikely(copy_size != authsize))
return -EINVAL;
@@ -1139,7 +1138,6 @@ static int sec_aead_fallback_setkey(struct sec_auth_ctx *a_ctx,
static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
const u32 keylen, const enum sec_hash_alg a_alg,
const enum sec_calg c_alg,
- const enum sec_mac_len mac_len,
const enum sec_cmode c_mode)
{
struct sec_ctx *ctx = crypto_aead_ctx(tfm);
@@ -1151,7 +1149,6 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
ctx->a_ctx.a_alg = a_alg;
ctx->c_ctx.c_alg = c_alg;
- ctx->a_ctx.mac_len = mac_len;
c_ctx->c_mode = c_mode;
if (c_mode == SEC_CMODE_CCM || c_mode == SEC_CMODE_GCM) {
@@ -1187,10 +1184,9 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
goto bad_key;
}
- if ((ctx->a_ctx.mac_len & SEC_SQE_LEN_RATE_MASK) ||
- (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK)) {
+ if (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK) {
ret = -EINVAL;
- dev_err(dev, "MAC or AUTH key length error!\n");
+ dev_err(dev, "AUTH key length error!\n");
goto bad_key;
}
@@ -1202,27 +1198,19 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
}
-#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, maclen, cmode) \
-static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key, \
- u32 keylen) \
-{ \
- return sec_aead_setkey(tfm, key, keylen, aalg, calg, maclen, cmode);\
-}
-
-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1,
- SEC_CALG_AES, SEC_HMAC_SHA1_MAC, SEC_CMODE_CBC)
-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256,
- SEC_CALG_AES, SEC_HMAC_SHA256_MAC, SEC_CMODE_CBC)
-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512,
- SEC_CALG_AES, SEC_HMAC_SHA512_MAC, SEC_CMODE_CBC)
-GEN_SEC_AEAD_SETKEY_FUNC(aes_ccm, 0, SEC_CALG_AES,
- SEC_HMAC_CCM_MAC, SEC_CMODE_CCM)
-GEN_SEC_AEAD_SETKEY_FUNC(aes_gcm, 0, SEC_CALG_AES,
- SEC_HMAC_GCM_MAC, SEC_CMODE_GCM)
-GEN_SEC_AEAD_SETKEY_FUNC(sm4_ccm, 0, SEC_CALG_SM4,
- SEC_HMAC_CCM_MAC, SEC_CMODE_CCM)
-GEN_SEC_AEAD_SETKEY_FUNC(sm4_gcm, 0, SEC_CALG_SM4,
- SEC_HMAC_GCM_MAC, SEC_CMODE_GCM)
+#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, cmode) \
+static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key, u32 keylen) \
+{ \
+ return sec_aead_setkey(tfm, key, keylen, aalg, calg, cmode); \
+}
+
+GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1, SEC_CALG_AES, SEC_CMODE_CBC)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256, SEC_CALG_AES, SEC_CMODE_CBC)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512, SEC_CALG_AES, SEC_CMODE_CBC)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_ccm, 0, SEC_CALG_AES, SEC_CMODE_CCM)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_gcm, 0, SEC_CALG_AES, SEC_CMODE_GCM)
+GEN_SEC_AEAD_SETKEY_FUNC(sm4_ccm, 0, SEC_CALG_SM4, SEC_CMODE_CCM)
+GEN_SEC_AEAD_SETKEY_FUNC(sm4_gcm, 0, SEC_CALG_SM4, SEC_CMODE_GCM)
static int sec_aead_sgl_map(struct sec_ctx *ctx, struct sec_req *req)
{
@@ -1470,9 +1458,10 @@ static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req,
static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req)
{
struct aead_request *aead_req = req->aead_req.aead_req;
- struct sec_cipher_req *c_req = &req->c_req;
+ struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req);
+ size_t authsize = crypto_aead_authsize(tfm);
struct sec_aead_req *a_req = &req->aead_req;
- size_t authsize = ctx->a_ctx.mac_len;
+ struct sec_cipher_req *c_req = &req->c_req;
u32 data_size = aead_req->cryptlen;
u8 flage = 0;
u8 cm, cl;
@@ -1513,10 +1502,8 @@ static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req)
static void sec_aead_set_iv(struct sec_ctx *ctx, struct sec_req *req)
{
struct aead_request *aead_req = req->aead_req.aead_req;
- struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req);
- size_t authsize = crypto_aead_authsize(tfm);
- struct sec_cipher_req *c_req = &req->c_req;
struct sec_aead_req *a_req = &req->aead_req;
+ struct sec_cipher_req *c_req = &req->c_req;
memcpy(c_req->c_ivin, aead_req->iv, ctx->c_ctx.ivsize);
@@ -1524,15 +1511,11 @@ static void sec_aead_set_iv(struct sec_ctx *ctx, struct sec_req *req)
/*
* CCM 16Byte Cipher_IV: {1B_Flage,13B_IV,2B_counter},
* the counter must set to 0x01
+ * CCM 16Byte Auth_IV: {1B_AFlage,13B_IV,2B_Ptext_length}
*/
- ctx->a_ctx.mac_len = authsize;
- /* CCM 16Byte Auth_IV: {1B_AFlage,13B_IV,2B_Ptext_length} */
set_aead_auth_iv(ctx, req);
- }
-
- /* GCM 12Byte Cipher_IV == Auth_IV */
- if (ctx->c_ctx.c_mode == SEC_CMODE_GCM) {
- ctx->a_ctx.mac_len = authsize;
+ } else if (ctx->c_ctx.c_mode == SEC_CMODE_GCM) {
+ /* GCM 12Byte Cipher_IV == Auth_IV */
memcpy(a_req->a_ivin, c_req->c_ivin, SEC_AIV_SIZE);
}
}
@@ -1542,9 +1525,11 @@ static void sec_auth_bd_fill_xcm(struct sec_auth_ctx *ctx, int dir,
{
struct sec_aead_req *a_req = &req->aead_req;
struct aead_request *aq = a_req->aead_req;
+ struct crypto_aead *tfm = crypto_aead_reqtfm(aq);
+ size_t authsize = crypto_aead_authsize(tfm);
/* C_ICV_Len is MAC size, 0x4 ~ 0x10 */
- sec_sqe->type2.icvw_kmode |= cpu_to_le16((u16)ctx->mac_len);
+ sec_sqe->type2.icvw_kmode |= cpu_to_le16((u16)authsize);
/* mode set to CCM/GCM, don't set {A_Alg, AKey_Len, MAC_Len} */
sec_sqe->type2.a_key_addr = sec_sqe->type2.c_key_addr;
@@ -1568,9 +1553,11 @@ static void sec_auth_bd_fill_xcm_v3(struct sec_auth_ctx *ctx, int dir,
{
struct sec_aead_req *a_req = &req->aead_req;
struct aead_request *aq = a_req->aead_req;
+ struct crypto_aead *tfm = crypto_aead_reqtfm(aq);
+ size_t authsize = crypto_aead_authsize(tfm);
/* C_ICV_Len is MAC size, 0x4 ~ 0x10 */
- sqe3->c_icv_key |= cpu_to_le16((u16)ctx->mac_len << SEC_MAC_OFFSET_V3);
+ sqe3->c_icv_key |= cpu_to_le16((u16)authsize << SEC_MAC_OFFSET_V3);
/* mode set to CCM/GCM, don't set {A_Alg, AKey_Len, MAC_Len} */
sqe3->a_key_addr = sqe3->c_key_addr;
@@ -1594,11 +1581,12 @@ static void sec_auth_bd_fill_ex(struct sec_auth_ctx *ctx, int dir,
struct sec_aead_req *a_req = &req->aead_req;
struct sec_cipher_req *c_req = &req->c_req;
struct aead_request *aq = a_req->aead_req;
+ struct crypto_aead *tfm = crypto_aead_reqtfm(aq);
+ size_t authsize = crypto_aead_authsize(tfm);
sec_sqe->type2.a_key_addr = cpu_to_le64(ctx->a_key_dma);
- sec_sqe->type2.mac_key_alg =
- cpu_to_le32(ctx->mac_len / SEC_SQE_LEN_RATE);
+ sec_sqe->type2.mac_key_alg = cpu_to_le32(authsize / SEC_SQE_LEN_RATE);
sec_sqe->type2.mac_key_alg |=
cpu_to_le32((u32)((ctx->a_key_len) /
@@ -1648,11 +1636,13 @@ static void sec_auth_bd_fill_ex_v3(struct sec_auth_ctx *ctx, int dir,
struct sec_aead_req *a_req = &req->aead_req;
struct sec_cipher_req *c_req = &req->c_req;
struct aead_request *aq = a_req->aead_req;
+ struct crypto_aead *tfm = crypto_aead_reqtfm(aq);
+ size_t authsize = crypto_aead_authsize(tfm);
sqe3->a_key_addr = cpu_to_le64(ctx->a_key_dma);
sqe3->auth_mac_key |=
- cpu_to_le32((u32)(ctx->mac_len /
+ cpu_to_le32((u32)(authsize /
SEC_SQE_LEN_RATE) << SEC_MAC_OFFSET_V3);
sqe3->auth_mac_key |=
@@ -1703,9 +1693,9 @@ static void sec_aead_callback(struct sec_ctx *c, struct sec_req *req, int err)
{
struct aead_request *a_req = req->aead_req.aead_req;
struct crypto_aead *tfm = crypto_aead_reqtfm(a_req);
+ size_t authsize = crypto_aead_authsize(tfm);
struct sec_aead_req *aead_req = &req->aead_req;
struct sec_cipher_req *c_req = &req->c_req;
- size_t authsize = crypto_aead_authsize(tfm);
struct sec_qp_ctx *qp_ctx = req->qp_ctx;
struct aead_request *backlog_aead_req;
struct sec_req *backlog_req;
@@ -1718,10 +1708,8 @@ static void sec_aead_callback(struct sec_ctx *c, struct sec_req *req, int err)
if (!err && c_req->encrypt) {
struct scatterlist *sgl = a_req->dst;
- sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl),
- aead_req->out_mac,
- authsize, a_req->cryptlen +
- a_req->assoclen);
+ sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl), aead_req->out_mac,
+ authsize, a_req->cryptlen + a_req->assoclen);
if (unlikely(sz != authsize)) {
dev_err(c->dev, "copy out mac err!\n");
err = -EINVAL;
@@ -2233,7 +2221,7 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
{
struct aead_request *req = sreq->aead_req.aead_req;
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
- size_t authsize = crypto_aead_authsize(tfm);
+ size_t sz = crypto_aead_authsize(tfm);
u8 c_mode = ctx->c_ctx.c_mode;
struct device *dev = ctx->dev;
int ret;
@@ -2244,9 +2232,8 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
return -EINVAL;
}
- if (unlikely((c_mode == SEC_CMODE_GCM && authsize < DES_BLOCK_SIZE) ||
- (c_mode == SEC_CMODE_CCM && (authsize < MIN_MAC_LEN ||
- authsize & MAC_LEN_MASK)))) {
+ if (unlikely((c_mode == SEC_CMODE_GCM && sz < DES_BLOCK_SIZE) ||
+ (c_mode == SEC_CMODE_CCM && (sz < MIN_MAC_LEN || sz & MAC_LEN_MASK)))) {
dev_err(dev, "aead input mac length error!\n");
return -EINVAL;
}
@@ -2266,7 +2253,7 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
if (sreq->c_req.encrypt)
sreq->c_req.c_len = req->cryptlen;
else
- sreq->c_req.c_len = req->cryptlen - authsize;
+ sreq->c_req.c_len = req->cryptlen - sz;
if (c_mode == SEC_CMODE_CBC) {
if (unlikely(sreq->c_req.c_len & (AES_BLOCK_SIZE - 1))) {
dev_err(dev, "aead crypto length error!\n");
@@ -2292,7 +2279,7 @@ static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
if (ctx->sec->qm.ver == QM_HW_V2) {
if (unlikely(!req->cryptlen || (!sreq->c_req.encrypt &&
- req->cryptlen <= authsize))) {
+ req->cryptlen <= authsize))) {
ctx->a_ctx.fallback = true;
return -EINVAL;
}
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.h b/drivers/crypto/hisilicon/sec2/sec_crypto.h
index 27a0ee5ad913..04725b514382 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.h
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.h
@@ -23,17 +23,6 @@ enum sec_hash_alg {
SEC_A_HMAC_SHA512 = 0x15,
};
-enum sec_mac_len {
- SEC_HMAC_CCM_MAC = 16,
- SEC_HMAC_GCM_MAC = 16,
- SEC_SM3_MAC = 32,
- SEC_HMAC_SM3_MAC = 32,
- SEC_HMAC_MD5_MAC = 16,
- SEC_HMAC_SHA1_MAC = 20,
- SEC_HMAC_SHA256_MAC = 32,
- SEC_HMAC_SHA512_MAC = 64,
-};
-
enum sec_cmode {
SEC_CMODE_ECB = 0x0,
SEC_CMODE_CBC = 0x1,
--
2.33.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize
2024-11-02 2:55 [PATCH v3 0/2] crypto: hisilicon - fix the authsize and icv problems of aead in sec Chenghai Huang
2024-11-02 2:55 ` [PATCH v3 1/2] crypto: hisilicon/sec2 - fix for aead icv error Chenghai Huang
@ 2024-11-02 2:55 ` Chenghai Huang
2024-11-10 3:36 ` Herbert Xu
1 sibling, 1 reply; 7+ messages in thread
From: Chenghai Huang @ 2024-11-02 2:55 UTC (permalink / raw)
To: herbert, davem
Cc: linux-kernel, linux-crypto, liulongfang, qianweili, linwenkai6,
wangzhou1, huangchenghai2
From: Wenkai Lin <linwenkai6@hisilicon.com>
When the digest alg is HMAC-SHAx or another, the authsize may be less
than 4 bytes and mac_len of the BD is set to zero, the hardware considers
it a BD configuration error and reports a ras error, so the sec driver
needs to switch to software calculation in this case, this patch add a
check for it and remove unnecessary check that has been done by crypto.
Fixes: 2f072d75d1ab ("crypto: hisilicon - Add aead support on SEC2")
Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com>
Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
---
drivers/crypto/hisilicon/sec2/sec_crypto.c | 59 ++++++++++++----------
1 file changed, 31 insertions(+), 28 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
index 8db995279545..2d260cdda584 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
@@ -1119,10 +1119,7 @@ static int sec_aead_setauthsize(struct crypto_aead *aead, unsigned int authsize)
struct sec_ctx *ctx = crypto_tfm_ctx(tfm);
struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
- if (unlikely(a_ctx->fallback_aead_tfm))
- return crypto_aead_setauthsize(a_ctx->fallback_aead_tfm, authsize);
-
- return 0;
+ return crypto_aead_setauthsize(a_ctx->fallback_aead_tfm, authsize);
}
static int sec_aead_fallback_setkey(struct sec_auth_ctx *a_ctx,
@@ -1159,13 +1156,7 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
}
memcpy(c_ctx->c_key, key, keylen);
- if (unlikely(a_ctx->fallback_aead_tfm)) {
- ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen);
- if (ret)
- return ret;
- }
-
- return 0;
+ return sec_aead_fallback_setkey(a_ctx, tfm, key, keylen);
}
ret = crypto_authenc_extractkeys(&keys, key, keylen);
@@ -1190,6 +1181,12 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
goto bad_key;
}
+ ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen);
+ if (ret) {
+ dev_err(dev, "set sec fallback key err!\n");
+ goto bad_key;
+ }
+
return 0;
bad_key:
@@ -1917,8 +1914,10 @@ static void sec_aead_exit(struct crypto_aead *tfm)
static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name)
{
+ struct aead_alg *alg = crypto_aead_alg(tfm);
struct sec_ctx *ctx = crypto_aead_ctx(tfm);
- struct sec_auth_ctx *auth_ctx = &ctx->a_ctx;
+ struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
+ const char *aead_name = alg->base.cra_name;
int ret;
ret = sec_aead_init(tfm);
@@ -1927,12 +1926,22 @@ static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name)
return ret;
}
- auth_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0);
- if (IS_ERR(auth_ctx->hash_tfm)) {
+ a_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0);
+ if (IS_ERR(a_ctx->hash_tfm)) {
dev_err(ctx->dev, "aead alloc shash error!\n");
sec_aead_exit(tfm);
- return PTR_ERR(auth_ctx->hash_tfm);
+ return PTR_ERR(a_ctx->hash_tfm);
+ }
+
+ a_ctx->fallback_aead_tfm = crypto_alloc_aead(aead_name, 0,
+ CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_ASYNC);
+ if (IS_ERR(a_ctx->fallback_aead_tfm)) {
+ dev_err(ctx->dev, "aead driver alloc fallback tfm error!\n");
+ crypto_free_shash(ctx->a_ctx.hash_tfm);
+ sec_aead_exit(tfm);
+ return PTR_ERR(a_ctx->fallback_aead_tfm);
}
+ a_ctx->fallback = false;
return 0;
}
@@ -1941,6 +1950,7 @@ static void sec_aead_ctx_exit(struct crypto_aead *tfm)
{
struct sec_ctx *ctx = crypto_aead_ctx(tfm);
+ crypto_free_aead(ctx->a_ctx.fallback_aead_tfm);
crypto_free_shash(ctx->a_ctx.hash_tfm);
sec_aead_exit(tfm);
}
@@ -2226,15 +2236,15 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
struct device *dev = ctx->dev;
int ret;
- if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN ||
- req->assoclen > SEC_MAX_AAD_LEN)) {
- dev_err(dev, "aead input spec error!\n");
+ /* Hardware does not handle cases where authsize is less than 4 bytes */
+ if (unlikely(sz < MIN_MAC_LEN)) {
+ ctx->a_ctx.fallback = true;
return -EINVAL;
}
- if (unlikely((c_mode == SEC_CMODE_GCM && sz < DES_BLOCK_SIZE) ||
- (c_mode == SEC_CMODE_CCM && (sz < MIN_MAC_LEN || sz & MAC_LEN_MASK)))) {
- dev_err(dev, "aead input mac length error!\n");
+ if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN ||
+ req->assoclen > SEC_MAX_AAD_LEN)) {
+ dev_err(dev, "aead input spec error!\n");
return -EINVAL;
}
@@ -2308,16 +2318,9 @@ static int sec_aead_soft_crypto(struct sec_ctx *ctx,
bool encrypt)
{
struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
- struct device *dev = ctx->dev;
struct aead_request *subreq;
int ret;
- /* Kunpeng920 aead mode not support input 0 size */
- if (!a_ctx->fallback_aead_tfm) {
- dev_err(dev, "aead fallback tfm is NULL!\n");
- return -EINVAL;
- }
-
subreq = aead_request_alloc(a_ctx->fallback_aead_tfm, GFP_KERNEL);
if (!subreq)
return -ENOMEM;
--
2.33.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize
2024-11-02 2:55 ` [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize Chenghai Huang
@ 2024-11-10 3:36 ` Herbert Xu
2024-11-12 2:46 ` linwenkai (C)
2024-11-14 12:47 ` linwenkai (C)
0 siblings, 2 replies; 7+ messages in thread
From: Herbert Xu @ 2024-11-10 3:36 UTC (permalink / raw)
To: Chenghai Huang
Cc: davem, linux-kernel, linux-crypto, liulongfang, qianweili,
linwenkai6, wangzhou1
On Sat, Nov 02, 2024 at 10:55:59AM +0800, Chenghai Huang wrote:
>
> @@ -2226,15 +2236,15 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
> struct device *dev = ctx->dev;
> int ret;
>
> - if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN ||
> - req->assoclen > SEC_MAX_AAD_LEN)) {
> - dev_err(dev, "aead input spec error!\n");
> + /* Hardware does not handle cases where authsize is less than 4 bytes */
> + if (unlikely(sz < MIN_MAC_LEN)) {
> + ctx->a_ctx.fallback = true;
This is broken. sec_aead_spec_check is a per-request function,
called without any locking. Therefore it must not modify any
field in the tfm context (at least not without additional locking),
because multiple requests can be issued on the same tfm at any time.
I suppose for this field in particular you could move it to
set_authsize and there it would be safe to change the tfm context.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize
2024-11-10 3:36 ` Herbert Xu
@ 2024-11-12 2:46 ` linwenkai (C)
2024-11-14 12:47 ` linwenkai (C)
1 sibling, 0 replies; 7+ messages in thread
From: linwenkai (C) @ 2024-11-12 2:46 UTC (permalink / raw)
To: Herbert Xu, Chenghai Huang
Cc: davem, linux-kernel, linux-crypto, liulongfang, qianweili,
wangzhou1
在 2024/11/10 11:36, Herbert Xu 写道:
> On Sat, Nov 02, 2024 at 10:55:59AM +0800, Chenghai Huang wrote:
>> @@ -2226,15 +2236,15 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
>> struct device *dev = ctx->dev;
>> int ret;
>>
>> - if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN ||
>> - req->assoclen > SEC_MAX_AAD_LEN)) {
>> - dev_err(dev, "aead input spec error!\n");
>> + /* Hardware does not handle cases where authsize is less than 4 bytes */
>> + if (unlikely(sz < MIN_MAC_LEN)) {
>> + ctx->a_ctx.fallback = true;
> This is broken. sec_aead_spec_check is a per-request function,
> called without any locking. Therefore it must not modify any
> field in the tfm context (at least not without additional locking),
> because multiple requests can be issued on the same tfm at any time.
>
> I suppose for this field in particular you could move it to
> set_authsize and there it would be safe to change the tfm context.
>
> Cheers,
Hi,
Thanks for your advice, it's better to move the setup to set_authsize, I
will send a new patchset soon.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize
2024-11-10 3:36 ` Herbert Xu
2024-11-12 2:46 ` linwenkai (C)
@ 2024-11-14 12:47 ` linwenkai (C)
2024-11-15 2:09 ` Herbert Xu
1 sibling, 1 reply; 7+ messages in thread
From: linwenkai (C) @ 2024-11-14 12:47 UTC (permalink / raw)
To: Herbert Xu, Chenghai Huang
Cc: davem, linux-kernel, linux-crypto, liulongfang, qianweili,
wangzhou1
在 2024/11/10 11:36, Herbert Xu 写道:
> On Sat, Nov 02, 2024 at 10:55:59AM +0800, Chenghai Huang wrote:
>> @@ -2226,15 +2236,15 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
>> struct device *dev = ctx->dev;
>> int ret;
>>
>> - if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN ||
>> - req->assoclen > SEC_MAX_AAD_LEN)) {
>> - dev_err(dev, "aead input spec error!\n");
>> + /* Hardware does not handle cases where authsize is less than 4 bytes */
>> + if (unlikely(sz < MIN_MAC_LEN)) {
>> + ctx->a_ctx.fallback = true;
> This is broken. sec_aead_spec_check is a per-request function,
> called without any locking. Therefore it must not modify any
> field in the tfm context (at least not without additional locking),
> because multiple requests can be issued on the same tfm at any time.
>
> I suppose for this field in particular you could move it to
> set_authsize and there it would be safe to change the tfm context.
>
> Cheers,
Hi,
I have found another setup for fallback in the sec_aead_param_check
function, so I need to fix it right too.
The orignal code:
static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
{
if (ctx->sec->qm.ver == QM_HW_V2) {
if (unlikely(!req->cryptlen || (!sreq->c_req.encrypt &&
req->cryptlen <= authsize))) {
ctx->a_ctx.fallback = true;
return -EINVAL;
}
}
}
After the modification, I used a temporary variable fallback to save the
state:
static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req
*sreq, bool *fallback)
{
if (ctx->sec->qm.ver == QM_HW_V2) {
if (unlikely(!req->cryptlen || (!sreq->c_req.encrypt &&
req->cryptlen <= authsize))) {
*fallback = true;
return -EINVAL;
}
}
}
Same with the sec_aead_spec_check function.
static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req
*sreq, bool *fallback) {
/* Hardware does not handle cases where authsize is less than 4
bytes */
if (unlikely(sz < MIN_MAC_LEN)) {
*fallback = true;
return -EINVAL;
}
}
Do you think it is a better way?
Thanks,
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize
2024-11-14 12:47 ` linwenkai (C)
@ 2024-11-15 2:09 ` Herbert Xu
0 siblings, 0 replies; 7+ messages in thread
From: Herbert Xu @ 2024-11-15 2:09 UTC (permalink / raw)
To: linwenkai (C)
Cc: Chenghai Huang, davem, linux-kernel, linux-crypto, liulongfang,
qianweili, wangzhou1
On Thu, Nov 14, 2024 at 08:47:11PM +0800, linwenkai (C) wrote:
>
> I have found another setup for fallback in the sec_aead_param_check
> function, so I need to fix it right too.
So you want to determine whether to use the fallback based on
the parameters of the request. In that case I think you should
create a new fallback field in the request context. Set its
initial value to that of the tfm context fallback variable, and
then modify it based on the request parameters.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-11-15 2:09 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-02 2:55 [PATCH v3 0/2] crypto: hisilicon - fix the authsize and icv problems of aead in sec Chenghai Huang
2024-11-02 2:55 ` [PATCH v3 1/2] crypto: hisilicon/sec2 - fix for aead icv error Chenghai Huang
2024-11-02 2:55 ` [PATCH v3 2/2] crypto: hisilicon/sec2 - fix for aead invalid authsize Chenghai Huang
2024-11-10 3:36 ` Herbert Xu
2024-11-12 2:46 ` linwenkai (C)
2024-11-14 12:47 ` linwenkai (C)
2024-11-15 2:09 ` Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox