158 lines
5.7 KiB
Diff
158 lines
5.7 KiB
Diff
|
From 658c9d2b9f374c835d0348d852a3f002196628d0 Mon Sep 17 00:00:00 2001
|
||
|
From: Christian Lamparter <chunkeey@gmail.com>
|
||
|
Date: Thu, 19 Apr 2018 18:41:57 +0200
|
||
|
Subject: [PATCH 8/8] crypto: crypto4xx - put temporary dst sg into request ctx
|
||
|
|
||
|
This patch fixes a crash that happens when testing rfc4543(gcm(aes))
|
||
|
|
||
|
Unable to handle kernel paging request for data at address 0xf59b3420
|
||
|
Faulting instruction address: 0xc0012994
|
||
|
Oops: Kernel access of bad area, sig: 11 [#1]
|
||
|
BE PowerPC 44x Platform
|
||
|
Modules linked in: tcrypt(+) crypto4xx [...]
|
||
|
CPU: 0 PID: 0 Comm: swapper Tainted: G O 4.17.0-rc1+ #23
|
||
|
NIP: c0012994 LR: d3077934 CTR: 06026d49
|
||
|
REGS: cfff7e30 TRAP: 0300 Tainted: G O (4.17.0-rc1+)
|
||
|
MSR: 00029000 <CE,EE,ME> CR: 44744822 XER: 00000000
|
||
|
DEAR: f59b3420 ESR: 00000000
|
||
|
NIP [c0012994] __dma_sync+0x58/0x10c
|
||
|
LR [d3077934] crypto4xx_bh_tasklet_cb+0x188/0x3c8 [crypto4xx]
|
||
|
|
||
|
__dma_sync was fed the temporary _dst that crypto4xx_build_pd()
|
||
|
had in it's function stack. This clearly never worked.
|
||
|
This patch therefore overhauls the code from the original driver
|
||
|
and puts the temporary dst sg list into aead's request context.
|
||
|
|
||
|
Fixes: a0aae821ba3d3 ("crypto: crypto4xx - prepare for AEAD support")
|
||
|
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||
|
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||
|
---
|
||
|
drivers/crypto/amcc/crypto4xx_alg.c | 15 ++++++++-------
|
||
|
drivers/crypto/amcc/crypto4xx_core.c | 10 +++++-----
|
||
|
drivers/crypto/amcc/crypto4xx_core.h | 7 ++++++-
|
||
|
3 files changed, 19 insertions(+), 13 deletions(-)
|
||
|
|
||
|
--- a/drivers/crypto/amcc/crypto4xx_alg.c
|
||
|
+++ b/drivers/crypto/amcc/crypto4xx_alg.c
|
||
|
@@ -87,7 +87,7 @@ static inline int crypto4xx_crypt(struct
|
||
|
|
||
|
return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
|
||
|
req->cryptlen, iv, ivlen, decrypt ? ctx->sa_in : ctx->sa_out,
|
||
|
- ctx->sa_len, 0);
|
||
|
+ ctx->sa_len, 0, NULL);
|
||
|
}
|
||
|
|
||
|
int crypto4xx_encrypt_noiv(struct skcipher_request *req)
|
||
|
@@ -223,7 +223,7 @@ int crypto4xx_rfc3686_encrypt(struct skc
|
||
|
|
||
|
return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
|
||
|
req->cryptlen, iv, AES_IV_SIZE,
|
||
|
- ctx->sa_out, ctx->sa_len, 0);
|
||
|
+ ctx->sa_out, ctx->sa_len, 0, NULL);
|
||
|
}
|
||
|
|
||
|
int crypto4xx_rfc3686_decrypt(struct skcipher_request *req)
|
||
|
@@ -238,7 +238,7 @@ int crypto4xx_rfc3686_decrypt(struct skc
|
||
|
|
||
|
return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
|
||
|
req->cryptlen, iv, AES_IV_SIZE,
|
||
|
- ctx->sa_out, ctx->sa_len, 0);
|
||
|
+ ctx->sa_out, ctx->sa_len, 0, NULL);
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
@@ -449,6 +449,7 @@ int crypto4xx_setkey_aes_ccm(struct cryp
|
||
|
static int crypto4xx_crypt_aes_ccm(struct aead_request *req, bool decrypt)
|
||
|
{
|
||
|
struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
|
||
|
+ struct crypto4xx_aead_reqctx *rctx = aead_request_ctx(req);
|
||
|
struct crypto_aead *aead = crypto_aead_reqtfm(req);
|
||
|
__le32 iv[16];
|
||
|
u32 tmp_sa[SA_AES128_CCM_LEN + 4];
|
||
|
@@ -474,7 +475,7 @@ static int crypto4xx_crypt_aes_ccm(struc
|
||
|
|
||
|
return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
|
||
|
len, iv, sizeof(iv),
|
||
|
- sa, ctx->sa_len, req->assoclen);
|
||
|
+ sa, ctx->sa_len, req->assoclen, rctx->dst);
|
||
|
}
|
||
|
|
||
|
int crypto4xx_encrypt_aes_ccm(struct aead_request *req)
|
||
|
@@ -622,7 +623,7 @@ static inline int crypto4xx_crypt_aes_gc
|
||
|
return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
|
||
|
len, iv, sizeof(iv),
|
||
|
decrypt ? ctx->sa_in : ctx->sa_out,
|
||
|
- ctx->sa_len, req->assoclen);
|
||
|
+ ctx->sa_len, req->assoclen, rctx->dst);
|
||
|
}
|
||
|
|
||
|
int crypto4xx_encrypt_aes_gcm(struct aead_request *req)
|
||
|
@@ -707,7 +708,7 @@ int crypto4xx_hash_update(struct ahash_r
|
||
|
|
||
|
return crypto4xx_build_pd(&req->base, ctx, req->src, &dst,
|
||
|
req->nbytes, NULL, 0, ctx->sa_in,
|
||
|
- ctx->sa_len, 0);
|
||
|
+ ctx->sa_len, 0, NULL);
|
||
|
}
|
||
|
|
||
|
int crypto4xx_hash_final(struct ahash_request *req)
|
||
|
@@ -726,7 +727,7 @@ int crypto4xx_hash_digest(struct ahash_r
|
||
|
|
||
|
return crypto4xx_build_pd(&req->base, ctx, req->src, &dst,
|
||
|
req->nbytes, NULL, 0, ctx->sa_in,
|
||
|
- ctx->sa_len, 0);
|
||
|
+ ctx->sa_len, 0, NULL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
--- a/drivers/crypto/amcc/crypto4xx_core.c
|
||
|
+++ b/drivers/crypto/amcc/crypto4xx_core.c
|
||
|
@@ -695,9 +695,9 @@ int crypto4xx_build_pd(struct crypto_asy
|
||
|
const __le32 *iv, const u32 iv_len,
|
||
|
const struct dynamic_sa_ctl *req_sa,
|
||
|
const unsigned int sa_len,
|
||
|
- const unsigned int assoclen)
|
||
|
+ const unsigned int assoclen,
|
||
|
+ struct scatterlist *_dst)
|
||
|
{
|
||
|
- struct scatterlist _dst[2];
|
||
|
struct crypto4xx_device *dev = ctx->dev;
|
||
|
struct dynamic_sa_ctl *sa;
|
||
|
struct ce_gd *gd;
|
||
|
@@ -996,9 +996,9 @@ static int crypto4xx_aead_init(struct cr
|
||
|
|
||
|
amcc_alg = container_of(alg, struct crypto4xx_alg, alg.u.aead);
|
||
|
crypto4xx_ctx_init(amcc_alg, ctx);
|
||
|
- crypto_aead_set_reqsize(tfm, sizeof(struct aead_request) +
|
||
|
- max(sizeof(struct crypto4xx_ctx), 32 +
|
||
|
- crypto_aead_reqsize(ctx->sw_cipher.aead)));
|
||
|
+ crypto_aead_set_reqsize(tfm, max(sizeof(struct aead_request) + 32 +
|
||
|
+ crypto_aead_reqsize(ctx->sw_cipher.aead),
|
||
|
+ sizeof(struct crypto4xx_aead_reqctx)));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
--- a/drivers/crypto/amcc/crypto4xx_core.h
|
||
|
+++ b/drivers/crypto/amcc/crypto4xx_core.h
|
||
|
@@ -133,6 +133,10 @@ struct crypto4xx_ctx {
|
||
|
} sw_cipher;
|
||
|
};
|
||
|
|
||
|
+struct crypto4xx_aead_reqctx {
|
||
|
+ struct scatterlist dst[2];
|
||
|
+};
|
||
|
+
|
||
|
struct crypto4xx_alg_common {
|
||
|
u32 type;
|
||
|
union {
|
||
|
@@ -159,7 +163,8 @@ int crypto4xx_build_pd(struct crypto_asy
|
||
|
const __le32 *iv, const u32 iv_len,
|
||
|
const struct dynamic_sa_ctl *sa,
|
||
|
const unsigned int sa_len,
|
||
|
- const unsigned int assoclen);
|
||
|
+ const unsigned int assoclen,
|
||
|
+ struct scatterlist *dst_tmp);
|
||
|
int crypto4xx_setkey_aes_cbc(struct crypto_skcipher *cipher,
|
||
|
const u8 *key, unsigned int keylen);
|
||
|
int crypto4xx_setkey_aes_cfb(struct crypto_skcipher *cipher,
|