From patchwork Tue Apr 21 02:46:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 6245211 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1D3C0BF4A6 for ; Tue, 21 Apr 2015 02:46:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E9E762041F for ; Tue, 21 Apr 2015 02:46:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C04DF20435 for ; Tue, 21 Apr 2015 02:46:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751930AbbDUCql (ORCPT ); Mon, 20 Apr 2015 22:46:41 -0400 Received: from helcar.hengli.com.au ([209.40.204.226]:50682 "EHLO helcar.hengli.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751764AbbDUCql (ORCPT ); Mon, 20 Apr 2015 22:46:41 -0400 Received: from gondolin.me.apana.org.au ([192.168.0.6]) by norbury.hengli.com.au with esmtp (Exim 4.80 #3 (Debian)) id 1YkOCs-0001lh-P9; Tue, 21 Apr 2015 12:46:38 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 4.80) (envelope-from ) id 1YkOCs-0007Jp-CU; Tue, 21 Apr 2015 10:46:38 +0800 Subject: [v2 PATCH 2/11] crypto: rng - Convert low-level crypto_rng to new style References: <20150421024436.GA28057@gondor.apana.org.au> To: Linux Crypto Mailing List , Stephan Mueller Message-Id: From: Herbert Xu Date: Tue, 21 Apr 2015 10:46:38 +0800 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 This patch converts the low-level crypto_rng interface to the "new" style. This allows existing implementations to be converted over one- by-one. Once that is complete we can then remove the old rng interface. Signed-off-by: Herbert Xu --- crypto/rng.c | 56 +++++++++++++++++++++++++++++++++++++----- include/crypto/internal/rng.h | 3 ++ include/crypto/rng.h | 42 ++++++++++++++++++++++++++++++- include/linux/crypto.h | 6 ++-- 4 files changed, 96 insertions(+), 11 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/crypto/rng.c b/crypto/rng.c index f1d6494..5e0425a 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -36,10 +36,15 @@ static inline struct crypto_rng *__crypto_rng_cast(struct crypto_tfm *tfm) return container_of(tfm, struct crypto_rng, base); } +static inline struct old_rng_alg *crypto_old_rng_alg(struct crypto_rng *tfm) +{ + return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng; +} + static int generate(struct crypto_rng *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int dlen) { - return crypto_rng_alg(tfm)->rng_make_random(tfm, dst, dlen); + return crypto_old_rng_alg(tfm)->rng_make_random(tfm, dst, dlen); } static int rngapi_reset(struct crypto_rng *tfm, const u8 *seed, @@ -58,7 +63,7 @@ static int rngapi_reset(struct crypto_rng *tfm, const u8 *seed, src = buf; } - err = crypto_rng_alg(tfm)->rng_reset(tfm, src, slen); + err = crypto_old_rng_alg(tfm)->rng_reset(tfm, src, slen); kzfree(buf); return err; @@ -88,13 +93,31 @@ EXPORT_SYMBOL_GPL(crypto_rng_reset); static int crypto_rng_init_tfm(struct crypto_tfm *tfm) { struct crypto_rng *rng = __crypto_rng_cast(tfm); + struct rng_alg *alg = crypto_rng_alg(rng); + struct old_rng_alg *oalg = crypto_old_rng_alg(rng); + + if (oalg->rng_make_random) { + rng->generate = generate; + rng->seed = rngapi_reset; + rng->seedsize = oalg->seedsize; + return 0; + } - rng->generate = generate; - rng->seed = rngapi_reset; + rng->generate = alg->generate; + rng->seed = alg->seed; + rng->seedsize = alg->seedsize; return 0; } +static unsigned int seedsize(struct crypto_alg *alg) +{ + struct rng_alg *ralg = container_of(alg, struct rng_alg, base); + + return alg->cra_rng.rng_make_random ? + alg->cra_rng.seedsize : ralg->seedsize; +} + #ifdef CONFIG_NET static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) { @@ -102,7 +125,7 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) strncpy(rrng.type, "rng", sizeof(rrng.type)); - rrng.seedsize = alg->cra_rng.seedsize; + rrng.seedsize = seedsize(alg); if (nla_put(skb, CRYPTOCFGA_REPORT_RNG, sizeof(struct crypto_report_rng), &rrng)) @@ -124,7 +147,7 @@ static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) { seq_printf(m, "type : rng\n"); - seq_printf(m, "seedsize : %u\n", alg->cra_rng.seedsize); + seq_printf(m, "seedsize : %u\n", seedsize(alg)); } const struct crypto_type crypto_rng_type = { @@ -189,5 +212,26 @@ void crypto_put_default_rng(void) } EXPORT_SYMBOL_GPL(crypto_put_default_rng); +int crypto_register_rng(struct rng_alg *alg) +{ + struct crypto_alg *base = &alg->base; + + if (alg->seedsize > PAGE_SIZE / 8) + return -EINVAL; + + base->cra_type = &crypto_rng_type; + base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; + base->cra_flags |= CRYPTO_ALG_TYPE_RNG; + + return crypto_register_alg(base); +} +EXPORT_SYMBOL_GPL(crypto_register_rng); + +void crypto_unregister_rng(struct rng_alg *alg) +{ + crypto_unregister_alg(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_unregister_rng); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Random Number Generator"); diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h index 8969733..76f3c95 100644 --- a/include/crypto/internal/rng.h +++ b/include/crypto/internal/rng.h @@ -18,6 +18,9 @@ extern const struct crypto_type crypto_rng_type; +int crypto_register_rng(struct rng_alg *alg); +void crypto_unregister_rng(struct rng_alg *alg); + static inline void *crypto_rng_ctx(struct crypto_rng *tfm) { return crypto_tfm_ctx(&tfm->base); diff --git a/include/crypto/rng.h b/include/crypto/rng.h index 7fca371..133f044 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -15,11 +15,48 @@ #include +struct crypto_rng; + +/** + * struct rng_alg - random number generator definition + * + * @generate: The function defined by this variable obtains a + * random number. The random number generator transform + * must generate the random number out of the context + * provided with this call, plus any additional data + * if provided to the call. + * @seed: Seed or reseed the random number generator. With the + * invocation of this function call, the random number + * generator shall become ready fo generation. If the + * random number generator requires a seed for setting + * up a new state, the seed must be provided by the + * consumer while invoking this function. The required + * size of the seed is defined with @seedsize . + * @seedsize: The seed size required for a random number generator + * initialization defined with this variable. Some + * random number generators does not require a seed + * as the seeding is implemented internally without + * the need of support by the consumer. In this case, + * the seed size is set to zero. + * @base: Common crypto API algorithm data structure. + */ +struct rng_alg { + int (*generate)(struct crypto_rng *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int dlen); + int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); + + unsigned int seedsize; + + struct crypto_alg base; +}; + struct crypto_rng { int (*generate)(struct crypto_rng *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int dlen); int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); + unsigned int seedsize; struct crypto_tfm base; }; @@ -72,7 +109,8 @@ static inline struct crypto_tfm *crypto_rng_tfm(struct crypto_rng *tfm) */ static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm) { - return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng; + return container_of(crypto_rng_tfm(tfm)->__crt_alg, + struct rng_alg, base); } /** @@ -156,7 +194,7 @@ int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, */ static inline int crypto_rng_seedsize(struct crypto_rng *tfm) { - return crypto_rng_alg(tfm)->seedsize; + return tfm->seedsize; } #endif diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 781f7d5..2fa9b05 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -427,7 +427,7 @@ struct compress_alg { }; /** - * struct rng_alg - random number generator definition + * struct old_rng_alg - random number generator definition * @rng_make_random: The function defined by this variable obtains a random * number. The random number generator transform must generate * the random number out of the context provided with this @@ -445,7 +445,7 @@ struct compress_alg { * seeding is implemented internally without the need of support by * the consumer. In this case, the seed size is set to zero. */ -struct rng_alg { +struct old_rng_alg { int (*rng_make_random)(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen); int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); @@ -559,7 +559,7 @@ struct crypto_alg { struct blkcipher_alg blkcipher; struct cipher_alg cipher; struct compress_alg compress; - struct rng_alg rng; + struct old_rng_alg rng; } cra_u; int (*cra_init)(struct crypto_tfm *tfm);