lkml.org 
[lkml]   [2019]   [Mar]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 009/183] crypto: rockchip - update new iv to device in multiple operations
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Zhang Zhijie <zhangzj@rock-chips.com>

    commit c1c214adcb56d36433480c8fedf772498e7e539c upstream.

    For chain mode in cipher(eg. AES-CBC/DES-CBC), the iv is continuously
    updated in the operation. The new iv value should be written to device
    register by software.

    Reported-by: Eric Biggers <ebiggers@google.com>
    Fixes: 433cd2c617bf ("crypto: rockchip - add crypto driver for rk3288")
    Cc: <stable@vger.kernel.org> # v4.5+
    Signed-off-by: Zhang Zhijie <zhangzj@rock-chips.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/crypto/rockchip/rk3288_crypto.h | 1
    drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 34 +++++++++++++++++++++
    2 files changed, 35 insertions(+)

    --- a/drivers/crypto/rockchip/rk3288_crypto.h
    +++ b/drivers/crypto/rockchip/rk3288_crypto.h
    @@ -245,6 +245,7 @@ struct rk_cipher_ctx {
    struct rk_crypto_info *dev;
    unsigned int keylen;
    u32 mode;
    + u8 iv[AES_BLOCK_SIZE];
    };

    enum alg_type {
    --- a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c
    +++ b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c
    @@ -242,6 +242,17 @@ static void crypto_dma_start(struct rk_c
    static int rk_set_data_start(struct rk_crypto_info *dev)
    {
    int err;
    + struct ablkcipher_request *req =
    + ablkcipher_request_cast(dev->async_req);
    + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
    + struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm);
    + u32 ivsize = crypto_ablkcipher_ivsize(tfm);
    + u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
    + dev->sg_src->offset + dev->sg_src->length - ivsize;
    +
    + /* store the iv that need to be updated in chain mode */
    + if (ctx->mode & RK_CRYPTO_DEC)
    + memcpy(ctx->iv, src_last_blk, ivsize);

    err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
    if (!err)
    @@ -286,6 +297,28 @@ static void rk_iv_copyback(struct rk_cry
    memcpy_fromio(req->info, dev->reg + RK_CRYPTO_AES_IV_0, ivsize);
    }

    +static void rk_update_iv(struct rk_crypto_info *dev)
    +{
    + struct ablkcipher_request *req =
    + ablkcipher_request_cast(dev->async_req);
    + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
    + struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm);
    + u32 ivsize = crypto_ablkcipher_ivsize(tfm);
    + u8 *new_iv = NULL;
    +
    + if (ctx->mode & RK_CRYPTO_DEC) {
    + new_iv = ctx->iv;
    + } else {
    + new_iv = page_address(sg_page(dev->sg_dst)) +
    + dev->sg_dst->offset + dev->sg_dst->length - ivsize;
    + }
    +
    + if (ivsize == DES_BLOCK_SIZE)
    + memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize);
    + else if (ivsize == AES_BLOCK_SIZE)
    + memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize);
    +}
    +
    /* return:
    * true some err was occurred
    * fault no err, continue
    @@ -307,6 +340,7 @@ static int rk_ablk_rx(struct rk_crypto_i
    }
    }
    if (dev->left_bytes) {
    + rk_update_iv(dev);
    if (dev->aligned) {
    if (sg_is_last(dev->sg_src)) {
    dev_err(dev->dev, "[%s:%d] Lack of data\n",

    \
     
     \ /
      Last update: 2019-03-22 13:59    [W:4.857 / U:0.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site