summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-01-01 18:37:02 +1100
committerHerbert Xu <herbert@gondor.apana.org.au>2007-05-02 14:38:31 +1000
commitef7b2ede2a57a4a1c7c26966ae48cddad09ed5c9 (patch)
tree5ee60457dc2b088961700c11fc7de8aae831e826
parent69eedc401de2e22ee30d6fa0608546efe7d8a076 (diff)
downloadlinux-crypto-ef7b2ede2a57a4a1c7c26966ae48cddad09ed5c9.tar.gz
linux-crypto-ef7b2ede2a57a4a1c7c26966ae48cddad09ed5c9.zip
[CRYPTO] templates: Pass type/mask when creating instances
This patch passes the type/mask along when constructing instances of templates. This is in preparation for templates that may support multiple types of instances depending on what is requested. For example, the planned software async crypto driver will use this construct. For the moment this allows us to check whether the instance constructed is of the correct type and avoid returning success if the type does not match. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to '')
-rw-r--r--crypto/algapi.c42
-rw-r--r--crypto/cbc.c11
-rw-r--r--crypto/cryptomgr.c28
-rw-r--r--crypto/ecb.c11
-rw-r--r--crypto/hmac.c11
-rw-r--r--crypto/lrw.c11
-rw-r--r--crypto/pcbc.c11
-rw-r--r--crypto/xcbc.c12
8 files changed, 103 insertions, 34 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index f7d2185b..491205e1 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -425,15 +425,45 @@ int crypto_unregister_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
-struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len,
- u32 type, u32 mask)
+struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
{
- struct rtattr *rta = param;
+ struct rtattr *rta = tb[CRYPTOA_TYPE - 1];
+ struct crypto_attr_type *algt;
+
+ if (!rta)
+ return ERR_PTR(-ENOENT);
+ if (RTA_PAYLOAD(rta) < sizeof(*algt))
+ return ERR_PTR(-EINVAL);
+
+ algt = RTA_DATA(rta);
+
+ return algt;
+}
+EXPORT_SYMBOL_GPL(crypto_get_attr_type);
+
+int crypto_check_attr_type(struct rtattr **tb, u32 type)
+{
+ struct crypto_attr_type *algt;
+
+ algt = crypto_get_attr_type(tb);
+ if (IS_ERR(algt))
+ return PTR_ERR(algt);
+
+ if ((algt->type ^ type) & algt->mask)
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_check_attr_type);
+
+struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask)
+{
+ struct rtattr *rta = tb[CRYPTOA_ALG - 1];
struct crypto_attr_alg *alga;
- if (!RTA_OK(rta, len))
- return ERR_PTR(-EBADR);
- if (rta->rta_type != CRYPTOA_ALG || RTA_PAYLOAD(rta) < sizeof(*alga))
+ if (!rta)
+ return ERR_PTR(-ENOENT);
+ if (RTA_PAYLOAD(rta) < sizeof(*alga))
return ERR_PTR(-EINVAL);
alga = RTA_DATA(rta);
diff --git a/crypto/cbc.c b/crypto/cbc.c
index 136fea7e..1f2649e1 100644
--- a/crypto/cbc.c
+++ b/crypto/cbc.c
@@ -275,13 +275,18 @@ static void crypto_cbc_exit_tfm(struct crypto_tfm *tfm)
crypto_free_cipher(ctx->child);
}
-static struct crypto_instance *crypto_cbc_alloc(void *param, unsigned int len)
+static struct crypto_instance *crypto_cbc_alloc(struct rtattr **tb)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+ if (err)
+ return ERR_PTR(err);
- alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
- CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
+ alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c
index 2ebffb84..7a3df9b4 100644
--- a/crypto/cryptomgr.c
+++ b/crypto/cryptomgr.c
@@ -26,14 +26,19 @@
struct cryptomgr_param {
struct work_struct work;
+ struct rtattr *tb[CRYPTOA_MAX];
+
+ struct {
+ struct rtattr attr;
+ struct crypto_attr_type data;
+ } type;
+
struct {
struct rtattr attr;
struct crypto_attr_alg data;
} alg;
struct {
- u32 type;
- u32 mask;
char name[CRYPTO_MAX_ALG_NAME];
} larval;
@@ -53,7 +58,7 @@ static void cryptomgr_probe(struct work_struct *work)
goto err;
do {
- inst = tmpl->alloc(&param->alg, sizeof(param->alg));
+ inst = tmpl->alloc(param->tb);
if (IS_ERR(inst))
err = PTR_ERR(inst);
else if ((err = crypto_register_instance(tmpl, inst)))
@@ -70,8 +75,8 @@ out:
return;
err:
- crypto_larval_error(param->larval.name, param->larval.type,
- param->larval.mask);
+ crypto_larval_error(param->larval.name, param->type.data.type,
+ param->type.data.mask);
goto out;
}
@@ -82,7 +87,7 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
const char *p;
unsigned int len;
- param = kmalloc(sizeof(*param), GFP_KERNEL);
+ param = kzalloc(sizeof(*param), GFP_KERNEL);
if (!param)
goto err;
@@ -94,7 +99,6 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
goto err_free_param;
memcpy(param->template, name, len);
- param->template[len] = 0;
name = p + 1;
for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++)
@@ -104,14 +108,18 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
if (!len || *p != ')' || p[1])
goto err_free_param;
+ param->type.attr.rta_len = sizeof(param->type);
+ param->type.attr.rta_type = CRYPTOA_TYPE;
+ param->type.data.type = larval->alg.cra_flags;
+ param->type.data.mask = larval->mask;
+ param->tb[CRYPTOA_TYPE - 1] = &param->type.attr;
+
param->alg.attr.rta_len = sizeof(param->alg);
param->alg.attr.rta_type = CRYPTOA_ALG;
memcpy(param->alg.data.name, name, len);
- param->alg.data.name[len] = 0;
+ param->tb[CRYPTOA_ALG - 1] = &param->alg.attr;
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);
schedule_work(&param->work);
diff --git a/crypto/ecb.c b/crypto/ecb.c
index 839a0aed..6310387a 100644
--- a/crypto/ecb.c
+++ b/crypto/ecb.c
@@ -115,13 +115,18 @@ static void crypto_ecb_exit_tfm(struct crypto_tfm *tfm)
crypto_free_cipher(ctx->child);
}
-static struct crypto_instance *crypto_ecb_alloc(void *param, unsigned int len)
+static struct crypto_instance *crypto_ecb_alloc(struct rtattr **tb)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+ if (err)
+ return ERR_PTR(err);
- alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
- CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
+ alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 44187c5e..8802fb6d 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -197,13 +197,18 @@ static void hmac_free(struct crypto_instance *inst)
kfree(inst);
}
-static struct crypto_instance *hmac_alloc(void *param, unsigned int len)
+static struct crypto_instance *hmac_alloc(struct rtattr **tb)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH);
+ if (err)
+ return ERR_PTR(err);
- alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_HASH,
- CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC);
+ alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_HASH,
+ CRYPTO_ALG_TYPE_HASH_MASK);
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
diff --git a/crypto/lrw.c b/crypto/lrw.c
index b4105080..621095db 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -228,13 +228,18 @@ static void exit_tfm(struct crypto_tfm *tfm)
crypto_free_cipher(ctx->child);
}
-static struct crypto_instance *alloc(void *param, unsigned int len)
+static struct crypto_instance *alloc(struct rtattr **tb)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+ if (err)
+ return ERR_PTR(err);
- alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
- CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
+ alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
diff --git a/crypto/pcbc.c b/crypto/pcbc.c
index 5174d7fd..c3ed8a1c 100644
--- a/crypto/pcbc.c
+++ b/crypto/pcbc.c
@@ -279,13 +279,18 @@ static void crypto_pcbc_exit_tfm(struct crypto_tfm *tfm)
crypto_free_cipher(ctx->child);
}
-static struct crypto_instance *crypto_pcbc_alloc(void *param, unsigned int len)
+static struct crypto_instance *crypto_pcbc_alloc(struct rtattr **tb)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+ if (err)
+ return ERR_PTR(err);
- alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
- CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
+ alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 53e8ccbf..9f502b86 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -288,12 +288,18 @@ static void xcbc_exit_tfm(struct crypto_tfm *tfm)
crypto_free_cipher(ctx->child);
}
-static struct crypto_instance *xcbc_alloc(void *param, unsigned int len)
+static struct crypto_instance *xcbc_alloc(struct rtattr **tb)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
- alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
- CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC);
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH);
+ if (err)
+ return ERR_PTR(err);
+
+ alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));