From patchwork Fri Nov 21 05:30:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 5352921 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Original-To: patchwork-linux-crypto@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 56300C11AC for ; Fri, 21 Nov 2014 05:43:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5029620176 for ; Fri, 21 Nov 2014 05:43:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3694920172 for ; Fri, 21 Nov 2014 05:43:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757978AbaKUFne (ORCPT ); Fri, 21 Nov 2014 00:43:34 -0500 Received: from mail.eperm.de ([89.247.134.16]:54757 "EHLO mail.eperm.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757431AbaKUFmu (ORCPT ); Fri, 21 Nov 2014 00:42:50 -0500 X-AuthUser: sm@eperm.de Received: from tachyon.chronox.de by mail.eperm.de with [XMail 1.27 ESMTP Server] id for from ; Fri, 21 Nov 2014 06:42:48 +0100 From: Stephan Mueller To: Herbert Xu Cc: Daniel Borkmann , 'Quentin Gouchet' , lkml - Kernel Mailing List , linux-crypto@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v3 3/7] crypto: AF_ALG: crypto API calls to inline functions Date: Fri, 21 Nov 2014 06:30:49 +0100 Message-ID: <6008064.Pc9dQem1Ya@tachyon.chronox.de> User-Agent: KMail/4.14.3 (Linux/3.17.3-300.fc21.x86_64; KDE/4.14.3; x86_64; ; ) In-Reply-To: <4088013.2O8zCP0xXa@tachyon.chronox.de> References: <4088013.2O8zCP0xXa@tachyon.chronox.de> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To avoid excessive branches and cluttering the code, all kernel crypto API calls are extracted into separate inline functions. These functions invoke either the ablkcipher or the aead crypto API function calls, as necessary. Signed-off-by: Stephan Mueller --- crypto/algif_skcipher.c | 143 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 18 deletions(-) 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;