diff options
Diffstat (limited to 'include/crypto')
| -rw-r--r-- | include/crypto/aead.h | 12 | ||||
| -rw-r--r-- | include/crypto/algapi.h | 4 | ||||
| -rw-r--r-- | include/crypto/chacha20.h | 1 | ||||
| -rw-r--r-- | include/crypto/cryptd.h | 5 | ||||
| -rw-r--r-- | include/crypto/dh.h | 29 | ||||
| -rw-r--r-- | include/crypto/drbg.h | 12 | ||||
| -rw-r--r-- | include/crypto/ecdh.h | 30 | ||||
| -rw-r--r-- | include/crypto/internal/aead.h | 21 | ||||
| -rw-r--r-- | include/crypto/internal/geniv.h | 2 | ||||
| -rw-r--r-- | include/crypto/internal/hash.h | 12 | ||||
| -rw-r--r-- | include/crypto/internal/kpp.h | 64 | ||||
| -rw-r--r-- | include/crypto/internal/rsa.h | 42 | ||||
| -rw-r--r-- | include/crypto/internal/skcipher.h | 122 | ||||
| -rw-r--r-- | include/crypto/kpp.h | 330 | ||||
| -rw-r--r-- | include/crypto/mcryptd.h | 8 | ||||
| -rw-r--r-- | include/crypto/null.h | 12 | ||||
| -rw-r--r-- | include/crypto/scatterwalk.h | 48 | ||||
| -rw-r--r-- | include/crypto/sha3.h | 29 | ||||
| -rw-r--r-- | include/crypto/skcipher.h | 207 | 
19 files changed, 844 insertions, 146 deletions
| diff --git a/include/crypto/aead.h b/include/crypto/aead.h index 75174f80a106..12f84327ca36 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -112,11 +112,12 @@ struct aead_request {   *		 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 + * @setkey: see struct skcipher_alg + * @encrypt: see struct skcipher_alg + * @decrypt: see struct skcipher_alg + * @geniv: see struct skcipher_alg + * @ivsize: see struct skcipher_alg + * @chunksize: see struct skcipher_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 @@ -145,6 +146,7 @@ struct aead_alg {  	unsigned int ivsize;  	unsigned int maxauthsize; +	unsigned int chunksize;  	struct crypto_alg base;  }; diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index eeafd21afb44..8637cdfe382a 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -244,6 +244,8 @@ static inline struct crypto_alg *crypto_attr_alg(struct rtattr *rta,  }  int crypto_attr_u32(struct rtattr *rta, u32 *num); +int crypto_inst_setname(struct crypto_instance *inst, const char *name, +			struct crypto_alg *alg);  void *crypto_alloc_instance2(const char *name, struct crypto_alg *alg,  			     unsigned int head);  struct crypto_instance *crypto_alloc_instance(const char *name, @@ -440,8 +442,10 @@ static inline int crypto_memneq(const void *a, const void *b, size_t size)  static inline void crypto_yield(u32 flags)  { +#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_VOLUNTARY)  	if (flags & CRYPTO_TFM_REQ_MAY_SLEEP)  		cond_resched(); +#endif  }  #endif	/* _CRYPTO_ALGAPI_H */ diff --git a/include/crypto/chacha20.h b/include/crypto/chacha20.h index 274bbaeeed0f..20d20f681a72 100644 --- a/include/crypto/chacha20.h +++ b/include/crypto/chacha20.h @@ -16,6 +16,7 @@ struct chacha20_ctx {  	u32 key[8];  }; +void chacha20_block(u32 *state, void *stream);  void crypto_chacha20_init(u32 *state, struct chacha20_ctx *ctx, u8 *iv);  int crypto_chacha20_setkey(struct crypto_tfm *tfm, const u8 *key,  			   unsigned int keysize); diff --git a/include/crypto/cryptd.h b/include/crypto/cryptd.h index 1547f540c920..bc792d5a9e88 100644 --- a/include/crypto/cryptd.h +++ b/include/crypto/cryptd.h @@ -31,6 +31,7 @@ static inline struct cryptd_ablkcipher *__cryptd_ablkcipher_cast(  struct cryptd_ablkcipher *cryptd_alloc_ablkcipher(const char *alg_name,  						  u32 type, u32 mask);  struct crypto_blkcipher *cryptd_ablkcipher_child(struct cryptd_ablkcipher *tfm); +bool cryptd_ablkcipher_queued(struct cryptd_ablkcipher *tfm);  void cryptd_free_ablkcipher(struct cryptd_ablkcipher *tfm);  struct cryptd_ahash { @@ -48,6 +49,8 @@ struct cryptd_ahash *cryptd_alloc_ahash(const char *alg_name,  					u32 type, u32 mask);  struct crypto_shash *cryptd_ahash_child(struct cryptd_ahash *tfm);  struct shash_desc *cryptd_shash_desc(struct ahash_request *req); +/* Must be called without moving CPUs. */ +bool cryptd_ahash_queued(struct cryptd_ahash *tfm);  void cryptd_free_ahash(struct cryptd_ahash *tfm);  struct cryptd_aead { @@ -64,6 +67,8 @@ struct cryptd_aead *cryptd_alloc_aead(const char *alg_name,  					  u32 type, u32 mask);  struct crypto_aead *cryptd_aead_child(struct cryptd_aead *tfm); +/* Must be called without moving CPUs. */ +bool cryptd_aead_queued(struct cryptd_aead *tfm);  void cryptd_free_aead(struct cryptd_aead *tfm); diff --git a/include/crypto/dh.h b/include/crypto/dh.h new file mode 100644 index 000000000000..5102a8f282e6 --- /dev/null +++ b/include/crypto/dh.h @@ -0,0 +1,29 @@ +/* + * Diffie-Hellman secret to be used with kpp API along with helper functions + * + * Copyright (c) 2016, Intel Corporation + * Authors: Salvatore Benedetto <[email protected]> + * + * 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_DH_ +#define _CRYPTO_DH_ + +struct dh { +	void *key; +	void *p; +	void *g; +	unsigned int key_size; +	unsigned int p_size; +	unsigned int g_size; +}; + +int crypto_dh_key_len(const struct dh *params); +int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params); +int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params); + +#endif diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index d961b2b16f55..61580b19f9f6 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -43,6 +43,7 @@  #include <linux/random.h>  #include <linux/scatterlist.h>  #include <crypto/hash.h> +#include <crypto/skcipher.h>  #include <linux/module.h>  #include <linux/crypto.h>  #include <linux/slab.h> @@ -107,14 +108,25 @@ struct drbg_test_data {  struct drbg_state {  	struct mutex drbg_mutex;	/* lock around DRBG */  	unsigned char *V;	/* internal state 10.1.1.1 1a) */ +	unsigned char *Vbuf;  	/* hash: static value 10.1.1.1 1b) hmac / ctr: key */  	unsigned char *C; +	unsigned char *Cbuf;  	/* 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; +	unsigned char *scratchpadbuf;  	void *priv_data;	/* Cipher handle */ + +	struct crypto_skcipher *ctr_handle;	/* CTR mode cipher handle */ +	struct skcipher_request *ctr_req;	/* CTR mode request handle */ +	__u8 *ctr_null_value_buf;		/* CTR mode unaligned buffer */ +	__u8 *ctr_null_value;			/* CTR mode aligned zero buf */ +	struct completion ctr_completion;	/* CTR mode async handler */ +	int ctr_async_err;			/* CTR mode async error */ +  	bool seeded;		/* DRBG fully seeded? */  	bool pr;		/* Prediction resistance enabled? */  	struct work_struct seed_work;	/* asynchronous seeding support */ diff --git a/include/crypto/ecdh.h b/include/crypto/ecdh.h new file mode 100644 index 000000000000..84bad548d194 --- /dev/null +++ b/include/crypto/ecdh.h @@ -0,0 +1,30 @@ +/* + * ECDH params to be used with kpp API + * + * Copyright (c) 2016, Intel Corporation + * Authors: Salvatore Benedetto <[email protected]> + * + * 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_ECDH_ +#define _CRYPTO_ECDH_ + +/* Curves IDs */ +#define ECC_CURVE_NIST_P192	0x0001 +#define ECC_CURVE_NIST_P256	0x0002 + +struct ecdh { +	unsigned short curve_id; +	char *key; +	unsigned short key_size; +}; + +int crypto_ecdh_key_len(const struct ecdh *params); +int crypto_ecdh_encode_key(char *buf, unsigned int len, const struct ecdh *p); +int crypto_ecdh_decode_key(const char *buf, unsigned int len, struct ecdh *p); + +#endif diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h index da3864991d4c..6ad8e31d3868 100644 --- a/include/crypto/internal/aead.h +++ b/include/crypto/internal/aead.h @@ -159,6 +159,27 @@ static inline struct aead_request *aead_get_backlog(struct aead_queue *queue)  	return req ? container_of(req, struct aead_request, base) : NULL;  } +static inline unsigned int crypto_aead_alg_chunksize(struct aead_alg *alg) +{ +	return alg->chunksize; +} + +/** + * crypto_aead_chunksize() - obtain chunk size + * @tfm: cipher handle + * + * The block size is set to one for ciphers such as CCM.  However, + * you still need to provide incremental updates in multiples of + * the underlying block size as the IV does not have sub-block + * granularity.  This is known in this API as the chunk size. + * + * Return: chunk size in bytes + */ +static inline unsigned int crypto_aead_chunksize(struct crypto_aead *tfm) +{ +	return crypto_aead_alg_chunksize(crypto_aead_alg(tfm)); +} +  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); diff --git a/include/crypto/internal/geniv.h b/include/crypto/internal/geniv.h index 59333635e712..2bcfb931bc5b 100644 --- a/include/crypto/internal/geniv.h +++ b/include/crypto/internal/geniv.h @@ -20,7 +20,7 @@  struct aead_geniv_ctx {  	spinlock_t lock;  	struct crypto_aead *child; -	struct crypto_blkcipher *null; +	struct crypto_skcipher *sknull;  	u8 salt[] __attribute__ ((aligned(__alignof__(u32))));  }; diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 49dae16f8929..1d4f365d8f03 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -114,14 +114,10 @@ int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc);  int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc);  int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc); -int shash_ahash_mcryptd_update(struct ahash_request *req, -			       struct shash_desc *desc); -int shash_ahash_mcryptd_final(struct ahash_request *req, -			      struct shash_desc *desc); -int shash_ahash_mcryptd_finup(struct ahash_request *req, -			      struct shash_desc *desc); -int shash_ahash_mcryptd_digest(struct ahash_request *req, -			       struct shash_desc *desc); +int ahash_mcryptd_update(struct ahash_request *desc); +int ahash_mcryptd_final(struct ahash_request *desc); +int ahash_mcryptd_finup(struct ahash_request *desc); +int ahash_mcryptd_digest(struct ahash_request *desc);  int crypto_init_shash_ops_async(struct crypto_tfm *tfm); diff --git a/include/crypto/internal/kpp.h b/include/crypto/internal/kpp.h new file mode 100644 index 000000000000..ad3acf3649be --- /dev/null +++ b/include/crypto/internal/kpp.h @@ -0,0 +1,64 @@ +/* + * Key-agreement Protocol Primitives (KPP) + * + * Copyright (c) 2016, Intel Corporation + * Authors: Salvatore Benedetto <[email protected]> + * + * 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_KPP_INT_H +#define _CRYPTO_KPP_INT_H +#include <crypto/kpp.h> +#include <crypto/algapi.h> + +/* + * Transform internal helpers. + */ +static inline void *kpp_request_ctx(struct kpp_request *req) +{ +	return req->__ctx; +} + +static inline void *kpp_tfm_ctx(struct crypto_kpp *tfm) +{ +	return tfm->base.__crt_ctx; +} + +static inline void kpp_request_complete(struct kpp_request *req, int err) +{ +	req->base.complete(&req->base, err); +} + +static inline const char *kpp_alg_name(struct crypto_kpp *tfm) +{ +	return crypto_kpp_tfm(tfm)->__crt_alg->cra_name; +} + +/** + * crypto_register_kpp() -- Register key-agreement protocol primitives algorithm + * + * Function registers an implementation of a key-agreement protocol primitive + * algorithm + * + * @alg:	algorithm definition + * + * Return: zero on success; error code in case of error + */ +int crypto_register_kpp(struct kpp_alg *alg); + +/** + * crypto_unregister_kpp() -- Unregister key-agreement protocol primitive + * algorithm + * + * Function unregisters an implementation of a key-agreement protocol primitive + * algorithm + * + * @alg:	algorithm definition + */ +void crypto_unregister_kpp(struct kpp_alg *alg); + +#endif diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h index c7585bdecbc2..9e8f1590de98 100644 --- a/include/crypto/internal/rsa.h +++ b/include/crypto/internal/rsa.h @@ -12,12 +12,44 @@   */  #ifndef _RSA_HELPER_  #define _RSA_HELPER_ -#include <linux/mpi.h> +#include <linux/types.h> +/** + * rsa_key - RSA key structure + * @n           : RSA modulus raw byte stream + * @e           : RSA public exponent raw byte stream + * @d           : RSA private exponent raw byte stream + * @p           : RSA prime factor p of n raw byte stream + * @q           : RSA prime factor q of n raw byte stream + * @dp          : RSA exponent d mod (p - 1) raw byte stream + * @dq          : RSA exponent d mod (q - 1) raw byte stream + * @qinv        : RSA CRT coefficient q^(-1) mod p raw byte stream + * @n_sz        : length in bytes of RSA modulus n + * @e_sz        : length in bytes of RSA public exponent + * @d_sz        : length in bytes of RSA private exponent + * @p_sz        : length in bytes of p field + * @q_sz        : length in bytes of q field + * @dp_sz       : length in bytes of dp field + * @dq_sz       : length in bytes of dq field + * @qinv_sz     : length in bytes of qinv field + */  struct rsa_key { -	MPI n; -	MPI e; -	MPI d; +	const u8 *n; +	const u8 *e; +	const u8 *d; +	const u8 *p; +	const u8 *q; +	const u8 *dp; +	const u8 *dq; +	const u8 *qinv; +	size_t n_sz; +	size_t e_sz; +	size_t d_sz; +	size_t p_sz; +	size_t q_sz; +	size_t dp_sz; +	size_t dq_sz; +	size_t qinv_sz;  };  int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key, @@ -26,7 +58,5 @@ int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,  int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,  		       unsigned int key_len); -void rsa_free_key(struct rsa_key *rsa_key); -  extern struct crypto_template rsa_pkcs1pad_tmpl;  #endif diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h index 2cf7a61ece59..a21a95e1a375 100644 --- a/include/crypto/internal/skcipher.h +++ b/include/crypto/internal/skcipher.h @@ -19,12 +19,46 @@  struct rtattr; +struct skcipher_instance { +	void (*free)(struct skcipher_instance *inst); +	union { +		struct { +			char head[offsetof(struct skcipher_alg, base)]; +			struct crypto_instance base; +		} s; +		struct skcipher_alg alg; +	}; +}; +  struct crypto_skcipher_spawn {  	struct crypto_spawn base;  };  extern const struct crypto_type crypto_givcipher_type; +static inline struct crypto_instance *skcipher_crypto_instance( +	struct skcipher_instance *inst) +{ +	return &inst->s.base; +} + +static inline struct skcipher_instance *skcipher_alg_instance( +	struct crypto_skcipher *skcipher) +{ +	return container_of(crypto_skcipher_alg(skcipher), +			    struct skcipher_instance, alg); +} + +static inline void *skcipher_instance_ctx(struct skcipher_instance *inst) +{ +	return crypto_instance_ctx(skcipher_crypto_instance(inst)); +} + +static inline void skcipher_request_complete(struct skcipher_request *req, int err) +{ +	req->base.complete(&req->base, err); +} +  static inline void crypto_set_skcipher_spawn(  	struct crypto_skcipher_spawn *spawn, struct crypto_instance *inst)  { @@ -34,6 +68,12 @@ static inline void crypto_set_skcipher_spawn(  int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,  			 u32 type, u32 mask); +static inline int crypto_grab_skcipher2(struct crypto_skcipher_spawn *spawn, +					const char *name, u32 type, u32 mask) +{ +	return crypto_grab_skcipher(spawn, name, type, mask); +} +  struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, u32 mask);  static inline void crypto_drop_skcipher(struct crypto_skcipher_spawn *spawn) @@ -41,54 +81,42 @@ static inline void crypto_drop_skcipher(struct crypto_skcipher_spawn *spawn)  	crypto_drop_spawn(&spawn->base);  } -static inline struct crypto_alg *crypto_skcipher_spawn_alg( +static inline struct skcipher_alg *crypto_skcipher_spawn_alg(  	struct crypto_skcipher_spawn *spawn)  { -	return spawn->base.alg; +	return container_of(spawn->base.alg, struct skcipher_alg, base);  } -static inline struct crypto_ablkcipher *crypto_spawn_skcipher( +static inline struct skcipher_alg *crypto_spawn_skcipher_alg(  	struct crypto_skcipher_spawn *spawn)  { -	return __crypto_ablkcipher_cast( -		crypto_spawn_tfm(&spawn->base, crypto_skcipher_type(0), -				 crypto_skcipher_mask(0))); +	return crypto_skcipher_spawn_alg(spawn);  } -int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req); -int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req); -const char *crypto_default_geniv(const struct crypto_alg *alg); - -struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl, -					     struct rtattr **tb, u32 type, -					     u32 mask); -void skcipher_geniv_free(struct crypto_instance *inst); -int skcipher_geniv_init(struct crypto_tfm *tfm); -void skcipher_geniv_exit(struct crypto_tfm *tfm); - -static inline struct crypto_ablkcipher *skcipher_geniv_cipher( -	struct crypto_ablkcipher *geniv) +static inline struct crypto_skcipher *crypto_spawn_skcipher( +	struct crypto_skcipher_spawn *spawn)  { -	return crypto_ablkcipher_crt(geniv)->base; +	return crypto_spawn_tfm2(&spawn->base);  } -static inline int skcipher_enqueue_givcrypt( -	struct crypto_queue *queue, struct skcipher_givcrypt_request *request) +static inline struct crypto_skcipher *crypto_spawn_skcipher2( +	struct crypto_skcipher_spawn *spawn)  { -	return ablkcipher_enqueue_request(queue, &request->creq); +	return crypto_spawn_skcipher(spawn);  } -static inline struct skcipher_givcrypt_request *skcipher_dequeue_givcrypt( -	struct crypto_queue *queue) +static inline void crypto_skcipher_set_reqsize( +	struct crypto_skcipher *skcipher, unsigned int reqsize)  { -	return skcipher_givcrypt_cast(crypto_dequeue_request(queue)); +	skcipher->reqsize = reqsize;  } -static inline void *skcipher_givcrypt_reqctx( -	struct skcipher_givcrypt_request *req) -{ -	return ablkcipher_request_ctx(&req->creq); -} +int crypto_register_skcipher(struct skcipher_alg *alg); +void crypto_unregister_skcipher(struct skcipher_alg *alg); +int crypto_register_skciphers(struct skcipher_alg *algs, int count); +void crypto_unregister_skciphers(struct skcipher_alg *algs, int count); +int skcipher_register_instance(struct crypto_template *tmpl, +			       struct skcipher_instance *inst);  static inline void ablkcipher_request_complete(struct ablkcipher_request *req,  					       int err) @@ -96,12 +124,6 @@ static inline void ablkcipher_request_complete(struct ablkcipher_request *req,  	req->base.complete(&req->base, err);  } -static inline void skcipher_givcrypt_complete( -	struct skcipher_givcrypt_request *req, int err) -{ -	ablkcipher_request_complete(&req->creq, err); -} -  static inline u32 ablkcipher_request_flags(struct ablkcipher_request *req)  {  	return req->base.flags; @@ -122,5 +144,31 @@ static inline u32 skcipher_request_flags(struct skcipher_request *req)  	return req->base.flags;  } +static inline unsigned int crypto_skcipher_alg_min_keysize( +	struct skcipher_alg *alg) +{ +	if ((alg->base.cra_flags & CRYPTO_ALG_TYPE_MASK) == +	    CRYPTO_ALG_TYPE_BLKCIPHER) +		return alg->base.cra_blkcipher.min_keysize; + +	if (alg->base.cra_ablkcipher.encrypt) +		return alg->base.cra_ablkcipher.min_keysize; + +	return alg->min_keysize; +} + +static inline unsigned int crypto_skcipher_alg_max_keysize( +	struct skcipher_alg *alg) +{ +	if ((alg->base.cra_flags & CRYPTO_ALG_TYPE_MASK) == +	    CRYPTO_ALG_TYPE_BLKCIPHER) +		return alg->base.cra_blkcipher.max_keysize; + +	if (alg->base.cra_ablkcipher.encrypt) +		return alg->base.cra_ablkcipher.max_keysize; + +	return alg->max_keysize; +} +  #endif	/* _CRYPTO_INTERNAL_SKCIPHER_H */ diff --git a/include/crypto/kpp.h b/include/crypto/kpp.h new file mode 100644 index 000000000000..30791f75c180 --- /dev/null +++ b/include/crypto/kpp.h @@ -0,0 +1,330 @@ +/* + * Key-agreement Protocol Primitives (KPP) + * + * Copyright (c) 2016, Intel Corporation + * Authors: Salvatore Benedetto <[email protected]> + * + * 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_KPP_ +#define _CRYPTO_KPP_ +#include <linux/crypto.h> + +/** + * struct kpp_request + * + * @base:	Common attributes for async crypto requests + * @src:	Source data + * @dst:	Destination data + * @src_len:	Size of the input buffer + * @dst_len:	Size of the output buffer. It needs to be at least + *		as big as the expected result depending	on the operation + *		After operation it will be updated with the actual size of the + *		result. In case of error where the dst sgl size was insufficient, + *		it will be updated to the size required for the operation. + * @__ctx:	Start of private context data + */ +struct kpp_request { +	struct crypto_async_request base; +	struct scatterlist *src; +	struct scatterlist *dst; +	unsigned int src_len; +	unsigned int dst_len; +	void *__ctx[] CRYPTO_MINALIGN_ATTR; +}; + +/** + * struct crypto_kpp - user-instantiated object which encapsulate + * algorithms and core processing logic + * + * @base:	Common crypto API algorithm data structure + */ +struct crypto_kpp { +	struct crypto_tfm base; +}; + +/** + * struct kpp_alg - generic key-agreement protocol primitives + * + * @set_secret:		Function invokes the protocol specific function to + *			store the secret private key along with parameters. + *			The implementation knows how to decode thie buffer + * @generate_public_key: Function generate the public key to be sent to the + *			counterpart. In case of error, where output is not big + *			enough req->dst_len will be updated to the size + *			required + * @compute_shared_secret: Function compute the shared secret as defined by + *			the algorithm. The result is given back to the user. + *			In case of error, where output is not big enough, + *			req->dst_len will be updated to the size required + * @max_size:		Function returns the size of the output buffer + * @init:		Initialize the object. This is called only once at + *			instantiation time. In case the cryptographic hardware + *			needs to be initialized. Software fallback should be + *			put in place here. + * @exit:		Undo everything @init did. + * + * @reqsize:		Request context size required by algorithm + *			implementation + * @base		Common crypto API algorithm data structure + */ +struct kpp_alg { +	int (*set_secret)(struct crypto_kpp *tfm, void *buffer, +			  unsigned int len); +	int (*generate_public_key)(struct kpp_request *req); +	int (*compute_shared_secret)(struct kpp_request *req); + +	int (*max_size)(struct crypto_kpp *tfm); + +	int (*init)(struct crypto_kpp *tfm); +	void (*exit)(struct crypto_kpp *tfm); + +	unsigned int reqsize; +	struct crypto_alg base; +}; + +/** + * DOC: Generic Key-agreement Protocol Primitevs API + * + * The KPP API is used with the algorithm type + * CRYPTO_ALG_TYPE_KPP (listed as type "kpp" in /proc/crypto) + */ + +/** + * crypto_alloc_kpp() - allocate KPP tfm handle + * @alg_name: is the name of the kpp algorithm (e.g. "dh", "ecdh") + * @type: specifies the type of the algorithm + * @mask: specifies the mask for the algorithm + * + * Allocate a handle for kpp algorithm. The returned struct crypto_kpp + * is requeried for any following API invocation + * + * Return: allocated handle in case of success; IS_ERR() is true in case of + *	   an error, PTR_ERR() returns the error code. + */ +struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask); + +static inline struct crypto_tfm *crypto_kpp_tfm(struct crypto_kpp *tfm) +{ +	return &tfm->base; +} + +static inline struct kpp_alg *__crypto_kpp_alg(struct crypto_alg *alg) +{ +	return container_of(alg, struct kpp_alg, base); +} + +static inline struct crypto_kpp *__crypto_kpp_tfm(struct crypto_tfm *tfm) +{ +	return container_of(tfm, struct crypto_kpp, base); +} + +static inline struct kpp_alg *crypto_kpp_alg(struct crypto_kpp *tfm) +{ +	return __crypto_kpp_alg(crypto_kpp_tfm(tfm)->__crt_alg); +} + +static inline unsigned int crypto_kpp_reqsize(struct crypto_kpp *tfm) +{ +	return crypto_kpp_alg(tfm)->reqsize; +} + +static inline void kpp_request_set_tfm(struct kpp_request *req, +				       struct crypto_kpp *tfm) +{ +	req->base.tfm = crypto_kpp_tfm(tfm); +} + +static inline struct crypto_kpp *crypto_kpp_reqtfm(struct kpp_request *req) +{ +	return __crypto_kpp_tfm(req->base.tfm); +} + +/** + * crypto_free_kpp() - free KPP tfm handle + * + * @tfm: KPP tfm handle allocated with crypto_alloc_kpp() + */ +static inline void crypto_free_kpp(struct crypto_kpp *tfm) +{ +	crypto_destroy_tfm(tfm, crypto_kpp_tfm(tfm)); +} + +/** + * kpp_request_alloc() - allocates kpp request + * + * @tfm:	KPP tfm handle allocated with crypto_alloc_kpp() + * @gfp:	allocation flags + * + * Return: allocated handle in case of success or NULL in case of an error. + */ +static inline struct kpp_request *kpp_request_alloc(struct crypto_kpp *tfm, +						    gfp_t gfp) +{ +	struct kpp_request *req; + +	req = kmalloc(sizeof(*req) + crypto_kpp_reqsize(tfm), gfp); +	if (likely(req)) +		kpp_request_set_tfm(req, tfm); + +	return req; +} + +/** + * kpp_request_free() - zeroize and free kpp request + * + * @req:	request to free + */ +static inline void kpp_request_free(struct kpp_request *req) +{ +	kzfree(req); +} + +/** + * kpp_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 + * @cmpl:	callback which will be called + * @data:	private data used by the caller + */ +static inline void kpp_request_set_callback(struct kpp_request *req, +					    u32 flgs, +					    crypto_completion_t cmpl, +					    void *data) +{ +	req->base.complete = cmpl; +	req->base.data = data; +	req->base.flags = flgs; +} + +/** + * kpp_request_set_input() - Sets input buffer + * + * Sets parameters required by generate_public_key + * + * @req:	kpp request + * @input:	ptr to input scatter list + * @input_len:	size of the input scatter list + */ +static inline void kpp_request_set_input(struct kpp_request *req, +					 struct scatterlist *input, +					 unsigned int input_len) +{ +	req->src = input; +	req->src_len = input_len; +} + +/** + * kpp_request_set_output() - Sets output buffer + * + * Sets parameters required by kpp operation + * + * @req:	kpp request + * @output:	ptr to output scatter list + * @output_len:	size of the output scatter list + */ +static inline void kpp_request_set_output(struct kpp_request *req, +					  struct scatterlist *output, +					  unsigned int output_len) +{ +	req->dst = output; +	req->dst_len = output_len; +} + +enum { +	CRYPTO_KPP_SECRET_TYPE_UNKNOWN, +	CRYPTO_KPP_SECRET_TYPE_DH, +	CRYPTO_KPP_SECRET_TYPE_ECDH, +}; + +/** + * struct kpp_secret - small header for packing secret buffer + * + * @type:	define type of secret. Each kpp type will define its own + * @len:	specify the len of the secret, include the header, that + *		follows the struct + */ +struct kpp_secret { +	unsigned short type; +	unsigned short len; +}; + +/** + * crypto_kpp_set_secret() - Invoke kpp operation + * + * Function invokes the specific kpp operation for a given alg. + * + * @tfm:	tfm handle + * + * Return: zero on success; error code in case of error + */ +static inline int crypto_kpp_set_secret(struct crypto_kpp *tfm, void *buffer, +					unsigned int len) +{ +	struct kpp_alg *alg = crypto_kpp_alg(tfm); + +	return alg->set_secret(tfm, buffer, len); +} + +/** + * crypto_kpp_generate_public_key() - Invoke kpp operation + * + * Function invokes the specific kpp operation for generating the public part + * for a given kpp algorithm + * + * @req:	kpp key request + * + * Return: zero on success; error code in case of error + */ +static inline int crypto_kpp_generate_public_key(struct kpp_request *req) +{ +	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); +	struct kpp_alg *alg = crypto_kpp_alg(tfm); + +	return alg->generate_public_key(req); +} + +/** + * crypto_kpp_compute_shared_secret() - Invoke kpp operation + * + * Function invokes the specific kpp operation for computing the shared secret + * for a given kpp algorithm. + * + * @req:	kpp key request + * + * Return: zero on success; error code in case of error + */ +static inline int crypto_kpp_compute_shared_secret(struct kpp_request *req) +{ +	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); +	struct kpp_alg *alg = crypto_kpp_alg(tfm); + +	return alg->compute_shared_secret(req); +} + +/** + * crypto_kpp_maxsize() - Get len for output buffer + * + * Function returns the output buffer size required + * + * @tfm:	KPP tfm handle allocated with crypto_alloc_kpp() + * + * Return: minimum len for output buffer or error code if key hasn't been set + */ +static inline int crypto_kpp_maxsize(struct crypto_kpp *tfm) +{ +	struct kpp_alg *alg = crypto_kpp_alg(tfm); + +	return alg->max_size(tfm); +} + +#endif diff --git a/include/crypto/mcryptd.h b/include/crypto/mcryptd.h index c23ee1f7ee80..4a53c0d38cd2 100644 --- a/include/crypto/mcryptd.h +++ b/include/crypto/mcryptd.h @@ -39,7 +39,7 @@ struct mcryptd_instance_ctx {  };  struct mcryptd_hash_ctx { -	struct crypto_shash *child; +	struct crypto_ahash *child;  	struct mcryptd_alg_state *alg_state;  }; @@ -59,13 +59,13 @@ struct mcryptd_hash_request_ctx {  	struct crypto_hash_walk walk;  	u8 *out;  	int flag; -	struct shash_desc desc; +	struct ahash_request areq;  };  struct mcryptd_ahash *mcryptd_alloc_ahash(const char *alg_name,  					u32 type, u32 mask); -struct crypto_shash *mcryptd_ahash_child(struct mcryptd_ahash *tfm); -struct shash_desc *mcryptd_shash_desc(struct ahash_request *req); +struct crypto_ahash *mcryptd_ahash_child(struct mcryptd_ahash *tfm); +struct ahash_request *mcryptd_ahash_desc(struct ahash_request *req);  void mcryptd_free_ahash(struct mcryptd_ahash *tfm);  void mcryptd_flusher(struct work_struct *work); diff --git a/include/crypto/null.h b/include/crypto/null.h index 06dc30d9f56e..3f0c59fb0a61 100644 --- a/include/crypto/null.h +++ b/include/crypto/null.h @@ -8,7 +8,17 @@  #define NULL_DIGEST_SIZE	0  #define NULL_IV_SIZE		0 -struct crypto_blkcipher *crypto_get_default_null_skcipher(void); +struct crypto_skcipher *crypto_get_default_null_skcipher(void);  void crypto_put_default_null_skcipher(void); +static inline struct crypto_skcipher *crypto_get_default_null_skcipher2(void) +{ +	return crypto_get_default_null_skcipher(); +} + +static inline void crypto_put_default_null_skcipher2(void) +{ +	crypto_put_default_null_skcipher(); +} +  #endif diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h index 35f99b68d037..880e6be9e95e 100644 --- a/include/crypto/scatterwalk.h +++ b/include/crypto/scatterwalk.h @@ -16,14 +16,10 @@  #ifndef _CRYPTO_SCATTERWALK_H  #define _CRYPTO_SCATTERWALK_H -#include <asm/kmap_types.h>  #include <crypto/algapi.h> -#include <linux/hardirq.h>  #include <linux/highmem.h>  #include <linux/kernel.h> -#include <linux/mm.h>  #include <linux/scatterlist.h> -#include <linux/sched.h>  static inline void scatterwalk_crypto_chain(struct scatterlist *head,  					    struct scatterlist *sg, @@ -83,17 +79,53 @@ static inline void scatterwalk_unmap(void *vaddr)  	kunmap_atomic(vaddr);  } -void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg); +static inline void scatterwalk_start(struct scatter_walk *walk, +				     struct scatterlist *sg) +{ +	walk->sg = sg; +	walk->offset = sg->offset; +} + +static inline void *scatterwalk_map(struct scatter_walk *walk) +{ +	return kmap_atomic(scatterwalk_page(walk)) + +	       offset_in_page(walk->offset); +} + +static inline void scatterwalk_pagedone(struct scatter_walk *walk, int out, +					unsigned int more) +{ +	if (out) { +		struct page *page; + +		page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT); +		/* Test ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE first as +		 * PageSlab cannot be optimised away per se due to +		 * use of volatile pointer. +		 */ +		if (ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE && !PageSlab(page)) +			flush_dcache_page(page); +	} + +	if (more && walk->offset >= walk->sg->offset + walk->sg->length) +		scatterwalk_start(walk, sg_next(walk->sg)); +} + +static inline void scatterwalk_done(struct scatter_walk *walk, int out, +				    int more) +{ +	if (!more || walk->offset >= walk->sg->offset + walk->sg->length || +	    !(walk->offset & (PAGE_SIZE - 1))) +		scatterwalk_pagedone(walk, out, more); +} +  void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,  			    size_t nbytes, int out);  void *scatterwalk_map(struct scatter_walk *walk); -void scatterwalk_done(struct scatter_walk *walk, int out, int more);  void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,  			      unsigned int start, unsigned int nbytes, int out); -int scatterwalk_bytes_sglen(struct scatterlist *sg, int num_bytes); -  struct scatterlist *scatterwalk_ffwd(struct scatterlist dst[2],  				     struct scatterlist *src,  				     unsigned int len); diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h new file mode 100644 index 000000000000..f4c9f68f5ffe --- /dev/null +++ b/include/crypto/sha3.h @@ -0,0 +1,29 @@ +/* + * Common values for SHA-3 algorithms + */ +#ifndef __CRYPTO_SHA3_H__ +#define __CRYPTO_SHA3_H__ + +#define SHA3_224_DIGEST_SIZE	(224 / 8) +#define SHA3_224_BLOCK_SIZE	(200 - 2 * SHA3_224_DIGEST_SIZE) + +#define SHA3_256_DIGEST_SIZE	(256 / 8) +#define SHA3_256_BLOCK_SIZE	(200 - 2 * SHA3_256_DIGEST_SIZE) + +#define SHA3_384_DIGEST_SIZE	(384 / 8) +#define SHA3_384_BLOCK_SIZE	(200 - 2 * SHA3_384_DIGEST_SIZE) + +#define SHA3_512_DIGEST_SIZE	(512 / 8) +#define SHA3_512_BLOCK_SIZE	(200 - 2 * SHA3_512_DIGEST_SIZE) + +struct sha3_state { +	u64		st[25]; +	unsigned int	md_len; +	unsigned int	rsiz; +	unsigned int	rsizw; + +	unsigned int	partial; +	u8		buf[SHA3_224_BLOCK_SIZE]; +}; + +#endif diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h index 0f987f50bb52..cc4d98a7892e 100644 --- a/include/crypto/skcipher.h +++ b/include/crypto/skcipher.h @@ -65,86 +65,80 @@ struct crypto_skcipher {  	struct crypto_tfm base;  }; -#define SKCIPHER_REQUEST_ON_STACK(name, tfm) \ -	char __##name##_desc[sizeof(struct skcipher_request) + \ -		crypto_skcipher_reqsize(tfm)] CRYPTO_MINALIGN_ATTR; \ -	struct skcipher_request *name = (void *)__##name##_desc - -static inline struct crypto_ablkcipher *skcipher_givcrypt_reqtfm( -	struct skcipher_givcrypt_request *req) -{ -	return crypto_ablkcipher_reqtfm(&req->creq); -} +/** + * struct skcipher_alg - symmetric key cipher definition + * @min_keysize: Minimum key size supported by the transformation. This is the + *		 smallest key length supported by this transformation algorithm. + *		 This must be set to one of the pre-defined values as this is + *		 not hardware specific. Possible values for this field can be + *		 found via git grep "_MIN_KEY_SIZE" include/crypto/ + * @max_keysize: Maximum key size supported by the transformation. This is the + *		 largest key length supported by this transformation algorithm. + *		 This must be set to one of the pre-defined values as this is + *		 not hardware specific. Possible values for this field can be + *		 found via git grep "_MAX_KEY_SIZE" include/crypto/ + * @setkey: Set key for the transformation. This function is used to either + *	    program a supplied key into the hardware or store the key in the + *	    transformation context for programming it later. Note that this + *	    function does modify the transformation context. This function can + *	    be called multiple times during the existence of the transformation + *	    object, so one must make sure the key is properly reprogrammed into + *	    the hardware. This function is also responsible for checking the key + *	    length for validity. In case a software fallback was put in place in + *	    the @cra_init call, this function might need to use the fallback if + *	    the algorithm doesn't support all of the key sizes. + * @encrypt: Encrypt a scatterlist of blocks. This function is used to encrypt + *	     the supplied scatterlist containing the blocks of data. The crypto + *	     API consumer is responsible for aligning the entries of the + *	     scatterlist properly and making sure the chunks are correctly + *	     sized. In case a software fallback was put in place in the + *	     @cra_init call, this function might need to use the fallback if + *	     the algorithm doesn't support all of the key sizes. In case the + *	     key was stored in transformation context, the key might need to be + *	     re-programmed into the hardware in this function. This function + *	     shall not modify the transformation context, as this function may + *	     be called in parallel with the same transformation object. + * @decrypt: Decrypt a single block. This is a reverse counterpart to @encrypt + *	     and the conditions are exactly the same. + * @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. + * @ivsize: IV size applicable for transformation. The consumer must provide an + *	    IV of exactly that size to perform the encrypt or decrypt operation. + * @chunksize: Equal to the block size except for stream ciphers such as + *	       CTR where it is set to the underlying block size. + * @base: Definition of a generic crypto algorithm. + * + * All fields except @ivsize are mandatory and must be filled. + */ +struct skcipher_alg { +	int (*setkey)(struct crypto_skcipher *tfm, const u8 *key, +	              unsigned int keylen); +	int (*encrypt)(struct skcipher_request *req); +	int (*decrypt)(struct skcipher_request *req); +	int (*init)(struct crypto_skcipher *tfm); +	void (*exit)(struct crypto_skcipher *tfm); -static inline int crypto_skcipher_givencrypt( -	struct skcipher_givcrypt_request *req) -{ -	struct ablkcipher_tfm *crt = -		crypto_ablkcipher_crt(skcipher_givcrypt_reqtfm(req)); -	return crt->givencrypt(req); -}; +	unsigned int min_keysize; +	unsigned int max_keysize; +	unsigned int ivsize; +	unsigned int chunksize; -static inline int crypto_skcipher_givdecrypt( -	struct skcipher_givcrypt_request *req) -{ -	struct ablkcipher_tfm *crt = -		crypto_ablkcipher_crt(skcipher_givcrypt_reqtfm(req)); -	return crt->givdecrypt(req); +	struct crypto_alg base;  }; -static inline void skcipher_givcrypt_set_tfm( -	struct skcipher_givcrypt_request *req, struct crypto_ablkcipher *tfm) -{ -	req->creq.base.tfm = crypto_ablkcipher_tfm(tfm); -} - -static inline struct skcipher_givcrypt_request *skcipher_givcrypt_cast( -	struct crypto_async_request *req) -{ -	return container_of(ablkcipher_request_cast(req), -			    struct skcipher_givcrypt_request, creq); -} - -static inline struct skcipher_givcrypt_request *skcipher_givcrypt_alloc( -	struct crypto_ablkcipher *tfm, gfp_t gfp) -{ -	struct skcipher_givcrypt_request *req; - -	req = kmalloc(sizeof(struct skcipher_givcrypt_request) + -		      crypto_ablkcipher_reqsize(tfm), gfp); - -	if (likely(req)) -		skcipher_givcrypt_set_tfm(req, tfm); - -	return req; -} - -static inline void skcipher_givcrypt_free(struct skcipher_givcrypt_request *req) -{ -	kfree(req); -} - -static inline void skcipher_givcrypt_set_callback( -	struct skcipher_givcrypt_request *req, u32 flags, -	crypto_completion_t compl, void *data) -{ -	ablkcipher_request_set_callback(&req->creq, flags, compl, data); -} - -static inline void skcipher_givcrypt_set_crypt( -	struct skcipher_givcrypt_request *req, -	struct scatterlist *src, struct scatterlist *dst, -	unsigned int nbytes, void *iv) -{ -	ablkcipher_request_set_crypt(&req->creq, src, dst, nbytes, iv); -} - -static inline void skcipher_givcrypt_set_giv( -	struct skcipher_givcrypt_request *req, u8 *giv, u64 seq) -{ -	req->giv = giv; -	req->seq = seq; -} +#define SKCIPHER_REQUEST_ON_STACK(name, tfm) \ +	char __##name##_desc[sizeof(struct skcipher_request) + \ +		crypto_skcipher_reqsize(tfm)] CRYPTO_MINALIGN_ATTR; \ +	struct skcipher_request *name = (void *)__##name##_desc  /**   * DOC: Symmetric Key Cipher API @@ -231,12 +225,43 @@ static inline int crypto_has_skcipher(const char *alg_name, u32 type,  			      crypto_skcipher_mask(mask));  } +/** + * crypto_has_skcipher2() - Search for the availability of an skcipher. + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + *	      skcipher + * @type: specifies the type of the skcipher + * @mask: specifies the mask for the skcipher + * + * Return: true when the skcipher is known to the kernel crypto API; false + *	   otherwise + */ +int crypto_has_skcipher2(const char *alg_name, u32 type, u32 mask); +  static inline const char *crypto_skcipher_driver_name(  	struct crypto_skcipher *tfm)  {  	return crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));  } +static inline struct skcipher_alg *crypto_skcipher_alg( +	struct crypto_skcipher *tfm) +{ +	return container_of(crypto_skcipher_tfm(tfm)->__crt_alg, +			    struct skcipher_alg, base); +} + +static inline unsigned int crypto_skcipher_alg_ivsize(struct skcipher_alg *alg) +{ +	if ((alg->base.cra_flags & CRYPTO_ALG_TYPE_MASK) == +	    CRYPTO_ALG_TYPE_BLKCIPHER) +		return alg->base.cra_blkcipher.ivsize; + +	if (alg->base.cra_ablkcipher.encrypt) +		return alg->base.cra_ablkcipher.ivsize; + +	return alg->ivsize; +} +  /**   * crypto_skcipher_ivsize() - obtain IV size   * @tfm: cipher handle @@ -251,6 +276,36 @@ static inline unsigned int crypto_skcipher_ivsize(struct crypto_skcipher *tfm)  	return tfm->ivsize;  } +static inline unsigned int crypto_skcipher_alg_chunksize( +	struct skcipher_alg *alg) +{ +	if ((alg->base.cra_flags & CRYPTO_ALG_TYPE_MASK) == +	    CRYPTO_ALG_TYPE_BLKCIPHER) +		return alg->base.cra_blocksize; + +	if (alg->base.cra_ablkcipher.encrypt) +		return alg->base.cra_blocksize; + +	return alg->chunksize; +} + +/** + * crypto_skcipher_chunksize() - obtain chunk size + * @tfm: cipher handle + * + * The block size is set to one for ciphers such as CTR.  However, + * you still need to provide incremental updates in multiples of + * the underlying block size as the IV does not have sub-block + * granularity.  This is known in this API as the chunk size. + * + * Return: chunk size in bytes + */ +static inline unsigned int crypto_skcipher_chunksize( +	struct crypto_skcipher *tfm) +{ +	return crypto_skcipher_alg_chunksize(crypto_skcipher_alg(tfm)); +} +  /**   * crypto_skcipher_blocksize() - obtain block size of cipher   * @tfm: cipher handle |