diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2006-07-29 21:53:01 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2006-09-20 21:41:50 -0400 |
commit | 6d7d684d635ac5a345f075015f2c84169c111c6a (patch) | |
tree | 9a1b397fe8db3c14cc69880aba747e50c1a1faa2 | |
parent | 65b75c36f4e8422602826c75c803136e0da94122 (diff) |
[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: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/api.c | 60 | ||||
-rw-r--r-- | include/linux/crypto.h | 14 |
2 files changed, 63 insertions, 11 deletions
diff --git a/crypto/api.c b/crypto/api.c index 1e4692a13474..bc4b7901acdf 100644 --- a/crypto/api.c +++ b/crypto/api.c | |||
@@ -372,6 +372,66 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) | |||
372 | return tfm; | 372 | return tfm; |
373 | } | 373 | } |
374 | 374 | ||
375 | /* | ||
376 | * crypto_alloc_base - Locate algorithm and allocate transform | ||
377 | * @alg_name: Name of algorithm | ||
378 | * @type: Type of algorithm | ||
379 | * @mask: Mask for type comparison | ||
380 | * | ||
381 | * crypto_alloc_base() will first attempt to locate an already loaded | ||
382 | * algorithm. If that fails and the kernel supports dynamically loadable | ||
383 | * modules, it will then attempt to load a module of the same name or | ||
384 | * alias. If that fails it will send a query to any loaded crypto manager | ||
385 | * to construct an algorithm on the fly. A refcount is grabbed on the | ||
386 | * algorithm which is then associated with the new transform. | ||
387 | * | ||
388 | * The returned transform is of a non-determinate type. Most people | ||
389 | * should use one of the more specific allocation functions such as | ||
390 | * crypto_alloc_blkcipher. | ||
391 | * | ||
392 | * In case of error the return value is an error pointer. | ||
393 | */ | ||
394 | struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask) | ||
395 | { | ||
396 | struct crypto_tfm *tfm; | ||
397 | int err; | ||
398 | |||
399 | for (;;) { | ||
400 | struct crypto_alg *alg; | ||
401 | |||
402 | alg = crypto_alg_mod_lookup(alg_name, type, mask); | ||
403 | err = PTR_ERR(alg); | ||
404 | tfm = ERR_PTR(err); | ||
405 | if (IS_ERR(alg)) | ||
406 | goto err; | ||
407 | |||
408 | tfm = __crypto_alloc_tfm(alg, 0); | ||
409 | if (!IS_ERR(tfm)) | ||
410 | break; | ||
411 | |||
412 | crypto_mod_put(alg); | ||
413 | err = PTR_ERR(tfm); | ||
414 | |||
415 | err: | ||
416 | if (err != -EAGAIN) | ||
417 | break; | ||
418 | if (signal_pending(current)) { | ||
419 | err = -EINTR; | ||
420 | break; | ||
421 | } | ||
422 | }; | ||
423 | |||
424 | return tfm; | ||
425 | } | ||
426 | EXPORT_SYMBOL_GPL(crypto_alloc_base); | ||
427 | |||
428 | /* | ||
429 | * crypto_free_tfm - Free crypto transform | ||
430 | * @tfm: Transform to free | ||
431 | * | ||
432 | * crypto_free_tfm() frees up the transform and any associated resources, | ||
433 | * then drops the refcount on the associated algorithm. | ||
434 | */ | ||
375 | void crypto_free_tfm(struct crypto_tfm *tfm) | 435 | void crypto_free_tfm(struct crypto_tfm *tfm) |
376 | { | 436 | { |
377 | struct crypto_alg *alg; | 437 | struct crypto_alg *alg; |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 530dc4bf363c..6847ab0ea30e 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -194,8 +194,8 @@ static inline int crypto_alg_available(const char *name, u32 flags) | |||
194 | 194 | ||
195 | /* | 195 | /* |
196 | * Transforms: user-instantiated objects which encapsulate algorithms | 196 | * Transforms: user-instantiated objects which encapsulate algorithms |
197 | * and core processing logic. Managed via crypto_alloc_tfm() and | 197 | * and core processing logic. Managed via crypto_alloc_*() and |
198 | * crypto_free_tfm(), as well as the various helpers below. | 198 | * crypto_free_*(), as well as the various helpers below. |
199 | */ | 199 | */ |
200 | 200 | ||
201 | struct cipher_tfm { | 201 | struct cipher_tfm { |
@@ -278,16 +278,8 @@ struct crypto_attr_alg { | |||
278 | * Transform user interface. | 278 | * Transform user interface. |
279 | */ | 279 | */ |
280 | 280 | ||
281 | /* | ||
282 | * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm. | ||
283 | * If that fails and the kernel supports dynamically loadable modules, it | ||
284 | * will then attempt to load a module of the same name or alias. A refcount | ||
285 | * is grabbed on the algorithm which is then associated with the new transform. | ||
286 | * | ||
287 | * crypto_free_tfm() frees up the transform and any associated resources, | ||
288 | * then drops the refcount on the associated algorithm. | ||
289 | */ | ||
290 | struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); | 281 | struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); |
282 | struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask); | ||
291 | void crypto_free_tfm(struct crypto_tfm *tfm); | 283 | void crypto_free_tfm(struct crypto_tfm *tfm); |
292 | 284 | ||
293 | /* | 285 | /* |