diff mbox series

[v3,5/9] crypto/ycc: Add skcipher algorithm support

Message ID 1666691616-69983-6-git-send-email-guanjun@linux.alibaba.com
State Superseded
Headers show
Series [v3,1/9] crypto/ycc: Add YCC (Yitian Cryptography Complex) accelerator driver | expand

Commit Message

guanjun Oct. 25, 2022, 9:53 a.m. UTC
From: Guanjun <guanjun@linux.alibaba.com>

Support skcipher algorithm.

Signed-off-by: Guanjun <guanjun@linux.alibaba.com>
---
 drivers/crypto/ycc/Kconfig    |   9 +
 drivers/crypto/ycc/Makefile   |   2 +-
 drivers/crypto/ycc/ycc_algs.h | 114 ++++++
 drivers/crypto/ycc/ycc_dev.h  |   3 +
 drivers/crypto/ycc/ycc_drv.c  |  52 +++
 drivers/crypto/ycc/ycc_ring.h |  17 +-
 drivers/crypto/ycc/ycc_ske.c  | 925 ++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 1117 insertions(+), 5 deletions(-)
 create mode 100644 drivers/crypto/ycc/ycc_algs.h
 create mode 100644 drivers/crypto/ycc/ycc_ske.c

Comments

kernel test robot Oct. 26, 2022, 8:41 p.m. UTC | #1
Hi 'Guanjun',

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on herbert-cryptodev-2.6/master]
[also build test WARNING on herbert-crypto-2.6/master linus/master v6.1-rc2 next-20221026]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Guanjun/Drivers-for-Alibaba-YCC-Yitian-Cryptography-Complex-cryptographic-accelerator/20221025-180005
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
patch link:    https://lore.kernel.org/r/1666691616-69983-6-git-send-email-guanjun%40linux.alibaba.com
patch subject: [PATCH v3 5/9] crypto/ycc: Add skcipher algorithm support
config: arm-allmodconfig
compiler: arm-linux-gnueabi-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/085f9f4e861489eac45d22a53b0ef9ab669007a9
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Guanjun/Drivers-for-Alibaba-YCC-Yitian-Cryptography-Complex-cryptographic-accelerator/20221025-180005
        git checkout 085f9f4e861489eac45d22a53b0ef9ab669007a9
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash drivers/crypto/ycc/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/crypto/ycc/ycc_ske.c:41:5: warning: no previous prototype for 'ycc_skcipher_aes_ecb_setkey' [-Wmissing-prototypes]
      41 | int ycc_skcipher_aes_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:107:1: note: in expansion of macro 'DEFINE_YCC_SKE_AES_SETKEY'
     107 | DEFINE_YCC_SKE_AES_SETKEY(ecb, ECB, 32);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:41:5: warning: no previous prototype for 'ycc_skcipher_aes_cbc_setkey' [-Wmissing-prototypes]
      41 | int ycc_skcipher_aes_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:108:1: note: in expansion of macro 'DEFINE_YCC_SKE_AES_SETKEY'
     108 | DEFINE_YCC_SKE_AES_SETKEY(cbc, CBC, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:41:5: warning: no previous prototype for 'ycc_skcipher_aes_ctr_setkey' [-Wmissing-prototypes]
      41 | int ycc_skcipher_aes_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:109:1: note: in expansion of macro 'DEFINE_YCC_SKE_AES_SETKEY'
     109 | DEFINE_YCC_SKE_AES_SETKEY(ctr, CTR, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:41:5: warning: no previous prototype for 'ycc_skcipher_aes_cfb_setkey' [-Wmissing-prototypes]
      41 | int ycc_skcipher_aes_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:110:1: note: in expansion of macro 'DEFINE_YCC_SKE_AES_SETKEY'
     110 | DEFINE_YCC_SKE_AES_SETKEY(cfb, CFB, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:41:5: warning: no previous prototype for 'ycc_skcipher_aes_ofb_setkey' [-Wmissing-prototypes]
      41 | int ycc_skcipher_aes_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:111:1: note: in expansion of macro 'DEFINE_YCC_SKE_AES_SETKEY'
     111 | DEFINE_YCC_SKE_AES_SETKEY(ofb, OFB, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:63:5: warning: no previous prototype for 'ycc_skcipher_sm4_ecb_setkey' [-Wmissing-prototypes]
      63 | int ycc_skcipher_sm4_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:113:1: note: in expansion of macro 'DEFINE_YCC_SKE_SM4_SETKEY'
     113 | DEFINE_YCC_SKE_SM4_SETKEY(ecb, ECB, 32);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:63:5: warning: no previous prototype for 'ycc_skcipher_sm4_cbc_setkey' [-Wmissing-prototypes]
      63 | int ycc_skcipher_sm4_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:114:1: note: in expansion of macro 'DEFINE_YCC_SKE_SM4_SETKEY'
     114 | DEFINE_YCC_SKE_SM4_SETKEY(cbc, CBC, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:63:5: warning: no previous prototype for 'ycc_skcipher_sm4_ctr_setkey' [-Wmissing-prototypes]
      63 | int ycc_skcipher_sm4_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:115:1: note: in expansion of macro 'DEFINE_YCC_SKE_SM4_SETKEY'
     115 | DEFINE_YCC_SKE_SM4_SETKEY(ctr, CTR, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:63:5: warning: no previous prototype for 'ycc_skcipher_sm4_cfb_setkey' [-Wmissing-prototypes]
      63 | int ycc_skcipher_sm4_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:116:1: note: in expansion of macro 'DEFINE_YCC_SKE_SM4_SETKEY'
     116 | DEFINE_YCC_SKE_SM4_SETKEY(cfb, CFB, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:63:5: warning: no previous prototype for 'ycc_skcipher_sm4_ofb_setkey' [-Wmissing-prototypes]
      63 | int ycc_skcipher_sm4_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:117:1: note: in expansion of macro 'DEFINE_YCC_SKE_SM4_SETKEY'
     117 | DEFINE_YCC_SKE_SM4_SETKEY(ofb, OFB, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:74:5: warning: no previous prototype for 'ycc_skcipher_des_ecb_setkey' [-Wmissing-prototypes]
      74 | int ycc_skcipher_des_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:119:1: note: in expansion of macro 'DEFINE_YCC_SKE_DES_SETKEY'
     119 | DEFINE_YCC_SKE_DES_SETKEY(ecb, ECB, 32);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:74:5: warning: no previous prototype for 'ycc_skcipher_des_cbc_setkey' [-Wmissing-prototypes]
      74 | int ycc_skcipher_des_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:120:1: note: in expansion of macro 'DEFINE_YCC_SKE_DES_SETKEY'
     120 | DEFINE_YCC_SKE_DES_SETKEY(cbc, CBC, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:74:5: warning: no previous prototype for 'ycc_skcipher_des_ctr_setkey' [-Wmissing-prototypes]
      74 | int ycc_skcipher_des_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:121:1: note: in expansion of macro 'DEFINE_YCC_SKE_DES_SETKEY'
     121 | DEFINE_YCC_SKE_DES_SETKEY(ctr, CTR, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:74:5: warning: no previous prototype for 'ycc_skcipher_des_cfb_setkey' [-Wmissing-prototypes]
      74 | int ycc_skcipher_des_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:122:1: note: in expansion of macro 'DEFINE_YCC_SKE_DES_SETKEY'
     122 | DEFINE_YCC_SKE_DES_SETKEY(cfb, CFB, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:74:5: warning: no previous prototype for 'ycc_skcipher_des_ofb_setkey' [-Wmissing-prototypes]
      74 | int ycc_skcipher_des_##name##_setkey(struct crypto_skcipher *tfm,       \
         |     ^~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:123:1: note: in expansion of macro 'DEFINE_YCC_SKE_DES_SETKEY'
     123 | DEFINE_YCC_SKE_DES_SETKEY(ofb, OFB, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:89:5: warning: no previous prototype for 'ycc_skcipher_3des_ecb_setkey' [-Wmissing-prototypes]
      89 | int ycc_skcipher_3des_##name##_setkey(struct crypto_skcipher *tfm,      \
         |     ^~~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:125:1: note: in expansion of macro 'DEFINE_YCC_SKE_3DES_SETKEY'
     125 | DEFINE_YCC_SKE_3DES_SETKEY(ecb, ECB, 32);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:89:5: warning: no previous prototype for 'ycc_skcipher_3des_cbc_setkey' [-Wmissing-prototypes]
      89 | int ycc_skcipher_3des_##name##_setkey(struct crypto_skcipher *tfm,      \
         |     ^~~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:126:1: note: in expansion of macro 'DEFINE_YCC_SKE_3DES_SETKEY'
     126 | DEFINE_YCC_SKE_3DES_SETKEY(cbc, CBC, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:89:5: warning: no previous prototype for 'ycc_skcipher_3des_ctr_setkey' [-Wmissing-prototypes]
      89 | int ycc_skcipher_3des_##name##_setkey(struct crypto_skcipher *tfm,      \
         |     ^~~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:127:1: note: in expansion of macro 'DEFINE_YCC_SKE_3DES_SETKEY'
     127 | DEFINE_YCC_SKE_3DES_SETKEY(ctr, CTR, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:89:5: warning: no previous prototype for 'ycc_skcipher_3des_cfb_setkey' [-Wmissing-prototypes]
      89 | int ycc_skcipher_3des_##name##_setkey(struct crypto_skcipher *tfm,      \
         |     ^~~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:128:1: note: in expansion of macro 'DEFINE_YCC_SKE_3DES_SETKEY'
     128 | DEFINE_YCC_SKE_3DES_SETKEY(cfb, CFB, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ycc/ycc_ske.c:89:5: warning: no previous prototype for 'ycc_skcipher_3des_ofb_setkey' [-Wmissing-prototypes]
      89 | int ycc_skcipher_3des_##name##_setkey(struct crypto_skcipher *tfm,      \
         |     ^~~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:129:1: note: in expansion of macro 'DEFINE_YCC_SKE_3DES_SETKEY'
     129 | DEFINE_YCC_SKE_3DES_SETKEY(ofb, OFB, 48);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:131:5: warning: no previous prototype for 'ycc_skcipher_aes_xts_setkey' [-Wmissing-prototypes]
     131 | int ycc_skcipher_aes_xts_setkey(struct crypto_skcipher *tfm,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c:157:5: warning: no previous prototype for 'ycc_skcipher_sm4_xts_setkey' [-Wmissing-prototypes]
     157 | int ycc_skcipher_sm4_xts_setkey(struct crypto_skcipher *tfm,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/crypto/ycc/ycc_ske.c: In function 'ycc_skcipher_submit_desc':
   drivers/crypto/ycc/ycc_ske.c:384:33: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     384 |         req->desc.private_ptr = (u64)aflags;
         |                                 ^


vim +/ycc_skcipher_aes_ecb_setkey +41 drivers/crypto/ycc/ycc_ske.c

    39	
    40	#define DEFINE_YCC_SKE_AES_SETKEY(name, mode, size)			\
  > 41	int ycc_skcipher_aes_##name##_setkey(struct crypto_skcipher *tfm,	\
    42					     const u8 *key,			\
    43					     unsigned int key_size)		\
    44	{									\
    45		int alg_mode;							\
    46		switch (key_size) {						\
    47		case AES_KEYSIZE_128:						\
    48			alg_mode = YCC_AES_128_##mode;				\
    49			break;							\
    50		case AES_KEYSIZE_192:						\
    51			alg_mode = YCC_AES_192_##mode;				\
    52			break;							\
    53		case AES_KEYSIZE_256:						\
    54			alg_mode = YCC_AES_256_##mode;				\
    55			break;							\
    56		default:							\
    57			return -EINVAL;						\
    58		}								\
    59		return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, size);	\
    60	}
    61	
    62	#define DEFINE_YCC_SKE_SM4_SETKEY(name, mode, size)			\
  > 63	int ycc_skcipher_sm4_##name##_setkey(struct crypto_skcipher *tfm,	\
    64					     const u8 *key,			\
    65					     unsigned int key_size)		\
    66	{									\
    67		int alg_mode = YCC_SM4_##mode;					\
    68		if (key_size != SM4_KEY_SIZE)					\
    69			return -EINVAL;						\
    70		return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, size);	\
    71	}
    72	
    73	#define DEFINE_YCC_SKE_DES_SETKEY(name, mode, size)			\
  > 74	int ycc_skcipher_des_##name##_setkey(struct crypto_skcipher *tfm,	\
    75					     const u8 *key,			\
    76					     unsigned int key_size)		\
    77	{									\
    78		int alg_mode = YCC_DES_##mode;					\
    79		int ret;							\
    80		if (key_size != DES_KEY_SIZE)					\
    81			return -EINVAL;						\
    82		ret = verify_skcipher_des_key(tfm, key);			\
    83		if (ret)							\
    84			return ret;						\
    85		return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, size);	\
    86	}
    87	
    88	#define DEFINE_YCC_SKE_3DES_SETKEY(name, mode, size)			\
  > 89	int ycc_skcipher_3des_##name##_setkey(struct crypto_skcipher *tfm,	\
    90					      const u8 *key,			\
    91					      unsigned int key_size)		\
    92	{									\
    93		int alg_mode = YCC_TDES_192_##mode;				\
    94		int ret;							\
    95		if (key_size != DES3_EDE_KEY_SIZE)				\
    96			return -EINVAL;						\
    97		ret = verify_skcipher_des3_key(tfm, key);			\
    98		if (ret)							\
    99			return ret;						\
   100		return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, size);	\
   101	}
   102	
   103	/*
   104	 * ECB: Only has 1 key, without IV, at least 32 bytes.
   105	 * Others except XTS: |key|iv|, at least 48 bytes.
   106	 */
 > 107	DEFINE_YCC_SKE_AES_SETKEY(ecb, ECB, 32);
 > 108	DEFINE_YCC_SKE_AES_SETKEY(cbc, CBC, 48);
 > 109	DEFINE_YCC_SKE_AES_SETKEY(ctr, CTR, 48);
 > 110	DEFINE_YCC_SKE_AES_SETKEY(cfb, CFB, 48);
 > 111	DEFINE_YCC_SKE_AES_SETKEY(ofb, OFB, 48);
   112	
 > 113	DEFINE_YCC_SKE_SM4_SETKEY(ecb, ECB, 32);
 > 114	DEFINE_YCC_SKE_SM4_SETKEY(cbc, CBC, 48);
 > 115	DEFINE_YCC_SKE_SM4_SETKEY(ctr, CTR, 48);
 > 116	DEFINE_YCC_SKE_SM4_SETKEY(cfb, CFB, 48);
 > 117	DEFINE_YCC_SKE_SM4_SETKEY(ofb, OFB, 48);
   118	
 > 119	DEFINE_YCC_SKE_DES_SETKEY(ecb, ECB, 32);
 > 120	DEFINE_YCC_SKE_DES_SETKEY(cbc, CBC, 48);
 > 121	DEFINE_YCC_SKE_DES_SETKEY(ctr, CTR, 48);
 > 122	DEFINE_YCC_SKE_DES_SETKEY(cfb, CFB, 48);
 > 123	DEFINE_YCC_SKE_DES_SETKEY(ofb, OFB, 48);
   124	
 > 125	DEFINE_YCC_SKE_3DES_SETKEY(ecb, ECB, 32);
 > 126	DEFINE_YCC_SKE_3DES_SETKEY(cbc, CBC, 48);
 > 127	DEFINE_YCC_SKE_3DES_SETKEY(ctr, CTR, 48);
 > 128	DEFINE_YCC_SKE_3DES_SETKEY(cfb, CFB, 48);
   129	DEFINE_YCC_SKE_3DES_SETKEY(ofb, OFB, 48);
   130	
 > 131	int ycc_skcipher_aes_xts_setkey(struct crypto_skcipher *tfm,
   132					const u8 *key,
   133					unsigned int key_size)
   134	{
   135		int alg_mode;
   136		int ret;
   137	
   138		ret = xts_verify_key(tfm, key, key_size);
   139		if (ret)
   140			return ret;
   141	
   142		switch (key_size) {
   143		case AES_KEYSIZE_128 * 2:
   144			alg_mode = YCC_AES_128_XTS;
   145			break;
   146		case AES_KEYSIZE_256 * 2:
   147			alg_mode = YCC_AES_256_XTS;
   148			break;
   149		default:
   150			return -EINVAL;
   151		}
   152	
   153		/* XTS: |key1|key2|iv|, at least 32 + 32 + 16 bytes */
   154		return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, 80);
   155	}
   156	
 > 157	int ycc_skcipher_sm4_xts_setkey(struct crypto_skcipher *tfm,
   158					const u8 *key,
   159					unsigned int key_size)
   160	{
   161		int alg_mode;
   162		int ret;
   163	
   164		ret = xts_verify_key(tfm, key, key_size);
   165		if (ret)
   166			return ret;
   167	
   168		if (key_size != SM4_KEY_SIZE * 2)
   169			return -EINVAL;
   170	
   171		alg_mode = YCC_SM4_XTS;
   172		return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, 80);
   173	}
   174
diff mbox series

Patch

diff --git a/drivers/crypto/ycc/Kconfig b/drivers/crypto/ycc/Kconfig
index 6e88ecb..8dae75e 100644
--- a/drivers/crypto/ycc/Kconfig
+++ b/drivers/crypto/ycc/Kconfig
@@ -2,6 +2,15 @@  config CRYPTO_DEV_YCC
 	tristate "Support for Alibaba YCC cryptographic accelerator"
 	depends on CRYPTO && CRYPTO_HW && PCI
 	default n
+	select CRYPTO_SKCIPHER
+	select CRYPTO_LIB_DES
+	select CRYPTO_SM3_GENERIC
+	select CRYPTO_AES
+	select CRYPTO_CBC
+	select CRYPTO_ECB
+	select CRYPTO_CTR
+	select CRYPTO_XTS
+	select CRYPTO_SM4
 	help
 	  Enables the driver for the on-chip cryptographic accelerator of
 	  Alibaba Yitian SoCs which is based on ARMv9 architecture.
diff --git a/drivers/crypto/ycc/Makefile b/drivers/crypto/ycc/Makefile
index 31aae9c..eedc1c8 100644
--- a/drivers/crypto/ycc/Makefile
+++ b/drivers/crypto/ycc/Makefile
@@ -1,3 +1,3 @@ 
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_CRYPTO_DEV_YCC) += ycc.o
-ycc-objs := ycc_drv.o ycc_isr.o ycc_ring.o
+ycc-objs := ycc_drv.o ycc_isr.o ycc_ring.o ycc_ske.o
diff --git a/drivers/crypto/ycc/ycc_algs.h b/drivers/crypto/ycc/ycc_algs.h
new file mode 100644
index 00000000..6c7b0dc
--- /dev/null
+++ b/drivers/crypto/ycc/ycc_algs.h
@@ -0,0 +1,114 @@ 
+// SPDX-License-Identifier: GPL-2.0
+#ifndef __YCC_ALG_H
+#define __YCC_ALG_H
+
+#include <crypto/skcipher.h>
+
+#include "ycc_ring.h"
+#include "ycc_dev.h"
+
+enum ycc_gcm_mode {
+	YCC_AES_128_GCM = 0,
+	YCC_AES_192_GCM,
+	YCC_AES_256_GCM,
+	YCC_SM4_GCM,
+};
+
+enum ycc_ccm_mode {
+	YCC_AES_128_CCM = 0,
+	YCC_AES_192_CCM,
+	YCC_AES_256_CCM,
+	YCC_SM4_CCM,
+};
+
+enum ycc_ske_alg_mode {
+	YCC_DES_ECB = 26,
+	YCC_DES_CBC,
+	YCC_DES_CFB,
+	YCC_DES_OFB,
+	YCC_DES_CTR, /* 30 */
+
+	YCC_TDES_128_ECB = 31,
+	YCC_TDES_128_CBC,
+	YCC_TDES_128_CFB,
+	YCC_TDES_128_OFB,
+	YCC_TDES_128_CTR,
+	YCC_TDES_192_ECB,
+	YCC_TDES_192_CBC,
+	YCC_TDES_192_CFB,
+	YCC_TDES_192_OFB,
+	YCC_TDES_192_CTR, /* 40 */
+
+	YCC_AES_128_ECB = 41,
+	YCC_AES_128_CBC,
+	YCC_AES_128_CFB,
+	YCC_AES_128_OFB,
+	YCC_AES_128_CTR,
+	YCC_AES_128_XTS, /* 46 */
+
+	YCC_AES_192_ECB = 48,
+	YCC_AES_192_CBC,
+	YCC_AES_192_CFB,
+	YCC_AES_192_OFB,
+	YCC_AES_192_CTR, /* 52 */
+
+	YCC_AES_256_ECB = 55,
+	YCC_AES_256_CBC,
+	YCC_AES_256_CFB,
+	YCC_AES_256_OFB,
+	YCC_AES_256_CTR,
+	YCC_AES_256_XTS, /* 60 */
+
+	YCC_SM4_ECB = 62,
+	YCC_SM4_CBC,
+	YCC_SM4_CFB,
+	YCC_SM4_OFB,
+	YCC_SM4_CTR,
+	YCC_SM4_XTS, /* 67 */
+};
+
+enum ycc_cmd_id {
+	YCC_CMD_SKE_ENC = 0x23,
+	YCC_CMD_SKE_DEC,
+};
+
+struct ycc_crypto_ctx {
+	struct ycc_ring *ring;
+	void *soft_tfm;
+
+	u32 keysize;
+	u32 key_dma_size; /* dma memory size for key/key+iv */
+
+	u8 mode;
+	u8 *cipher_key;
+	u8 reserved[4];
+};
+
+struct ycc_crypto_req {
+	int mapped_src_nents;
+	int mapped_dst_nents;
+
+	void *key_vaddr;
+	dma_addr_t key_paddr;
+
+	struct ycc_cmd_desc desc;
+	struct skcipher_request *ske_req;
+	struct skcipher_request ske_subreq;
+
+	void *src_vaddr;
+	dma_addr_t src_paddr;
+	void *dst_vaddr;
+	dma_addr_t dst_paddr;
+
+	int in_len;
+	int out_len;
+	int aad_offset;
+	struct ycc_crypto_ctx *ctx;
+	u8 last_block[16]; /* used to store iv out when decrypt */
+};
+
+#define YCC_DEV(ctx)		(&(ctx)->ring->ydev->pdev->dev)
+
+int ycc_sym_register(void);
+void ycc_sym_unregister(void);
+#endif
diff --git a/drivers/crypto/ycc/ycc_dev.h b/drivers/crypto/ycc/ycc_dev.h
index dda82b0f..08f9a05 100644
--- a/drivers/crypto/ycc/ycc_dev.h
+++ b/drivers/crypto/ycc/ycc_dev.h
@@ -151,4 +151,7 @@  static inline void ycc_g_err_unmask(void *vaddr)
 	YCC_CSR_WR(vaddr, REG_YCC_DEV_INT_MASK, 0);
 }
 
+int ycc_algorithm_register(void);
+void ycc_algorithm_unregister(void);
+
 #endif
diff --git a/drivers/crypto/ycc/ycc_drv.c b/drivers/crypto/ycc/ycc_drv.c
index 8d0fcfd..79c1e18 100644
--- a/drivers/crypto/ycc/ycc_drv.c
+++ b/drivers/crypto/ycc/ycc_drv.c
@@ -25,6 +25,7 @@ 
 
 #include "ycc_isr.h"
 #include "ycc_ring.h"
+#include "ycc_algs.h"
 
 static const char ycc_name[] = "ycc";
 
@@ -35,6 +36,8 @@ 
 module_param(is_polling, bool, 0644);
 module_param(user_rings, int, 0644);
 
+static atomic_t ycc_algs_refcnt;
+
 LIST_HEAD(ycc_table);
 DEFINE_MUTEX(ycc_mutex);
 
@@ -75,6 +78,40 @@  static int ycc_dev_debugfs_statistics_open(struct inode *inode, struct file *fil
 	.owner		= THIS_MODULE,
 };
 
+int ycc_algorithm_register(void)
+{
+	int ret = 0;
+
+	/* No kernel rings */
+	if (user_rings == YCC_RINGPAIR_NUM)
+		return ret;
+
+	/* Only register once */
+	if (atomic_inc_return(&ycc_algs_refcnt) > 1)
+		return ret;
+
+	ret = ycc_sym_register();
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	atomic_dec(&ycc_algs_refcnt);
+	return ret;
+}
+
+void ycc_algorithm_unregister(void)
+{
+	if (user_rings == YCC_RINGPAIR_NUM)
+		return;
+
+	if (atomic_dec_return(&ycc_algs_refcnt))
+		return;
+
+	ycc_sym_unregister();
+}
+
 static int ycc_device_flr(struct pci_dev *pdev, struct pci_dev *rcec_pdev)
 {
 	int ret;
@@ -321,6 +358,7 @@  static void ycc_rcec_unbind(struct ycc_dev *ydev)
 	ycc_resource_free(rciep);
 	rciep->assoc_dev = NULL;
 	rcec->assoc_dev = NULL;
+	ycc_algorithm_unregister();
 }
 
 static int ycc_dev_add(struct ycc_dev *ydev)
@@ -421,8 +459,20 @@  static int ycc_drv_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (ret)
 		goto remove_debugfs;
 
+	if (test_bit(YDEV_STATUS_READY, &ydev->status)) {
+		ret = ycc_algorithm_register();
+		if (ret) {
+			pr_err("Failed to register algorithm\n");
+			clear_bit(YDEV_STATUS_READY, &ydev->status);
+			clear_bit(YDEV_STATUS_READY, &ydev->assoc_dev->status);
+			goto dev_del;
+		}
+	}
+
 	return ret;
 
+dev_del:
+	ycc_dev_del(ydev);
 remove_debugfs:
 	if (ydev->type == YCC_RCIEP) {
 		debugfs_remove_recursive(ydev->debug_dir);
@@ -478,6 +528,8 @@  static int __init ycc_drv_init(void)
 {
 	int ret;
 
+	atomic_set(&ycc_algs_refcnt, 0);
+
 	ret = pci_register_driver(&ycc_driver);
 	if (ret)
 		goto out;
diff --git a/drivers/crypto/ycc/ycc_ring.h b/drivers/crypto/ycc/ycc_ring.h
index c3e7cbf..78ba959 100644
--- a/drivers/crypto/ycc/ycc_ring.h
+++ b/drivers/crypto/ycc/ycc_ring.h
@@ -75,11 +75,20 @@  struct ycc_resp_desc {
 	u8 reserved[6];
 };
 
+struct ycc_skcipher_cmd {
+	u8 cmd_id;
+	u8 mode;
+	u64 sptr:48;
+	u64 dptr:48;
+	u32 dlen;
+	u16 key_idx;	/* key used to decrypt kek */
+	u8 reserved[2];
+	u64 keyptr:48;
+	u8 padding;
+} __packed;
+
 union ycc_real_cmd {
-	/*
-	 * TODO: Real command will implement when
-	 * corresponding algorithm is ready
-	 */
+	struct ycc_skcipher_cmd ske_cmd;
 	u8 padding[32];
 };
 
diff --git a/drivers/crypto/ycc/ycc_ske.c b/drivers/crypto/ycc/ycc_ske.c
new file mode 100644
index 00000000..afe1745
--- /dev/null
+++ b/drivers/crypto/ycc/ycc_ske.c
@@ -0,0 +1,925 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+#define pr_fmt(fmt) "YCC: Crypto: " fmt
+
+#include <crypto/internal/des.h>
+#include <crypto/scatterwalk.h>
+#include <linux/dma-mapping.h>
+#include <crypto/skcipher.h>
+#include <linux/crypto.h>
+#include <crypto/aes.h>
+#include <crypto/des.h>
+#include <crypto/xts.h>
+#include <crypto/sm4.h>
+#include "ycc_algs.h"
+
+static int ycc_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
+			       unsigned int key_size, int mode,
+			       unsigned int key_dma_size)
+{
+	struct ycc_crypto_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+	if (ctx->cipher_key) {
+		memset(ctx->cipher_key, 0, ctx->keysize);
+	} else {
+		ctx->cipher_key = kzalloc(key_size, GFP_KERNEL);
+		if (!ctx->cipher_key)
+			return -ENOMEM;
+	}
+	memcpy(ctx->cipher_key, key, key_size);
+	ctx->mode = mode;
+	ctx->keysize = key_size;
+	ctx->key_dma_size = key_dma_size;
+
+	if (ctx->soft_tfm && crypto_skcipher_setkey(ctx->soft_tfm, key, key_size))
+		pr_warn("Failed to setkey for soft skcipher tfm\n");
+
+	return 0;
+}
+
+#define DEFINE_YCC_SKE_AES_SETKEY(name, mode, size)			\
+int ycc_skcipher_aes_##name##_setkey(struct crypto_skcipher *tfm,	\
+				     const u8 *key,			\
+				     unsigned int key_size)		\
+{									\
+	int alg_mode;							\
+	switch (key_size) {						\
+	case AES_KEYSIZE_128:						\
+		alg_mode = YCC_AES_128_##mode;				\
+		break;							\
+	case AES_KEYSIZE_192:						\
+		alg_mode = YCC_AES_192_##mode;				\
+		break;							\
+	case AES_KEYSIZE_256:						\
+		alg_mode = YCC_AES_256_##mode;				\
+		break;							\
+	default:							\
+		return -EINVAL;						\
+	}								\
+	return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, size);	\
+}
+
+#define DEFINE_YCC_SKE_SM4_SETKEY(name, mode, size)			\
+int ycc_skcipher_sm4_##name##_setkey(struct crypto_skcipher *tfm,	\
+				     const u8 *key,			\
+				     unsigned int key_size)		\
+{									\
+	int alg_mode = YCC_SM4_##mode;					\
+	if (key_size != SM4_KEY_SIZE)					\
+		return -EINVAL;						\
+	return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, size);	\
+}
+
+#define DEFINE_YCC_SKE_DES_SETKEY(name, mode, size)			\
+int ycc_skcipher_des_##name##_setkey(struct crypto_skcipher *tfm,	\
+				     const u8 *key,			\
+				     unsigned int key_size)		\
+{									\
+	int alg_mode = YCC_DES_##mode;					\
+	int ret;							\
+	if (key_size != DES_KEY_SIZE)					\
+		return -EINVAL;						\
+	ret = verify_skcipher_des_key(tfm, key);			\
+	if (ret)							\
+		return ret;						\
+	return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, size);	\
+}
+
+#define DEFINE_YCC_SKE_3DES_SETKEY(name, mode, size)			\
+int ycc_skcipher_3des_##name##_setkey(struct crypto_skcipher *tfm,	\
+				      const u8 *key,			\
+				      unsigned int key_size)		\
+{									\
+	int alg_mode = YCC_TDES_192_##mode;				\
+	int ret;							\
+	if (key_size != DES3_EDE_KEY_SIZE)				\
+		return -EINVAL;						\
+	ret = verify_skcipher_des3_key(tfm, key);			\
+	if (ret)							\
+		return ret;						\
+	return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, size);	\
+}
+
+/*
+ * ECB: Only has 1 key, without IV, at least 32 bytes.
+ * Others except XTS: |key|iv|, at least 48 bytes.
+ */
+DEFINE_YCC_SKE_AES_SETKEY(ecb, ECB, 32);
+DEFINE_YCC_SKE_AES_SETKEY(cbc, CBC, 48);
+DEFINE_YCC_SKE_AES_SETKEY(ctr, CTR, 48);
+DEFINE_YCC_SKE_AES_SETKEY(cfb, CFB, 48);
+DEFINE_YCC_SKE_AES_SETKEY(ofb, OFB, 48);
+
+DEFINE_YCC_SKE_SM4_SETKEY(ecb, ECB, 32);
+DEFINE_YCC_SKE_SM4_SETKEY(cbc, CBC, 48);
+DEFINE_YCC_SKE_SM4_SETKEY(ctr, CTR, 48);
+DEFINE_YCC_SKE_SM4_SETKEY(cfb, CFB, 48);
+DEFINE_YCC_SKE_SM4_SETKEY(ofb, OFB, 48);
+
+DEFINE_YCC_SKE_DES_SETKEY(ecb, ECB, 32);
+DEFINE_YCC_SKE_DES_SETKEY(cbc, CBC, 48);
+DEFINE_YCC_SKE_DES_SETKEY(ctr, CTR, 48);
+DEFINE_YCC_SKE_DES_SETKEY(cfb, CFB, 48);
+DEFINE_YCC_SKE_DES_SETKEY(ofb, OFB, 48);
+
+DEFINE_YCC_SKE_3DES_SETKEY(ecb, ECB, 32);
+DEFINE_YCC_SKE_3DES_SETKEY(cbc, CBC, 48);
+DEFINE_YCC_SKE_3DES_SETKEY(ctr, CTR, 48);
+DEFINE_YCC_SKE_3DES_SETKEY(cfb, CFB, 48);
+DEFINE_YCC_SKE_3DES_SETKEY(ofb, OFB, 48);
+
+int ycc_skcipher_aes_xts_setkey(struct crypto_skcipher *tfm,
+				const u8 *key,
+				unsigned int key_size)
+{
+	int alg_mode;
+	int ret;
+
+	ret = xts_verify_key(tfm, key, key_size);
+	if (ret)
+		return ret;
+
+	switch (key_size) {
+	case AES_KEYSIZE_128 * 2:
+		alg_mode = YCC_AES_128_XTS;
+		break;
+	case AES_KEYSIZE_256 * 2:
+		alg_mode = YCC_AES_256_XTS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* XTS: |key1|key2|iv|, at least 32 + 32 + 16 bytes */
+	return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, 80);
+}
+
+int ycc_skcipher_sm4_xts_setkey(struct crypto_skcipher *tfm,
+				const u8 *key,
+				unsigned int key_size)
+{
+	int alg_mode;
+	int ret;
+
+	ret = xts_verify_key(tfm, key, key_size);
+	if (ret)
+		return ret;
+
+	if (key_size != SM4_KEY_SIZE * 2)
+		return -EINVAL;
+
+	alg_mode = YCC_SM4_XTS;
+	return ycc_skcipher_setkey(tfm, key, key_size, alg_mode, 80);
+}
+
+static int ycc_skcipher_fill_key(struct ycc_crypto_req *req)
+{
+	struct ycc_crypto_ctx *ctx = req->ctx;
+	struct device *dev = YCC_DEV(ctx);
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req->ske_req);
+	u32 ivsize = crypto_skcipher_ivsize(tfm);
+
+	if (!req->key_vaddr) {
+		req->key_vaddr = dma_alloc_coherent(dev, ALIGN(ctx->key_dma_size, 64),
+						    &req->key_paddr, GFP_ATOMIC);
+		if (!req->key_vaddr)
+			return -ENOMEM;
+	}
+
+	memset(req->key_vaddr, 0, ALIGN(ctx->key_dma_size, 64));
+	/* XTS Mode has 2 keys & 1 iv */
+	if (ctx->key_dma_size == 80) {
+		memcpy(req->key_vaddr + (32 - ctx->keysize / 2),
+		       ctx->cipher_key, ctx->keysize / 2);
+		memcpy(req->key_vaddr + (64 - ctx->keysize / 2),
+		       ctx->cipher_key + ctx->keysize / 2, ctx->keysize / 2);
+	} else {
+		memcpy(req->key_vaddr + (32 - ctx->keysize), ctx->cipher_key,
+		       ctx->keysize);
+	}
+
+	if (ivsize) {
+		if (ctx->mode == YCC_DES_ECB ||
+		    ctx->mode == YCC_TDES_128_ECB ||
+		    ctx->mode == YCC_TDES_192_ECB ||
+		    ctx->mode == YCC_AES_128_ECB ||
+		    ctx->mode == YCC_AES_192_ECB ||
+		    ctx->mode == YCC_AES_256_ECB ||
+		    ctx->mode == YCC_SM4_ECB) {
+			pr_err("Illegal ivsize for ECB mode, should be zero");
+			goto clear_key;
+		}
+
+		/* DES or 3DES */
+		if (ctx->mode >= YCC_DES_ECB && ctx->mode <= YCC_TDES_192_CTR) {
+			if (ivsize > 8)
+				goto clear_key;
+			memcpy(req->key_vaddr + ctx->key_dma_size - 8,
+			       req->ske_req->iv, ivsize);
+		} else {
+			memcpy(req->key_vaddr + ctx->key_dma_size - 16,
+			       req->ske_req->iv, ivsize);
+		}
+	}
+
+	return 0;
+clear_key:
+	memset(req->key_vaddr, 0, ALIGN(ctx->key_dma_size, 64));
+	dma_free_coherent(dev, ctx->key_dma_size, req->key_vaddr, req->key_paddr);
+	req->key_vaddr = NULL;
+	return -EINVAL;
+}
+
+static int ycc_skcipher_sg_map(struct ycc_crypto_req *req)
+{
+	struct device *dev = YCC_DEV(req->ctx);
+	struct skcipher_request *ske_req = req->ske_req;
+	int src_nents;
+
+	src_nents = sg_nents_for_len(ske_req->src, ske_req->cryptlen);
+	if (unlikely(src_nents <= 0)) {
+		pr_err("Failed to get src sg len\n");
+		return -EINVAL;
+	}
+
+	req->src_vaddr = dma_alloc_coherent(dev, ALIGN(req->in_len, 64),
+					    &req->src_paddr, GFP_ATOMIC);
+	if (!req->src_vaddr)
+		return -ENOMEM;
+
+	req->dst_vaddr = dma_alloc_coherent(dev, ALIGN(req->in_len, 64),
+					    &req->dst_paddr, GFP_ATOMIC);
+	if (!req->dst_vaddr) {
+		dma_free_coherent(dev, ALIGN(req->in_len, 64),
+				  req->src_vaddr, req->src_paddr);
+		return -ENOMEM;
+	}
+
+	sg_copy_to_buffer(ske_req->src, src_nents, req->src_vaddr, ske_req->cryptlen);
+	return 0;
+}
+
+static inline void ycc_skcipher_sg_unmap(struct ycc_crypto_req *req)
+{
+	struct device *dev = YCC_DEV(req->ctx);
+
+	dma_free_coherent(dev, ALIGN(req->in_len, 64), req->src_vaddr, req->src_paddr);
+	dma_free_coherent(dev, ALIGN(req->in_len, 64), req->dst_vaddr, req->dst_paddr);
+}
+
+/*
+ * For CBC & CTR
+ */
+static void ycc_skcipher_iv_out(struct ycc_crypto_req *req, void *dst)
+{
+	struct skcipher_request *ske_req = req->ske_req;
+	struct crypto_skcipher *stfm = crypto_skcipher_reqtfm(ske_req);
+	u8 bs = crypto_skcipher_blocksize(stfm);
+	u8 mode = req->ctx->mode;
+	u8 cmd = req->desc.cmd.ske_cmd.cmd_id;
+	u32 nb = (ske_req->cryptlen + bs - 1) / bs;
+
+	switch (mode) {
+	case YCC_DES_CBC:
+	case YCC_TDES_128_CBC:
+	case YCC_TDES_192_CBC:
+	case YCC_AES_128_CBC:
+	case YCC_AES_192_CBC:
+	case YCC_AES_256_CBC:
+	case YCC_SM4_CBC:
+		if (cmd == YCC_CMD_SKE_DEC)
+			memcpy(ske_req->iv, req->last_block, bs);
+		else
+			memcpy(ske_req->iv,
+			       (u8 *)dst + ALIGN(ske_req->cryptlen, bs) - bs,
+			       bs);
+		break;
+	case YCC_DES_CTR:
+	case YCC_TDES_128_CTR:
+	case YCC_TDES_192_CTR:
+	case YCC_AES_128_CTR:
+	case YCC_AES_192_CTR:
+	case YCC_AES_256_CTR:
+	case YCC_SM4_CTR:
+		for ( ; nb-- ; )
+			crypto_inc(ske_req->iv, bs);
+		break;
+	default:
+		return;
+	}
+}
+
+static int ycc_skcipher_callback(void *ptr, u16 state)
+{
+	struct ycc_crypto_req *req = (struct ycc_crypto_req *)ptr;
+	struct skcipher_request *ske_req = req->ske_req;
+	struct ycc_crypto_ctx *ctx = req->ctx;
+	struct device *dev = YCC_DEV(ctx);
+
+	sg_copy_from_buffer(ske_req->dst,
+			    sg_nents_for_len(ske_req->dst, ske_req->cryptlen),
+			    req->dst_vaddr, ske_req->cryptlen);
+
+	if (state == CMD_SUCCESS)
+		ycc_skcipher_iv_out(req, req->dst_vaddr);
+
+	ycc_skcipher_sg_unmap(req);
+
+	if (req->key_vaddr) {
+		memset(req->key_vaddr, 0, ALIGN(ctx->key_dma_size, 64));
+		dma_free_coherent(dev, ALIGN(ctx->key_dma_size, 64),
+				  req->key_vaddr, req->key_paddr);
+		req->key_vaddr = NULL;
+	}
+	if (ske_req->base.complete)
+		ske_req->base.complete(&ske_req->base,
+				       state == CMD_SUCCESS ? 0 : -EBADMSG);
+
+	return 0;
+}
+
+static inline bool ycc_skcipher_do_soft(struct ycc_dev *ydev)
+{
+	return !test_bit(YDEV_STATUS_READY, &ydev->status);
+}
+
+static int ycc_skcipher_submit_desc(struct skcipher_request *ske_req, u8 cmd)
+{
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ske_req);
+	struct ycc_crypto_req *req = skcipher_request_ctx(ske_req);
+	struct ycc_skcipher_cmd *ske_cmd = &req->desc.cmd.ske_cmd;
+	struct ycc_crypto_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct ycc_flags *aflags;
+	u8 bs = crypto_skcipher_blocksize(tfm);
+	int ret;
+
+	memset(req, 0, sizeof(*req));
+	req->ctx = ctx;
+	req->ske_req = ske_req;
+	req->in_len = ALIGN(ske_req->cryptlen, bs);
+
+	/*
+	 * The length of request, 64n + bs, may lead the device hung.
+	 * So append one bs here. This is a workaround for hardware issue.
+	 */
+	if (req->in_len % 64 == bs)
+		req->in_len += bs;
+
+	ret = ycc_skcipher_fill_key(req);
+	if (ret)
+		return ret;
+
+	ret = ycc_skcipher_sg_map(req);
+	if (ret)
+		goto free_key;
+
+	ret = -ENOMEM;
+	aflags = kzalloc(sizeof(struct ycc_flags), GFP_ATOMIC);
+	if (!aflags)
+		goto sg_unmap;
+
+	aflags->ptr = (void *)req;
+	aflags->ycc_done_callback = ycc_skcipher_callback;
+
+	req->desc.private_ptr = (u64)aflags;
+	ske_cmd->cmd_id  = cmd;
+	ske_cmd->mode    = ctx->mode;
+	ske_cmd->sptr    = req->src_paddr;
+	ske_cmd->dptr    = req->dst_paddr;
+	ske_cmd->dlen    = req->in_len;
+	ske_cmd->keyptr  = req->key_paddr;
+	ske_cmd->padding = 0;
+
+	/* LKCF will check iv output, for decryption, the iv is its last block */
+	if (cmd == YCC_CMD_SKE_DEC)
+		memcpy(req->last_block,
+		       req->src_vaddr + ALIGN(ske_req->cryptlen, bs) - bs, bs);
+
+	ret = ycc_enqueue(ctx->ring, &req->desc);
+	if (!ret)
+		return -EINPROGRESS;
+
+	pr_debug("Failed to submit desc to ring\n");
+	kfree(aflags);
+
+sg_unmap:
+	ycc_skcipher_sg_unmap(req);
+free_key:
+	memset(req->key_vaddr, 0, ALIGN(ctx->key_dma_size, 64));
+	dma_free_coherent(YCC_DEV(ctx),
+			  ALIGN(ctx->key_dma_size, 64),
+			  req->key_vaddr, req->key_paddr);
+	req->key_vaddr = NULL;
+	return ret;
+}
+
+static int ycc_skcipher_encrypt(struct skcipher_request *req)
+{
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	struct ycc_crypto_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct skcipher_request *subreq =
+		&((struct ycc_crypto_req *)skcipher_request_ctx(req))->ske_subreq;
+
+	if (ycc_skcipher_do_soft(ctx->ring->ydev)) {
+		skcipher_request_set_tfm(subreq, ctx->soft_tfm);
+		skcipher_request_set_callback(subreq, req->base.flags,
+					      req->base.complete, req->base.data);
+		skcipher_request_set_crypt(subreq, req->src, req->dst,
+					   req->cryptlen, req->iv);
+		return crypto_skcipher_encrypt(subreq);
+	}
+
+	return ycc_skcipher_submit_desc(req, YCC_CMD_SKE_ENC);
+}
+
+static int ycc_skcipher_decrypt(struct skcipher_request *req)
+{
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	struct ycc_crypto_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct skcipher_request *subreq =
+		&((struct ycc_crypto_req *)skcipher_request_ctx(req))->ske_subreq;
+
+	if (ycc_skcipher_do_soft(ctx->ring->ydev)) {
+		skcipher_request_set_tfm(subreq, ctx->soft_tfm);
+		skcipher_request_set_callback(subreq, req->base.flags,
+					      req->base.complete, req->base.data);
+		skcipher_request_set_crypt(subreq, req->src, req->dst,
+					   req->cryptlen, req->iv);
+		return crypto_skcipher_encrypt(subreq);
+	}
+
+	return ycc_skcipher_submit_desc(req, YCC_CMD_SKE_DEC);
+}
+
+static int ycc_skcipher_init(struct crypto_skcipher *tfm)
+{
+	struct ycc_crypto_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct ycc_ring *ring;
+
+	ctx->soft_tfm = crypto_alloc_skcipher(crypto_tfm_alg_name(crypto_skcipher_tfm(tfm)), 0,
+					      CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_ASYNC);
+	if (IS_ERR(ctx->soft_tfm)) {
+		pr_warn("Failed to allocate soft tfm for:%s, software fallback is limited\n",
+			crypto_tfm_alg_name(crypto_skcipher_tfm(tfm)));
+		ctx->soft_tfm = NULL;
+		crypto_skcipher_set_reqsize(tfm, sizeof(struct ycc_crypto_req));
+	} else {
+		/*
+		 * If it's software fallback, store meta data of soft request.
+		 */
+		crypto_skcipher_set_reqsize(tfm, sizeof(struct ycc_crypto_req) +
+					    crypto_skcipher_reqsize(ctx->soft_tfm));
+	}
+
+	ring = ycc_crypto_get_ring();
+	if (!ring)
+		return -ENOMEM;
+
+	ctx->ring = ring;
+	return 0;
+}
+
+static void ycc_skcipher_exit(struct crypto_skcipher *tfm)
+{
+	struct ycc_crypto_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+	if (ctx->ring)
+		ycc_crypto_free_ring(ctx->ring);
+
+	kfree(ctx->cipher_key);
+
+	if (ctx->soft_tfm)
+		crypto_free_skcipher((struct crypto_skcipher *)ctx->soft_tfm);
+}
+
+
+static struct skcipher_alg ycc_skciphers[] = {
+	{
+		.base = {
+			.cra_name = "cbc(aes)",
+			.cra_driver_name = "cbc-aes-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_aes_cbc_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = AES_MIN_KEY_SIZE,
+		.max_keysize = AES_MAX_KEY_SIZE,
+		.ivsize = AES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "ecb(aes)",
+			.cra_driver_name = "ecb-aes-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_aes_ecb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = AES_MIN_KEY_SIZE,
+		.max_keysize = AES_MAX_KEY_SIZE,
+		.ivsize = 0,
+	},
+	{
+		.base = {
+			.cra_name = "ctr(aes)",
+			.cra_driver_name = "ctr-aes-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_aes_ctr_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = AES_MIN_KEY_SIZE,
+		.max_keysize = AES_MAX_KEY_SIZE,
+		.ivsize = AES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "cfb(aes)",
+			.cra_driver_name = "cfb-aes-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_aes_cfb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = AES_MIN_KEY_SIZE,
+		.max_keysize = AES_MAX_KEY_SIZE,
+		.ivsize = AES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "ofb(aes)",
+			.cra_driver_name = "ofb-aes-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_aes_ofb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = AES_MIN_KEY_SIZE,
+		.max_keysize = AES_MAX_KEY_SIZE,
+		.ivsize = AES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "xts(aes)",
+			.cra_driver_name = "xts-aes-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_aes_xts_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = AES_MIN_KEY_SIZE * 2,
+		.max_keysize = AES_MAX_KEY_SIZE * 2,
+		.ivsize = AES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "cbc(sm4)",
+			.cra_driver_name = "cbc-sm4-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = SM4_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_sm4_cbc_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = SM4_KEY_SIZE,
+		.max_keysize = SM4_KEY_SIZE,
+		.ivsize = SM4_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "ecb(sm4)",
+			.cra_driver_name = "ecb-sm4-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = SM4_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_sm4_ecb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = SM4_KEY_SIZE,
+		.max_keysize = SM4_KEY_SIZE,
+		.ivsize = 0,
+	},
+	{
+		.base = {
+			.cra_name = "ctr(sm4)",
+			.cra_driver_name = "ctr-sm4-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = SM4_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_sm4_ctr_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = SM4_KEY_SIZE,
+		.max_keysize = SM4_KEY_SIZE,
+		.ivsize = SM4_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "cfb(sm4)",
+			.cra_driver_name = "cfb-sm4-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = SM4_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_sm4_cfb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = SM4_KEY_SIZE,
+		.max_keysize = SM4_KEY_SIZE,
+		.ivsize = SM4_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "ofb(sm4)",
+			.cra_driver_name = "ofb-sm4-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = SM4_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_sm4_ofb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = SM4_KEY_SIZE,
+		.max_keysize = SM4_KEY_SIZE,
+		.ivsize = SM4_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "xts(sm4)",
+			.cra_driver_name = "xts-sm4-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = SM4_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_sm4_xts_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = SM4_KEY_SIZE * 2,
+		.max_keysize = SM4_KEY_SIZE * 2,
+		.ivsize = SM4_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "cbc(des)",
+			.cra_driver_name = "cbc-des-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_des_cbc_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES_KEY_SIZE,
+		.max_keysize = DES_KEY_SIZE,
+		.ivsize = DES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "ecb(des)",
+			.cra_driver_name = "ecb-des-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_des_ecb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES_KEY_SIZE,
+		.max_keysize = DES_KEY_SIZE,
+		.ivsize = 0,
+	},
+	{
+		.base = {
+			.cra_name = "ctr(des)",
+			.cra_driver_name = "ctr-des-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_des_ctr_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES_KEY_SIZE,
+		.max_keysize = DES_KEY_SIZE,
+		.ivsize = DES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "cfb(des)",
+			.cra_driver_name = "cfb-des-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_des_cfb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES_KEY_SIZE,
+		.max_keysize = DES_KEY_SIZE,
+		.ivsize = DES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "ofb(des)",
+			.cra_driver_name = "ofb-des-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_des_ofb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES_KEY_SIZE,
+		.max_keysize = DES_KEY_SIZE,
+		.ivsize = DES_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "cbc(des3_ede)",
+			.cra_driver_name = "cbc-des3_ede-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_3des_cbc_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES3_EDE_KEY_SIZE,
+		.max_keysize = DES3_EDE_KEY_SIZE,
+		.ivsize = DES3_EDE_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "ecb(des3_ede)",
+			.cra_driver_name = "ecb-des3_ede-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_3des_ecb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES3_EDE_KEY_SIZE,
+		.max_keysize = DES3_EDE_KEY_SIZE,
+		.ivsize = 0,
+	},
+	{
+		.base = {
+			.cra_name = "ctr(des3_ede)",
+			.cra_driver_name = "ctr-des3_ede-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_3des_ctr_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES3_EDE_KEY_SIZE,
+		.max_keysize = DES3_EDE_KEY_SIZE,
+		.ivsize = DES3_EDE_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "cfb(des3_ede)",
+			.cra_driver_name = "cfb-des3_ede-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_3des_cfb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES3_EDE_KEY_SIZE,
+		.max_keysize = DES3_EDE_KEY_SIZE,
+		.ivsize = DES3_EDE_BLOCK_SIZE,
+	},
+	{
+		.base = {
+			.cra_name = "ofb(des3_ede)",
+			.cra_driver_name = "ofb-des3_ede-ycc",
+			.cra_priority = 4001,
+			.cra_flags = CRYPTO_ALG_ASYNC,
+			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct ycc_crypto_ctx),
+			.cra_module = THIS_MODULE,
+		},
+		.init = ycc_skcipher_init,
+		.exit = ycc_skcipher_exit,
+		.setkey = ycc_skcipher_3des_ofb_setkey,
+		.encrypt = ycc_skcipher_encrypt,
+		.decrypt = ycc_skcipher_decrypt,
+		.min_keysize = DES3_EDE_KEY_SIZE,
+		.max_keysize = DES3_EDE_KEY_SIZE,
+		.ivsize = DES3_EDE_BLOCK_SIZE,
+	},
+};
+
+int ycc_sym_register(void)
+{
+	return crypto_register_skciphers(ycc_skciphers, ARRAY_SIZE(ycc_skciphers));
+}
+
+void ycc_sym_unregister(void)
+{
+	crypto_unregister_skciphers(ycc_skciphers, ARRAY_SIZE(ycc_skciphers));
+}