From 76899a41f830d17affe6f9c58cc4b23ba26f5e00 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Sat, 18 Apr 2015 19:36:17 +0200 Subject: crypto: drbg - replace spinlock with mutex The creation of a shadow copy is intended to only hold a short term lock. But the drawback is that parallel users have a very similar DRBG state which only differs by a high-resolution time stamp. The DRBG will now hold a long term lock. Therefore, the lock is changed to a mutex which implies that the DRBG can only be used in process context. The lock now guards the instantiation as well as the entire DRBG generation operation. Therefore, multiple callers are fully serialized when generating a random number. As the locking is changed to use a long-term lock to avoid such similar DRBG states, the entire creation and maintenance of a shadow copy can be removed. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/drbg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index 5186f750c713..a43a7ed4d9fc 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include /* @@ -104,7 +104,7 @@ struct drbg_test_data { }; struct drbg_state { - spinlock_t drbg_lock; /* lock around DRBG */ + struct mutex drbg_mutex; /* lock around DRBG */ unsigned char *V; /* internal state 10.1.1.1 1a) */ /* hash: static value 10.1.1.1 1b) hmac / ctr: key */ unsigned char *C; -- cgit v1.2.3 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/crypto/rng.h | 32 ++++++++++---------------------- include/linux/crypto.h | 12 ------------ 2 files changed, 10 insertions(+), 34 deletions(-) (limited to 'include') diff --git a/include/crypto/rng.h b/include/crypto/rng.h index 6e28ea5be9f1..f13f3faca4d7 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -15,6 +15,12 @@ #include +struct crypto_rng { + int (*generate)(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen); + int (*seed)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); + struct crypto_tfm base; +}; + extern struct crypto_rng *crypto_default_rng; int crypto_get_default_rng(void); @@ -27,11 +33,6 @@ void crypto_put_default_rng(void); * CRYPTO_ALG_TYPE_RNG (listed as type "rng" in /proc/crypto) */ -static inline struct crypto_rng *__crypto_rng_cast(struct crypto_tfm *tfm) -{ - return (struct crypto_rng *)tfm; -} - /** * crypto_alloc_rng() -- allocate RNG handle * @alg_name: is the cra_name / name or cra_driver_name / driver name of the @@ -52,15 +53,7 @@ static inline struct crypto_rng *__crypto_rng_cast(struct crypto_tfm *tfm) * Return: allocated cipher handle in case of success; IS_ERR() is true in case * of an error, PTR_ERR() returns the error code. */ -static inline struct crypto_rng *crypto_alloc_rng(const char *alg_name, - u32 type, u32 mask) -{ - type &= ~CRYPTO_ALG_TYPE_MASK; - type |= CRYPTO_ALG_TYPE_RNG; - mask |= CRYPTO_ALG_TYPE_MASK; - - return __crypto_rng_cast(crypto_alloc_base(alg_name, type, mask)); -} +struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask); static inline struct crypto_tfm *crypto_rng_tfm(struct crypto_rng *tfm) { @@ -80,18 +73,13 @@ static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm) return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng; } -static inline struct rng_tfm *crypto_rng_crt(struct crypto_rng *tfm) -{ - return &crypto_rng_tfm(tfm)->crt_rng; -} - /** * crypto_free_rng() - zeroize and free RNG handle * @tfm: cipher handle to be freed */ static inline void crypto_free_rng(struct crypto_rng *tfm) { - crypto_free_tfm(crypto_rng_tfm(tfm)); + crypto_destroy_tfm(tfm, crypto_rng_tfm(tfm)); } /** @@ -108,7 +96,7 @@ static inline void crypto_free_rng(struct crypto_rng *tfm) static inline int crypto_rng_get_bytes(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen) { - return crypto_rng_crt(tfm)->rng_gen_random(tfm, rdata, dlen); + return tfm->generate(tfm, rdata, dlen); } /** @@ -131,7 +119,7 @@ static inline int crypto_rng_get_bytes(struct crypto_rng *tfm, static inline int crypto_rng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) { - return crypto_rng_crt(tfm)->rng_reset(tfm, seed, slen); + return tfm->seed(tfm, seed, slen); } /** 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 ff030b099a21a4753af575b4304249e88400e506 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 20 Apr 2015 13:39:04 +0800 Subject: crypto: rng - Introduce crypto_rng_generate This patch adds the new top-level function crypto_rng_generate which generates random numbers with additional input. It also extends the mid-level rng_gen_random function to take additional data as input. Signed-off-by: Herbert Xu --- include/crypto/rng.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/crypto/rng.h b/include/crypto/rng.h index f13f3faca4d7..f20f068154bc 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -16,7 +16,9 @@ #include struct crypto_rng { - int (*generate)(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen); + int (*generate)(struct crypto_rng *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int dlen); int (*seed)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); struct crypto_tfm base; }; @@ -82,6 +84,27 @@ static inline void crypto_free_rng(struct crypto_rng *tfm) crypto_destroy_tfm(tfm, crypto_rng_tfm(tfm)); } +/** + * crypto_rng_generate() - get random number + * @tfm: cipher handle + * @src: Input buffer holding additional data, may be NULL + * @slen: Length of additional data + * @dst: output buffer holding the random numbers + * @dlen: length of the output buffer + * + * This function fills the caller-allocated buffer with random + * numbers using the random number generator referenced by the + * cipher handle. + * + * Return: 0 function was successful; < 0 if an error occurred + */ +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); +} + /** * crypto_rng_get_bytes() - get random number * @tfm: cipher handle @@ -96,7 +119,7 @@ static inline void crypto_free_rng(struct crypto_rng *tfm) static inline int crypto_rng_get_bytes(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen) { - return tfm->generate(tfm, rdata, dlen); + return crypto_rng_generate(tfm, NULL, 0, rdata, dlen); } /** -- cgit v1.2.3 From 3c5d8fa9f56ad0928e7a1f06003e5034f5eedb52 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Apr 2015 10:46:37 +0800 Subject: crypto: rng - Mark crypto_rng_reset seed as const There is no reason why crypto_rng_reset should modify the seed so this patch marks it as const. Since our algorithms don't export a const seed function yet we have to go through some contortions for now. Signed-off-by: Herbert Xu --- include/crypto/rng.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/crypto/rng.h b/include/crypto/rng.h index f20f068154bc..7fca37144b59 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -19,7 +19,7 @@ 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, u8 *seed, unsigned int slen); + int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); struct crypto_tfm base; }; @@ -139,11 +139,8 @@ static inline int crypto_rng_get_bytes(struct crypto_rng *tfm, * * Return: 0 if the setting of the key was successful; < 0 if an error occurred */ -static inline int crypto_rng_reset(struct crypto_rng *tfm, - u8 *seed, unsigned int slen) -{ - return tfm->seed(tfm, seed, slen); -} +int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, + unsigned int slen); /** * crypto_rng_seedsize() - obtain seed size of RNG -- 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 --- include/crypto/internal/rng.h | 3 +++ include/crypto/rng.h | 42 ++++++++++++++++++++++++++++++++++++++++-- include/linux/crypto.h | 6 +++--- 3 files changed, 46 insertions(+), 5 deletions(-) (limited to 'include') 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 7ca99d814821e8a8ac6d7c48b2ccfc24bda27b1f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Apr 2015 10:46:39 +0800 Subject: crypto: rng - Add crypto_rng_set_entropy This patch adds the function crypto_rng_set_entropy. It is only meant to be used by testmgr when testing RNG implementations by providing fixed entropy data in order to verify test vectors. Signed-off-by: Herbert Xu --- include/crypto/internal/rng.h | 6 ++++++ include/crypto/rng.h | 4 ++++ 2 files changed, 10 insertions(+) (limited to 'include') diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h index 76f3c9519ba5..93d41bcc444e 100644 --- a/include/crypto/internal/rng.h +++ b/include/crypto/internal/rng.h @@ -26,4 +26,10 @@ static inline void *crypto_rng_ctx(struct crypto_rng *tfm) return crypto_tfm_ctx(&tfm->base); } +static inline void crypto_rng_set_entropy(struct crypto_rng *tfm, + const u8 *data, unsigned int len) +{ + crypto_rng_alg(tfm)->set_ent(tfm, data, len); +} + #endif diff --git a/include/crypto/rng.h b/include/crypto/rng.h index 133f0441ad3e..cc22e52a129a 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -32,6 +32,8 @@ struct crypto_rng; * 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 . + * @set_ent: Set entropy that would otherwise be obtained from + * entropy source. Internal use only. * @seedsize: The seed size required for a random number generator * initialization defined with this variable. Some * random number generators does not require a seed @@ -45,6 +47,8 @@ struct rng_alg { const u8 *src, unsigned int slen, u8 *dst, unsigned int dlen); int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen); + void (*set_ent)(struct crypto_rng *tfm, const u8 *data, + unsigned int len); unsigned int seedsize; -- cgit v1.2.3 From 881cd6c570af412c2fab278b0656f7597dc5ee74 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Apr 2015 10:46:40 +0800 Subject: crypto: rng - Add multiple algorithm registration interface This patch adds the helpers that allow the registration and removal of multiple RNG algorithms. Signed-off-by: Herbert Xu --- include/crypto/internal/rng.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h index 93d41bcc444e..2c9a865c66e2 100644 --- a/include/crypto/internal/rng.h +++ b/include/crypto/internal/rng.h @@ -20,6 +20,8 @@ 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); +void crypto_unregister_rngs(struct rng_alg *algs, int count); static inline void *crypto_rng_ctx(struct crypto_rng *tfm) { -- cgit v1.2.3 From 8fded5925d0a733c46f8d0b5edd1c9b315882b1d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Apr 2015 10:46:41 +0800 Subject: crypto: drbg - Convert to new rng interface This patch converts the DRBG implementation to the new low-level rng interface. This allows us to get rid of struct drbg_gen by using the new RNG API instead. Signed-off-by: Herbert Xu Acked-by: Stephan Mueller --- include/crypto/drbg.h | 50 ++++++++++++-------------------------------------- 1 file changed, 12 insertions(+), 38 deletions(-) (limited to 'include') diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index a43a7ed4d9fc..480d7a0f4dac 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -121,7 +121,7 @@ struct drbg_state { #endif const struct drbg_state_ops *d_ops; const struct drbg_core *core; - struct drbg_test_data *test_data; + struct drbg_string test_data; }; static inline __u8 drbg_statelen(struct drbg_state *drbg) @@ -176,20 +176,9 @@ static inline size_t drbg_max_requests(struct drbg_state *drbg) #endif } -/* - * kernel crypto API input data structure for DRBG generate in case dlen - * is set to 0 - */ -struct drbg_gen { - unsigned char *outbuf; /* output buffer for random numbers */ - unsigned int outlen; /* size of output buffer */ - struct drbg_string *addtl; /* additional information string */ - struct drbg_test_data *test_data; /* test data */ -}; - /* * This is a wrapper to the kernel crypto API function of - * crypto_rng_get_bytes() to allow the caller to provide additional data. + * crypto_rng_generate() to allow the caller to provide additional data. * * @drng DRBG handle -- see crypto_rng_get_bytes * @outbuf output buffer -- see crypto_rng_get_bytes @@ -204,21 +193,15 @@ static inline int crypto_drbg_get_bytes_addtl(struct crypto_rng *drng, unsigned char *outbuf, unsigned int outlen, struct drbg_string *addtl) { - int ret; - struct drbg_gen genbuf; - genbuf.outbuf = outbuf; - genbuf.outlen = outlen; - genbuf.addtl = addtl; - genbuf.test_data = NULL; - ret = crypto_rng_get_bytes(drng, (u8 *)&genbuf, 0); - return ret; + return crypto_rng_generate(drng, addtl->buf, addtl->len, + outbuf, outlen); } /* * TEST code * * This is a wrapper to the kernel crypto API function of - * crypto_rng_get_bytes() to allow the caller to provide additional data and + * crypto_rng_generate() to allow the caller to provide additional data and * allow furnishing of test_data * * @drng DRBG handle -- see crypto_rng_get_bytes @@ -236,14 +219,10 @@ static inline int crypto_drbg_get_bytes_addtl_test(struct crypto_rng *drng, struct drbg_string *addtl, struct drbg_test_data *test_data) { - int ret; - struct drbg_gen genbuf; - genbuf.outbuf = outbuf; - genbuf.outlen = outlen; - genbuf.addtl = addtl; - genbuf.test_data = test_data; - ret = crypto_rng_get_bytes(drng, (u8 *)&genbuf, 0); - return ret; + crypto_rng_set_entropy(drng, test_data->testentropy->buf, + test_data->testentropy->len); + return crypto_rng_generate(drng, addtl->buf, addtl->len, + outbuf, outlen); } /* @@ -264,14 +243,9 @@ static inline int crypto_drbg_reset_test(struct crypto_rng *drng, struct drbg_string *pers, struct drbg_test_data *test_data) { - int ret; - struct drbg_gen genbuf; - genbuf.outbuf = NULL; - genbuf.outlen = 0; - genbuf.addtl = pers; - genbuf.test_data = test_data; - ret = crypto_rng_reset(drng, (u8 *)&genbuf, 0); - return ret; + crypto_rng_set_entropy(drng, test_data->testentropy->buf, + test_data->testentropy->len); + return crypto_rng_reset(drng, pers->buf, pers->len); } /* DRBG type flags */ -- 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 --- include/crypto/internal/rng.h | 3 +-- include/crypto/rng.h | 10 +++------- include/linux/crypto.h | 30 ------------------------------ 3 files changed, 4 insertions(+), 39 deletions(-) (limited to 'include') 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 --- include/linux/module.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') 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 f94a359763c19e1d03dac61352b1041692c6a698 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 28 Apr 2015 15:36:30 +0100 Subject: crypto: pcomp - Constify (de)compression parameters In testmgr, struct pcomp_testvec takes a non-const 'params' field, which is pointed to a const deflate_comp_params or deflate_decomp_params object. With gcc-5 this incurs the following warnings: In file included from ../crypto/testmgr.c:44:0: ../crypto/testmgr.h:28736:13: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-array-qualifiers] .params = &deflate_comp_params, ^ ../crypto/testmgr.h:28748:13: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-array-qualifiers] .params = &deflate_comp_params, ^ ../crypto/testmgr.h:28776:13: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-array-qualifiers] .params = &deflate_decomp_params, ^ ../crypto/testmgr.h:28800:13: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-array-qualifiers] .params = &deflate_decomp_params, ^ Fix this by making the parameters pointer const and constifying the things that use it. Signed-off-by: David Howells Signed-off-by: Herbert Xu --- include/crypto/compress.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/crypto/compress.h b/include/crypto/compress.h index 86163ef24219..5b67af834d83 100644 --- a/include/crypto/compress.h +++ b/include/crypto/compress.h @@ -55,14 +55,14 @@ struct crypto_pcomp { }; struct pcomp_alg { - int (*compress_setup)(struct crypto_pcomp *tfm, void *params, + int (*compress_setup)(struct crypto_pcomp *tfm, const void *params, unsigned int len); int (*compress_init)(struct crypto_pcomp *tfm); int (*compress_update)(struct crypto_pcomp *tfm, struct comp_request *req); int (*compress_final)(struct crypto_pcomp *tfm, struct comp_request *req); - int (*decompress_setup)(struct crypto_pcomp *tfm, void *params, + int (*decompress_setup)(struct crypto_pcomp *tfm, const void *params, unsigned int len); int (*decompress_init)(struct crypto_pcomp *tfm); int (*decompress_update)(struct crypto_pcomp *tfm, @@ -97,7 +97,7 @@ static inline struct pcomp_alg *crypto_pcomp_alg(struct crypto_pcomp *tfm) } static inline int crypto_compress_setup(struct crypto_pcomp *tfm, - void *params, unsigned int len) + const void *params, unsigned int len) { return crypto_pcomp_alg(tfm)->compress_setup(tfm, params, len); } @@ -120,7 +120,7 @@ static inline int crypto_compress_final(struct crypto_pcomp *tfm, } static inline int crypto_decompress_setup(struct crypto_pcomp *tfm, - void *params, unsigned int len) + const void *params, unsigned int len) { return crypto_pcomp_alg(tfm)->decompress_setup(tfm, params, len); } -- 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 --- include/linux/sw842.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 include/linux/sw842.h (limited to 'include') 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 -- cgit v1.2.3 From 7011a122383e36dab594406720fa1d089e0be8f9 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2015 13:49:17 -0400 Subject: crypto: nx - add NX-842 platform frontend driver Add NX-842 frontend that allows using either the pSeries platform or PowerNV platform driver (to be added by later patch) for the NX-842 hardware. Update the MAINTAINERS file to include the new filenames. Update Kconfig files to clarify titles and descriptions, and correct dependencies. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- include/linux/nx842.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/nx842.h b/include/linux/nx842.h index a4d324c6406a..d919c22b7fd6 100644 --- a/include/linux/nx842.h +++ b/include/linux/nx842.h @@ -1,11 +1,13 @@ #ifndef __NX842_H__ #define __NX842_H__ -int nx842_get_workmem_size(void); -int nx842_get_workmem_size_aligned(void); +#define __NX842_PSERIES_MEM_COMPRESS ((PAGE_SIZE * 2) + 10240) + +#define NX842_MEM_COMPRESS __NX842_PSERIES_MEM_COMPRESS + int nx842_compress(const unsigned char *in, unsigned int in_len, - unsigned char *out, unsigned int *out_len, void *wrkmem); + unsigned char *out, unsigned int *out_len, void *wrkmem); int nx842_decompress(const unsigned char *in, unsigned int in_len, - unsigned char *out, unsigned int *out_len, void *wrkmem); + unsigned char *out, unsigned int *out_len, void *wrkmem); #endif -- cgit v1.2.3 From 959e6659b6f74ec1fa4d391a3b88d63dc0189f36 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2015 13:49:18 -0400 Subject: crypto: nx - add nx842 constraints Add "constraints" for the NX-842 driver. The constraints are used to indicate what the current NX-842 platform driver is capable of. The constraints tell the NX-842 user what alignment, min and max length, and length multiple each provided buffers should conform to. These are required because the 842 hardware requires buffers to meet specific constraints that vary based on platform - for example, the pSeries max length is much lower than the PowerNV max length. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- include/linux/nx842.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/linux/nx842.h b/include/linux/nx842.h index d919c22b7fd6..aa1a97e90dea 100644 --- a/include/linux/nx842.h +++ b/include/linux/nx842.h @@ -5,6 +5,15 @@ #define NX842_MEM_COMPRESS __NX842_PSERIES_MEM_COMPRESS +struct nx842_constraints { + int alignment; + int multiple; + int minimum; + int maximum; +}; + +int nx842_constraints(struct nx842_constraints *constraints); + int nx842_compress(const unsigned char *in, unsigned int in_len, unsigned char *out, unsigned int *out_len, void *wrkmem); int nx842_decompress(const unsigned char *in, unsigned int in_len, -- cgit v1.2.3 From 99182a42b7ef3d5e4180992ce01befd9e87526d2 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2015 13:49:19 -0400 Subject: crypto: nx - add PowerNV platform NX-842 driver Add driver for NX-842 hardware on the PowerNV platform. This allows the use of the 842 compression hardware coprocessor on the PowerNV platform. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- include/linux/nx842.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/nx842.h b/include/linux/nx842.h index aa1a97e90dea..4ddf68d9c0d4 100644 --- a/include/linux/nx842.h +++ b/include/linux/nx842.h @@ -1,9 +1,11 @@ #ifndef __NX842_H__ #define __NX842_H__ -#define __NX842_PSERIES_MEM_COMPRESS ((PAGE_SIZE * 2) + 10240) +#define __NX842_PSERIES_MEM_COMPRESS (10240) +#define __NX842_POWERNV_MEM_COMPRESS (1024) -#define NX842_MEM_COMPRESS __NX842_PSERIES_MEM_COMPRESS +#define NX842_MEM_COMPRESS (max_t(unsigned int, \ + __NX842_PSERIES_MEM_COMPRESS, __NX842_POWERNV_MEM_COMPRESS)) struct nx842_constraints { int alignment; -- cgit v1.2.3 From d6ef2f198d4c9d95b77ee4918b97fc8a53c8a7b7 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 11 May 2015 17:47:39 +0800 Subject: crypto: api - Add crypto_grab_spawn primitive This patch adds a new primitive crypto_grab_spawn which is meant to replace crypto_init_spawn and crypto_init_spawn2. Under the new scheme the user no longer has to worry about reference counting the alg object before it is subsumed by the spawn. It is pretty much an exact copy of crypto_grab_aead. Prior to calling this function spawn->frontend and spawn->inst must have been set. Signed-off-by: Herbert Xu --- include/crypto/algapi.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 0ecb7688af71..a949bf70983b 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -144,6 +144,8 @@ int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, int crypto_init_spawn2(struct crypto_spawn *spawn, struct crypto_alg *alg, struct crypto_instance *inst, const struct crypto_type *frontend); +int crypto_grab_spawn(struct crypto_spawn *spawn, const char *name, + u32 type, u32 mask); void crypto_drop_spawn(struct crypto_spawn *spawn); struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, -- cgit v1.2.3 From 21b7013414db320be418d5f28f72af5c0665dc18 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 11 May 2015 17:47:52 +0800 Subject: crypto: aead - Add crypto_aead_set_reqsize helper This patch adds the helper crypto_aead_set_reqsize so that people don't have to directly access the aead internals to set the reqsize. Signed-off-by: Herbert Xu --- include/crypto/internal/aead.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index 2eba340230a7..750948cf4621 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -78,5 +78,11 @@ static inline void aead_givcrypt_complete(struct aead_givcrypt_request *req, aead_request_complete(&req->areq, err); } +static inline void crypto_aead_set_reqsize(struct crypto_aead *aead, + unsigned int reqsize) +{ + crypto_aead_crt(aead)->reqsize = reqsize; +} + #endif /* _CRYPTO_INTERNAL_AEAD_H */ -- cgit v1.2.3 From 53033d4d36b0299ef02e28155913414ec1089aac Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 11 May 2015 17:48:11 +0800 Subject: crypto: cryptd - Add missing aead.h inclusion cryptd.h needs to include crypto/aead.h because it uses crypto_aead. Signed-off-by: Herbert Xu --- include/crypto/cryptd.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/crypto/cryptd.h b/include/crypto/cryptd.h index ba98918bbd9b..1547f540c920 100644 --- a/include/crypto/cryptd.h +++ b/include/crypto/cryptd.h @@ -14,6 +14,7 @@ #include #include +#include #include struct cryptd_ablkcipher { -- cgit v1.2.3 From 5d1d65f8bea6de3d9c2c60fdfdd2da02da5ea672 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 11 May 2015 17:48:12 +0800 Subject: crypto: aead - Convert top level interface to new style This patch converts the top-level aead interface to the new style. All user-level AEAD interface code have been moved into crypto/aead.h. The allocation/free functions have switched over to the new way of allocating tfms. This patch also removes the double indrection on setkey so the indirection now exists only at the alg level. Apart from these there are no user-visible changes. Signed-off-by: Herbert Xu --- include/crypto/aead.h | 436 +++++++++++++++++++++++++++++++++++++++- include/crypto/algapi.h | 33 +-- include/crypto/internal/aead.h | 38 +++- include/linux/crypto.h | 442 +---------------------------------------- 4 files changed, 468 insertions(+), 481 deletions(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index 94b19be67574..dbcad08f4891 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -17,6 +17,62 @@ #include #include +/** + * DOC: Authenticated Encryption With Associated Data (AEAD) Cipher API + * + * The AEAD cipher API is used with the ciphers of type CRYPTO_ALG_TYPE_AEAD + * (listed as type "aead" in /proc/crypto) + * + * The most prominent examples for this type of encryption is GCM and CCM. + * However, the kernel supports other types of AEAD ciphers which are defined + * with the following cipher string: + * + * authenc(keyed message digest, block cipher) + * + * For example: authenc(hmac(sha256), cbc(aes)) + * + * The example code provided for the asynchronous block cipher operation + * applies here as well. Naturally all *ablkcipher* symbols must be exchanged + * the *aead* pendants discussed in the following. In addtion, for the AEAD + * operation, the aead_request_set_assoc function must be used to set the + * pointer to the associated data memory location before performing the + * encryption or decryption operation. In case of an encryption, the associated + * data memory is filled during the encryption operation. For decryption, the + * associated data memory must contain data that is used to verify the integrity + * of the decrypted data. Another deviation from the asynchronous block cipher + * operation is that the caller should explicitly check for -EBADMSG of the + * crypto_aead_decrypt. That error indicates an authentication error, i.e. + * a breach in the integrity of the message. In essence, that -EBADMSG error + * code is the key bonus an AEAD cipher has over "standard" block chaining + * modes. + */ + +/** + * struct aead_request - AEAD request + * @base: Common attributes for async crypto requests + * @assoclen: Length in bytes of associated data for authentication + * @cryptlen: Length of data to be encrypted or decrypted + * @iv: Initialisation vector + * @assoc: Associated data + * @src: Source data + * @dst: Destination data + * @__ctx: Start of private context data + */ +struct aead_request { + struct crypto_async_request base; + + unsigned int assoclen; + unsigned int cryptlen; + + u8 *iv; + + struct scatterlist *assoc; + struct scatterlist *src; + struct scatterlist *dst; + + void *__ctx[] CRYPTO_MINALIGN_ATTR; +}; + /** * struct aead_givcrypt_request - AEAD request with IV generation * @seq: Sequence number for IV generation @@ -30,6 +86,380 @@ struct aead_givcrypt_request { struct aead_request areq; }; +struct crypto_aead { + int (*encrypt)(struct aead_request *req); + int (*decrypt)(struct aead_request *req); + int (*givencrypt)(struct aead_givcrypt_request *req); + int (*givdecrypt)(struct aead_givcrypt_request *req); + + struct crypto_aead *child; + + unsigned int ivsize; + unsigned int authsize; + unsigned int reqsize; + + struct crypto_tfm base; +}; + +static inline struct crypto_aead *__crypto_aead_cast(struct crypto_tfm *tfm) +{ + return container_of(tfm, struct crypto_aead, base); +} + +/** + * crypto_alloc_aead() - allocate AEAD cipher handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * AEAD cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for an AEAD. The returned struct + * crypto_aead is the cipher handle that is required for any subsequent + * API invocation for that AEAD. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ +struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask); + +static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm) +{ + return &tfm->base; +} + +/** + * crypto_free_aead() - zeroize and free aead handle + * @tfm: cipher handle to be freed + */ +static inline void crypto_free_aead(struct crypto_aead *tfm) +{ + crypto_destroy_tfm(tfm, crypto_aead_tfm(tfm)); +} + +static inline struct crypto_aead *crypto_aead_crt(struct crypto_aead *tfm) +{ + return tfm; +} + +/** + * crypto_aead_ivsize() - obtain IV size + * @tfm: cipher handle + * + * The size of the IV for the aead referenced by the cipher handle is + * returned. This IV size may be zero if the cipher does not need an IV. + * + * Return: IV size in bytes + */ +static inline unsigned int crypto_aead_ivsize(struct crypto_aead *tfm) +{ + return tfm->ivsize; +} + +/** + * crypto_aead_authsize() - obtain maximum authentication data size + * @tfm: cipher handle + * + * The maximum size of the authentication data for the AEAD cipher referenced + * by the AEAD cipher handle is returned. The authentication data size may be + * zero if the cipher implements a hard-coded maximum. + * + * The authentication data may also be known as "tag value". + * + * Return: authentication data size / tag size in bytes + */ +static inline unsigned int crypto_aead_authsize(struct crypto_aead *tfm) +{ + return tfm->authsize; +} + +/** + * crypto_aead_blocksize() - obtain block size of cipher + * @tfm: cipher handle + * + * The block size for the AEAD referenced with the cipher handle is returned. + * The caller may use that information to allocate appropriate memory for the + * data returned by the encryption or decryption operation + * + * Return: block size of cipher + */ +static inline unsigned int crypto_aead_blocksize(struct crypto_aead *tfm) +{ + return crypto_tfm_alg_blocksize(crypto_aead_tfm(tfm)); +} + +static inline unsigned int crypto_aead_alignmask(struct crypto_aead *tfm) +{ + return crypto_tfm_alg_alignmask(crypto_aead_tfm(tfm)); +} + +static inline u32 crypto_aead_get_flags(struct crypto_aead *tfm) +{ + return crypto_tfm_get_flags(crypto_aead_tfm(tfm)); +} + +static inline void crypto_aead_set_flags(struct crypto_aead *tfm, u32 flags) +{ + crypto_tfm_set_flags(crypto_aead_tfm(tfm), flags); +} + +static inline void crypto_aead_clear_flags(struct crypto_aead *tfm, u32 flags) +{ + crypto_tfm_clear_flags(crypto_aead_tfm(tfm), flags); +} + +/** + * crypto_aead_setkey() - set key for cipher + * @tfm: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the AEAD referenced by the cipher + * handle. + * + * Note, the key length determines the cipher type. Many block ciphers implement + * different cipher modes depending on the key size, such as AES-128 vs AES-192 + * vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 + * is performed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ +int crypto_aead_setkey(struct crypto_aead *tfm, + const u8 *key, unsigned int keylen); + +/** + * crypto_aead_setauthsize() - set authentication data size + * @tfm: cipher handle + * @authsize: size of the authentication data / tag in bytes + * + * Set the authentication data size / tag size. AEAD requires an authentication + * tag (or MAC) in addition to the associated data. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ +int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize); + +static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) +{ + return __crypto_aead_cast(req->base.tfm); +} + +/** + * crypto_aead_encrypt() - encrypt plaintext + * @req: reference to the aead_request handle that holds all information + * needed to perform the cipher operation + * + * Encrypt plaintext data using the aead_request handle. That data structure + * and how it is filled with data is discussed with the aead_request_* + * functions. + * + * IMPORTANT NOTE The encryption operation creates the authentication data / + * tag. That data is concatenated with the created ciphertext. + * The ciphertext memory size is therefore the given number of + * block cipher blocks + the size defined by the + * crypto_aead_setauthsize invocation. The caller must ensure + * that sufficient memory is available for the ciphertext and + * the authentication tag. + * + * Return: 0 if the cipher operation was successful; < 0 if an error occurred + */ +static inline int crypto_aead_encrypt(struct aead_request *req) +{ + return crypto_aead_reqtfm(req)->encrypt(req); +} + +/** + * crypto_aead_decrypt() - decrypt ciphertext + * @req: reference to the ablkcipher_request handle that holds all information + * needed to perform the cipher operation + * + * Decrypt ciphertext data using the aead_request handle. That data structure + * and how it is filled with data is discussed with the aead_request_* + * functions. + * + * IMPORTANT NOTE The caller must concatenate the ciphertext followed by the + * authentication data / tag. That authentication data / tag + * must have the size defined by the crypto_aead_setauthsize + * invocation. + * + * + * Return: 0 if the cipher operation was successful; -EBADMSG: The AEAD + * cipher operation performs the authentication of the data during the + * decryption operation. Therefore, the function returns this error if + * the authentication of the ciphertext was unsuccessful (i.e. the + * integrity of the ciphertext or the associated data was violated); + * < 0 if an error occurred. + */ +static inline int crypto_aead_decrypt(struct aead_request *req) +{ + if (req->cryptlen < crypto_aead_authsize(crypto_aead_reqtfm(req))) + return -EINVAL; + + return crypto_aead_reqtfm(req)->decrypt(req); +} + +/** + * DOC: Asynchronous AEAD Request Handle + * + * The aead_request data structure contains all pointers to data required for + * the AEAD cipher operation. This includes the cipher handle (which can be + * used by multiple aead_request instances), pointer to plaintext and + * ciphertext, asynchronous callback function, etc. It acts as a handle to the + * aead_request_* API calls in a similar way as AEAD handle to the + * crypto_aead_* API calls. + */ + +/** + * crypto_aead_reqsize() - obtain size of the request data structure + * @tfm: cipher handle + * + * Return: number of bytes + */ +static inline unsigned int crypto_aead_reqsize(struct crypto_aead *tfm) +{ + return tfm->reqsize; +} + +/** + * aead_request_set_tfm() - update cipher handle reference in request + * @req: request handle to be modified + * @tfm: cipher handle that shall be added to the request handle + * + * Allow the caller to replace the existing aead handle in the request + * data structure with a different one. + */ +static inline void aead_request_set_tfm(struct aead_request *req, + struct crypto_aead *tfm) +{ + req->base.tfm = crypto_aead_tfm(tfm->child); +} + +/** + * aead_request_alloc() - allocate request data structure + * @tfm: cipher handle to be registered with the request + * @gfp: memory allocation flag that is handed to kmalloc by the API call. + * + * Allocate the request data structure that must be used with the AEAD + * encrypt and decrypt API calls. During the allocation, the provided aead + * handle is registered in the request data structure. + * + * Return: allocated request handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ +static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm, + gfp_t gfp) +{ + struct aead_request *req; + + req = kmalloc(sizeof(*req) + crypto_aead_reqsize(tfm), gfp); + + if (likely(req)) + aead_request_set_tfm(req, tfm); + + return req; +} + +/** + * aead_request_free() - zeroize and free request data structure + * @req: request data structure cipher handle to be freed + */ +static inline void aead_request_free(struct aead_request *req) +{ + kzfree(req); +} + +/** + * aead_request_set_callback() - set asynchronous callback function + * @req: request handle + * @flags: specify zero or an ORing of the flags + * CRYPTO_TFM_REQ_MAY_BACKLOG the request queue may back log and + * increase the wait queue beyond the initial maximum size; + * CRYPTO_TFM_REQ_MAY_SLEEP the request processing may sleep + * @compl: callback function pointer to be registered with the request handle + * @data: The data pointer refers to memory that is not used by the kernel + * crypto API, but provided to the callback function for it to use. Here, + * the caller can provide a reference to memory the callback function can + * operate on. As the callback function is invoked asynchronously to the + * related functionality, it may need to access data structures of the + * related functionality which can be referenced using this pointer. The + * callback function can access the memory via the "data" field in the + * crypto_async_request data structure provided to the callback function. + * + * Setting the callback function that is triggered once the cipher operation + * completes + * + * The callback function is registered with the aead_request handle and + * must comply with the following template + * + * void callback_function(struct crypto_async_request *req, int error) + */ +static inline void aead_request_set_callback(struct aead_request *req, + u32 flags, + crypto_completion_t compl, + void *data) +{ + req->base.complete = compl; + req->base.data = data; + req->base.flags = flags; +} + +/** + * aead_request_set_crypt - set data buffers + * @req: request handle + * @src: source scatter / gather list + * @dst: destination scatter / gather list + * @cryptlen: number of bytes to process from @src + * @iv: IV for the cipher operation which must comply with the IV size defined + * by crypto_aead_ivsize() + * + * Setting the source data and destination data scatter / gather lists. + * + * For encryption, the source is treated as the plaintext and the + * destination is the ciphertext. For a decryption operation, the use is + * reversed - the source is the ciphertext and the destination is the plaintext. + * + * IMPORTANT NOTE AEAD requires an authentication tag (MAC). For decryption, + * the caller must concatenate the ciphertext followed by the + * authentication tag and provide the entire data stream to the + * decryption operation (i.e. the data length used for the + * initialization of the scatterlist and the data length for the + * decryption operation is identical). For encryption, however, + * the authentication tag is created while encrypting the data. + * The destination buffer must hold sufficient space for the + * ciphertext and the authentication tag while the encryption + * invocation must only point to the plaintext data size. The + * following code snippet illustrates the memory usage + * buffer = kmalloc(ptbuflen + (enc ? authsize : 0)); + * sg_init_one(&sg, buffer, ptbuflen + (enc ? authsize : 0)); + * aead_request_set_crypt(req, &sg, &sg, ptbuflen, iv); + */ +static inline void aead_request_set_crypt(struct aead_request *req, + struct scatterlist *src, + struct scatterlist *dst, + unsigned int cryptlen, u8 *iv) +{ + req->src = src; + req->dst = dst; + req->cryptlen = cryptlen; + req->iv = iv; +} + +/** + * aead_request_set_assoc() - set the associated data scatter / gather list + * @req: request handle + * @assoc: associated data scatter / gather list + * @assoclen: number of bytes to process from @assoc + * + * For encryption, the memory is filled with the associated data. For + * decryption, the memory must point to the associated data. + */ +static inline void aead_request_set_assoc(struct aead_request *req, + struct scatterlist *assoc, + unsigned int assoclen) +{ + req->assoc = assoc; + req->assoclen = assoclen; +} + static inline struct crypto_aead *aead_givcrypt_reqtfm( struct aead_givcrypt_request *req) { @@ -38,14 +468,12 @@ static inline struct crypto_aead *aead_givcrypt_reqtfm( static inline int crypto_aead_givencrypt(struct aead_givcrypt_request *req) { - struct aead_tfm *crt = crypto_aead_crt(aead_givcrypt_reqtfm(req)); - return crt->givencrypt(req); + return aead_givcrypt_reqtfm(req)->givencrypt(req); }; static inline int crypto_aead_givdecrypt(struct aead_givcrypt_request *req) { - struct aead_tfm *crt = crypto_aead_crt(aead_givcrypt_reqtfm(req)); - return crt->givdecrypt(req); + return aead_givcrypt_reqtfm(req)->givdecrypt(req); }; static inline void aead_givcrypt_set_tfm(struct aead_givcrypt_request *req, diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index a949bf70983b..d4ebf6e9af6a 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -17,6 +17,7 @@ #include #include +struct crypto_aead; struct module; struct rtattr; struct seq_file; @@ -126,7 +127,6 @@ struct ablkcipher_walk { }; extern const struct crypto_type crypto_ablkcipher_type; -extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_blkcipher_type; void crypto_mod_put(struct crypto_alg *alg); @@ -241,22 +241,6 @@ static inline void *crypto_ablkcipher_ctx_aligned(struct crypto_ablkcipher *tfm) return crypto_tfm_ctx_aligned(&tfm->base); } -static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm) -{ - return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; -} - -static inline void *crypto_aead_ctx(struct crypto_aead *tfm) -{ - return crypto_tfm_ctx(&tfm->base); -} - -static inline struct crypto_instance *crypto_aead_alg_instance( - struct crypto_aead *aead) -{ - return crypto_tfm_alg_instance(&aead->base); -} - static inline struct crypto_blkcipher *crypto_spawn_blkcipher( struct crypto_spawn *spawn) { @@ -365,21 +349,6 @@ static inline int ablkcipher_tfm_in_queue(struct crypto_queue *queue, return crypto_tfm_in_queue(queue, crypto_ablkcipher_tfm(tfm)); } -static inline void *aead_request_ctx(struct aead_request *req) -{ - return req->__ctx; -} - -static inline void aead_request_complete(struct aead_request *req, int err) -{ - req->base.complete(&req->base, err); -} - -static inline u32 aead_request_flags(struct aead_request *req) -{ - return req->base.flags; -} - static inline struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask) { diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index 750948cf4621..a2d104aa3430 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -23,8 +23,40 @@ struct crypto_aead_spawn { struct crypto_spawn base; }; +extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_nivaead_type; +static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm) +{ + return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; +} + +static inline void *crypto_aead_ctx(struct crypto_aead *tfm) +{ + return crypto_tfm_ctx(&tfm->base); +} + +static inline struct crypto_instance *crypto_aead_alg_instance( + struct crypto_aead *aead) +{ + return crypto_tfm_alg_instance(&aead->base); +} + +static inline void *aead_request_ctx(struct aead_request *req) +{ + return req->__ctx; +} + +static inline void aead_request_complete(struct aead_request *req, int err) +{ + req->base.complete(&req->base, err); +} + +static inline u32 aead_request_flags(struct aead_request *req) +{ + return req->base.flags; +} + static inline void crypto_set_aead_spawn( struct crypto_aead_spawn *spawn, struct crypto_instance *inst) { @@ -50,9 +82,7 @@ static inline struct crypto_alg *crypto_aead_spawn_alg( static inline struct crypto_aead *crypto_spawn_aead( struct crypto_aead_spawn *spawn) { - return __crypto_aead_cast( - crypto_spawn_tfm(&spawn->base, CRYPTO_ALG_TYPE_AEAD, - CRYPTO_ALG_TYPE_MASK)); + return crypto_spawn_tfm2(&spawn->base); } struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl, @@ -64,7 +94,7 @@ void aead_geniv_exit(struct crypto_tfm *tfm); static inline struct crypto_aead *aead_geniv_base(struct crypto_aead *geniv) { - return crypto_aead_crt(geniv)->base; + return geniv->child; } static inline void *aead_givcrypt_reqctx(struct aead_givcrypt_request *req) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index ee14140f8893..59ca4086ce6a 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -140,6 +140,7 @@ struct crypto_blkcipher; struct crypto_hash; struct crypto_tfm; struct crypto_type; +struct aead_request; struct aead_givcrypt_request; struct skcipher_givcrypt_request; @@ -174,32 +175,6 @@ struct ablkcipher_request { void *__ctx[] CRYPTO_MINALIGN_ATTR; }; -/** - * struct aead_request - AEAD request - * @base: Common attributes for async crypto requests - * @assoclen: Length in bytes of associated data for authentication - * @cryptlen: Length of data to be encrypted or decrypted - * @iv: Initialisation vector - * @assoc: Associated data - * @src: Source data - * @dst: Destination data - * @__ctx: Start of private context data - */ -struct aead_request { - struct crypto_async_request base; - - unsigned int assoclen; - unsigned int cryptlen; - - u8 *iv; - - struct scatterlist *assoc; - struct scatterlist *src; - struct scatterlist *dst; - - void *__ctx[] CRYPTO_MINALIGN_ATTR; -}; - struct blkcipher_desc { struct crypto_blkcipher *tfm; void *info; @@ -572,21 +547,6 @@ struct ablkcipher_tfm { unsigned int reqsize; }; -struct aead_tfm { - int (*setkey)(struct crypto_aead *tfm, const u8 *key, - unsigned int keylen); - int (*encrypt)(struct aead_request *req); - int (*decrypt)(struct aead_request *req); - int (*givencrypt)(struct aead_givcrypt_request *req); - int (*givdecrypt)(struct aead_givcrypt_request *req); - - struct crypto_aead *base; - - unsigned int ivsize; - unsigned int authsize; - unsigned int reqsize; -}; - struct blkcipher_tfm { void *iv; int (*setkey)(struct crypto_tfm *tfm, const u8 *key, @@ -626,7 +586,6 @@ struct compress_tfm { }; #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 @@ -638,7 +597,6 @@ struct crypto_tfm { union { struct ablkcipher_tfm ablkcipher; - struct aead_tfm aead; struct blkcipher_tfm blkcipher; struct cipher_tfm cipher; struct hash_tfm hash; @@ -656,10 +614,6 @@ struct crypto_ablkcipher { struct crypto_tfm base; }; -struct crypto_aead { - struct crypto_tfm base; -}; - struct crypto_blkcipher { struct crypto_tfm base; }; @@ -1151,400 +1105,6 @@ static inline void ablkcipher_request_set_crypt( req->info = iv; } -/** - * DOC: Authenticated Encryption With Associated Data (AEAD) Cipher API - * - * The AEAD cipher API is used with the ciphers of type CRYPTO_ALG_TYPE_AEAD - * (listed as type "aead" in /proc/crypto) - * - * The most prominent examples for this type of encryption is GCM and CCM. - * However, the kernel supports other types of AEAD ciphers which are defined - * with the following cipher string: - * - * authenc(keyed message digest, block cipher) - * - * For example: authenc(hmac(sha256), cbc(aes)) - * - * The example code provided for the asynchronous block cipher operation - * applies here as well. Naturally all *ablkcipher* symbols must be exchanged - * the *aead* pendants discussed in the following. In addtion, for the AEAD - * operation, the aead_request_set_assoc function must be used to set the - * pointer to the associated data memory location before performing the - * encryption or decryption operation. In case of an encryption, the associated - * data memory is filled during the encryption operation. For decryption, the - * associated data memory must contain data that is used to verify the integrity - * of the decrypted data. Another deviation from the asynchronous block cipher - * operation is that the caller should explicitly check for -EBADMSG of the - * crypto_aead_decrypt. That error indicates an authentication error, i.e. - * a breach in the integrity of the message. In essence, that -EBADMSG error - * code is the key bonus an AEAD cipher has over "standard" block chaining - * modes. - */ - -static inline struct crypto_aead *__crypto_aead_cast(struct crypto_tfm *tfm) -{ - return (struct crypto_aead *)tfm; -} - -/** - * crypto_alloc_aead() - allocate AEAD cipher handle - * @alg_name: is the cra_name / name or cra_driver_name / driver name of the - * AEAD cipher - * @type: specifies the type of the cipher - * @mask: specifies the mask for the cipher - * - * Allocate a cipher handle for an AEAD. The returned struct - * crypto_aead is the cipher handle that is required for any subsequent - * API invocation for that AEAD. - * - * Return: allocated cipher handle in case of success; IS_ERR() is true in case - * of an error, PTR_ERR() returns the error code. - */ -struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask); - -static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm) -{ - return &tfm->base; -} - -/** - * crypto_free_aead() - zeroize and free aead handle - * @tfm: cipher handle to be freed - */ -static inline void crypto_free_aead(struct crypto_aead *tfm) -{ - crypto_free_tfm(crypto_aead_tfm(tfm)); -} - -static inline struct aead_tfm *crypto_aead_crt(struct crypto_aead *tfm) -{ - return &crypto_aead_tfm(tfm)->crt_aead; -} - -/** - * crypto_aead_ivsize() - obtain IV size - * @tfm: cipher handle - * - * The size of the IV for the aead referenced by the cipher handle is - * returned. This IV size may be zero if the cipher does not need an IV. - * - * Return: IV size in bytes - */ -static inline unsigned int crypto_aead_ivsize(struct crypto_aead *tfm) -{ - return crypto_aead_crt(tfm)->ivsize; -} - -/** - * crypto_aead_authsize() - obtain maximum authentication data size - * @tfm: cipher handle - * - * The maximum size of the authentication data for the AEAD cipher referenced - * by the AEAD cipher handle is returned. The authentication data size may be - * zero if the cipher implements a hard-coded maximum. - * - * The authentication data may also be known as "tag value". - * - * Return: authentication data size / tag size in bytes - */ -static inline unsigned int crypto_aead_authsize(struct crypto_aead *tfm) -{ - return crypto_aead_crt(tfm)->authsize; -} - -/** - * crypto_aead_blocksize() - obtain block size of cipher - * @tfm: cipher handle - * - * The block size for the AEAD referenced with the cipher handle is returned. - * The caller may use that information to allocate appropriate memory for the - * data returned by the encryption or decryption operation - * - * Return: block size of cipher - */ -static inline unsigned int crypto_aead_blocksize(struct crypto_aead *tfm) -{ - return crypto_tfm_alg_blocksize(crypto_aead_tfm(tfm)); -} - -static inline unsigned int crypto_aead_alignmask(struct crypto_aead *tfm) -{ - return crypto_tfm_alg_alignmask(crypto_aead_tfm(tfm)); -} - -static inline u32 crypto_aead_get_flags(struct crypto_aead *tfm) -{ - return crypto_tfm_get_flags(crypto_aead_tfm(tfm)); -} - -static inline void crypto_aead_set_flags(struct crypto_aead *tfm, u32 flags) -{ - crypto_tfm_set_flags(crypto_aead_tfm(tfm), flags); -} - -static inline void crypto_aead_clear_flags(struct crypto_aead *tfm, u32 flags) -{ - crypto_tfm_clear_flags(crypto_aead_tfm(tfm), flags); -} - -/** - * crypto_aead_setkey() - set key for cipher - * @tfm: cipher handle - * @key: buffer holding the key - * @keylen: length of the key in bytes - * - * The caller provided key is set for the AEAD referenced by the cipher - * handle. - * - * Note, the key length determines the cipher type. Many block ciphers implement - * different cipher modes depending on the key size, such as AES-128 vs AES-192 - * vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 - * is performed. - * - * Return: 0 if the setting of the key was successful; < 0 if an error occurred - */ -static inline int crypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, - unsigned int keylen) -{ - struct aead_tfm *crt = crypto_aead_crt(tfm); - - return crt->setkey(crt->base, key, keylen); -} - -/** - * crypto_aead_setauthsize() - set authentication data size - * @tfm: cipher handle - * @authsize: size of the authentication data / tag in bytes - * - * Set the authentication data size / tag size. AEAD requires an authentication - * tag (or MAC) in addition to the associated data. - * - * Return: 0 if the setting of the key was successful; < 0 if an error occurred - */ -int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize); - -static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) -{ - return __crypto_aead_cast(req->base.tfm); -} - -/** - * crypto_aead_encrypt() - encrypt plaintext - * @req: reference to the aead_request handle that holds all information - * needed to perform the cipher operation - * - * Encrypt plaintext data using the aead_request handle. That data structure - * and how it is filled with data is discussed with the aead_request_* - * functions. - * - * IMPORTANT NOTE The encryption operation creates the authentication data / - * tag. That data is concatenated with the created ciphertext. - * The ciphertext memory size is therefore the given number of - * block cipher blocks + the size defined by the - * crypto_aead_setauthsize invocation. The caller must ensure - * that sufficient memory is available for the ciphertext and - * the authentication tag. - * - * Return: 0 if the cipher operation was successful; < 0 if an error occurred - */ -static inline int crypto_aead_encrypt(struct aead_request *req) -{ - return crypto_aead_crt(crypto_aead_reqtfm(req))->encrypt(req); -} - -/** - * crypto_aead_decrypt() - decrypt ciphertext - * @req: reference to the ablkcipher_request handle that holds all information - * needed to perform the cipher operation - * - * Decrypt ciphertext data using the aead_request handle. That data structure - * and how it is filled with data is discussed with the aead_request_* - * functions. - * - * IMPORTANT NOTE The caller must concatenate the ciphertext followed by the - * authentication data / tag. That authentication data / tag - * must have the size defined by the crypto_aead_setauthsize - * invocation. - * - * - * Return: 0 if the cipher operation was successful; -EBADMSG: The AEAD - * cipher operation performs the authentication of the data during the - * decryption operation. Therefore, the function returns this error if - * the authentication of the ciphertext was unsuccessful (i.e. the - * integrity of the ciphertext or the associated data was violated); - * < 0 if an error occurred. - */ -static inline int crypto_aead_decrypt(struct aead_request *req) -{ - if (req->cryptlen < crypto_aead_authsize(crypto_aead_reqtfm(req))) - return -EINVAL; - - return crypto_aead_crt(crypto_aead_reqtfm(req))->decrypt(req); -} - -/** - * DOC: Asynchronous AEAD Request Handle - * - * The aead_request data structure contains all pointers to data required for - * the AEAD cipher operation. This includes the cipher handle (which can be - * used by multiple aead_request instances), pointer to plaintext and - * ciphertext, asynchronous callback function, etc. It acts as a handle to the - * aead_request_* API calls in a similar way as AEAD handle to the - * crypto_aead_* API calls. - */ - -/** - * crypto_aead_reqsize() - obtain size of the request data structure - * @tfm: cipher handle - * - * Return: number of bytes - */ -static inline unsigned int crypto_aead_reqsize(struct crypto_aead *tfm) -{ - return crypto_aead_crt(tfm)->reqsize; -} - -/** - * aead_request_set_tfm() - update cipher handle reference in request - * @req: request handle to be modified - * @tfm: cipher handle that shall be added to the request handle - * - * Allow the caller to replace the existing aead handle in the request - * data structure with a different one. - */ -static inline void aead_request_set_tfm(struct aead_request *req, - struct crypto_aead *tfm) -{ - req->base.tfm = crypto_aead_tfm(crypto_aead_crt(tfm)->base); -} - -/** - * aead_request_alloc() - allocate request data structure - * @tfm: cipher handle to be registered with the request - * @gfp: memory allocation flag that is handed to kmalloc by the API call. - * - * Allocate the request data structure that must be used with the AEAD - * encrypt and decrypt API calls. During the allocation, the provided aead - * handle is registered in the request data structure. - * - * Return: allocated request handle in case of success; IS_ERR() is true in case - * of an error, PTR_ERR() returns the error code. - */ -static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm, - gfp_t gfp) -{ - struct aead_request *req; - - req = kmalloc(sizeof(*req) + crypto_aead_reqsize(tfm), gfp); - - if (likely(req)) - aead_request_set_tfm(req, tfm); - - return req; -} - -/** - * aead_request_free() - zeroize and free request data structure - * @req: request data structure cipher handle to be freed - */ -static inline void aead_request_free(struct aead_request *req) -{ - kzfree(req); -} - -/** - * aead_request_set_callback() - set asynchronous callback function - * @req: request handle - * @flags: specify zero or an ORing of the flags - * CRYPTO_TFM_REQ_MAY_BACKLOG the request queue may back log and - * increase the wait queue beyond the initial maximum size; - * CRYPTO_TFM_REQ_MAY_SLEEP the request processing may sleep - * @compl: callback function pointer to be registered with the request handle - * @data: The data pointer refers to memory that is not used by the kernel - * crypto API, but provided to the callback function for it to use. Here, - * the caller can provide a reference to memory the callback function can - * operate on. As the callback function is invoked asynchronously to the - * related functionality, it may need to access data structures of the - * related functionality which can be referenced using this pointer. The - * callback function can access the memory via the "data" field in the - * crypto_async_request data structure provided to the callback function. - * - * Setting the callback function that is triggered once the cipher operation - * completes - * - * The callback function is registered with the aead_request handle and - * must comply with the following template - * - * void callback_function(struct crypto_async_request *req, int error) - */ -static inline void aead_request_set_callback(struct aead_request *req, - u32 flags, - crypto_completion_t compl, - void *data) -{ - req->base.complete = compl; - req->base.data = data; - req->base.flags = flags; -} - -/** - * aead_request_set_crypt - set data buffers - * @req: request handle - * @src: source scatter / gather list - * @dst: destination scatter / gather list - * @cryptlen: number of bytes to process from @src - * @iv: IV for the cipher operation which must comply with the IV size defined - * by crypto_aead_ivsize() - * - * Setting the source data and destination data scatter / gather lists. - * - * For encryption, the source is treated as the plaintext and the - * destination is the ciphertext. For a decryption operation, the use is - * reversed - the source is the ciphertext and the destination is the plaintext. - * - * IMPORTANT NOTE AEAD requires an authentication tag (MAC). For decryption, - * the caller must concatenate the ciphertext followed by the - * authentication tag and provide the entire data stream to the - * decryption operation (i.e. the data length used for the - * initialization of the scatterlist and the data length for the - * decryption operation is identical). For encryption, however, - * the authentication tag is created while encrypting the data. - * The destination buffer must hold sufficient space for the - * ciphertext and the authentication tag while the encryption - * invocation must only point to the plaintext data size. The - * following code snippet illustrates the memory usage - * buffer = kmalloc(ptbuflen + (enc ? authsize : 0)); - * sg_init_one(&sg, buffer, ptbuflen + (enc ? authsize : 0)); - * aead_request_set_crypt(req, &sg, &sg, ptbuflen, iv); - */ -static inline void aead_request_set_crypt(struct aead_request *req, - struct scatterlist *src, - struct scatterlist *dst, - unsigned int cryptlen, u8 *iv) -{ - req->src = src; - req->dst = dst; - req->cryptlen = cryptlen; - req->iv = iv; -} - -/** - * aead_request_set_assoc() - set the associated data scatter / gather list - * @req: request handle - * @assoc: associated data scatter / gather list - * @assoclen: number of bytes to process from @assoc - * - * For encryption, the memory is filled with the associated data. For - * decryption, the memory must point to the associated data. - */ -static inline void aead_request_set_assoc(struct aead_request *req, - struct scatterlist *assoc, - unsigned int assoclen) -{ - req->assoc = assoc; - req->assoclen = assoclen; -} - /** * DOC: Synchronous Block Cipher API * -- cgit v1.2.3 From f79f1f7289b8e46763beedc9fd68f3072f1643e4 Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Sun, 17 May 2015 12:54:12 +0200 Subject: crypto: md5 - add MD5 initial vectors This patch simply adds the MD5 IV in the md5 header. Signed-off-by: LABBE Corentin Signed-off-by: Herbert Xu --- include/crypto/md5.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/crypto/md5.h b/include/crypto/md5.h index 65f299b08b0d..146af825eedb 100644 --- a/include/crypto/md5.h +++ b/include/crypto/md5.h @@ -8,6 +8,11 @@ #define MD5_BLOCK_WORDS 16 #define MD5_HASH_WORDS 4 +#define MD5_H0 0x67452301UL +#define MD5_H1 0xefcdab89UL +#define MD5_H2 0x98badcfeUL +#define MD5_H3 0x10325476UL + struct md5_state { u32 hash[MD5_HASH_WORDS]; u32 block[MD5_BLOCK_WORDS]; -- cgit v1.2.3 From fc42bcba97bae738f905b83741134a63af7e6c02 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 21 May 2015 15:10:59 +0800 Subject: crypto: scatterwalk - Add scatterwalk_ffwd helper This patch adds the scatterwalk_ffwd helper which can create an SG list that starts in the middle of an existing SG list. The new list may either be part of the existing list or be a chain that latches onto part of the existing list. Signed-off-by: Herbert Xu --- include/crypto/scatterwalk.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h index 20e4226a2e14..96670e7e7c14 100644 --- a/include/crypto/scatterwalk.h +++ b/include/crypto/scatterwalk.h @@ -102,4 +102,8 @@ void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg, int scatterwalk_bytes_sglen(struct scatterlist *sg, int num_bytes); +struct scatterlist *scatterwalk_ffwd(struct scatterlist dst[2], + struct scatterlist *src, + unsigned int len); + #endif /* _CRYPTO_SCATTERWALK_H */ -- cgit v1.2.3 From 996d98d85ccc27d9c592ad7dc1371c60cd6585cc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 21 May 2015 15:11:01 +0800 Subject: crypto: aead - Add new interface with single SG list The primary user of AEAD, IPsec includes the IV in the AD in most cases, except where it is implicitly authenticated by the underlying algorithm. The way it is currently implemented is a hack because we pass the data in piecemeal and the underlying algorithms try to stitch them back up into one piece. This is why this patch is adding a new interface that allows a single SG list to be passed in that contains everything so the algorithm implementors do not have to stitch. The new interface accepts a single source SG list and a single destination SG list. Both must be laid out as follows: AD, skipped data, plain/cipher text, ICV The ICV is not present from the source during encryption and from the destination during decryption. For the top-level IPsec AEAD algorithm the plain/cipher text will contain the generated (or received) IV. Signed-off-by: Herbert Xu --- include/crypto/aead.h | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index dbcad08f4891..e2d2c3c62e68 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -52,6 +52,7 @@ * @base: Common attributes for async crypto requests * @assoclen: Length in bytes of associated data for authentication * @cryptlen: Length of data to be encrypted or decrypted + * @cryptoff: Bytes to skip after AD before plain/cipher text * @iv: Initialisation vector * @assoc: Associated data * @src: Source data @@ -61,8 +62,11 @@ struct aead_request { struct crypto_async_request base; + bool old; + unsigned int assoclen; unsigned int cryptlen; + unsigned int cryptoff; u8 *iv; @@ -314,10 +318,7 @@ static inline int crypto_aead_decrypt(struct aead_request *req) * * Return: number of bytes */ -static inline unsigned int crypto_aead_reqsize(struct crypto_aead *tfm) -{ - return tfm->reqsize; -} +unsigned int crypto_aead_reqsize(struct crypto_aead *tfm); /** * aead_request_set_tfm() - update cipher handle reference in request @@ -417,6 +418,9 @@ static inline void aead_request_set_callback(struct aead_request *req, * destination is the ciphertext. For a decryption operation, the use is * reversed - the source is the ciphertext and the destination is the plaintext. * + * For both src/dst the layout is associated data, skipped data, + * plain/cipher text, authentication tag. + * * IMPORTANT NOTE AEAD requires an authentication tag (MAC). For decryption, * the caller must concatenate the ciphertext followed by the * authentication tag and provide the entire data stream to the @@ -449,8 +453,7 @@ static inline void aead_request_set_crypt(struct aead_request *req, * @assoc: associated data scatter / gather list * @assoclen: number of bytes to process from @assoc * - * For encryption, the memory is filled with the associated data. For - * decryption, the memory must point to the associated data. + * Obsolete, do not use. */ static inline void aead_request_set_assoc(struct aead_request *req, struct scatterlist *assoc, @@ -458,6 +461,26 @@ static inline void aead_request_set_assoc(struct aead_request *req, { req->assoc = assoc; req->assoclen = assoclen; + req->old = true; +} + +/** + * aead_request_set_ad - set associated data information + * @req: request handle + * @assoclen: number of bytes in associated data + * @cryptoff: Number of bytes to skip after AD before plain/cipher text + * + * Setting the AD information. This function sets the length of + * the associated data and the number of bytes to skip after it to + * access the plain/cipher text. + */ +static inline void aead_request_set_ad(struct aead_request *req, + unsigned int assoclen, + unsigned int cryptoff) +{ + req->assoclen = assoclen; + req->cryptoff = cryptoff; + req->old = false; } static inline struct crypto_aead *aead_givcrypt_reqtfm( -- cgit v1.2.3 From 2d0f230fe0649758394466cb69b553c0e8184df9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 21 May 2015 15:11:02 +0800 Subject: crypto: aead - Rename aead_alg to old_aead_alg This patch is the first step in the introduction of a new AEAD alg type. Unlike normal conversions this patch only renames the existing aead_alg structure because there are external references to it. Those references will be removed after this patch. Signed-off-by: Herbert Xu --- include/crypto/aead.h | 2 ++ include/crypto/internal/aead.h | 5 +++++ include/linux/crypto.h | 6 +++--- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index e2d2c3c62e68..aebf57dfb903 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -17,6 +17,8 @@ #include #include +#define aead_alg old_aead_alg + /** * DOC: Authenticated Encryption With Associated Data (AEAD) Cipher API * diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index a2d104aa3430..84c17bb92b6a 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -26,6 +26,11 @@ struct crypto_aead_spawn { extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_nivaead_type; +static inline struct old_aead_alg *crypto_old_aead_alg(struct crypto_aead *tfm) +{ + return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; +} + static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm) { return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 59ca4086ce6a..7d290a91c6f9 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -268,7 +268,7 @@ struct ablkcipher_alg { }; /** - * struct aead_alg - AEAD cipher definition + * struct old_aead_alg - AEAD cipher definition * @maxauthsize: Set the maximum authentication tag size supported by the * transformation. A transformation may support smaller tag sizes. * As the authentication tag is a message digest to ensure the @@ -293,7 +293,7 @@ struct ablkcipher_alg { * All fields except @givencrypt , @givdecrypt , @geniv and @ivsize are * mandatory and must be filled. */ -struct aead_alg { +struct old_aead_alg { int (*setkey)(struct crypto_aead *tfm, const u8 *key, unsigned int keylen); int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize); @@ -501,7 +501,7 @@ struct crypto_alg { union { struct ablkcipher_alg ablkcipher; - struct aead_alg aead; + struct old_aead_alg aead; struct blkcipher_alg blkcipher; struct cipher_alg cipher; struct compress_alg compress; -- cgit v1.2.3 From f569525911d3dce024ff2b1908e16a20e9052338 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 21 May 2015 15:11:05 +0800 Subject: crypto: aead - Add crypto_aead_maxauthsize This patch adds the helper crypto_aead_maxauthsize to remove the need to directly dereference aead_alg internals by AEAD implementors. Signed-off-by: Herbert Xu --- include/crypto/internal/aead.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index 84c17bb92b6a..4614f795f8bc 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -119,5 +119,10 @@ static inline void crypto_aead_set_reqsize(struct crypto_aead *aead, crypto_aead_crt(aead)->reqsize = reqsize; } +static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead) +{ + return crypto_old_aead_alg(aead)->maxauthsize; +} + #endif /* _CRYPTO_INTERNAL_AEAD_H */ -- cgit v1.2.3 From 63293c61133447249d7e5b49d333f68825d30e43 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 21 May 2015 15:11:08 +0800 Subject: crypto: aead - Add support for new AEAD implementations This patch adds the basic structure of the new AEAD type. Unlike the current version, there is no longer any concept of geniv. IV generation will still be carried out by wrappers but they will be normal AEAD algorithms that simply take the IPsec sequence number as the IV. Signed-off-by: Herbert Xu --- include/crypto/aead.h | 44 ++++++++++++++++++++++++++++++++++++++++-- include/crypto/internal/aead.h | 36 ++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index aebf57dfb903..177e6f46e2bb 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -17,8 +17,6 @@ #include #include -#define aead_alg old_aead_alg - /** * DOC: Authenticated Encryption With Associated Data (AEAD) Cipher API * @@ -92,7 +90,48 @@ struct aead_givcrypt_request { struct aead_request areq; }; +/** + * struct aead_alg - AEAD cipher definition + * @maxauthsize: Set the maximum authentication tag size supported by the + * transformation. A transformation may support smaller tag sizes. + * As the authentication tag is a message digest to ensure the + * integrity of the encrypted data, a consumer typically wants the + * largest authentication tag possible as defined by this + * variable. + * @setauthsize: Set authentication size for the AEAD transformation. This + * function is used to specify the consumer requested size of the + * authentication tag to be either generated by the transformation + * during encryption or the size of the authentication tag to be + * supplied during the decryption operation. This function is also + * responsible for checking the authentication tag size for + * validity. + * @setkey: see struct ablkcipher_alg + * @encrypt: see struct ablkcipher_alg + * @decrypt: see struct ablkcipher_alg + * @geniv: see struct ablkcipher_alg + * @ivsize: see struct ablkcipher_alg + * + * All fields except @ivsize is mandatory and must be filled. + */ +struct aead_alg { + int (*setkey)(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen); + int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize); + int (*encrypt)(struct aead_request *req); + int (*decrypt)(struct aead_request *req); + + const char *geniv; + + unsigned int ivsize; + unsigned int maxauthsize; + + struct crypto_alg base; +}; + struct crypto_aead { + int (*setkey)(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen); + int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize); int (*encrypt)(struct aead_request *req); int (*decrypt)(struct aead_request *req); int (*givencrypt)(struct aead_givcrypt_request *req); @@ -102,6 +141,7 @@ struct crypto_aead { unsigned int ivsize; unsigned int authsize; + unsigned int maxauthsize; unsigned int reqsize; struct crypto_tfm base; diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index 4614f795f8bc..6cd31519c4f6 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -19,6 +19,10 @@ struct rtattr; +struct aead_instance { + struct aead_alg alg; +}; + struct crypto_aead_spawn { struct crypto_spawn base; }; @@ -33,7 +37,8 @@ static inline struct old_aead_alg *crypto_old_aead_alg(struct crypto_aead *tfm) static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm) { - return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; + return container_of(crypto_aead_tfm(tfm)->__crt_alg, + struct aead_alg, base); } static inline void *crypto_aead_ctx(struct crypto_aead *tfm) @@ -47,6 +52,22 @@ static inline struct crypto_instance *crypto_aead_alg_instance( return crypto_tfm_alg_instance(&aead->base); } +static inline struct crypto_instance *aead_crypto_instance( + struct aead_instance *inst) +{ + return container_of(&inst->alg.base, struct crypto_instance, alg); +} + +static inline struct aead_instance *aead_instance(struct crypto_instance *inst) +{ + return container_of(&inst->alg, struct aead_instance, alg.base); +} + +static inline void *aead_instance_ctx(struct aead_instance *inst) +{ + return crypto_instance_ctx(aead_crypto_instance(inst)); +} + static inline void *aead_request_ctx(struct aead_request *req) { return req->__ctx; @@ -84,6 +105,12 @@ static inline struct crypto_alg *crypto_aead_spawn_alg( return spawn->base.alg; } +static inline struct aead_alg *crypto_spawn_aead_alg( + struct crypto_aead_spawn *spawn) +{ + return container_of(spawn->base.alg, struct aead_alg, base); +} + static inline struct crypto_aead *crypto_spawn_aead( struct crypto_aead_spawn *spawn) { @@ -121,8 +148,13 @@ static inline void crypto_aead_set_reqsize(struct crypto_aead *aead, static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead) { - return crypto_old_aead_alg(aead)->maxauthsize; + return aead->maxauthsize; } +int crypto_register_aead(struct aead_alg *alg); +int crypto_unregister_aead(struct aead_alg *alg); +int aead_register_instance(struct crypto_template *tmpl, + struct aead_instance *inst); + #endif /* _CRYPTO_INTERNAL_AEAD_H */ -- cgit v1.2.3 From 330234638e16b7b95e8e5e6be719a61a93f074b8 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 21 May 2015 15:11:09 +0800 Subject: crypto: null - Add default null skcipher This patch adds a default null skcipher for users such as gcm to perform copies on SG lists. Signed-off-by: Herbert Xu --- include/crypto/null.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/crypto/null.h b/include/crypto/null.h index b7c864cc70df..06dc30d9f56e 100644 --- a/include/crypto/null.h +++ b/include/crypto/null.h @@ -8,4 +8,7 @@ #define NULL_DIGEST_SIZE 0 #define NULL_IV_SIZE 0 +struct crypto_blkcipher *crypto_get_default_null_skcipher(void); +void crypto_put_default_null_skcipher(void); + #endif -- cgit v1.2.3 From 856e3f4092cfd9ea6d6564e73f5bce5a0ac3cae3 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 21 May 2015 15:11:13 +0800 Subject: crypto: seqiv - Add support for new AEAD interface This patch converts the seqiv IV generator to work with the new AEAD interface where IV generators are just normal AEAD algorithms. Full backwards compatibility is paramount at this point since no users have yet switched over to the new interface. Nor can they switch to the new interface until IV generation is fully supported by it. So this means we are adding two versions of seqiv alongside the existing one. The first one is the one that will be used when the underlying AEAD algorithm has switched over to the new AEAD interface. The second one handles the current case where the underlying AEAD algorithm still uses the old interface. Both versions export themselves through the new AEAD interface. Signed-off-by: Herbert Xu --- include/crypto/internal/aead.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index 6cd31519c4f6..08f2ca6c020e 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -117,10 +117,9 @@ static inline struct crypto_aead *crypto_spawn_aead( return crypto_spawn_tfm2(&spawn->base); } -struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl, - struct rtattr **tb, u32 type, - u32 mask); -void aead_geniv_free(struct crypto_instance *inst); +struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl, + struct rtattr **tb, u32 type, u32 mask); +void aead_geniv_free(struct aead_instance *inst); int aead_geniv_init(struct crypto_tfm *tfm); void aead_geniv_exit(struct crypto_tfm *tfm); -- cgit v1.2.3 From 30e4c010aefdbb81b2aaf64758850432eb289f47 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 22 May 2015 16:30:48 +0800 Subject: crypto: aead - Add crypto_aead_alg_ivsize/maxauthsize AEAD algorithm implementors need to figure out a given algorithm's IV size and maximum authentication size. During the transition this is difficult to do as an algorithm could be new style or old style. This patch creates two helpers to make this easier. Signed-off-by: Herbert Xu --- include/crypto/aead.h | 21 ++++++++++++++++++--- include/crypto/internal/aead.h | 19 +++++++------------ 2 files changed, 25 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index 177e6f46e2bb..ba28c61e765f 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -139,9 +139,7 @@ struct crypto_aead { struct crypto_aead *child; - unsigned int ivsize; unsigned int authsize; - unsigned int maxauthsize; unsigned int reqsize; struct crypto_tfm base; @@ -187,6 +185,23 @@ static inline struct crypto_aead *crypto_aead_crt(struct crypto_aead *tfm) return tfm; } +static inline struct old_aead_alg *crypto_old_aead_alg(struct crypto_aead *tfm) +{ + return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; +} + +static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm) +{ + return container_of(crypto_aead_tfm(tfm)->__crt_alg, + struct aead_alg, base); +} + +static inline unsigned int crypto_aead_alg_ivsize(struct aead_alg *alg) +{ + return alg->base.cra_aead.encrypt ? alg->base.cra_aead.ivsize : + alg->ivsize; +} + /** * crypto_aead_ivsize() - obtain IV size * @tfm: cipher handle @@ -198,7 +213,7 @@ static inline struct crypto_aead *crypto_aead_crt(struct crypto_aead *tfm) */ static inline unsigned int crypto_aead_ivsize(struct crypto_aead *tfm) { - return tfm->ivsize; + return crypto_aead_alg_ivsize(crypto_aead_alg(tfm)); } /** diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index 08f2ca6c020e..4137330f01ab 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -30,17 +30,6 @@ struct crypto_aead_spawn { extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_nivaead_type; -static inline struct old_aead_alg *crypto_old_aead_alg(struct crypto_aead *tfm) -{ - return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; -} - -static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm) -{ - return container_of(crypto_aead_tfm(tfm)->__crt_alg, - struct aead_alg, base); -} - static inline void *crypto_aead_ctx(struct crypto_aead *tfm) { return crypto_tfm_ctx(&tfm->base); @@ -145,9 +134,15 @@ static inline void crypto_aead_set_reqsize(struct crypto_aead *aead, crypto_aead_crt(aead)->reqsize = reqsize; } +static inline unsigned int crypto_aead_alg_maxauthsize(struct aead_alg *alg) +{ + return alg->base.cra_aead.encrypt ? alg->base.cra_aead.maxauthsize : + alg->maxauthsize; +} + static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead) { - return aead->maxauthsize; + return crypto_aead_alg_maxauthsize(crypto_aead_alg(aead)); } int crypto_register_aead(struct aead_alg *alg); -- cgit v1.2.3 From 374d4ad18a0c4bc844dee42b3b43916e5f46608d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 23 May 2015 15:41:57 +0800 Subject: crypto: aead - Remove unused cryptoff parameter This patch removes the cryptoff parameter now that all users set it to zero. Signed-off-by: Herbert Xu --- include/crypto/aead.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index ba28c61e765f..94141dc1225e 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -52,7 +52,6 @@ * @base: Common attributes for async crypto requests * @assoclen: Length in bytes of associated data for authentication * @cryptlen: Length of data to be encrypted or decrypted - * @cryptoff: Bytes to skip after AD before plain/cipher text * @iv: Initialisation vector * @assoc: Associated data * @src: Source data @@ -66,7 +65,6 @@ struct aead_request { unsigned int assoclen; unsigned int cryptlen; - unsigned int cryptoff; u8 *iv; @@ -525,18 +523,15 @@ static inline void aead_request_set_assoc(struct aead_request *req, * aead_request_set_ad - set associated data information * @req: request handle * @assoclen: number of bytes in associated data - * @cryptoff: Number of bytes to skip after AD before plain/cipher text * * Setting the AD information. This function sets the length of * the associated data and the number of bytes to skip after it to * access the plain/cipher text. */ static inline void aead_request_set_ad(struct aead_request *req, - unsigned int assoclen, - unsigned int cryptoff) + unsigned int assoclen) { req->assoclen = assoclen; - req->cryptoff = cryptoff; req->old = false; } -- cgit v1.2.3 From 16b369a91d0dd80be214b7f7801fbc51875454cc Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Mon, 25 May 2015 15:08:47 +0200 Subject: random: Blocking API for accessing nonblocking_pool The added API calls provide a synchronous function call get_blocking_random_bytes where the caller is blocked until the nonblocking_pool is initialized. CC: Andreas Steffen CC: Theodore Ts'o CC: Sandy Harris Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/linux/random.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/random.h b/include/linux/random.h index b05856e16b75..796267d56901 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -14,6 +14,7 @@ extern void add_input_randomness(unsigned int type, unsigned int code, extern void add_interrupt_randomness(int irq, int irq_flags); extern void get_random_bytes(void *buf, int nbytes); +extern void get_blocking_random_bytes(void *buf, int nbytes); extern void get_random_bytes_arch(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); extern int random_int_secret_init(void); -- cgit v1.2.3 From 3d6a5f75d1340539dcdcec4609761fa4b836a1f2 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Mon, 25 May 2015 15:09:14 +0200 Subject: crypto: drbg - prepare for async seeding In order to prepare for the addition of the asynchronous seeding call, the invocation of seeding the DRBG is moved out into a helper function. In addition, a block of memory is allocated during initialization time that will be used as a scratchpad for obtaining entropy. That scratchpad is used for the initial seeding operation as well as by the asynchronous seeding call. The memory must be zeroized every time the DRBG seeding call succeeds to avoid entropy data lingering in memory. CC: Andreas Steffen CC: Theodore Ts'o CC: Sandy Harris Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/drbg.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index 480d7a0f4dac..b0526981aa85 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -119,6 +119,8 @@ struct drbg_state { bool fips_primed; /* Continuous test primed? */ unsigned char *prev; /* FIPS 140-2 continuous test value */ #endif + u8 *seed_buf; /* buffer holding the seed */ + size_t seed_buf_len; const struct drbg_state_ops *d_ops; const struct drbg_core *core; struct drbg_string test_data; -- cgit v1.2.3 From 4c7879907eddd5b3ec09489bc980aab4f44e38dd Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Mon, 25 May 2015 15:09:36 +0200 Subject: crypto: drbg - add async seeding operation The async seeding operation is triggered during initalization right after the first non-blocking seeding is completed. As required by the asynchronous operation of random.c, a callback function is provided that is triggered by random.c once entropy is available. That callback function performs the actual seeding of the DRBG. CC: Andreas Steffen CC: Theodore Ts'o CC: Sandy Harris Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/drbg.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index b0526981aa85..46994b25dc85 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -51,6 +51,7 @@ #include #include #include +#include /* * Concatenation Helper and string operation helper @@ -119,6 +120,7 @@ struct drbg_state { bool fips_primed; /* Continuous test primed? */ unsigned char *prev; /* FIPS 140-2 continuous test value */ #endif + struct work_struct seed_work; /* asynchronous seeding support */ u8 *seed_buf; /* buffer holding the seed */ size_t seed_buf_len; const struct drbg_state_ops *d_ops; -- cgit v1.2.3 From b8ec5ba42c4a3854e27c44e697d9b4f0b84b32bb Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Mon, 25 May 2015 15:09:59 +0200 Subject: crypto: drbg - use Jitter RNG to obtain seed During initialization, the DRBG now tries to allocate a handle of the Jitter RNG. If such a Jitter RNG is available during seeding, the DRBG pulls the required entropy/nonce string from get_random_bytes and concatenates it with a string of equal size from the Jitter RNG. That combined string is now the seed for the DRBG. Written differently, the initial seed of the DRBG is now: get_random_bytes(entropy/nonce) || jitterentropy (entropy/nonce) If the Jitter RNG is not available, the DRBG only seeds from get_random_bytes. CC: Andreas Steffen CC: Theodore Ts'o CC: Sandy Harris Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/drbg.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index 46994b25dc85..c3f208dc83ee 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -123,6 +123,7 @@ struct drbg_state { struct work_struct seed_work; /* asynchronous seeding support */ u8 *seed_buf; /* buffer holding the seed */ size_t seed_buf_len; + struct crypto_rng *jent; const struct drbg_state_ops *d_ops; const struct drbg_core *core; struct drbg_string test_data; -- cgit v1.2.3 From 693b549d39ea755abea721eb53b4262f75f41fb9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 27 May 2015 14:37:26 +0800 Subject: crypto: aead - Document behaviour of AD in destination buffer This patch defines the behaviour of AD in the new interface more clearly. In particular, it specifies that if the user must copy the AD to the destination manually when src != dst if they wish to guarantee that the destination buffer contains a copy of the AD. The reason for this is that otherwise every AEAD implementation would have to perform such a copy when src != dst. In reality most users do in-place processing where src == dst so this is not an issue. This patch also kills some remaining references to cryptoff. Signed-off-by: Herbert Xu --- include/crypto/aead.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index 94141dc1225e..61306ed81b8f 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -473,8 +473,15 @@ static inline void aead_request_set_callback(struct aead_request *req, * destination is the ciphertext. For a decryption operation, the use is * reversed - the source is the ciphertext and the destination is the plaintext. * - * For both src/dst the layout is associated data, skipped data, - * plain/cipher text, authentication tag. + * For both src/dst the layout is associated data, plain/cipher text, + * authentication tag. + * + * The content of the AD in the destination buffer after processing + * will either be untouched, or it will contain a copy of the AD + * from the source buffer. In order to ensure that it always has + * a copy of the AD, the user must copy the AD over either before + * or after processing. Of course this is not relevant if the user + * is doing in-place processing where src == dst. * * IMPORTANT NOTE AEAD requires an authentication tag (MAC). For decryption, * the caller must concatenate the ciphertext followed by the @@ -525,8 +532,7 @@ static inline void aead_request_set_assoc(struct aead_request *req, * @assoclen: number of bytes in associated data * * Setting the AD information. This function sets the length of - * the associated data and the number of bytes to skip after it to - * access the plain/cipher text. + * the associated data. */ static inline void aead_request_set_ad(struct aead_request *req, unsigned int assoclen) -- cgit v1.2.3 From 6350449fbf269aa78281b08852e64d5a4845df96 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 27 May 2015 14:37:30 +0800 Subject: crypto: aead - Add common IV generation code This patch adds some common IV generation code currently duplicated by seqiv and echainiv. For example, the setkey and setauthsize functions are completely identical. Signed-off-by: Herbert Xu --- include/crypto/internal/geniv.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 include/crypto/internal/geniv.h (limited to 'include') diff --git a/include/crypto/internal/geniv.h b/include/crypto/internal/geniv.h new file mode 100644 index 000000000000..9ca9b871aba5 --- /dev/null +++ b/include/crypto/internal/geniv.h @@ -0,0 +1,24 @@ +/* + * geniv: IV generation + * + * 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 + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ + +#ifndef _CRYPTO_INTERNAL_GENIV_H +#define _CRYPTO_INTERNAL_GENIV_H + +#include +#include + +struct aead_geniv_ctx { + spinlock_t lock; + struct crypto_aead *child; +}; + +#endif /* _CRYPTO_INTERNAL_GENIV_H */ -- cgit v1.2.3 From 165ecc6373c7bfcd63da6dc489980c892fac2db9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 27 May 2015 16:03:44 +0800 Subject: xfrm: Add IV generator information to xfrm_algo_desc This patch adds IV generator information for each AEAD and block cipher to xfrm_algo_desc. This will be used to access the new AEAD interface. Signed-off-by: Herbert Xu --- include/net/xfrm.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 36ac102c97c7..30bca865c9dc 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1314,6 +1314,7 @@ static inline int xfrm_id_proto_match(u8 proto, u8 userproto) * xfrm algorithm information */ struct xfrm_algo_aead_info { + char *geniv; u16 icv_truncbits; }; @@ -1323,6 +1324,7 @@ struct xfrm_algo_auth_info { }; struct xfrm_algo_encr_info { + char *geniv; u16 blockbits; u16 defkeybits; }; -- cgit v1.2.3 From 69b0137f6164a14993504d4cf5a61dabf79e6c43 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 27 May 2015 16:03:45 +0800 Subject: ipsec: Add IV generator information to xfrm_state This patch adds IV generator information to xfrm_state. This is currently obtained from our own list of algorithm descriptions. Signed-off-by: Herbert Xu --- include/net/xfrm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 30bca865c9dc..f0ee97eec24d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -168,6 +168,7 @@ struct xfrm_state { struct xfrm_algo *ealg; struct xfrm_algo *calg; struct xfrm_algo_aead *aead; + const char *geniv; /* Data for encapsulator */ struct xfrm_encap_tmpl *encap; -- cgit v1.2.3 From bfa1ce5f38938cc9e6c7f2d1011f88eba2b9e2b2 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 28 May 2015 11:40:54 +0200 Subject: bus: mvebu-mbus: add mv_mbus_dram_info_nooverlap() This commit introduces a variant of the mv_mbus_dram_info() function called mv_mbus_dram_info_nooverlap(). Both functions are used by Marvell drivers supporting devices doing DMA, and provide them a description the DRAM ranges that they need to configure their DRAM windows. The ranges provided by the mv_mbus_dram_info() function may overlap with the I/O windows if there is a lot (>= 4 GB) of RAM installed. This is not a problem for most of the DMA masters, except for the upcoming new CESA crypto driver because it does DMA to the SRAM, which is mapped through an I/O window. For this unit, we need to have DRAM ranges that do not overlap with the I/O windows. A first implementation done in commit 1737cac69369 ("bus: mvebu-mbus: make sure SDRAM CS for DMA don't overlap the MBus bridge window"), changed the information returned by mv_mbus_dram_info() to match this requirement. However, it broke the requirement of the other DMA masters than the DRAM ranges should have power of two sizes. To solve this situation, this commit introduces a new mv_mbus_dram_info_nooverlap() function, which returns the same information as mv_mbus_dram_info(), but guaranteed to not overlap with the I/O windows. In the end, it gives us two variants of the mv_mbus_dram_info*() functions: - The normal one, mv_mbus_dram_info(), which has been around for many years. This function returns the raw DRAM ranges, which are guaranteed to use power of two sizes, but will overlap with I/O windows. This function will therefore be used by all DMA masters (SATA, XOR, Ethernet, etc.) except the CESA crypto driver. - The new 'nooverlap' variant, mv_mbus_dram_info_nooverlap(). This function returns DRAM ranges after they have been "tweaked" to make sure they don't overlap with I/O windows. By doing this tweaking, we remove the power of two size guarantee. This variant will be used by the new CESA crypto driver. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- include/linux/mbus.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/mbus.h b/include/linux/mbus.h index 611b69fa8594..1f7bc630d225 100644 --- a/include/linux/mbus.h +++ b/include/linux/mbus.h @@ -54,11 +54,16 @@ struct mbus_dram_target_info */ #ifdef CONFIG_PLAT_ORION extern const struct mbus_dram_target_info *mv_mbus_dram_info(void); +extern const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap(void); #else static inline const struct mbus_dram_target_info *mv_mbus_dram_info(void) { return NULL; } +static inline const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap(void) +{ + return NULL; +} #endif int mvebu_mbus_save_cpu_target(u32 *store_addr); -- cgit v1.2.3 From addfda2fc2ed2fcd7896ef689aa75a7d35a7579b Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Thu, 28 May 2015 08:52:42 +0200 Subject: crypto: doc - cover new AEAD interface The patch updates the DocBook to cover the new AEAD interface implementation. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/aead.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index 61306ed81b8f..1a273bc5656c 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -50,6 +50,7 @@ /** * struct aead_request - AEAD request * @base: Common attributes for async crypto requests + * @old: Boolean whether the old or new AEAD API is used * @assoclen: Length in bytes of associated data for authentication * @cryptlen: Length of data to be encrypted or decrypted * @iv: Initialisation vector @@ -467,7 +468,9 @@ static inline void aead_request_set_callback(struct aead_request *req, * @iv: IV for the cipher operation which must comply with the IV size defined * by crypto_aead_ivsize() * - * Setting the source data and destination data scatter / gather lists. + * Setting the source data and destination data scatter / gather lists which + * hold the associated data concatenated with the plaintext or ciphertext. See + * below for the authentication tag. * * For encryption, the source is treated as the plaintext and the * destination is the ciphertext. For a decryption operation, the use is -- cgit v1.2.3 From 5eb8ec6dc857d5027bc8cf7268a199107a583ae5 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 28 May 2015 22:07:53 +0800 Subject: crypto: aead - Add type-safe init/exit functions As it stands the only non-type safe functions left in the new AEAD interface are the cra_init/cra_exit functions. It means exposing the ugly __crypto_aead_cast to every AEAD implementor. This patch adds type-safe init/exit functions to AEAD. Existing algorithms are unaffected while new implementations can simply fill in these two instead of cra_init/cra_exit. Signed-off-by: Herbert Xu --- include/crypto/aead.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index 1a273bc5656c..5cb0066be30b 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -109,6 +109,17 @@ struct aead_givcrypt_request { * @decrypt: see struct ablkcipher_alg * @geniv: see struct ablkcipher_alg * @ivsize: see struct ablkcipher_alg + * @init: Initialize the cryptographic transformation object. This function + * is used to initialize the cryptographic transformation object. + * This function is called only once at the instantiation time, right + * after the transformation context was allocated. In case the + * cryptographic hardware has some special requirements which need to + * be handled by software, this function shall check for the precise + * requirement of the transformation and put any software fallbacks + * in place. + * @exit: Deinitialize the cryptographic transformation object. This is a + * counterpart to @init, used to remove various changes set in + * @init. * * All fields except @ivsize is mandatory and must be filled. */ @@ -118,6 +129,8 @@ struct aead_alg { int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize); int (*encrypt)(struct aead_request *req); int (*decrypt)(struct aead_request *req); + int (*init)(struct crypto_aead *tfm); + void (*exit)(struct crypto_aead *tfm); const char *geniv; -- cgit v1.2.3 From 5c98d62059faf7c59211cb591da671eaac7b7c3c Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 28 May 2015 22:07:55 +0800 Subject: crypto: aead - Add aead_alg_instance Now that type-safe init/exit functions exist, they often need to access the underlying aead_instance. So this patch adds the helper aead_alg_instance to access aead_instance from a crypto_aead object. Signed-off-by: Herbert Xu --- include/crypto/internal/aead.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index 4137330f01ab..f068d74da9f6 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -52,6 +52,11 @@ static inline struct aead_instance *aead_instance(struct crypto_instance *inst) return container_of(&inst->alg, struct aead_instance, alg.base); } +static inline struct aead_instance *aead_alg_instance(struct crypto_aead *aead) +{ + return aead_instance(crypto_aead_alg_instance(aead)); +} + static inline void *aead_instance_ctx(struct aead_instance *inst) { return crypto_instance_ctx(aead_crypto_instance(inst)); -- cgit v1.2.3 From 43615369ab79f2c06532ea1607266b8307ccce82 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 28 May 2015 22:07:57 +0800 Subject: crypto: aead - Ignore return value from crypto_unregister_alg No new code should be using the return value of crypto_unregister_alg as it will become void soon. Signed-off-by: Herbert Xu --- include/crypto/internal/aead.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index f068d74da9f6..3cb35d882930 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -151,7 +151,7 @@ static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead) } int crypto_register_aead(struct aead_alg *alg); -int crypto_unregister_aead(struct aead_alg *alg); +void crypto_unregister_aead(struct aead_alg *alg); int aead_register_instance(struct crypto_template *tmpl, struct aead_instance *inst); -- cgit v1.2.3 From caab94612ac677523d2bf4a4904c8d080c2c7f73 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 28 May 2015 22:07:59 +0800 Subject: crypto: aead - Add multiple algorithm registration interface This patch adds the helpers that allow the registration and removal of multiple algorithms. Signed-off-by: Herbert Xu --- include/crypto/internal/aead.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index 3cb35d882930..ba52c37b8c40 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -152,6 +152,8 @@ static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead) int crypto_register_aead(struct aead_alg *alg); void crypto_unregister_aead(struct aead_alg *alg); +int crypto_register_aeads(struct aead_alg *algs, int count); +void crypto_unregister_aeads(struct aead_alg *algs, int count); int aead_register_instance(struct crypto_template *tmpl, struct aead_instance *inst); -- cgit v1.2.3 From cfaed10d1f27d036b72bbdc6b1e59ea28c38ec7f Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Mon, 1 Jun 2015 11:15:25 -0500 Subject: scatterlist: introduce sg_nents_for_len When performing a dma_map_sg() call, the number of sg entries to map is required. Using sg_nents to retrieve the number of sg entries will return the total number of entries in the sg list up to the entry marked as the end. If there happen to be unused entries in the list, these will still be counted. Some dma_map_sg() implementations will not handle the unused entries correctly (lib/swiotlb.c) and execute a BUG_ON. The sg_nents_for_len() function will traverse the sg list and return the number of entries required to satisfy the supplied length argument. This can then be supplied to the dma_map_sg() call to successfully map the sg. Signed-off-by: Tom Lendacky Signed-off-by: Herbert Xu --- include/linux/scatterlist.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index ed8f9e70df9b..a0edb992c9c3 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -221,6 +221,7 @@ static inline void *sg_virt(struct scatterlist *sg) } int sg_nents(struct scatterlist *sg); +int sg_nents_for_len(struct scatterlist *sg, u64 len); struct scatterlist *sg_next(struct scatterlist *); struct scatterlist *sg_last(struct scatterlist *s, unsigned int); void sg_init_table(struct scatterlist *, unsigned int); -- cgit v1.2.3 From 12f7c14aa602f15ad60e5a9da459271f63b92917 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 4 Jun 2015 00:01:21 +0900 Subject: crypto: doc - Fix typo in crypto-API.xml This patch fix some typos found in crypto-API.xml. It is because the file is generated from comments in sources, so I had to fix typo in sources. Signed-off-by: Masanari Iida Acked-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/aead.h | 2 +- include/crypto/hash.h | 2 +- include/crypto/rng.h | 2 +- include/linux/crypto.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/crypto/aead.h b/include/crypto/aead.h index 5cb0066be30b..7169ad04acc0 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -33,7 +33,7 @@ * * The example code provided for the asynchronous block cipher operation * applies here as well. Naturally all *ablkcipher* symbols must be exchanged - * the *aead* pendants discussed in the following. In addtion, for the AEAD + * the *aead* pendants discussed in the following. In addition, for the AEAD * operation, the aead_request_set_assoc function must be used to set the * pointer to the associated data memory location before performing the * encryption or decryption operation. In case of an encryption, the associated diff --git a/include/crypto/hash.h b/include/crypto/hash.h index 98abda9ed3aa..57c8a6ee33c2 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -66,7 +66,7 @@ struct ahash_request { /** * struct ahash_alg - asynchronous message digest definition * @init: Initialize the transformation context. Intended only to initialize the - * state of the HASH transformation at the begining. This shall fill in + * state of the HASH transformation at the beginning. This shall fill in * the internal structures used during the entire duration of the whole * transformation. No data processing happens at this point. * @update: Push a chunk of data into the driver for transformation. This diff --git a/include/crypto/rng.h b/include/crypto/rng.h index c5d4684429f5..b95ede354a66 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -28,7 +28,7 @@ struct crypto_rng; * 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 + * generator shall become ready for 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 diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 7d290a91c6f9..25a4b71d6d1f 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -451,7 +451,7 @@ struct compress_alg { * transformation algorithm. * @cra_type: Type of the cryptographic transformation. This is a pointer to * struct crypto_type, which implements callbacks common for all - * trasnformation types. There are multiple options: + * transformation types. There are multiple options: * &crypto_blkcipher_type, &crypto_ablkcipher_type, * &crypto_ahash_type, &crypto_aead_type, &crypto_rng_type. * This field might be empty. In that case, there are no common -- cgit v1.2.3 From 205a525c334295e3cd4cc7755fd2c0398e3a787f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 9 Jun 2015 18:19:39 +0800 Subject: random: Add callback API for random pool readiness The get_blocking_random_bytes API is broken because the wait can be arbitrarily long (potentially forever) so there is no safe way of calling it from within the kernel. This patch replaces it with a callback API instead. The callback is invoked potentially from interrupt context so the user needs to schedule their own work thread if necessary. In addition to adding callbacks, they can also be removed as otherwise this opens up a way for user-space to allocate kernel memory with no bound (by opening algif_rng descriptors and then closing them). Signed-off-by: Herbert Xu --- include/linux/random.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/linux/random.h b/include/linux/random.h index 796267d56901..30e2aca0b16a 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -6,8 +6,15 @@ #ifndef _LINUX_RANDOM_H #define _LINUX_RANDOM_H +#include #include +struct random_ready_callback { + struct list_head list; + void (*func)(struct random_ready_callback *rdy); + struct module *owner; +}; + extern void add_device_randomness(const void *, unsigned int); extern void add_input_randomness(unsigned int type, unsigned int code, unsigned int value); @@ -15,6 +22,8 @@ extern void add_interrupt_randomness(int irq, int irq_flags); extern void get_random_bytes(void *buf, int nbytes); extern void get_blocking_random_bytes(void *buf, int nbytes); +extern int add_random_ready_callback(struct random_ready_callback *rdy); +extern void del_random_ready_callback(struct random_ready_callback *rdy); extern void get_random_bytes_arch(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); extern int random_int_secret_init(void); -- cgit v1.2.3 From 57225e6797885e31302e76fc5926c0bedd7e5ad4 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Tue, 9 Jun 2015 21:55:38 +0800 Subject: crypto: drbg - Use callback API for random readiness The get_blocking_random_bytes API is broken because the wait can be arbitrarily long (potentially forever) so there is no safe way of calling it from within the kernel. This patch replaces it with the new callback API which does not have this problem. The patch also removes the entropy buffer registered with the DRBG handle in favor of stack variables to hold the seed data. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/drbg.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index c3f208dc83ee..fad6450b99f9 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -121,12 +121,11 @@ struct drbg_state { unsigned char *prev; /* FIPS 140-2 continuous test value */ #endif struct work_struct seed_work; /* asynchronous seeding support */ - u8 *seed_buf; /* buffer holding the seed */ - size_t seed_buf_len; struct crypto_rng *jent; const struct drbg_state_ops *d_ops; const struct drbg_core *core; struct drbg_string test_data; + struct random_ready_callback random_ready; }; static inline __u8 drbg_statelen(struct drbg_state *drbg) -- cgit v1.2.3 From c2719503f5e1e6213d716bb078bdad01e28ebcbf Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 9 Jun 2015 18:19:42 +0800 Subject: random: Remove kernel blocking API This patch removes the kernel blocking API as it has been completely replaced by the callback API. Signed-off-by: Herbert Xu --- include/linux/random.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/random.h b/include/linux/random.h index 30e2aca0b16a..e651874df2c9 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -21,7 +21,6 @@ extern void add_input_randomness(unsigned int type, unsigned int code, extern void add_interrupt_randomness(int irq, int irq_flags); extern void get_random_bytes(void *buf, int nbytes); -extern void get_blocking_random_bytes(void *buf, int nbytes); extern int add_random_ready_callback(struct random_ready_callback *rdy); extern void del_random_ready_callback(struct random_ready_callback *rdy); extern void get_random_bytes_arch(void *buf, int nbytes); -- cgit v1.2.3 From 42ea507fae1ac4b4af0d9d715ab56fa4de2a0341 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 10 Jun 2015 03:33:37 +0200 Subject: crypto: drbg - reseed often if seedsource is degraded As required by SP800-90A, the DRBG implements are reseeding threshold. This threshold is at 2**48 (64 bit) and 2**32 bit (32 bit) as implemented in drbg_max_requests. With the recently introduced changes, the DRBG is now always used as a stdrng which is initialized very early in the boot cycle. To ensure that sufficient entropy is present, the Jitter RNG is added to even provide entropy at early boot time. However, the 2nd seed source, the nonblocking pool, is usually degraded at that time. Therefore, the DRBG is seeded with the Jitter RNG (which I believe contains good entropy, which however is questioned by others) and is seeded with a degradded nonblocking pool. This seed is now used for quasi the lifetime of the system (2**48 requests is a lot). The patch now changes the reseed threshold as follows: up until the time the DRBG obtains a seed from a fully iniitialized nonblocking pool, the reseeding threshold is lowered such that the DRBG is forced to reseed itself resonably often. Once it obtains the seed from a fully initialized nonblocking pool, the reseed threshold is set to the value required by SP800-90A. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/drbg.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index fad6450b99f9..9756c70899d8 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -111,6 +111,7 @@ struct drbg_state { unsigned char *C; /* Number of RNG requests since last reseed -- 10.1.1.1 1c) */ size_t reseed_ctr; + size_t reseed_threshold; /* some memory the DRBG can use for its operation */ unsigned char *scratchpad; void *priv_data; /* Cipher handle */ -- cgit v1.2.3 From 32be6d3e362b896c81aae7c635d44e5a91406ce2 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Fri, 12 Jun 2015 10:58:46 -0400 Subject: crypto: nx - move include/linux/nx842.h into drivers/crypto/nx/nx-842.h Move the contents of the include/linux/nx842.h header file into the drivers/crypto/nx/nx-842.h header file. Remove the nx842.h header file and its entry in the MAINTAINERS file. The include/linux/nx842.h header originally was there because the crypto/842.c driver needed it to communicate with the nx-842 hw driver. However, that crypto compression driver was moved into the drivers/crypto/nx/ directory, and now can directly include the nx-842.h header. Nothing else needs the public include/linux/nx842.h header file, as all use of the nx-842 hardware driver will be through the "842-nx" crypto compression driver, since the direct nx-842 api is very limited in the buffer alignments and sizes that it will accept, and the crypto compression interface handles those limitations and allows any alignment and size buffers. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- include/linux/nx842.h | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 include/linux/nx842.h (limited to 'include') diff --git a/include/linux/nx842.h b/include/linux/nx842.h deleted file mode 100644 index 4ddf68d9c0d4..000000000000 --- a/include/linux/nx842.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __NX842_H__ -#define __NX842_H__ - -#define __NX842_PSERIES_MEM_COMPRESS (10240) -#define __NX842_POWERNV_MEM_COMPRESS (1024) - -#define NX842_MEM_COMPRESS (max_t(unsigned int, \ - __NX842_PSERIES_MEM_COMPRESS, __NX842_POWERNV_MEM_COMPRESS)) - -struct nx842_constraints { - int alignment; - int multiple; - int minimum; - int maximum; -}; - -int nx842_constraints(struct nx842_constraints *constraints); - -int nx842_compress(const unsigned char *in, unsigned int in_len, - unsigned char *out, unsigned int *out_len, void *wrkmem); -int nx842_decompress(const unsigned char *in, unsigned int in_len, - unsigned char *out, unsigned int *out_len, void *wrkmem); - -#endif -- cgit v1.2.3 From d37e296979ed1652aec6850e2d736bd0ebf0cdb1 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Mon, 15 Jun 2015 13:18:36 -0700 Subject: MPILIB: add mpi_read_buf() and mpi_get_size() helpers Added a mpi_read_buf() helper function to export MPI to a buf provided by the user, and a mpi_get_size() helper, that tells the user how big the buf is. Changed mpi_free to use kzfree instead of kfree because it is used to free crypto keys. Signed-off-by: Tadeusz Struk Signed-off-by: Herbert Xu --- include/linux/mpi.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/linux/mpi.h b/include/linux/mpi.h index 5af1b81def49..641b7d6fd096 100644 --- a/include/linux/mpi.h +++ b/include/linux/mpi.h @@ -81,6 +81,8 @@ MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread); int mpi_fromstr(MPI val, const char *str); u32 mpi_get_keyid(MPI a, u32 *keyid); void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign); +int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes, + int *sign); void *mpi_get_secure_buffer(MPI a, unsigned *nbytes, int *sign); int mpi_set_buffer(MPI a, const void *buffer, unsigned nbytes, int sign); @@ -142,4 +144,17 @@ int mpi_rshift(MPI x, MPI a, unsigned n); /*-- mpi-inv.c --*/ int mpi_invm(MPI x, MPI u, MPI v); +/* inline functions */ + +/** + * mpi_get_size() - returns max size required to store the number + * + * @a: A multi precision integer for which we want to allocate a bufer + * + * Return: size required to store the number + */ +static inline unsigned int mpi_get_size(MPI a) +{ + return a->nlimbs * BYTES_PER_MPI_LIMB; +} #endif /*G10_MPI_H */ -- cgit v1.2.3 From 3c339ab83fc09d9d91fb7e8b4a60e8ddc91de417 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Tue, 16 Jun 2015 10:30:55 -0700 Subject: crypto: akcipher - add PKE API Add Public Key Encryption API. Signed-off-by: Tadeusz Struk Made CRYPTO_AKCIPHER invisible like other type config options. Signed-off-by: Herbert Xu --- include/crypto/akcipher.h | 340 +++++++++++++++++++++++++++++++++++++ include/crypto/internal/akcipher.h | 60 +++++++ include/linux/crypto.h | 1 + include/linux/cryptouser.h | 5 + 4 files changed, 406 insertions(+) create mode 100644 include/crypto/akcipher.h create mode 100644 include/crypto/internal/akcipher.h (limited to 'include') diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h new file mode 100644 index 000000000000..69d163e39101 --- /dev/null +++ b/include/crypto/akcipher.h @@ -0,0 +1,340 @@ +/* + * Public Key Encryption + * + * Copyright (c) 2015, Intel Corporation + * Authors: Tadeusz Struk + * + * 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 + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#ifndef _CRYPTO_AKCIPHER_H +#define _CRYPTO_AKCIPHER_H +#include + +/** + * struct akcipher_request - public key request + * + * @base: Common attributes for async crypto requests + * @src: Pointer to memory containing the input parameters + * The format of the parameter(s) is expeted to be Octet String + * @dst: Pointer to memory whare the result will be stored + * @src_len: Size of the input parameter + * @dst_len: Size of the output buffer. It needs to be at leaset + * as big as the expected result depending on the operation + * After operation it will be updated with the acctual size of the + * result. In case of error, where the dst_len was insufficient, + * it will be updated to the size required for the operation. + * @__ctx: Start of private context data + */ +struct akcipher_request { + struct crypto_async_request base; + void *src; + void *dst; + unsigned int src_len; + unsigned int dst_len; + void *__ctx[] CRYPTO_MINALIGN_ATTR; +}; + +/** + * struct crypto_akcipher - user-instantiated objects which encapsulate + * algorithms and core processing logic + * + * @base: Common crypto API algorithm data structure + */ +struct crypto_akcipher { + struct crypto_tfm base; +}; + +/** + * struct akcipher_alg - generic public key algorithm + * + * @sign: Function performs a sign operation as defined by public key + * algorithm. In case of error, where the dst_len was insufficient, + * the req->dst_len will be updated to the size required for the + * operation + * @verify: Function performs a sign operation as defined by public key + * algorithm. In case of error, where the dst_len was insufficient, + * the req->dst_len will be updated to the size required for the + * operation + * @encrypt: Function performs an encrytp operation as defined by public key + * algorithm. In case of error, where the dst_len was insufficient, + * the req->dst_len will be updated to the size required for the + * operation + * @decrypt: Function performs a decrypt operation as defined by public key + * algorithm. In case of error, where the dst_len was insufficient, + * the req->dst_len will be updated to the size required for the + * operation + * @setkey: Function invokes the algorithm specific set key function, which + * knows how to decode and interpret the BER encoded key + * @init: Initialize the cryptographic transformation object. + * This function is used to initialize the cryptographic + * transformation object. This function is called only once at + * the instantiation time, right after the transformation context + * was allocated. In case the cryptographic hardware has some + * special requirements which need to be handled by software, this + * function shall check for the precise requirement of the + * transformation and put any software fallbacks in place. + * @exit: Deinitialize the cryptographic transformation object. This is a + * counterpart to @init, used to remove various changes set in + * @init. + * + * @reqsize: Request context size required by algorithm implementation + * @base: Common crypto API algorithm data structure + */ +struct akcipher_alg { + int (*sign)(struct akcipher_request *req); + int (*verify)(struct akcipher_request *req); + int (*encrypt)(struct akcipher_request *req); + int (*decrypt)(struct akcipher_request *req); + int (*setkey)(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen); + int (*init)(struct crypto_akcipher *tfm); + void (*exit)(struct crypto_akcipher *tfm); + + unsigned int reqsize; + struct crypto_alg base; +}; + +/** + * DOC: Generic Public Key API + * + * The Public Key API is used with the algorithms of type + * CRYPTO_ALG_TYPE_AKCIPHER (listed as type "akcipher" in /proc/crypto) + */ + +/** + * crypto_alloc_akcipher() -- allocate AKCIPHER tfm handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * public key algorithm e.g. "rsa" + * @type: specifies the type of the algorithm + * @mask: specifies the mask for the algorithm + * + * Allocate a handle for public key algorithm. The returned struct + * crypto_akcipher is the handle that is required for any subsequent + * API invocation for the public key operations. + * + * Return: allocated handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ +struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type, + u32 mask); + +static inline struct crypto_tfm *crypto_akcipher_tfm( + struct crypto_akcipher *tfm) +{ + return &tfm->base; +} + +static inline struct akcipher_alg *__crypto_akcipher_alg(struct crypto_alg *alg) +{ + return container_of(alg, struct akcipher_alg, base); +} + +static inline struct crypto_akcipher *__crypto_akcipher_tfm( + struct crypto_tfm *tfm) +{ + return container_of(tfm, struct crypto_akcipher, base); +} + +static inline struct akcipher_alg *crypto_akcipher_alg( + struct crypto_akcipher *tfm) +{ + return __crypto_akcipher_alg(crypto_akcipher_tfm(tfm)->__crt_alg); +} + +static inline unsigned int crypto_akcipher_reqsize(struct crypto_akcipher *tfm) +{ + return crypto_akcipher_alg(tfm)->reqsize; +} + +static inline void akcipher_request_set_tfm(struct akcipher_request *req, + struct crypto_akcipher *tfm) +{ + req->base.tfm = crypto_akcipher_tfm(tfm); +} + +static inline struct crypto_akcipher *crypto_akcipher_reqtfm( + struct akcipher_request *req) +{ + return __crypto_akcipher_tfm(req->base.tfm); +} + +/** + * crypto_free_akcipher() -- free AKCIPHER tfm handle + * + * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher() + */ +static inline void crypto_free_akcipher(struct crypto_akcipher *tfm) +{ + crypto_destroy_tfm(tfm, crypto_akcipher_tfm(tfm)); +} + +/** + * akcipher_request_alloc() -- allocates public key request + * + * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher() + * @gfp: allocation flags + * + * Return: allocated handle in case of success or NULL in case of an error. + */ +static inline struct akcipher_request *akcipher_request_alloc( + struct crypto_akcipher *tfm, gfp_t gfp) +{ + struct akcipher_request *req; + + req = kmalloc(sizeof(*req) + crypto_akcipher_reqsize(tfm), gfp); + if (likely(req)) + akcipher_request_set_tfm(req, tfm); + + return req; +} + +/** + * akcipher_request_free() -- zeroize and free public key request + * + * @req: request to free + */ +static inline void akcipher_request_free(struct akcipher_request *req) +{ + kzfree(req); +} + +/** + * akcipher_request_set_callback() -- Sets an asynchronous callback. + * + * Callback will be called when an asynchronous operation on a given + * request is finished. + * + * @req: request that the callback will be set for + * @flgs: specify for instance if the operation may backlog + * @cmlp: callback which will be called + * @data: private data used by the caller + */ +static inline void akcipher_request_set_callback(struct akcipher_request *req, + u32 flgs, + crypto_completion_t cmpl, + void *data) +{ + req->base.complete = cmpl; + req->base.data = data; + req->base.flags = flgs; +} + +/** + * akcipher_request_set_crypt() -- Sets reqest parameters + * + * Sets parameters required by crypto operation + * + * @req: public key request + * @src: ptr to input parameter + * @dst: ptr of output parameter + * @src_len: size of the input buffer + * @dst_len: size of the output buffer. It will be updated by the + * implementation to reflect the acctual size of the result + */ +static inline void akcipher_request_set_crypt(struct akcipher_request *req, + void *src, void *dst, + unsigned int src_len, + unsigned int dst_len) +{ + req->src = src; + req->dst = dst; + req->src_len = src_len; + req->dst_len = dst_len; +} + +/** + * crypto_akcipher_encrypt() -- Invoke public key encrypt operation + * + * Function invokes the specific public key encrypt operation for a given + * public key algorithm + * + * @req: asymmetric key request + * + * Return: zero on success; error code in case of error + */ +static inline int crypto_akcipher_encrypt(struct akcipher_request *req) +{ + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct akcipher_alg *alg = crypto_akcipher_alg(tfm); + + return alg->encrypt(req); +} + +/** + * crypto_akcipher_decrypt() -- Invoke public key decrypt operation + * + * Function invokes the specific public key decrypt operation for a given + * public key algorithm + * + * @req: asymmetric key request + * + * Return: zero on success; error code in case of error + */ +static inline int crypto_akcipher_decrypt(struct akcipher_request *req) +{ + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct akcipher_alg *alg = crypto_akcipher_alg(tfm); + + return alg->decrypt(req); +} + +/** + * crypto_akcipher_sign() -- Invoke public key sign operation + * + * Function invokes the specific public key sign operation for a given + * public key algorithm + * + * @req: asymmetric key request + * + * Return: zero on success; error code in case of error + */ +static inline int crypto_akcipher_sign(struct akcipher_request *req) +{ + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct akcipher_alg *alg = crypto_akcipher_alg(tfm); + + return alg->sign(req); +} + +/** + * crypto_akcipher_verify() -- Invoke public key verify operation + * + * Function invokes the specific public key verify operation for a given + * public key algorithm + * + * @req: asymmetric key request + * + * Return: zero on success; error code in case of error + */ +static inline int crypto_akcipher_verify(struct akcipher_request *req) +{ + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct akcipher_alg *alg = crypto_akcipher_alg(tfm); + + return alg->verify(req); +} + +/** + * crypto_akcipher_setkey() -- Invoke public key setkey operation + * + * Function invokes the algorithm specific set key function, which knows + * how to decode and interpret the encoded key + * + * @tfm: tfm handle + * @key: BER encoded private or public key + * @keylen: length of the key + * + * Return: zero on success; error code in case of error + */ +static inline int crypto_akcipher_setkey(struct crypto_akcipher *tfm, void *key, + unsigned int keylen) +{ + struct akcipher_alg *alg = crypto_akcipher_alg(tfm); + + return alg->setkey(tfm, key, keylen); +} +#endif diff --git a/include/crypto/internal/akcipher.h b/include/crypto/internal/akcipher.h new file mode 100644 index 000000000000..9a2bda15e454 --- /dev/null +++ b/include/crypto/internal/akcipher.h @@ -0,0 +1,60 @@ +/* + * Public Key Encryption + * + * Copyright (c) 2015, Intel Corporation + * Authors: Tadeusz Struk + * + * 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 + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#ifndef _CRYPTO_AKCIPHER_INT_H +#define _CRYPTO_AKCIPHER_INT_H +#include + +/* + * Transform internal helpers. + */ +static inline void *akcipher_request_ctx(struct akcipher_request *req) +{ + return req->__ctx; +} + +static inline void *akcipher_tfm_ctx(struct crypto_akcipher *tfm) +{ + return tfm->base.__crt_ctx; +} + +static inline void akcipher_request_complete(struct akcipher_request *req, + int err) +{ + req->base.complete(&req->base, err); +} + +static inline const char *akcipher_alg_name(struct crypto_akcipher *tfm) +{ + return crypto_akcipher_tfm(tfm)->__crt_alg->cra_name; +} + +/** + * crypto_register_akcipher() -- Register public key algorithm + * + * Function registers an implementation of a public key verify algorithm + * + * @alg: algorithm definition + * + * Return: zero on success; error code in case of error + */ +int crypto_register_akcipher(struct akcipher_alg *alg); + +/** + * crypto_unregister_akcipher() -- Unregister public key algorithm + * + * Function unregisters an implementation of a public key verify algorithm + * + * @alg: algorithm definition + */ +void crypto_unregister_akcipher(struct akcipher_alg *alg); +#endif diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 25a4b71d6d1f..0e3f71a73e3b 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -53,6 +53,7 @@ #define CRYPTO_ALG_TYPE_SHASH 0x00000009 #define CRYPTO_ALG_TYPE_AHASH 0x0000000a #define CRYPTO_ALG_TYPE_RNG 0x0000000c +#define CRYPTO_ALG_TYPE_AKCIPHER 0x0000000d #define CRYPTO_ALG_TYPE_PCOMPRESS 0x0000000f #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h index 4abf2ea6a887..36efbbbf2f83 100644 --- a/include/linux/cryptouser.h +++ b/include/linux/cryptouser.h @@ -43,6 +43,7 @@ enum crypto_attr_type_t { CRYPTOCFGA_REPORT_COMPRESS, /* struct crypto_report_comp */ CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */ CRYPTOCFGA_REPORT_CIPHER, /* struct crypto_report_cipher */ + CRYPTOCFGA_REPORT_AKCIPHER, /* struct crypto_report_akcipher */ __CRYPTOCFGA_MAX #define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1) @@ -101,5 +102,9 @@ struct crypto_report_rng { unsigned int seedsize; }; +struct crypto_report_akcipher { + char type[CRYPTO_MAX_NAME]; +}; + #define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \ sizeof(struct crypto_report_blkcipher)) -- cgit v1.2.3 From cfc2bb32b31371d6bffc6bf2da3548f20ad48c83 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Tue, 16 Jun 2015 10:31:01 -0700 Subject: crypto: rsa - add a new rsa generic implementation Add a new rsa generic SW implementation. This implements only cryptographic primitives. Signed-off-by: Tadeusz Struk Added select on ASN1. Signed-off-by: Herbert Xu --- include/crypto/internal/rsa.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 include/crypto/internal/rsa.h (limited to 'include') diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h new file mode 100644 index 000000000000..a8c86365439f --- /dev/null +++ b/include/crypto/internal/rsa.h @@ -0,0 +1,27 @@ +/* + * RSA internal helpers + * + * Copyright (c) 2015, Intel Corporation + * Authors: Tadeusz Struk + * + * 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 + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#ifndef _RSA_HELPER_ +#define _RSA_HELPER_ +#include + +struct rsa_key { + MPI n; + MPI e; + MPI d; +}; + +int rsa_parse_key(struct rsa_key *rsa_key, const void *key, + unsigned int key_len); + +void rsa_free_key(struct rsa_key *rsa_key); +#endif -- cgit v1.2.3 From edf18b9108f5025f9e83b2c167c9122954acbc62 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 18 Jun 2015 14:00:48 +0800 Subject: crypto: api - Add CRYPTO_MINALIGN_ATTR to struct crypto_alg The struct crypto_alg is embedded into various type-specific structs such as aead_alg. This is then used as part of instances such as struct aead_instance. It is also embedded into the generic struct crypto_instance. In order to ensure that struct aead_instance can be converted to struct crypto_instance when necessary, we need to ensure that crypto_alg is aligned properly. This patch adds an alignment attribute to struct crypto_alg to ensure this. Signed-off-by: Herbert Xu --- include/linux/crypto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 0e3f71a73e3b..964e5735a6a9 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -513,7 +513,7 @@ struct crypto_alg { void (*cra_destroy)(struct crypto_alg *alg); struct module *cra_module; -}; +} CRYPTO_MINALIGN_ATTR; /* * Algorithm registration interface. -- cgit v1.2.3 From f5d8660acb9623470adcef426c6ff7b07cbe4b74 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 18 Jun 2015 14:00:49 +0800 Subject: crypto: aead - Fix aead_instance struct size The struct aead_instance is meant to extend struct crypto_instance by incorporating the extra members of struct aead_alg. However, the current layout which is copied from shash/ahash does not specify the struct fully. In particular only aead_alg is present. For shash/ahash this works because users there add extra headroom to sizeof(struct crypto_instance) when allocating the instance. Unfortunately for aead, this bit was lost when the new aead_instance was added. Rather than fixing it like shash/ahash, this patch simply expands struct aead_instance to contain what is supposed to be there, i.e., adding struct crypto_instance. In order to not break existing AEAD users, this is done through an anonymous union. Signed-off-by: Herbert Xu --- include/crypto/internal/aead.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index ba52c37b8c40..4b2547186519 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -15,12 +15,19 @@ #include #include +#include #include struct rtattr; struct aead_instance { - struct aead_alg alg; + union { + struct { + char head[offsetof(struct aead_alg, base)]; + struct crypto_instance base; + } s; + struct aead_alg alg; + }; }; struct crypto_aead_spawn { -- cgit v1.2.3 From 7cecadb7cca83953e7857fe9f7273b705cb8ebe7 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 21 Jun 2015 19:11:43 +0800 Subject: crypto: rng - Do not free default RNG when it becomes unused Currently we free the default RNG when its use count hits zero. This was OK when the IV generators would latch onto the RNG at instance creation time and keep it until the instance is torn down. Now that IV generators only keep the RNG reference during init time this scheme causes the default RNG to come and go at a high frequencey. This is highly undesirable as we want to keep a single RNG in use unless the admin wants it to be removed. This patch changes the scheme so that the system RNG once allocated is never removed unless a specifically requested. Signed-off-by: Herbert Xu --- include/crypto/internal/rng.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h index 263f1a5eebc7..a52ef3483dd7 100644 --- a/include/crypto/internal/rng.h +++ b/include/crypto/internal/rng.h @@ -22,6 +22,15 @@ void crypto_unregister_rng(struct rng_alg *alg); int crypto_register_rngs(struct rng_alg *algs, int count); void crypto_unregister_rngs(struct rng_alg *algs, int count); +#if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE) +int crypto_del_default_rng(void); +#else +static inline int crypto_del_default_rng(void) +{ + return 0; +} +#endif + static inline void *crypto_rng_ctx(struct crypto_rng *tfm) { return crypto_tfm_ctx(&tfm->base); -- cgit v1.2.3 From d0497524658e37956737d7dbee73cc42120255dc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 21 Jun 2015 19:11:44 +0800 Subject: crypto: user - Move cryptouser.h to uapi The header file cryptouser.h only contains information that is exported to user-space. Signed-off-by: Herbert Xu --- include/linux/cryptouser.h | 110 ---------------------------------------- include/uapi/linux/cryptouser.h | 110 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 110 deletions(-) delete mode 100644 include/linux/cryptouser.h create mode 100644 include/uapi/linux/cryptouser.h (limited to 'include') diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h deleted file mode 100644 index 36efbbbf2f83..000000000000 --- a/include/linux/cryptouser.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Crypto user configuration API. - * - * Copyright (C) 2011 secunet Security Networks AG - * Copyright (C) 2011 Steffen Klassert - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* Netlink configuration messages. */ -enum { - CRYPTO_MSG_BASE = 0x10, - CRYPTO_MSG_NEWALG = 0x10, - CRYPTO_MSG_DELALG, - CRYPTO_MSG_UPDATEALG, - CRYPTO_MSG_GETALG, - __CRYPTO_MSG_MAX -}; -#define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1) -#define CRYPTO_NR_MSGTYPES (CRYPTO_MSG_MAX + 1 - CRYPTO_MSG_BASE) - -#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME - -/* Netlink message attributes. */ -enum crypto_attr_type_t { - CRYPTOCFGA_UNSPEC, - CRYPTOCFGA_PRIORITY_VAL, /* __u32 */ - CRYPTOCFGA_REPORT_LARVAL, /* struct crypto_report_larval */ - CRYPTOCFGA_REPORT_HASH, /* struct crypto_report_hash */ - CRYPTOCFGA_REPORT_BLKCIPHER, /* struct crypto_report_blkcipher */ - CRYPTOCFGA_REPORT_AEAD, /* struct crypto_report_aead */ - CRYPTOCFGA_REPORT_COMPRESS, /* struct crypto_report_comp */ - CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */ - CRYPTOCFGA_REPORT_CIPHER, /* struct crypto_report_cipher */ - CRYPTOCFGA_REPORT_AKCIPHER, /* struct crypto_report_akcipher */ - __CRYPTOCFGA_MAX - -#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1) -}; - -struct crypto_user_alg { - char cru_name[CRYPTO_MAX_ALG_NAME]; - char cru_driver_name[CRYPTO_MAX_ALG_NAME]; - char cru_module_name[CRYPTO_MAX_ALG_NAME]; - __u32 cru_type; - __u32 cru_mask; - __u32 cru_refcnt; - __u32 cru_flags; -}; - -struct crypto_report_larval { - char type[CRYPTO_MAX_NAME]; -}; - -struct crypto_report_hash { - char type[CRYPTO_MAX_NAME]; - unsigned int blocksize; - unsigned int digestsize; -}; - -struct crypto_report_cipher { - char type[CRYPTO_MAX_ALG_NAME]; - unsigned int blocksize; - unsigned int min_keysize; - unsigned int max_keysize; -}; - -struct crypto_report_blkcipher { - char type[CRYPTO_MAX_NAME]; - char geniv[CRYPTO_MAX_NAME]; - unsigned int blocksize; - unsigned int min_keysize; - unsigned int max_keysize; - unsigned int ivsize; -}; - -struct crypto_report_aead { - char type[CRYPTO_MAX_NAME]; - char geniv[CRYPTO_MAX_NAME]; - unsigned int blocksize; - unsigned int maxauthsize; - unsigned int ivsize; -}; - -struct crypto_report_comp { - char type[CRYPTO_MAX_NAME]; -}; - -struct crypto_report_rng { - char type[CRYPTO_MAX_NAME]; - unsigned int seedsize; -}; - -struct crypto_report_akcipher { - char type[CRYPTO_MAX_NAME]; -}; - -#define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \ - sizeof(struct crypto_report_blkcipher)) diff --git a/include/uapi/linux/cryptouser.h b/include/uapi/linux/cryptouser.h new file mode 100644 index 000000000000..36efbbbf2f83 --- /dev/null +++ b/include/uapi/linux/cryptouser.h @@ -0,0 +1,110 @@ +/* + * Crypto user configuration API. + * + * Copyright (C) 2011 secunet Security Networks AG + * Copyright (C) 2011 Steffen Klassert + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Netlink configuration messages. */ +enum { + CRYPTO_MSG_BASE = 0x10, + CRYPTO_MSG_NEWALG = 0x10, + CRYPTO_MSG_DELALG, + CRYPTO_MSG_UPDATEALG, + CRYPTO_MSG_GETALG, + __CRYPTO_MSG_MAX +}; +#define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1) +#define CRYPTO_NR_MSGTYPES (CRYPTO_MSG_MAX + 1 - CRYPTO_MSG_BASE) + +#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME + +/* Netlink message attributes. */ +enum crypto_attr_type_t { + CRYPTOCFGA_UNSPEC, + CRYPTOCFGA_PRIORITY_VAL, /* __u32 */ + CRYPTOCFGA_REPORT_LARVAL, /* struct crypto_report_larval */ + CRYPTOCFGA_REPORT_HASH, /* struct crypto_report_hash */ + CRYPTOCFGA_REPORT_BLKCIPHER, /* struct crypto_report_blkcipher */ + CRYPTOCFGA_REPORT_AEAD, /* struct crypto_report_aead */ + CRYPTOCFGA_REPORT_COMPRESS, /* struct crypto_report_comp */ + CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */ + CRYPTOCFGA_REPORT_CIPHER, /* struct crypto_report_cipher */ + CRYPTOCFGA_REPORT_AKCIPHER, /* struct crypto_report_akcipher */ + __CRYPTOCFGA_MAX + +#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1) +}; + +struct crypto_user_alg { + char cru_name[CRYPTO_MAX_ALG_NAME]; + char cru_driver_name[CRYPTO_MAX_ALG_NAME]; + char cru_module_name[CRYPTO_MAX_ALG_NAME]; + __u32 cru_type; + __u32 cru_mask; + __u32 cru_refcnt; + __u32 cru_flags; +}; + +struct crypto_report_larval { + char type[CRYPTO_MAX_NAME]; +}; + +struct crypto_report_hash { + char type[CRYPTO_MAX_NAME]; + unsigned int blocksize; + unsigned int digestsize; +}; + +struct crypto_report_cipher { + char type[CRYPTO_MAX_ALG_NAME]; + unsigned int blocksize; + unsigned int min_keysize; + unsigned int max_keysize; +}; + +struct crypto_report_blkcipher { + char type[CRYPTO_MAX_NAME]; + char geniv[CRYPTO_MAX_NAME]; + unsigned int blocksize; + unsigned int min_keysize; + unsigned int max_keysize; + unsigned int ivsize; +}; + +struct crypto_report_aead { + char type[CRYPTO_MAX_NAME]; + char geniv[CRYPTO_MAX_NAME]; + unsigned int blocksize; + unsigned int maxauthsize; + unsigned int ivsize; +}; + +struct crypto_report_comp { + char type[CRYPTO_MAX_NAME]; +}; + +struct crypto_report_rng { + char type[CRYPTO_MAX_NAME]; + unsigned int seedsize; +}; + +struct crypto_report_akcipher { + char type[CRYPTO_MAX_NAME]; +}; + +#define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \ + sizeof(struct crypto_report_blkcipher)) -- cgit v1.2.3 From 9aa867e46565d61491f884c793e4988678fbffa3 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 21 Jun 2015 19:11:45 +0800 Subject: crypto: user - Add CRYPTO_MSG_DELRNG This patch adds a new crypto_user command that allows the admin to delete the crypto system RNG. Note that this can only be done if the RNG is currently not in use. The next time it is used a new system RNG will be allocated. Signed-off-by: Herbert Xu --- include/uapi/linux/cryptouser.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/uapi/linux/cryptouser.h b/include/uapi/linux/cryptouser.h index 36efbbbf2f83..2e67bb64c1da 100644 --- a/include/uapi/linux/cryptouser.h +++ b/include/uapi/linux/cryptouser.h @@ -25,6 +25,7 @@ enum { CRYPTO_MSG_DELALG, CRYPTO_MSG_UPDATEALG, CRYPTO_MSG_GETALG, + CRYPTO_MSG_DELRNG, __CRYPTO_MSG_MAX }; #define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1) -- cgit v1.2.3 From 3e90950d36f19e5477becd5acb02e9b8d8c8956f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 22 Jun 2015 10:31:40 +0800 Subject: crypto: algif_aead - Temporarily disable all AEAD algorithms As the AEAD conversion is still ongoing, we do not yet wish to export legacy AEAD implementations to user-space, as their calling convention will change. This patch actually disables all AEAD algorithms because some of them (e.g., cryptd) will need to be modified to propagate this flag. Subsequent patches will reenable them on an individual basis. Signed-off-by: Herbert Xu --- include/linux/crypto.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 964e5735a6a9..81ef938b0a8e 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -101,6 +101,12 @@ */ #define CRYPTO_ALG_INTERNAL 0x00002000 +/* + * Temporary flag used to prevent legacy AEAD implementations from + * being used by user-space. + */ +#define CRYPTO_ALG_AEAD_NEW 0x00004000 + /* * Transform masks and values (for crt_flags). */ -- cgit v1.2.3