lkml.org 
[lkml]   [2019]   [Jul]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 028/293] crypto: talitos - properly handle split ICV.
    Date
    [ Upstream commit eae55a586c3c8b50982bad3c3426e9c9dd7a0075 ]

    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: 9c4a79653b35 ("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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/crypto/talitos.c | 26 +++++++++++++++-----------
    1 file changed, 15 insertions(+), 11 deletions(-)

    diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
    index 8707607039d3..62dca638105d 100644
    --- a/drivers/crypto/talitos.c
    +++ b/drivers/crypto/talitos.c
    @@ -984,7 +984,6 @@ static void ipsec_esp_encrypt_done(struct device *dev,
    struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
    unsigned int authsize = crypto_aead_authsize(authenc);
    struct talitos_edesc *edesc;
    - struct scatterlist *sg;
    void *icvdata;

    edesc = container_of(desc, struct talitos_edesc, desc);
    @@ -998,9 +997,8 @@ static void ipsec_esp_encrypt_done(struct device *dev,
    else
    icvdata = &edesc->link_tbl[edesc->src_nents +
    edesc->dst_nents + 2];
    - sg = sg_last(areq->dst, edesc->dst_nents);
    - memcpy((char *)sg_virt(sg) + sg->length - authsize,
    - icvdata, authsize);
    + sg_pcopy_from_buffer(areq->dst, edesc->dst_nents ? : 1, icvdata,
    + authsize, areq->assoclen + areq->cryptlen);
    }

    kfree(edesc);
    @@ -1016,7 +1014,6 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
    struct crypto_aead *authenc = crypto_aead_reqtfm(req);
    unsigned int authsize = crypto_aead_authsize(authenc);
    struct talitos_edesc *edesc;
    - struct scatterlist *sg;
    char *oicv, *icv;
    struct talitos_private *priv = dev_get_drvdata(dev);
    bool is_sec1 = has_ftr_sec1(priv);
    @@ -1026,9 +1023,18 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
    ipsec_esp_unmap(dev, edesc, req);

    if (!err) {
    + char icvdata[SHA512_DIGEST_SIZE];
    + int nents = edesc->dst_nents ? : 1;
    + unsigned int len = req->assoclen + req->cryptlen;
    +
    /* auth check */
    - sg = sg_last(req->dst, edesc->dst_nents ? : 1);
    - icv = (char *)sg_virt(sg) + sg->length - authsize;
    + if (nents > 1) {
    + 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 (is_sec1)
    @@ -1458,7 +1464,6 @@ static int aead_decrypt(struct aead_request *req)
    struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
    struct talitos_private *priv = dev_get_drvdata(ctx->dev);
    struct talitos_edesc *edesc;
    - struct scatterlist *sg;
    void *icvdata;

    req->cryptlen -= authsize;
    @@ -1493,9 +1498,8 @@ static int aead_decrypt(struct aead_request *req)
    else
    icvdata = &edesc->link_tbl[0];

    - sg = sg_last(req->src, edesc->src_nents ? : 1);
    -
    - memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
    + sg_pcopy_to_buffer(req->src, edesc->src_nents ? : 1, icvdata, authsize,
    + req->assoclen + req->cryptlen - authsize);

    return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
    }
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-07-29 21:25    [W:4.405 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site