mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 07:04:24 +00:00
crypto: talitos - properly handle split ICV.
The driver assumes that the ICV is as a single piece in the last
element of the scatterlist. This assumption is wrong.
This patch ensures that the ICV is properly handled regardless of
the scatterlist layout.
Fixes: 9c4a79653b
("crypto: talitos - Freescale integrated security engine (SEC) driver")
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
4bbfb83925
commit
eae55a586c
1 changed files with 15 additions and 11 deletions
|
@ -1069,7 +1069,6 @@ static void ipsec_esp_encrypt_done(struct device *dev,
|
||||||
unsigned int authsize = crypto_aead_authsize(authenc);
|
unsigned int authsize = crypto_aead_authsize(authenc);
|
||||||
unsigned int ivsize = crypto_aead_ivsize(authenc);
|
unsigned int ivsize = crypto_aead_ivsize(authenc);
|
||||||
struct talitos_edesc *edesc;
|
struct talitos_edesc *edesc;
|
||||||
struct scatterlist *sg;
|
|
||||||
void *icvdata;
|
void *icvdata;
|
||||||
|
|
||||||
edesc = container_of(desc, struct talitos_edesc, desc);
|
edesc = container_of(desc, struct talitos_edesc, desc);
|
||||||
|
@ -1083,9 +1082,8 @@ static void ipsec_esp_encrypt_done(struct device *dev,
|
||||||
else
|
else
|
||||||
icvdata = &edesc->link_tbl[edesc->src_nents +
|
icvdata = &edesc->link_tbl[edesc->src_nents +
|
||||||
edesc->dst_nents + 2];
|
edesc->dst_nents + 2];
|
||||||
sg = sg_last(areq->dst, edesc->dst_nents);
|
sg_pcopy_from_buffer(areq->dst, edesc->dst_nents ? : 1, icvdata,
|
||||||
memcpy((char *)sg_virt(sg) + sg->length - authsize,
|
authsize, areq->assoclen + areq->cryptlen);
|
||||||
icvdata, authsize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
|
dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
|
||||||
|
@ -1103,7 +1101,6 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
|
||||||
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
|
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
|
||||||
unsigned int authsize = crypto_aead_authsize(authenc);
|
unsigned int authsize = crypto_aead_authsize(authenc);
|
||||||
struct talitos_edesc *edesc;
|
struct talitos_edesc *edesc;
|
||||||
struct scatterlist *sg;
|
|
||||||
char *oicv, *icv;
|
char *oicv, *icv;
|
||||||
struct talitos_private *priv = dev_get_drvdata(dev);
|
struct talitos_private *priv = dev_get_drvdata(dev);
|
||||||
bool is_sec1 = has_ftr_sec1(priv);
|
bool is_sec1 = has_ftr_sec1(priv);
|
||||||
|
@ -1113,9 +1110,18 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
|
||||||
ipsec_esp_unmap(dev, edesc, req, false);
|
ipsec_esp_unmap(dev, edesc, req, false);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
char icvdata[SHA512_DIGEST_SIZE];
|
||||||
|
int nents = edesc->dst_nents ? : 1;
|
||||||
|
unsigned int len = req->assoclen + req->cryptlen;
|
||||||
|
|
||||||
/* auth check */
|
/* auth check */
|
||||||
sg = sg_last(req->dst, edesc->dst_nents ? : 1);
|
if (nents > 1) {
|
||||||
icv = (char *)sg_virt(sg) + sg->length - authsize;
|
sg_pcopy_to_buffer(req->dst, nents, icvdata, authsize,
|
||||||
|
len - authsize);
|
||||||
|
icv = icvdata;
|
||||||
|
} else {
|
||||||
|
icv = (char *)sg_virt(req->dst) + len - authsize;
|
||||||
|
}
|
||||||
|
|
||||||
if (edesc->dma_len) {
|
if (edesc->dma_len) {
|
||||||
if (is_sec1)
|
if (is_sec1)
|
||||||
|
@ -1537,7 +1543,6 @@ static int aead_decrypt(struct aead_request *req)
|
||||||
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
|
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
|
||||||
struct talitos_private *priv = dev_get_drvdata(ctx->dev);
|
struct talitos_private *priv = dev_get_drvdata(ctx->dev);
|
||||||
struct talitos_edesc *edesc;
|
struct talitos_edesc *edesc;
|
||||||
struct scatterlist *sg;
|
|
||||||
void *icvdata;
|
void *icvdata;
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
|
@ -1571,9 +1576,8 @@ static int aead_decrypt(struct aead_request *req)
|
||||||
else
|
else
|
||||||
icvdata = &edesc->link_tbl[0];
|
icvdata = &edesc->link_tbl[0];
|
||||||
|
|
||||||
sg = sg_last(req->src, edesc->src_nents ? : 1);
|
sg_pcopy_to_buffer(req->src, edesc->src_nents ? : 1, icvdata, authsize,
|
||||||
|
req->assoclen + req->cryptlen - authsize);
|
||||||
memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
|
|
||||||
|
|
||||||
return ipsec_esp(edesc, req, false, ipsec_esp_decrypt_swauth_done);
|
return ipsec_esp(edesc, req, false, ipsec_esp_decrypt_swauth_done);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue