diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 49d5b08..9637365 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -244,14 +244,121 @@ static void skcipher_data_wakeup(struct sock *sk)
 	rcu_read_unlock();
 }
 
+static inline bool skcipher_is_aead(struct crypto_tfm *tfm)
+{
+	return ((crypto_tfm_alg_type(tfm) & CRYPTO_ALG_TYPE_MASK) ==
+		CRYPTO_ALG_TYPE_AEAD);
+}
+
+static inline unsigned int skcipher_crypto_ivsize(void *private)
+{
+	if (skcipher_is_aead(private))
+		return crypto_aead_ivsize(private);
+	else
+		return crypto_ablkcipher_ivsize(private);
+}
+
+static inline unsigned int skcipher_crypto_ivsize_ctx(struct skcipher_ctx *ctx)
+{
+	if (ctx->aead)
+		return crypto_aead_ivsize(crypto_aead_reqtfm(&ctx->u.aead_req));
+	else
+		return crypto_ablkcipher_ivsize(
+			crypto_ablkcipher_reqtfm(&ctx->u.ablkcipher_req));
+}
+
+static inline unsigned int skcipher_crypto_blocksize(struct skcipher_ctx *ctx)
+{
+	if (ctx->aead)
+		return crypto_aead_blocksize(
+			crypto_aead_reqtfm(&ctx->u.aead_req));
+	else
+		return crypto_ablkcipher_blocksize(
+			crypto_ablkcipher_reqtfm(&ctx->u.ablkcipher_req));
+}
+
+static inline unsigned int skcipher_crypto_reqsize(void *private)
+{
+	if (skcipher_is_aead(private))
+		return crypto_aead_reqsize(private);
+	else
+		return crypto_ablkcipher_reqsize(private);
+}
+
+static inline unsigned int skcipher_crypto_setkey(void *private, const u8 *key,
+						  unsigned int keylen)
+{
+	if (skcipher_is_aead(private))
+		return crypto_aead_setkey(private, key, keylen);
+	else
+		return crypto_ablkcipher_setkey(private, key, keylen);
+}
+
+static inline void skcipher_crypto_free(void *private)
+{
+	if (skcipher_is_aead(private))
+		crypto_free_aead(private);
+	else
+		crypto_free_ablkcipher(private);
+}
+
+static inline void skcipher_request_set_tfm(struct skcipher_ctx *ctx, void *tfm)
+{
+	if (ctx->aead)
+		aead_request_set_tfm(&ctx->u.aead_req, tfm);
+	else
+		ablkcipher_request_set_tfm(&ctx->u.ablkcipher_req, tfm);
+}
+
+static inline int skcipher_crypto_encrypt(struct skcipher_ctx *ctx)
+{
+	if (ctx->aead)
+		return crypto_aead_encrypt(&ctx->u.aead_req);
+	else
+		return crypto_ablkcipher_encrypt(&ctx->u.ablkcipher_req);
+}
+
+static inline int skcipher_crypto_decrypt(struct skcipher_ctx *ctx)
+{
+	if (ctx->aead)
+		return crypto_aead_decrypt(&ctx->u.aead_req);
+	else
+		return crypto_ablkcipher_decrypt(&ctx->u.ablkcipher_req);
+}
+
+static inline void skcipher_crypto_set_crypt(struct skcipher_ctx *ctx,
+					     struct scatterlist *src,
+					     struct scatterlist *dst,
+					     unsigned int cryptlen, u8 *iv)
+{
+	if (ctx->aead)
+		return aead_request_set_crypt(&ctx->u.aead_req, src, dst,
+					      cryptlen, iv);
+	else
+		return ablkcipher_request_set_crypt(&ctx->u.ablkcipher_req, src,
+						    dst, cryptlen, iv);
+}
+
+static inline void skcipher_request_set_callback(struct skcipher_ctx *ctx,
+						 u32 flags,
+						 crypto_completion_t complete,
+						 void *data)
+{
+	if (ctx->aead)
+		aead_request_set_callback(&ctx->u.aead_req, flags, complete,
+					  data);
+	else
+		ablkcipher_request_set_callback(&ctx->u.ablkcipher_req, flags,
+						complete, data);
+}
+
 static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock,
 			    struct msghdr *msg, size_t size)
 {
 	struct sock *sk = sock->sk;
 	struct alg_sock *ask = alg_sk(sk);
 	struct skcipher_ctx *ctx = ask->private;
-	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req);
-	unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
+	unsigned ivsize = skcipher_crypto_ivsize_ctx(ctx);
 	struct skcipher_sg_list *sgl;
 	struct af_alg_control con = {};
 	long copied = 0;
@@ -429,8 +536,7 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
 	struct sock *sk = sock->sk;
 	struct alg_sock *ask = alg_sk(sk);
 	struct skcipher_ctx *ctx = ask->private;
-	unsigned bs = crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(
-		&ctx->req));
+	unsigned bs = skcipher_crypto_blocksize(ctx);
 	struct skcipher_sg_list *sgl;
 	struct scatterlist *sg;
 	unsigned long iovlen;
@@ -480,8 +586,8 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
 
 			err = af_alg_wait_for_completion(
 				ctx->enc ?
-					crypto_ablkcipher_encrypt(&ctx->req) :
-					crypto_ablkcipher_decrypt(&ctx->req),
+					skcipher_crypto_encrypt(ctx) :
+					skcipher_crypto_decrypt(ctx),
 				&ctx->completion);
 
 free:
@@ -556,23 +662,23 @@ static void *skcipher_bind(const char *name, u32 type, u32 mask)
 
 static void skcipher_release(void *private)
 {
-	crypto_free_ablkcipher(private);
+	skcipher_crypto_free(private);
 }
 
 static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-	return crypto_ablkcipher_setkey(private, key, keylen);
+	return skcipher_crypto_setkey(private, key, keylen);
 }
 
 static void skcipher_sock_destruct(struct sock *sk)
 {
 	struct alg_sock *ask = alg_sk(sk);
 	struct skcipher_ctx *ctx = ask->private;
-	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req);
+	unsigned int ivlen = skcipher_crypto_ivsize_ctx(ctx);
 
 	skcipher_free_sgl(sk);
-	memzero_explicit(ctx->iv, crypto_ablkcipher_ivsize(tfm));
-	sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm));
+	memzero_explicit(ctx->iv, ivlen);
+	sock_kfree_s(sk, ctx->iv, ivlen);
 	sock_kfree_s(sk, ctx, ctx->len);
 	af_alg_release_parent(sk);
 }
@@ -581,20 +687,20 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 {
 	struct skcipher_ctx *ctx;
 	struct alg_sock *ask = alg_sk(sk);
-	unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private);
+	unsigned int len = sizeof(*ctx) + skcipher_crypto_reqsize(private);
+	unsigned int ivlen = skcipher_crypto_ivsize(private);
 
 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
 
-	ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private),
-			       GFP_KERNEL);
+	ctx->iv = sock_kmalloc(sk, ivlen, GFP_KERNEL);
 	if (!ctx->iv) {
 		sock_kfree_s(sk, ctx, len);
 		return -ENOMEM;
 	}
 
-	memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private));
+	memset(ctx->iv, 0, ivlen);
 
 	INIT_LIST_HEAD(&ctx->tsgl);
 	ctx->len = len;
@@ -602,13 +708,14 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 	ctx->more = 0;
 	ctx->merge = 0;
 	ctx->enc = 0;
+	ctx->aead = skcipher_is_aead(private);
 	af_alg_init_completion(&ctx->completion);
 
 	ask->private = ctx;
 
-	ablkcipher_request_set_tfm(&ctx->req, private);
-	ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-					af_alg_complete, &ctx->completion);
+	skcipher_request_set_tfm(ctx, private);
+	skcipher_request_set_callback(ctx, CRYPTO_TFM_REQ_MAY_BACKLOG,
+				      af_alg_complete, &ctx->completion);
 
 	sk->sk_destruct = skcipher_sock_destruct;
 
