|
|
@@ -250,9 +250,14 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
|
|
|
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)
|
|
|
+ /* Store the iv that need to be updated in chain mode.
|
|
|
+ * And update the IV buffer to contain the next IV for decryption mode.
|
|
|
+ */
|
|
|
+ if (ctx->mode & RK_CRYPTO_DEC) {
|
|
|
memcpy(ctx->iv, src_last_blk, ivsize);
|
|
|
+ sg_pcopy_to_buffer(dev->first, dev->src_nents, req->info,
|
|
|
+ ivsize, dev->total - ivsize);
|
|
|
+ }
|
|
|
|
|
|
err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
|
|
|
if (!err)
|
|
|
@@ -288,13 +293,19 @@ static void rk_iv_copyback(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);
|
|
|
|
|
|
- if (ivsize == DES_BLOCK_SIZE)
|
|
|
- memcpy_fromio(req->info, dev->reg + RK_CRYPTO_TDES_IV_0,
|
|
|
- ivsize);
|
|
|
- else if (ivsize == AES_BLOCK_SIZE)
|
|
|
- memcpy_fromio(req->info, dev->reg + RK_CRYPTO_AES_IV_0, ivsize);
|
|
|
+ /* Update the IV buffer to contain the next IV for encryption mode. */
|
|
|
+ if (!(ctx->mode & RK_CRYPTO_DEC)) {
|
|
|
+ if (dev->aligned) {
|
|
|
+ memcpy(req->info, sg_virt(dev->sg_dst) +
|
|
|
+ dev->sg_dst->length - ivsize, ivsize);
|
|
|
+ } else {
|
|
|
+ memcpy(req->info, dev->addr_vir +
|
|
|
+ dev->count - ivsize, ivsize);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void rk_update_iv(struct rk_crypto_info *dev)
|