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 - 1 file changed, 1 deletion(-) (limited to 'include/crypto') diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 60d06e784be3..5fb6d8618d4d 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); }; -- 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 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/crypto') diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 5fb6d8618d4d..986db68548f6 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 { -- 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 ++++ 2 files changed, 112 insertions(+) (limited to 'include/crypto') diff --git a/include/crypto/hash.h b/include/crypto/hash.h index ee48ef8fb2ea..f9b51d408953 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 917ae57bad4a..32d3a8ed06de 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 */ -- 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 ----- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'include/crypto') diff --git a/include/crypto/hash.h b/include/crypto/hash.h index f9b51d408953..cd16d6e668ce 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 32d3a8ed06de..92fbe7385856 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) { -- 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 +++ 2 files changed, 8 insertions(+) (limited to 'include/crypto') diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 986db68548f6..010545436efa 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 92fbe7385856..82b70564bcab 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); -- 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/crypto') diff --git a/include/crypto/aes.h b/include/crypto/aes.h index 40008d67ee3d..656a4c66a568 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