Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d7d684d authored by Herbert Xu's avatar Herbert Xu
Browse files

[CRYPTO] api: Added crypto_alloc_base



Up until now all crypto transforms have been of the same type, struct
crypto_tfm, regardless of whether they are ciphers, digests, or other
types.  As a result of that, we check the types at run-time before
each crypto operation.

This is rather cumbersome.  We could instead use different C types for
each crypto type to ensure that the correct types are used at compile
time.  That is, we would have crypto_cipher/crypto_digest instead of
just crypto_tfm.  The appropriate type would then be required for the
actual operations such as crypto_digest_digest.

Now that we have the type/mask fields when looking up algorithms, it
is easy to request for an algorithm of the precise type that the user
wants.  However, crypto_alloc_tfm currently does not expose these new
attributes.

This patch introduces the function crypto_alloc_base which will carry
these new parameters.  It will be renamed to crypto_alloc_tfm once
all existing users have been converted.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 65b75c36
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -372,6 +372,66 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
	return tfm;
}

/*
 *	crypto_alloc_base - Locate algorithm and allocate transform
 *	@alg_name: Name of algorithm
 *	@type: Type of algorithm
 *	@mask: Mask for type comparison
 *
 *	crypto_alloc_base() will first attempt to locate an already loaded
 *	algorithm.  If that fails and the kernel supports dynamically loadable
 *	modules, it will then attempt to load a module of the same name or
 *	alias.  If that fails it will send a query to any loaded crypto manager
 *	to construct an algorithm on the fly.  A refcount is grabbed on the
 *	algorithm which is then associated with the new transform.
 *
 *	The returned transform is of a non-determinate type.  Most people
 *	should use one of the more specific allocation functions such as
 *	crypto_alloc_blkcipher.
 *
 *	In case of error the return value is an error pointer.
 */
struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
{
	struct crypto_tfm *tfm;
	int err;

	for (;;) {
		struct crypto_alg *alg;

		alg = crypto_alg_mod_lookup(alg_name, type, mask);
		err = PTR_ERR(alg);
		tfm = ERR_PTR(err);
		if (IS_ERR(alg))
			goto err;

		tfm = __crypto_alloc_tfm(alg, 0);
		if (!IS_ERR(tfm))
			break;

		crypto_mod_put(alg);
		err = PTR_ERR(tfm);

err:
		if (err != -EAGAIN)
			break;
		if (signal_pending(current)) {
			err = -EINTR;
			break;
		}
	};

	return tfm;
}
EXPORT_SYMBOL_GPL(crypto_alloc_base);
 
/*
 *	crypto_free_tfm - Free crypto transform
 *	@tfm: Transform to free
 *
 *	crypto_free_tfm() frees up the transform and any associated resources,
 *	then drops the refcount on the associated algorithm.
 */
void crypto_free_tfm(struct crypto_tfm *tfm)
{
	struct crypto_alg *alg;
+3 −11
Original line number Diff line number Diff line
@@ -194,8 +194,8 @@ static inline int crypto_alg_available(const char *name, u32 flags)

/*
 * Transforms: user-instantiated objects which encapsulate algorithms
 * and core processing logic.  Managed via crypto_alloc_tfm() and
 * crypto_free_tfm(), as well as the various helpers below.
 * and core processing logic.  Managed via crypto_alloc_*() and
 * crypto_free_*(), as well as the various helpers below.
 */

struct cipher_tfm {
@@ -278,16 +278,8 @@ struct crypto_attr_alg {
 * Transform user interface.
 */
 
/*
 * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
 * If that fails and the kernel supports dynamically loadable modules, it
 * will then attempt to load a module of the same name or alias.  A refcount
 * is grabbed on the algorithm which is then associated with the new transform.
 *
 * crypto_free_tfm() frees up the transform and any associated resources,
 * then drops the refcount on the associated algorithm.
 */
struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask);
void crypto_free_tfm(struct crypto_tfm *tfm);

/*