Skip to content

Commit

Permalink
[CRYPTO] api: Allow algorithm lookup by type
Browse files Browse the repository at this point in the history
This patch also adds the infrastructure to pick an algorithm based on
their type.  For example, this allows you to select the encryption
algorithm "aes", instead of any algorithm registered under the name
"aes".  For now this is only accessible internally.  Eventually it
will be made available through crypto_alloc_tfm.

Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
herbertx committed Sep 21, 2006
1 parent 2b8c19d commit 492e2b6
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 18 deletions.
6 changes: 4 additions & 2 deletions crypto/algapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@

static LIST_HEAD(crypto_template_list);

void crypto_larval_error(const char *name)
void crypto_larval_error(const char *name, u32 type, u32 mask)
{
struct crypto_alg *alg;

down_read(&crypto_alg_sem);
alg = __crypto_alg_lookup(name);
alg = __crypto_alg_lookup(name, type, mask);
up_read(&crypto_alg_sem);

if (alg) {
Expand Down Expand Up @@ -87,6 +87,8 @@ static int __crypto_register_alg(struct crypto_alg *alg)
!strcmp(alg->cra_driver_name, q->cra_name))) {
struct crypto_larval *larval = (void *)q;

if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
continue;
if (!crypto_mod_get(alg))
continue;
larval->adult = alg;
Expand Down
39 changes: 26 additions & 13 deletions crypto/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,21 @@ void crypto_mod_put(struct crypto_alg *alg)
}
EXPORT_SYMBOL_GPL(crypto_mod_put);

struct crypto_alg *__crypto_alg_lookup(const char *name)
struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask)
{
struct crypto_alg *q, *alg = NULL;
int best = -2;

list_for_each_entry(q, &crypto_alg_list, cra_list) {
int exact, fuzzy;

if ((q->cra_flags ^ type) & mask)
continue;

if (crypto_is_larval(q) &&
((struct crypto_larval *)q)->mask != mask)
continue;

exact = !strcmp(q->cra_driver_name, name);
fuzzy = !strcmp(q->cra_name, name);
if (!exact && !(fuzzy && q->cra_priority > best))
Expand Down Expand Up @@ -96,7 +103,8 @@ static void crypto_larval_destroy(struct crypto_alg *alg)
kfree(larval);
}

static struct crypto_alg *crypto_larval_alloc(const char *name)
static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
u32 mask)
{
struct crypto_alg *alg;
struct crypto_larval *larval;
Expand All @@ -105,7 +113,8 @@ static struct crypto_alg *crypto_larval_alloc(const char *name)
if (!larval)
return NULL;

larval->alg.cra_flags = CRYPTO_ALG_LARVAL;
larval->mask = mask;
larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type;
larval->alg.cra_priority = -1;
larval->alg.cra_destroy = crypto_larval_destroy;

Expand All @@ -114,7 +123,7 @@ static struct crypto_alg *crypto_larval_alloc(const char *name)
init_completion(&larval->completion);

down_write(&crypto_alg_sem);
alg = __crypto_alg_lookup(name);
alg = __crypto_alg_lookup(name, type, mask);
if (!alg) {
alg = &larval->alg;
list_add(&alg->cra_list, &crypto_alg_list);
Expand Down Expand Up @@ -151,33 +160,36 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
return alg;
}

static struct crypto_alg *crypto_alg_lookup(const char *name)
static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
u32 mask)
{
struct crypto_alg *alg;

if (!name)
return NULL;

down_read(&crypto_alg_sem);
alg = __crypto_alg_lookup(name);
alg = __crypto_alg_lookup(name, type, mask);
up_read(&crypto_alg_sem);

return alg;
}

/* A far more intelligent version of this is planned. For now, just
* try an exact match on the name of the algorithm. */
static struct crypto_alg *crypto_alg_mod_lookup(const char *name)
struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
{
struct crypto_alg *alg;
struct crypto_alg *larval;
int ok;

alg = try_then_request_module(crypto_alg_lookup(name), name);
mask &= ~CRYPTO_ALG_LARVAL;
type &= mask;

alg = try_then_request_module(crypto_alg_lookup(name, type, mask),
name);
if (alg)
return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;

larval = crypto_larval_alloc(name);
larval = crypto_larval_alloc(name, type, mask);
if (!larval || !crypto_is_larval(larval))
return larval;

Expand All @@ -196,6 +208,7 @@ static struct crypto_alg *crypto_alg_mod_lookup(const char *name)
crypto_larval_kill(larval);
return alg;
}
EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup);

static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
{
Expand Down Expand Up @@ -291,7 +304,7 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
struct crypto_alg *alg;
unsigned int tfm_size;

alg = crypto_alg_mod_lookup(name);
alg = crypto_alg_mod_lookup(name, 0, 0);
if (alg == NULL)
goto out;

Expand Down Expand Up @@ -346,7 +359,7 @@ void crypto_free_tfm(struct crypto_tfm *tfm)
int crypto_alg_available(const char *name, u32 flags)
{
int ret = 0;
struct crypto_alg *alg = crypto_alg_mod_lookup(name);
struct crypto_alg *alg = crypto_alg_mod_lookup(name, 0, 0);

if (alg) {
crypto_mod_put(alg);
Expand Down
7 changes: 6 additions & 1 deletion crypto/cryptomgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ struct cryptomgr_param {
} alg;

struct {
u32 type;
u32 mask;
char name[CRYPTO_MAX_ALG_NAME];
} larval;

Expand Down Expand Up @@ -62,7 +64,8 @@ static void cryptomgr_probe(void *data)
return;

err:
crypto_larval_error(param->larval.name);
crypto_larval_error(param->larval.name, param->larval.type,
param->larval.mask);
goto out;
}

Expand Down Expand Up @@ -101,6 +104,8 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
param->alg.data.name[len] = 0;

memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
param->larval.type = larval->alg.cra_flags;
param->larval.mask = larval->mask;

INIT_WORK(&param->work, cryptomgr_probe, param);
schedule_work(&param->work);
Expand Down
6 changes: 4 additions & 2 deletions crypto/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct crypto_larval {
struct crypto_alg alg;
struct crypto_alg *adult;
struct completion completion;
u32 mask;
};

extern struct list_head crypto_alg_list;
Expand Down Expand Up @@ -124,7 +125,8 @@ static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg,

struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
void crypto_mod_put(struct crypto_alg *alg);
struct crypto_alg *__crypto_alg_lookup(const char *name);
struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask);
struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);

int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
Expand All @@ -138,7 +140,7 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm);
void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
void crypto_exit_compress_ops(struct crypto_tfm *tfm);

void crypto_larval_error(const char *name);
void crypto_larval_error(const char *name, u32 type, u32 mask);

int crypto_register_instance(struct crypto_template *tmpl,
struct crypto_instance *inst);
Expand Down

0 comments on commit 492e2b6

Please sign in to comment.