From d0e83059a6c9b04f00264a74b8f6439948de4613 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 20 Apr 2015 13:39:03 +0800 Subject: crypto: rng - Convert crypto_rng to new style crypto_type This patch converts the top-level crypto_rng to the "new" style. It was the last algorithm type added before we switched over to the new way of doing things exemplified by shash. All users will automatically switch over to the new interface. Note that this patch does not touch the low-level interface to rng implementations. Signed-off-by: Herbert Xu --- include/linux/crypto.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 10df5d2d093a..781f7d546020 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -655,19 +655,12 @@ struct compress_tfm { u8 *dst, unsigned int *dlen); }; -struct rng_tfm { - int (*rng_gen_random)(struct crypto_rng *tfm, u8 *rdata, - unsigned int dlen); - int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); -}; - #define crt_ablkcipher crt_u.ablkcipher #define crt_aead crt_u.aead #define crt_blkcipher crt_u.blkcipher #define crt_cipher crt_u.cipher #define crt_hash crt_u.hash #define crt_compress crt_u.compress -#define crt_rng crt_u.rng struct crypto_tfm { @@ -680,7 +673,6 @@ struct crypto_tfm { struct cipher_tfm cipher; struct hash_tfm hash; struct compress_tfm compress; - struct rng_tfm rng; } crt_u; void (*exit)(struct crypto_tfm *tfm); @@ -714,10 +706,6 @@ struct crypto_hash { struct crypto_tfm base; }; -struct crypto_rng { - struct crypto_tfm base; -}; - enum { CRYPTOA_UNSPEC, CRYPTOA_ALG, -- cgit v1.2.3 From acec27ff35af9caf34d76d16ee17ff3b292e7d83 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Apr 2015 10:46:38 +0800 Subject: crypto: rng - Convert low-level crypto_rng to new style 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(-) (limited to 'include/linux') diff --git a/crypto/rng.c b/crypto/rng.c index f1d64948f6fc..5e0425a24657 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 896973369573..76f3c9519ba5 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 7fca37144b59..133f0441ad3e 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 781f7d546020..2fa9b05360f7 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); -- cgit v1.2.3 From 94f1bb15bed84ad6c893916b7e7b9db6f1d7eec6 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Apr 2015 10:46:46 +0800 Subject: crypto: rng - Remove old low-level rng interface Now that all rng implementations have switched over to the new interface, we can remove the old low-level interface. Signed-off-by: Herbert Xu --- crypto/rng.c | 57 +++---------------------------------------- include/crypto/internal/rng.h | 3 +-- include/crypto/rng.h | 10 +++----- include/linux/crypto.h | 30 ----------------------- 4 files changed, 8 insertions(+), 92 deletions(-) (limited to 'include/linux') diff --git a/crypto/rng.c b/crypto/rng.c index e98ce1ca527d..055e276427b1 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -4,6 +4,7 @@ * RNG operations. * * Copyright (c) 2008 Neil Horman + * Copyright (c) 2015 Herbert Xu * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -36,39 +37,6 @@ 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_old_rng_alg(tfm)->rng_make_random(tfm, dst, dlen); -} - -static int rngapi_reset(struct crypto_rng *tfm, const u8 *seed, - unsigned int slen) -{ - u8 *buf = NULL; - u8 *src = (u8 *)seed; - int err; - - if (slen) { - buf = kmalloc(slen, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - memcpy(buf, seed, slen); - src = buf; - } - - err = crypto_old_rng_alg(tfm)->rng_reset(tfm, src, slen); - - kzfree(buf); - return err; -} - int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen) { u8 *buf = NULL; @@ -83,7 +51,7 @@ int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen) seed = buf; } - err = tfm->seed(tfm, seed, slen); + err = crypto_rng_alg(tfm)->seed(tfm, seed, slen); kfree(buf); return err; @@ -92,21 +60,6 @@ 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 = alg->generate; - rng->seed = alg->seed; - rng->seedsize = alg->seedsize; - return 0; } @@ -114,8 +67,7 @@ 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; + return ralg->seedsize; } #ifdef CONFIG_NET @@ -150,7 +102,7 @@ static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) seq_printf(m, "seedsize : %u\n", seedsize(alg)); } -const struct crypto_type crypto_rng_type = { +static const struct crypto_type crypto_rng_type = { .extsize = crypto_alg_extsize, .init_tfm = crypto_rng_init_tfm, #ifdef CONFIG_PROC_FS @@ -162,7 +114,6 @@ const struct crypto_type crypto_rng_type = { .type = CRYPTO_ALG_TYPE_RNG, .tfmsize = offsetof(struct crypto_rng, base), }; -EXPORT_SYMBOL_GPL(crypto_rng_type); struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask) { diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h index 2c9a865c66e2..263f1a5eebc7 100644 --- a/include/crypto/internal/rng.h +++ b/include/crypto/internal/rng.h @@ -2,6 +2,7 @@ * RNG: Random Number Generator algorithms under the crypto API * * Copyright (c) 2008 Neil Horman + * Copyright (c) 2015 Herbert Xu * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -16,8 +17,6 @@ #include #include -extern const struct crypto_type crypto_rng_type; - int crypto_register_rng(struct rng_alg *alg); void crypto_unregister_rng(struct rng_alg *alg); int crypto_register_rngs(struct rng_alg *algs, int count); diff --git a/include/crypto/rng.h b/include/crypto/rng.h index cc22e52a129a..c5d4684429f5 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -2,6 +2,7 @@ * RNG: Random Number Generator algorithms under the crypto API * * Copyright (c) 2008 Neil Horman + * Copyright (c) 2015 Herbert Xu * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -56,11 +57,6 @@ struct rng_alg { }; 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; }; @@ -144,7 +140,7 @@ static inline int crypto_rng_generate(struct crypto_rng *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int dlen) { - return tfm->generate(tfm, src, slen, dst, dlen); + return crypto_rng_alg(tfm)->generate(tfm, src, slen, dst, dlen); } /** @@ -198,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 tfm->seedsize; + return crypto_rng_alg(tfm)->seedsize; } #endif diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 2fa9b05360f7..ee14140f8893 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -138,7 +138,6 @@ struct crypto_async_request; struct crypto_aead; struct crypto_blkcipher; struct crypto_hash; -struct crypto_rng; struct crypto_tfm; struct crypto_type; struct aead_givcrypt_request; @@ -426,40 +425,12 @@ struct compress_alg { unsigned int slen, u8 *dst, unsigned int *dlen); }; -/** - * 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 - * call. - * @rng_reset: Reset of the random number generator by clearing the entire state. - * With the invocation of this function call, the random number - * generator shall completely reinitialize its state. 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 like the SP800-90A DRBG 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. - */ -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); - - unsigned int seedsize; -}; - #define cra_ablkcipher cra_u.ablkcipher #define cra_aead cra_u.aead #define cra_blkcipher cra_u.blkcipher #define cra_cipher cra_u.cipher #define cra_compress cra_u.compress -#define cra_rng cra_u.rng /** * struct crypto_alg - definition of a cryptograpic cipher algorithm @@ -559,7 +530,6 @@ struct crypto_alg { struct blkcipher_alg blkcipher; struct cipher_alg cipher; struct compress_alg compress; - struct old_rng_alg rng; } cra_u; int (*cra_init)(struct crypto_tfm *tfm); -- cgit v1.2.3 From 59afdc7b32143528524455039e7557a46b60e4c8 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 22 Apr 2015 11:28:46 +0800 Subject: crypto: api - Move module sig ifdef into accessor function Currently we're hiding mod->sig_ok under an ifdef in open code. This patch adds a module_sig_ok accessor function and removes that ifdef. Signed-off-by: Herbert Xu Acked-by: Rusty Russell --- crypto/algapi.c | 5 +---- include/linux/module.h | 12 ++++++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/crypto/algapi.c b/crypto/algapi.c index a60f62625b5f..f835f439bb23 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -43,12 +43,9 @@ static inline int crypto_set_driver_name(struct crypto_alg *alg) static inline void crypto_check_module_sig(struct module *mod) { -#ifdef CONFIG_CRYPTO_FIPS - if (fips_enabled && mod && !mod->sig_ok) + if (fips_enabled && mod && !module_sig_ok(mod)) panic("Module %s signature verification failed in FIPS mode\n", mod->name); -#endif - return; } static int crypto_check_alg(struct crypto_alg *alg) diff --git a/include/linux/module.h b/include/linux/module.h index c883b86ea964..1e5436042eb0 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -655,4 +655,16 @@ static inline void module_bug_finalize(const Elf_Ehdr *hdr, static inline void module_bug_cleanup(struct module *mod) {} #endif /* CONFIG_GENERIC_BUG */ +#ifdef CONFIG_MODULE_SIG +static inline bool module_sig_ok(struct module *module) +{ + return module->sig_ok; +} +#else /* !CONFIG_MODULE_SIG */ +static inline bool module_sig_ok(struct module *module) +{ + return true; +} +#endif /* CONFIG_MODULE_SIG */ + #endif /* _LINUX_MODULE_H */ -- cgit v1.2.3 From 2da572c959dd5815aef153cf62010b16a498a0d3 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2015 13:49:14 -0400 Subject: lib: add software 842 compression/decompression Add 842-format software compression and decompression functions. Update the MAINTAINERS 842 section to include the new files. The 842 compression function can compress any input data into the 842 compression format. The 842 decompression function can decompress any standard-format 842 compressed data - specifically, either a compressed data buffer created by the 842 software compression function, or a compressed data buffer created by the 842 hardware compressor (located in PowerPC coprocessors). The 842 compressed data format is explained in the header comments. This is used in a later patch to provide a full software 842 compression and decompression crypto interface. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- MAINTAINERS | 2 + include/linux/sw842.h | 12 + lib/842/842.h | 127 ++++++++++ lib/842/842_compress.c | 626 +++++++++++++++++++++++++++++++++++++++++++++++ lib/842/842_debugfs.h | 52 ++++ lib/842/842_decompress.c | 405 ++++++++++++++++++++++++++++++ lib/842/Makefile | 2 + lib/Kconfig | 6 + lib/Makefile | 2 + 9 files changed, 1234 insertions(+) create mode 100644 include/linux/sw842.h create mode 100644 lib/842/842.h create mode 100644 lib/842/842_compress.c create mode 100644 lib/842/842_debugfs.h create mode 100644 lib/842/842_decompress.c create mode 100644 lib/842/Makefile (limited to 'include/linux') diff --git a/MAINTAINERS b/MAINTAINERS index 56a432d51119..96684fd49abc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4863,6 +4863,8 @@ M: Dan Streetman S: Supported F: drivers/crypto/nx/nx-842.c F: include/linux/nx842.h +F: include/linux/sw842.h +F: lib/842/ IBM Power Linux RAID adapter M: Brian King diff --git a/include/linux/sw842.h b/include/linux/sw842.h new file mode 100644 index 000000000000..109ba041c2ae --- /dev/null +++ b/include/linux/sw842.h @@ -0,0 +1,12 @@ +#ifndef __SW842_H__ +#define __SW842_H__ + +#define SW842_MEM_COMPRESS (0xf000) + +int sw842_compress(const u8 *src, unsigned int srclen, + u8 *dst, unsigned int *destlen, void *wmem); + +int sw842_decompress(const u8 *src, unsigned int srclen, + u8 *dst, unsigned int *destlen); + +#endif diff --git a/lib/842/842.h b/lib/842/842.h new file mode 100644 index 000000000000..7c200030acf7 --- /dev/null +++ b/lib/842/842.h @@ -0,0 +1,127 @@ + +#ifndef __842_H__ +#define __842_H__ + +/* The 842 compressed format is made up of multiple blocks, each of + * which have the format: + * + *