From df3d95db4d1886737ab50aa050e9e345048d99da Mon Sep 17 00:00:00 2001 From: Lin Jinhan Date: Fri, 3 Jul 2020 14:19:00 +0800 Subject: [PATCH] crypto: rockchip - add cfb/ofb/ctr mode for crypto v2 des : cfb/ofb des3_ede : cfb/ofb aes : cfb/ctr sm4 : cfb/ofb/ctr Change-Id: Idf0813785f4e629f14a5cd234fc211a9fa7b4ef3 Signed-off-by: Lin Jinhan --- drivers/crypto/Kconfig | 2 + drivers/crypto/rockchip/rk_crypto_core.c | 18 ++++-- drivers/crypto/rockchip/rk_crypto_core.h | 3 + drivers/crypto/rockchip/rk_crypto_v2.h | 11 ++++ .../crypto/rockchip/rk_crypto_v2_ablkcipher.c | 62 +++++++++++++++++-- 5 files changed, 88 insertions(+), 8 deletions(-) diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index f7be4cb1e276..12905719eb64 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -648,6 +648,8 @@ config CRYPTO_DEV_ROCKCHIP select CRYPTO_ECB select CRYPTO_CBC select CRYPTO_XTS + select CRYPTO_CFB + select CRYPTO_CTR select CRYPTO_DES select CRYPTO_MD5 select CRYPTO_SHA1 diff --git a/drivers/crypto/rockchip/rk_crypto_core.c b/drivers/crypto/rockchip/rk_crypto_core.c index 0005f09290e1..d26787e34d3d 100644 --- a/drivers/crypto/rockchip/rk_crypto_core.c +++ b/drivers/crypto/rockchip/rk_crypto_core.c @@ -379,16 +379,26 @@ static struct rk_crypto_tmp *crypto_v2_algs[] = { &rk_v2_ecb_sm4_alg, /* ecb(sm4) */ &rk_v2_cbc_sm4_alg, /* cbc(sm4) */ &rk_v2_xts_sm4_alg, /* xts(sm4) */ + &rk_v2_cfb_sm4_alg, /* cfb(sm4) */ + &rk_v2_ofb_sm4_alg, /* ofb(sm4) */ + &rk_v2_ctr_sm4_alg, /* ctr(sm4) */ &rk_v2_ecb_aes_alg, /* ecb(aes) */ &rk_v2_cbc_aes_alg, /* cbc(aes) */ &rk_v2_xts_aes_alg, /* xts(aes) */ + &rk_v2_cfb_aes_alg, /* cfb(aes) */ + &rk_v2_ofb_aes_alg, /* ofb(aes) */ + &rk_v2_ctr_aes_alg, /* ctr(aes) */ &rk_v2_ecb_des_alg, /* ecb(des) */ &rk_v2_cbc_des_alg, /* cbc(des) */ + &rk_v2_cfb_des_alg, /* cfb(des) */ + &rk_v2_ofb_des_alg, /* ofb(des) */ &rk_v2_ecb_des3_ede_alg, /* ecb(des3_ede) */ &rk_v2_cbc_des3_ede_alg, /* cbc(des3_ede) */ + &rk_v2_cfb_des3_ede_alg, /* cfb(des3_ede) */ + &rk_v2_ofb_des3_ede_alg, /* ofb(des3_ede) */ &rk_v2_ahash_sha1, /* sha1 */ &rk_v2_ahash_sha256, /* sha256 */ @@ -411,10 +421,10 @@ static char *px30_algs_name[] = { }; static char *rv1126_algs_name[] = { - "ecb(sm4)", "cbc(sm4)", "xts(sm4)", - "ecb(aes)", "cbc(aes)", "xts(aes)", - "ecb(des)", "cbc(des)", - "ecb(des3_ede)", "cbc(des3_ede)", + "ecb(sm4)", "cbc(sm4)", "cfb(sm4)", "ofb(sm4)", "ctr(sm4)", "xts(sm4)", + "ecb(aes)", "cbc(aes)", "cfb(aes)", "ctr(aes)", "xts(aes)", + "ecb(des)", "cbc(des)", "cfb(des)", "ofb(des)", + "ecb(des3_ede)", "cbc(des3_ede)", "cfb(des3_ede)", "ofb(des3_ede)", "sha1", "sha256", "sha512", "md5", "sm3", "hmac(sha1)", "hmac(sha256)", "hmac(sha512)", "hmac(md5)", "hmac(sm3)", }; diff --git a/drivers/crypto/rockchip/rk_crypto_core.h b/drivers/crypto/rockchip/rk_crypto_core.h index 67864c09191b..1b19a3d22e0d 100644 --- a/drivers/crypto/rockchip/rk_crypto_core.h +++ b/drivers/crypto/rockchip/rk_crypto_core.h @@ -145,6 +145,9 @@ enum rk_cipher_algo { enum rk_cipher_mode { CIPHER_MODE_ECB, CIPHER_MODE_CBC, + CIPHER_MODE_CFB, + CIPHER_MODE_OFB, + CIPHER_MODE_CTR, CIPHER_MODE_XTS, }; diff --git a/drivers/crypto/rockchip/rk_crypto_v2.h b/drivers/crypto/rockchip/rk_crypto_v2.h index 7999a10fd58e..49d7b6cf56a7 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2.h +++ b/drivers/crypto/rockchip/rk_crypto_v2.h @@ -26,15 +26,26 @@ struct rk_hw_crypto_v2_info { extern struct rk_crypto_tmp rk_v2_ecb_sm4_alg; extern struct rk_crypto_tmp rk_v2_cbc_sm4_alg; extern struct rk_crypto_tmp rk_v2_xts_sm4_alg; +extern struct rk_crypto_tmp rk_v2_cfb_sm4_alg; +extern struct rk_crypto_tmp rk_v2_ofb_sm4_alg; +extern struct rk_crypto_tmp rk_v2_ctr_sm4_alg; + extern struct rk_crypto_tmp rk_v2_ecb_aes_alg; extern struct rk_crypto_tmp rk_v2_cbc_aes_alg; extern struct rk_crypto_tmp rk_v2_xts_aes_alg; +extern struct rk_crypto_tmp rk_v2_cfb_aes_alg; +extern struct rk_crypto_tmp rk_v2_ofb_aes_alg; +extern struct rk_crypto_tmp rk_v2_ctr_aes_alg; extern struct rk_crypto_tmp rk_v2_ecb_des_alg; extern struct rk_crypto_tmp rk_v2_cbc_des_alg; +extern struct rk_crypto_tmp rk_v2_cfb_des_alg; +extern struct rk_crypto_tmp rk_v2_ofb_des_alg; extern struct rk_crypto_tmp rk_v2_ecb_des3_ede_alg; extern struct rk_crypto_tmp rk_v2_cbc_des3_ede_alg; +extern struct rk_crypto_tmp rk_v2_cfb_des3_ede_alg; +extern struct rk_crypto_tmp rk_v2_ofb_des3_ede_alg; extern struct rk_crypto_tmp rk_v2_ahash_sha1; extern struct rk_crypto_tmp rk_v2_ahash_sha256; diff --git a/drivers/crypto/rockchip/rk_crypto_v2_ablkcipher.c b/drivers/crypto/rockchip/rk_crypto_v2_ablkcipher.c index 033b50a3fc97..f2d61ba09d55 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2_ablkcipher.c +++ b/drivers/crypto/rockchip/rk_crypto_v2_ablkcipher.c @@ -29,6 +29,9 @@ static const u32 cipher_algo2bc[] = { static const u32 cipher_mode2bc[] = { [CIPHER_MODE_ECB] = CRYPTO_BC_ECB, [CIPHER_MODE_CBC] = CRYPTO_BC_CBC, + [CIPHER_MODE_CFB] = CRYPTO_BC_CFB, + [CIPHER_MODE_OFB] = CRYPTO_BC_OFB, + [CIPHER_MODE_CTR] = CRYPTO_BC_CTR, [CIPHER_MODE_XTS] = CRYPTO_BC_XTS, }; @@ -160,6 +163,18 @@ static bool is_use_fallback(struct rk_cipher_ctx *ctx) return ctx->keylen == AES_KEYSIZE_192 && ctx->fallback_tfm; } +static bool is_no_multi_blocksize(struct rk_crypto_info *dev) +{ + struct ablkcipher_request *req = + ablkcipher_request_cast(dev->async_req); + struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); + struct rk_crypto_tmp *algt = rk_cipher_get_algt(cipher); + + return (algt->mode == CIPHER_MODE_CFB || + algt->mode == CIPHER_MODE_OFB || + algt->mode == CIPHER_MODE_CTR) ? true : false; +} + static void rk_crypto_complete(struct crypto_async_request *base, int err) { if (base->complete) @@ -169,7 +184,8 @@ static void rk_crypto_complete(struct crypto_async_request *base, int err) static int rk_handle_req(struct rk_crypto_info *dev, struct ablkcipher_request *req) { - if (!IS_ALIGNED(req->nbytes, dev->align_size)) + if (!IS_ALIGNED(req->nbytes, dev->align_size) && + !is_no_multi_blocksize(dev)) return -EINVAL; else return dev->enqueue(dev, &req->base); @@ -354,13 +370,21 @@ static void crypto_dma_start(struct rk_crypto_info *dev) { struct rk_hw_crypto_v2_info *hw_info = (struct rk_hw_crypto_v2_info *)dev->hw_info; + u32 calc_len = dev->count; memset(hw_info->desc, 0x00, sizeof(*hw_info->desc)); + /* + * the data length is not aligned will use addr_vir to calculate, + * so crypto v2 could round up date date length to align_size + */ + if (is_no_multi_blocksize(dev)) + calc_len = round_up(calc_len, dev->align_size); + hw_info->desc->src_addr = dev->addr_in; - hw_info->desc->src_len = dev->count; + hw_info->desc->src_len = calc_len; hw_info->desc->dst_addr = dev->addr_out; - hw_info->desc->dst_len = dev->count; + hw_info->desc->dst_len = calc_len; hw_info->desc->next_addr = 0; hw_info->desc->dma_ctrl = 0x00000201; hw_info->desc->user_define = 0x7; @@ -497,7 +521,7 @@ static int rk_ablk_cra_init(struct crypto_tfm *tfm) CRYPTO_TRACE(); ctx->dev = algt->dev; - ctx->dev->align_size = crypto_tfm_alg_alignmask(tfm) + 1; + ctx->dev->align_size = crypto_tfm_alg_blocksize(tfm); ctx->dev->start = rk_ablk_start; ctx->dev->update = rk_ablk_rx; ctx->dev->complete = rk_crypto_complete; @@ -575,6 +599,15 @@ struct rk_crypto_tmp rk_v2_cbc_sm4_alg = struct rk_crypto_tmp rk_v2_xts_sm4_alg = RK_CIPHER_ALGO_XTS_INIT(SM4, xts(sm4), xts-sm4-rk); +struct rk_crypto_tmp rk_v2_cfb_sm4_alg = + RK_CIPHER_ALGO_INIT(SM4, CFB, cfb(sm4), cfb-sm4-rk); + +struct rk_crypto_tmp rk_v2_ofb_sm4_alg = + RK_CIPHER_ALGO_INIT(SM4, OFB, ofb(sm4), ofb-sm4-rk); + +struct rk_crypto_tmp rk_v2_ctr_sm4_alg = + RK_CIPHER_ALGO_INIT(SM4, CTR, ctr(sm4), ctr-sm4-rk); + struct rk_crypto_tmp rk_v2_ecb_aes_alg = RK_CIPHER_ALGO_INIT(AES, ECB, ecb(aes), ecb-aes-rk); @@ -584,15 +617,36 @@ struct rk_crypto_tmp rk_v2_cbc_aes_alg = struct rk_crypto_tmp rk_v2_xts_aes_alg = RK_CIPHER_ALGO_XTS_INIT(AES, xts(aes), xts-aes-rk); +struct rk_crypto_tmp rk_v2_cfb_aes_alg = + RK_CIPHER_ALGO_INIT(AES, CFB, cfb(aes), cfb-aes-rk); + +struct rk_crypto_tmp rk_v2_ofb_aes_alg = + RK_CIPHER_ALGO_INIT(AES, OFB, ofb(aes), ofb-aes-rk); + +struct rk_crypto_tmp rk_v2_ctr_aes_alg = + RK_CIPHER_ALGO_INIT(AES, CTR, ctr(aes), ctr-aes-rk); + struct rk_crypto_tmp rk_v2_ecb_des_alg = RK_CIPHER_ALGO_INIT(DES, ECB, ecb(des), ecb-des-rk); struct rk_crypto_tmp rk_v2_cbc_des_alg = RK_CIPHER_ALGO_INIT(DES, CBC, cbc(des), cbc-des-rk); +struct rk_crypto_tmp rk_v2_cfb_des_alg = + RK_CIPHER_ALGO_INIT(DES, CFB, cfb(des), cfb-des-rk); + +struct rk_crypto_tmp rk_v2_ofb_des_alg = + RK_CIPHER_ALGO_INIT(DES, OFB, ofb(des), ofb-des-rk); + struct rk_crypto_tmp rk_v2_ecb_des3_ede_alg = RK_CIPHER_ALGO_INIT(DES3_EDE, ECB, ecb(des3_ede), ecb-des3_ede-rk); struct rk_crypto_tmp rk_v2_cbc_des3_ede_alg = RK_CIPHER_ALGO_INIT(DES3_EDE, CBC, cbc(des3_ede), cbc-des3_ede-rk); +struct rk_crypto_tmp rk_v2_cfb_des3_ede_alg = + RK_CIPHER_ALGO_INIT(DES3_EDE, CFB, cfb(des3_ede), cfb-des3_ede-rk); + +struct rk_crypto_tmp rk_v2_ofb_des3_ede_alg = + RK_CIPHER_ALGO_INIT(DES3_EDE, OFB, ofb(des3_ede), ofb-des3_ede-rk); +