From 4a7794860ba2b56693b1d89fd485fd08cdc763e3 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 13 Sep 2008 18:19:03 -0700 Subject: crypto: api - Move type exit function into crypto_tfm The type exit function needs to undo any allocations done by the type init function. However, the type init function may differ depending on the upper-level type of the transform (e.g., a crypto_blkcipher instantiated as a crypto_ablkcipher). So we need to move the exit function out of the lower-level structure and into crypto_tfm itself. As it stands this is a no-op since nobody uses exit functions at all. However, all cases where a lower-level type is instantiated as a different upper-level type (such as blkcipher as ablkcipher) will be converted such that they allocate the underlying transform and use that instead of casting (e.g., crypto_ablkcipher casted into crypto_blkcipher). That will need to use a different exit function depending on the upper-level type. This patch also allows the type init/exit functions to call (or not) cra_init/cra_exit instead of always calling them from the top level. Signed-off-by: Herbert Xu --- include/crypto/algapi.h | 1 - include/linux/crypto.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 60d06e784be..5fb6d8618d4 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -23,7 +23,6 @@ struct seq_file; struct crypto_type { unsigned int (*ctxsize)(struct crypto_alg *alg, u32 type, u32 mask); int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask); - void (*exit)(struct crypto_tfm *tfm); void (*show)(struct seq_file *m, struct crypto_alg *alg); }; diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 3d2317e4af2..ea52cd944fd 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -480,6 +480,8 @@ struct crypto_tfm { struct compress_tfm compress; struct rng_tfm rng; } crt_u; + + void (*exit)(struct crypto_tfm *tfm); struct crypto_alg *__crt_alg; -- cgit v1.2.3 From 7b0bac64cd5b74d6f1147524c26216de13a501fd Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 21 Sep 2008 06:52:53 +0900 Subject: crypto: api - Rebirth of crypto_alloc_tfm This patch reintroduces a completely revamped crypto_alloc_tfm. The biggest change is that we now take two crypto_type objects when allocating a tfm, a frontend and a backend. In fact this simply formalises what we've been doing behind the API's back. For example, as it stands crypto_alloc_ahash may use an actual ahash algorithm or a crypto_hash algorithm. Putting this in the API allows us to do this much more cleanly. The existing types will be converted across gradually. Signed-off-by: Herbert Xu --- include/crypto/algapi.h | 10 ++++++++++ include/linux/crypto.h | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 5fb6d8618d4..986db68548f 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -22,8 +22,18 @@ struct seq_file; struct crypto_type { unsigned int (*ctxsize)(struct crypto_alg *alg, u32 type, u32 mask); + unsigned int (*extsize)(struct crypto_alg *alg, + const struct crypto_type *frontend); int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask); + int (*init_tfm)(struct crypto_tfm *tfm, + const struct crypto_type *frontend); void (*show)(struct seq_file *m, struct crypto_alg *alg); + struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask); + + unsigned int type; + unsigned int maskclear; + unsigned int maskset; + unsigned int tfmsize; }; struct crypto_instance { diff --git a/include/linux/crypto.h b/include/linux/crypto.h index ea52cd944fd..ffaaa418cf5 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -546,7 +546,9 @@ struct crypto_attr_u32 { * Transform user interface. */ -struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); +struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, + const struct crypto_type *frontend, + u32 type, u32 mask); struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask); void crypto_free_tfm(struct crypto_tfm *tfm); -- cgit v1.2.3 From 7b5a080b3c46f0cac71c0d0262634c6517d4ee4f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 31 Aug 2008 15:47:27 +1000 Subject: crypto: hash - Add shash interface The shash interface replaces the current synchronous hash interface. It improves over hash in two ways. Firstly shash is reentrant, meaning that the same tfm may be used by two threads simultaneously as all hashing state is stored in a local descriptor. The other enhancement is that shash no longer takes scatter list entries. This is because shash is specifically designed for synchronous algorithms and as such scatter lists are unnecessary. All existing hash users will be converted to shash once the algorithms have been completely converted. There is also a new finup function that combines update with final. This will be extended to ahash once the algorithm conversion is done. This is also the first time that an algorithm type has their own registration function. Existing algorithm types will be converted to this way in due course. Signed-off-by: Herbert Xu --- include/crypto/hash.h | 104 +++++++++++++++++++++++++++++++++++++++++ include/crypto/internal/hash.h | 8 ++++ include/linux/crypto.h | 1 + 3 files changed, 113 insertions(+) (limited to 'include') diff --git a/include/crypto/hash.h b/include/crypto/hash.h index ee48ef8fb2e..f9b51d40895 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -15,10 +15,39 @@ #include +struct shash_desc { + struct crypto_shash *tfm; + u32 flags; + + void *__ctx[] CRYPTO_MINALIGN_ATTR; +}; + +struct shash_alg { + int (*init)(struct shash_desc *desc); + int (*update)(struct shash_desc *desc, const u8 *data, + unsigned int len); + int (*final)(struct shash_desc *desc, u8 *out); + int (*finup)(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out); + int (*digest)(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out); + int (*setkey)(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen); + + unsigned int descsize; + unsigned int digestsize; + + struct crypto_alg base; +}; + struct crypto_ahash { struct crypto_tfm base; }; +struct crypto_shash { + struct crypto_tfm base; +}; + static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm) { return (struct crypto_ahash *)tfm; @@ -169,4 +198,79 @@ static inline void ahash_request_set_crypt(struct ahash_request *req, req->result = result; } +struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type, + u32 mask); + +static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm) +{ + return &tfm->base; +} + +static inline void crypto_free_shash(struct crypto_shash *tfm) +{ + crypto_free_tfm(crypto_shash_tfm(tfm)); +} + +static inline unsigned int crypto_shash_alignmask( + struct crypto_shash *tfm) +{ + return crypto_tfm_alg_alignmask(crypto_shash_tfm(tfm)); +} + +static inline struct shash_alg *__crypto_shash_alg(struct crypto_alg *alg) +{ + return container_of(alg, struct shash_alg, base); +} + +static inline struct shash_alg *crypto_shash_alg(struct crypto_shash *tfm) +{ + return __crypto_shash_alg(crypto_shash_tfm(tfm)->__crt_alg); +} + +static inline unsigned int crypto_shash_digestsize(struct crypto_shash *tfm) +{ + return crypto_shash_alg(tfm)->digestsize; +} + +static inline u32 crypto_shash_get_flags(struct crypto_shash *tfm) +{ + return crypto_tfm_get_flags(crypto_shash_tfm(tfm)); +} + +static inline void crypto_shash_set_flags(struct crypto_shash *tfm, u32 flags) +{ + crypto_tfm_set_flags(crypto_shash_tfm(tfm), flags); +} + +static inline void crypto_shash_clear_flags(struct crypto_shash *tfm, u32 flags) +{ + crypto_tfm_clear_flags(crypto_shash_tfm(tfm), flags); +} + +static inline unsigned int crypto_shash_descsize(struct crypto_shash *tfm) +{ + return crypto_shash_alg(tfm)->descsize; +} + +static inline void *shash_desc_ctx(struct shash_desc *desc) +{ + return desc->__ctx; +} + +int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen); +int crypto_shash_digest(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out); + +static inline int crypto_shash_init(struct shash_desc *desc) +{ + return crypto_shash_alg(desc->tfm)->init(desc); +} + +int crypto_shash_update(struct shash_desc *desc, const u8 *data, + unsigned int len); +int crypto_shash_final(struct shash_desc *desc, u8 *out); +int crypto_shash_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out); + #endif /* _CRYPTO_HASH_H */ diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 917ae57bad4..32d3a8ed06d 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -40,6 +40,9 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err); int crypto_hash_walk_first(struct ahash_request *req, struct crypto_hash_walk *walk); +int crypto_register_shash(struct shash_alg *alg); +int crypto_unregister_shash(struct shash_alg *alg); + static inline void *crypto_ahash_ctx(struct crypto_ahash *tfm) { return crypto_tfm_ctx(&tfm->base); @@ -74,5 +77,10 @@ static inline int ahash_tfm_in_queue(struct crypto_queue *queue, return crypto_tfm_in_queue(queue, crypto_ahash_tfm(tfm)); } +static inline void *crypto_shash_ctx(struct crypto_shash *tfm) +{ + return crypto_tfm_ctx(&tfm->base); +} + #endif /* _CRYPTO_INTERNAL_HASH_H */ diff --git a/include/linux/crypto.h b/include/linux/crypto.h index ffaaa418cf5..ee95c748695 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -39,6 +39,7 @@ #define CRYPTO_ALG_TYPE_HASH 0x00000009 #define CRYPTO_ALG_TYPE_AHASH 0x0000000a #define CRYPTO_ALG_TYPE_RNG 0x0000000c +#define CRYPTO_ALG_TYPE_SHASH 0x0000000d #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e #define CRYPTO_ALG_TYPE_AHASH_MASK 0x0000000c -- cgit v1.2.3 From 3b2f6df08258e2875f42bd630eece7e7241a053b Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 31 Aug 2008 18:52:18 +1000 Subject: crypto: hash - Export shash through ahash This patch allows shash algorithms to be used through the ahash interface. This is required before we can convert digest algorithms over to shash. 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 ee95c748695..44c72f0f9b0 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -38,8 +38,8 @@ #define CRYPTO_ALG_TYPE_DIGEST 0x00000008 #define CRYPTO_ALG_TYPE_HASH 0x00000009 #define CRYPTO_ALG_TYPE_AHASH 0x0000000a +#define CRYPTO_ALG_TYPE_SHASH 0x0000000b #define CRYPTO_ALG_TYPE_RNG 0x0000000c -#define CRYPTO_ALG_TYPE_SHASH 0x0000000d #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e #define CRYPTO_ALG_TYPE_AHASH_MASK 0x0000000c -- cgit v1.2.3 From dec8b78606ebd5f309c38f2fb10196ce996dd18d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 2 Nov 2008 21:38:11 +0800 Subject: crypto: hash - Add import/export interface It is often useful to save the partial state of a hash function so that it can be used as a base for two or more computations. The most prominent example is HMAC where all hashes start from a base determined by the key. Having an import/export interface means that we only have to compute that base once rather than for each message. Signed-off-by: Herbert Xu --- include/crypto/hash.h | 21 +++++++++++++++++++++ include/crypto/internal/hash.h | 5 ----- include/linux/crypto.h | 1 + 3 files changed, 22 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/crypto/hash.h b/include/crypto/hash.h index f9b51d40895..cd16d6e668c 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -24,6 +24,7 @@ struct shash_desc { struct shash_alg { int (*init)(struct shash_desc *desc); + int (*reinit)(struct shash_desc *desc); int (*update)(struct shash_desc *desc, const u8 *data, unsigned int len); int (*final)(struct shash_desc *desc, u8 *out); @@ -116,6 +117,11 @@ static inline unsigned int crypto_ahash_reqsize(struct crypto_ahash *tfm) return crypto_ahash_crt(tfm)->reqsize; } +static inline void *ahash_request_ctx(struct ahash_request *req) +{ + return req->__ctx; +} + static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen) { @@ -130,6 +136,14 @@ static inline int crypto_ahash_digest(struct ahash_request *req) return crt->digest(req); } +static inline void crypto_ahash_export(struct ahash_request *req, u8 *out) +{ + memcpy(out, ahash_request_ctx(req), + crypto_ahash_reqsize(crypto_ahash_reqtfm(req))); +} + +int crypto_ahash_import(struct ahash_request *req, const u8 *in); + static inline int crypto_ahash_init(struct ahash_request *req) { struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); @@ -262,6 +276,13 @@ int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key, int crypto_shash_digest(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out); +static inline void crypto_shash_export(struct shash_desc *desc, u8 *out) +{ + memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm)); +} + +int crypto_shash_import(struct shash_desc *desc, const u8 *in); + static inline int crypto_shash_init(struct shash_desc *desc) { return crypto_shash_alg(desc->tfm)->init(desc); diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 32d3a8ed06d..92fbe738585 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -66,11 +66,6 @@ static inline struct ahash_request *ahash_dequeue_request( return ahash_request_cast(crypto_dequeue_request(queue)); } -static inline void *ahash_request_ctx(struct ahash_request *req) -{ - return req->__ctx; -} - static inline int ahash_tfm_in_queue(struct crypto_queue *queue, struct crypto_ahash *tfm) { diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 44c72f0f9b0..77a1f3d9416 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -221,6 +221,7 @@ struct ablkcipher_alg { struct ahash_alg { int (*init)(struct ahash_request *req); + int (*reinit)(struct ahash_request *req); int (*update)(struct ahash_request *req); int (*final)(struct ahash_request *req); int (*digest)(struct ahash_request *req); -- cgit v1.2.3 From 5f7082ed4f482f05db01d84dbf58190492ebf0ad Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 31 Aug 2008 22:21:09 +1000 Subject: crypto: hash - Export shash through hash This patch allows shash algorithms to be used through the old hash interface. This is a transitional measure so we can convert the underlying algorithms to shash before converting the users across. Signed-off-by: Herbert Xu --- include/crypto/algapi.h | 5 +++++ include/crypto/internal/hash.h | 3 +++ include/linux/crypto.h | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 986db68548f..010545436ef 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -248,6 +248,11 @@ static inline struct crypto_hash *crypto_spawn_hash(struct crypto_spawn *spawn) return __crypto_hash_cast(crypto_spawn_tfm(spawn, type, mask)); } +static inline void *crypto_hash_ctx(struct crypto_hash *tfm) +{ + return crypto_tfm_ctx(&tfm->base); +} + static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm) { return crypto_tfm_ctx_aligned(&tfm->base); diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 92fbe738585..82b70564bca 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -39,6 +39,9 @@ extern const struct crypto_type crypto_ahash_type; int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err); int crypto_hash_walk_first(struct ahash_request *req, struct crypto_hash_walk *walk); +int crypto_hash_walk_first_compat(struct hash_desc *hdesc, + struct crypto_hash_walk *walk, + struct scatterlist *sg, unsigned int len); int crypto_register_shash(struct shash_alg *alg); int crypto_unregister_shash(struct shash_alg *alg); diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 77a1f3d9416..3bacd71509f 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -36,9 +36,9 @@ #define CRYPTO_ALG_TYPE_ABLKCIPHER 0x00000005 #define CRYPTO_ALG_TYPE_GIVCIPHER 0x00000006 #define CRYPTO_ALG_TYPE_DIGEST 0x00000008 -#define CRYPTO_ALG_TYPE_HASH 0x00000009 +#define CRYPTO_ALG_TYPE_HASH 0x00000008 +#define CRYPTO_ALG_TYPE_SHASH 0x00000009 #define CRYPTO_ALG_TYPE_AHASH 0x0000000a -#define CRYPTO_ALG_TYPE_SHASH 0x0000000b #define CRYPTO_ALG_TYPE_RNG 0x0000000c #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e -- cgit v1.2.3 From 69c35efcf1576ab5f00cba83e8ca740923afb6c9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 7 Nov 2008 15:11:47 +0800 Subject: libcrc32c: Move implementation to crypto crc32c This patch swaps the role of libcrc32c and crc32c. Previously the implementation was in libcrc32c and crc32c was a wrapper. Now the code is in crc32c and libcrc32c just calls the crypto layer. The reason for the change is to tap into the algorithm selection capability of the crypto API so that optimised implementations such as the one utilising Intel's CRC32C instruction can be used where available. Signed-off-by: Herbert Xu --- include/linux/crc32c.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/crc32c.h b/include/linux/crc32c.h index 508f512e5a2..66fa8ff795e 100644 --- a/include/linux/crc32c.h +++ b/include/linux/crc32c.h @@ -3,9 +3,6 @@ #include -extern u32 crc32c_le(u32 crc, unsigned char const *address, size_t length); -extern u32 crc32c_be(u32 crc, unsigned char const *address, size_t length); - -#define crc32c(seed, data, length) crc32c_le(seed, (unsigned char const *)data, length) +extern u32 crc32c(u32 crc, const void *address, unsigned int length); #endif /* _LINUX_CRC32C_H */ -- cgit v1.2.3 From 0426c166424ea6d3d0412f47879c8ba268f874c4 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 11 Nov 2008 12:20:06 +0800 Subject: libcrc32c: Add crc32c_le macro The bnx2x driver actually uses the crc32c_le name so this patch restores the crc32c_le symbol through a macro. Signed-off-by: Herbert Xu --- include/linux/crc32c.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/crc32c.h b/include/linux/crc32c.h index 66fa8ff795e..bd8b44d96bd 100644 --- a/include/linux/crc32c.h +++ b/include/linux/crc32c.h @@ -5,4 +5,7 @@ extern u32 crc32c(u32 crc, const void *address, unsigned int length); +/* This macro exists for backwards-compatibility. */ +#define crc32c_le crc32c + #endif /* _LINUX_CRC32C_H */ -- cgit v1.2.3 From 0ee4a96902dd7858e65f378c86f428a0355bd841 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 25 Dec 2008 11:05:13 +1100 Subject: crypto: aes - Precompute tables The tables used by the various AES algorithms are currently computed at run-time. This has created an init ordering problem because some AES algorithms may be registered before the tables have been initialised. This patch gets around this whole thing by precomputing the tables. Signed-off-by: Herbert Xu --- include/crypto/aes.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/crypto/aes.h b/include/crypto/aes.h index 40008d67ee3..656a4c66a56 100644 --- a/include/crypto/aes.h +++ b/include/crypto/aes.h @@ -23,10 +23,10 @@ struct crypto_aes_ctx { u32 key_dec[AES_MAX_KEYLENGTH_U32]; }; -extern u32 crypto_ft_tab[4][256]; -extern u32 crypto_fl_tab[4][256]; -extern u32 crypto_it_tab[4][256]; -extern u32 crypto_il_tab[4][256]; +extern const u32 crypto_ft_tab[4][256]; +extern const u32 crypto_fl_tab[4][256]; +extern const u32 crypto_it_tab[4][256]; +extern const u32 crypto_il_tab[4][256]; int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len); -- cgit v1.2.3