X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=crypto%2Fapi.c;h=80bba637fba7c1d325e0718bcfa800659f46251e;hp=959c4e5f264f42ed831720149b3627d9a9e6300c;hb=ba47f66bd9fc451e9ce88f291e057b2f4910d01c;hpb=c85b2a5fe200d744a814d23c258460d4fc98a546 diff --git a/crypto/api.c b/crypto/api.c index 959c4e5f264f..80bba637fba7 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -3,6 +3,7 @@ * * Copyright (c) 2002 James Morris * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * Copyright (c) 2005 Herbert Xu * * Portions derived from Cryptoapi, by Alexander Kjeldaas * and Nettle, by Niels Möller. @@ -18,9 +19,11 @@ #include #include #include +#include #include #include #include +#include #include "internal.h" LIST_HEAD(crypto_alg_list); @@ -39,6 +42,7 @@ static inline void crypto_alg_put(struct crypto_alg *alg) static struct crypto_alg *crypto_alg_lookup(const char *name) { struct crypto_alg *q, *alg = NULL; + int best = -1; if (!name) return NULL; @@ -46,11 +50,23 @@ static struct crypto_alg *crypto_alg_lookup(const char *name) down_read(&crypto_alg_sem); list_for_each_entry(q, &crypto_alg_list, cra_list) { - if (!(strcmp(q->cra_name, name))) { - if (crypto_alg_get(q)) - alg = q; + int exact, fuzzy; + + exact = !strcmp(q->cra_driver_name, name); + fuzzy = !strcmp(q->cra_name, name); + if (!exact && !(fuzzy && q->cra_priority > best)) + continue; + + if (unlikely(!crypto_alg_get(q))) + continue; + + best = q->cra_priority; + if (alg) + crypto_alg_put(alg); + alg = q; + + if (exact) break; - } } up_read(&crypto_alg_sem); @@ -149,7 +165,7 @@ static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags) break; } - return len + alg->cra_alignmask; + return len + (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1)); } struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) @@ -163,12 +179,10 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) goto out; tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags); - tfm = kmalloc(tfm_size, GFP_KERNEL); + tfm = kzalloc(tfm_size, GFP_KERNEL); if (tfm == NULL) goto out_put; - memset(tfm, 0, tfm_size); - tfm->__crt_alg = alg; if (crypto_init_flags(tfm, flags)) @@ -207,21 +221,48 @@ void crypto_free_tfm(struct crypto_tfm *tfm) kfree(tfm); } +static inline int crypto_set_driver_name(struct crypto_alg *alg) +{ + static const char suffix[] = "-generic"; + char *driver_name = (char *)alg->cra_driver_name; + int len; + + if (*driver_name) + return 0; + + len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); + if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME) + return -ENAMETOOLONG; + + memcpy(driver_name + len, suffix, sizeof(suffix)); + return 0; +} + int crypto_register_alg(struct crypto_alg *alg) { - int ret = 0; + int ret; struct crypto_alg *q; if (alg->cra_alignmask & (alg->cra_alignmask + 1)) return -EINVAL; - if (alg->cra_alignmask > PAGE_SIZE) + if (alg->cra_alignmask & alg->cra_blocksize) + return -EINVAL; + + if (alg->cra_blocksize > PAGE_SIZE / 8) + return -EINVAL; + + if (alg->cra_priority < 0) return -EINVAL; + ret = crypto_set_driver_name(alg); + if (unlikely(ret)) + return ret; + down_write(&crypto_alg_sem); list_for_each_entry(q, &crypto_alg_list, cra_list) { - if (!(strcmp(q->cra_name, alg->cra_name))) { + if (!strcmp(q->cra_driver_name, alg->cra_driver_name)) { ret = -EEXIST; goto out; }