Commit 5d1d65f8 authored by Herbert Xu's avatar Herbert Xu

crypto: aead - Convert top level interface to new style

This patch converts the top-level aead interface to the new style.
All user-level AEAD interface code have been moved into crypto/aead.h.

The allocation/free functions have switched over to the new way of
allocating tfms.

This patch also removes the double indrection on setkey so the
indirection now exists only at the alg level.

Apart from these there are no user-visible changes.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 53033d4d
......@@ -26,6 +26,9 @@
#include "internal.h"
static int aead_null_givencrypt(struct aead_givcrypt_request *req);
static int aead_null_givdecrypt(struct aead_givcrypt_request *req);
static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
unsigned int keylen)
{
......@@ -48,63 +51,63 @@ static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
return ret;
}
static int setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
int crypto_aead_setkey(struct crypto_aead *tfm,
const u8 *key, unsigned int keylen)
{
struct aead_alg *aead = crypto_aead_alg(tfm);
unsigned long alignmask = crypto_aead_alignmask(tfm);
tfm = tfm->child;
if ((unsigned long)key & alignmask)
return setkey_unaligned(tfm, key, keylen);
return aead->setkey(tfm, key, keylen);
}
EXPORT_SYMBOL_GPL(crypto_aead_setkey);
int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
{
struct aead_tfm *crt = crypto_aead_crt(tfm);
int err;
if (authsize > crypto_aead_alg(tfm)->maxauthsize)
return -EINVAL;
if (crypto_aead_alg(tfm)->setauthsize) {
err = crypto_aead_alg(tfm)->setauthsize(crt->base, authsize);
err = crypto_aead_alg(tfm)->setauthsize(tfm->child, authsize);
if (err)
return err;
}
crypto_aead_crt(crt->base)->authsize = authsize;
crt->authsize = authsize;
tfm->child->authsize = authsize;
tfm->authsize = authsize;
return 0;
}
EXPORT_SYMBOL_GPL(crypto_aead_setauthsize);
static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type,
u32 mask)
{
return alg->cra_ctxsize;
}
static int no_givcrypt(struct aead_givcrypt_request *req)
{
return -ENOSYS;
}
static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
static int crypto_aead_init_tfm(struct crypto_tfm *tfm)
{
struct aead_alg *alg = &tfm->__crt_alg->cra_aead;
struct aead_tfm *crt = &tfm->crt_aead;
struct crypto_aead *crt = __crypto_aead_cast(tfm);
if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
return -EINVAL;
crt->setkey = tfm->__crt_alg->cra_flags & CRYPTO_ALG_GENIV ?
alg->setkey : setkey;
crt->encrypt = alg->encrypt;
crt->decrypt = alg->decrypt;
if (alg->ivsize) {
crt->givencrypt = alg->givencrypt ?: no_givcrypt;
crt->givdecrypt = alg->givdecrypt ?: no_givcrypt;
crt->base = __crypto_aead_cast(tfm);
} else {
crt->givencrypt = aead_null_givencrypt;
crt->givdecrypt = aead_null_givdecrypt;
}
crt->child = __crypto_aead_cast(tfm);
crt->ivsize = alg->ivsize;
crt->authsize = alg->maxauthsize;
......@@ -155,12 +158,17 @@ static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
}
const struct crypto_type crypto_aead_type = {
.ctxsize = crypto_aead_ctxsize,
.init = crypto_init_aead_ops,
.extsize = crypto_alg_extsize,
.init_tfm = crypto_aead_init_tfm,
#ifdef CONFIG_PROC_FS
.show = crypto_aead_show,
#endif
.report = crypto_aead_report,
.lookup = crypto_lookup_aead,
.maskclear = ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV),
.maskset = CRYPTO_ALG_TYPE_MASK,
.type = CRYPTO_ALG_TYPE_AEAD,
.tfmsize = offsetof(struct crypto_aead, base),
};
EXPORT_SYMBOL_GPL(crypto_aead_type);
......@@ -174,28 +182,6 @@ static int aead_null_givdecrypt(struct aead_givcrypt_request *req)
return crypto_aead_decrypt(&req->areq);
}
static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
{
struct aead_alg *alg = &tfm->__crt_alg->cra_aead;
struct aead_tfm *crt = &tfm->crt_aead;
if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
return -EINVAL;
crt->setkey = setkey;
crt->encrypt = alg->encrypt;
crt->decrypt = alg->decrypt;
if (!alg->ivsize) {
crt->givencrypt = aead_null_givencrypt;
crt->givdecrypt = aead_null_givdecrypt;
}
crt->base = __crypto_aead_cast(tfm);
crt->ivsize = alg->ivsize;
crt->authsize = alg->maxauthsize;
return 0;
}
#ifdef CONFIG_NET
static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
{
......@@ -241,32 +227,24 @@ static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
}
const struct crypto_type crypto_nivaead_type = {
.ctxsize = crypto_aead_ctxsize,
.init = crypto_init_nivaead_ops,
.extsize = crypto_alg_extsize,
.init_tfm = crypto_aead_init_tfm,
#ifdef CONFIG_PROC_FS
.show = crypto_nivaead_show,
#endif
.report = crypto_nivaead_report,
.maskclear = ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV),
.maskset = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV,
.type = CRYPTO_ALG_TYPE_AEAD,
.tfmsize = offsetof(struct crypto_aead, base),
};
EXPORT_SYMBOL_GPL(crypto_nivaead_type);
static int crypto_grab_nivaead(struct crypto_aead_spawn *spawn,
const char *name, u32 type, u32 mask)
{
struct crypto_alg *alg;
int err;
type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
type |= CRYPTO_ALG_TYPE_AEAD;
mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV;
alg = crypto_alg_mod_lookup(name, type, mask);
if (IS_ERR(alg))
return PTR_ERR(alg);
err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
crypto_mod_put(alg);
return err;
spawn->base.frontend = &crypto_nivaead_type;
return crypto_grab_spawn(&spawn->base, name, type, mask);
}
struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl,
......@@ -374,14 +352,17 @@ EXPORT_SYMBOL_GPL(aead_geniv_free);
int aead_geniv_init(struct crypto_tfm *tfm)
{
struct crypto_instance *inst = (void *)tfm->__crt_alg;
struct crypto_aead *child;
struct crypto_aead *aead;
aead = crypto_spawn_aead(crypto_instance_ctx(inst));
if (IS_ERR(aead))
return PTR_ERR(aead);
aead = __crypto_aead_cast(tfm);
tfm->crt_aead.base = aead;
tfm->crt_aead.reqsize += crypto_aead_reqsize(aead);
child = crypto_spawn_aead(crypto_instance_ctx(inst));
if (IS_ERR(child))
return PTR_ERR(child);
aead->child = child;
aead->reqsize += crypto_aead_reqsize(child);
return 0;
}
......@@ -389,7 +370,7 @@ EXPORT_SYMBOL_GPL(aead_geniv_init);
void aead_geniv_exit(struct crypto_tfm *tfm)
{
crypto_free_aead(tfm->crt_aead.base);
crypto_free_aead(__crypto_aead_cast(tfm)->child);
}
EXPORT_SYMBOL_GPL(aead_geniv_exit);
......@@ -505,60 +486,14 @@ EXPORT_SYMBOL_GPL(crypto_lookup_aead);
int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name,
u32 type, u32 mask)
{
struct crypto_alg *alg;
int err;
type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
type |= CRYPTO_ALG_TYPE_AEAD;
mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
mask |= CRYPTO_ALG_TYPE_MASK;
alg = crypto_lookup_aead(name, type, mask);
if (IS_ERR(alg))
return PTR_ERR(alg);
err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
crypto_mod_put(alg);
return err;
spawn->base.frontend = &crypto_aead_type;
return crypto_grab_spawn(&spawn->base, name, type, mask);
}
EXPORT_SYMBOL_GPL(crypto_grab_aead);
struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask)
{
struct crypto_tfm *tfm;
int err;
type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
type |= CRYPTO_ALG_TYPE_AEAD;
mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
mask |= CRYPTO_ALG_TYPE_MASK;
for (;;) {
struct crypto_alg *alg;
alg = crypto_lookup_aead(alg_name, type, mask);
if (IS_ERR(alg)) {
err = PTR_ERR(alg);
goto err;
}
tfm = __crypto_alloc_tfm(alg, type, mask);
if (!IS_ERR(tfm))
return __crypto_aead_cast(tfm);
crypto_mod_put(alg);
err = PTR_ERR(tfm);
err:
if (err != -EAGAIN)
break;
if (signal_pending(current)) {
err = -EINTR;
break;
}
}
return ERR_PTR(err);
return crypto_alloc_tfm(alg_name, &crypto_aead_type, type, mask);
}
EXPORT_SYMBOL_GPL(crypto_alloc_aead);
......
This diff is collapsed.
......@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
struct crypto_aead;
struct module;
struct rtattr;
struct seq_file;
......@@ -126,7 +127,6 @@ struct ablkcipher_walk {
};
extern const struct crypto_type crypto_ablkcipher_type;
extern const struct crypto_type crypto_aead_type;
extern const struct crypto_type crypto_blkcipher_type;
void crypto_mod_put(struct crypto_alg *alg);
......@@ -241,22 +241,6 @@ static inline void *crypto_ablkcipher_ctx_aligned(struct crypto_ablkcipher *tfm)
return crypto_tfm_ctx_aligned(&tfm->base);
}
static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm)
{
return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead;
}
static inline void *crypto_aead_ctx(struct crypto_aead *tfm)
{
return crypto_tfm_ctx(&tfm->base);
}
static inline struct crypto_instance *crypto_aead_alg_instance(
struct crypto_aead *aead)
{
return crypto_tfm_alg_instance(&aead->base);
}
static inline struct crypto_blkcipher *crypto_spawn_blkcipher(
struct crypto_spawn *spawn)
{
......@@ -365,21 +349,6 @@ static inline int ablkcipher_tfm_in_queue(struct crypto_queue *queue,
return crypto_tfm_in_queue(queue, crypto_ablkcipher_tfm(tfm));
}
static inline void *aead_request_ctx(struct aead_request *req)
{
return req->__ctx;
}
static inline void aead_request_complete(struct aead_request *req, int err)
{
req->base.complete(&req->base, err);
}
static inline u32 aead_request_flags(struct aead_request *req)
{
return req->base.flags;
}
static inline struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb,
u32 type, u32 mask)
{
......
......@@ -23,8 +23,40 @@ struct crypto_aead_spawn {
struct crypto_spawn base;
};
extern const struct crypto_type crypto_aead_type;
extern const struct crypto_type crypto_nivaead_type;
static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm)
{
return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead;
}
static inline void *crypto_aead_ctx(struct crypto_aead *tfm)
{
return crypto_tfm_ctx(&tfm->base);
}
static inline struct crypto_instance *crypto_aead_alg_instance(
struct crypto_aead *aead)
{
return crypto_tfm_alg_instance(&aead->base);
}
static inline void *aead_request_ctx(struct aead_request *req)
{
return req->__ctx;
}
static inline void aead_request_complete(struct aead_request *req, int err)
{
req->base.complete(&req->base, err);
}
static inline u32 aead_request_flags(struct aead_request *req)
{
return req->base.flags;
}
static inline void crypto_set_aead_spawn(
struct crypto_aead_spawn *spawn, struct crypto_instance *inst)
{
......@@ -50,9 +82,7 @@ static inline struct crypto_alg *crypto_aead_spawn_alg(
static inline struct crypto_aead *crypto_spawn_aead(
struct crypto_aead_spawn *spawn)
{
return __crypto_aead_cast(
crypto_spawn_tfm(&spawn->base, CRYPTO_ALG_TYPE_AEAD,
CRYPTO_ALG_TYPE_MASK));
return crypto_spawn_tfm2(&spawn->base);
}
struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl,
......@@ -64,7 +94,7 @@ void aead_geniv_exit(struct crypto_tfm *tfm);
static inline struct crypto_aead *aead_geniv_base(struct crypto_aead *geniv)
{
return crypto_aead_crt(geniv)->base;
return geniv->child;
}
static inline void *aead_givcrypt_reqctx(struct aead_givcrypt_request *req)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment