lkml.org 
[lkml]   [2019]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 140/159] crypto: mxs-dcp - Fix AES issues
    Date
    From: Radu Solea <radu.solea@nxp.com>

    [ Upstream commit fadd7a6e616b89c7f4f7bfa7b824f290bab32c3c ]

    The DCP driver does not obey cryptlen, when doing android CTS this
    results in passing to hardware input stream lengths which are not
    multiple of block size.

    Add a check to prevent future erroneous stream lengths from reaching the
    hardware and adjust the scatterlist walking code to obey cryptlen.

    Also properly copy-out the IV for chaining.

    Signed-off-by: Radu Solea <radu.solea@nxp.com>
    Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
    Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/crypto/mxs-dcp.c | 33 +++++++++++++++++++++++++++++++--
    1 file changed, 31 insertions(+), 2 deletions(-)

    diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c
    index 38c5dd8891138..4b82cf9da0ba7 100644
    --- a/drivers/crypto/mxs-dcp.c
    +++ b/drivers/crypto/mxs-dcp.c
    @@ -225,6 +225,12 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
    dma_addr_t dst_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_out_buf,
    DCP_BUF_SZ, DMA_FROM_DEVICE);

    + if (actx->fill % AES_BLOCK_SIZE) {
    + dev_err(sdcp->dev, "Invalid block size!\n");
    + ret = -EINVAL;
    + goto aes_done_run;
    + }
    +
    /* Fill in the DMA descriptor. */
    desc->control0 = MXS_DCP_CONTROL0_DECR_SEMAPHORE |
    MXS_DCP_CONTROL0_INTERRUPT |
    @@ -254,6 +260,7 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,

    ret = mxs_dcp_start_dma(actx);

    +aes_done_run:
    dma_unmap_single(sdcp->dev, key_phys, 2 * AES_KEYSIZE_128,
    DMA_TO_DEVICE);
    dma_unmap_single(sdcp->dev, src_phys, DCP_BUF_SZ, DMA_TO_DEVICE);
    @@ -280,13 +287,15 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)

    uint8_t *out_tmp, *src_buf, *dst_buf = NULL;
    uint32_t dst_off = 0;
    + uint32_t last_out_len = 0;

    uint8_t *key = sdcp->coh->aes_key;

    int ret = 0;
    int split = 0;
    - unsigned int i, len, clen, rem = 0;
    + unsigned int i, len, clen, rem = 0, tlen = 0;
    int init = 0;
    + bool limit_hit = false;

    actx->fill = 0;

    @@ -305,6 +314,11 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
    for_each_sg(req->src, src, nents, i) {
    src_buf = sg_virt(src);
    len = sg_dma_len(src);
    + tlen += len;
    + limit_hit = tlen > req->nbytes;
    +
    + if (limit_hit)
    + len = req->nbytes - (tlen - len);

    do {
    if (actx->fill + len > out_off)
    @@ -321,13 +335,15 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
    * If we filled the buffer or this is the last SG,
    * submit the buffer.
    */
    - if (actx->fill == out_off || sg_is_last(src)) {
    + if (actx->fill == out_off || sg_is_last(src) ||
    + limit_hit) {
    ret = mxs_dcp_run_aes(actx, req, init);
    if (ret)
    return ret;
    init = 0;

    out_tmp = out_buf;
    + last_out_len = actx->fill;
    while (dst && actx->fill) {
    if (!split) {
    dst_buf = sg_virt(dst);
    @@ -350,6 +366,19 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
    }
    }
    } while (len);
    +
    + if (limit_hit)
    + break;
    + }
    +
    + /* Copy the IV for CBC for chaining */
    + if (!rctx->ecb) {
    + if (rctx->enc)
    + memcpy(req->info, out_buf+(last_out_len-AES_BLOCK_SIZE),
    + AES_BLOCK_SIZE);
    + else
    + memcpy(req->info, in_buf+(last_out_len-AES_BLOCK_SIZE),
    + AES_BLOCK_SIZE);
    }

    return ret;
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-11-22 11:38    [W:2.638 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site