Commit 3c09f17c authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[CRYPTO] aead: Add authenc

This patch adds the authenc algorithm which constructs an AEAD algorithm
from an asynchronous block cipher and a hash.  The construction is done
by concatenating the encrypted result from the cipher with the output
from the hash, as is used by the IPsec ESP protocol.

The authenc algorithm exists as a template with four parameters:

	authenc(auth, authsize, enc, enckeylen).

The authentication algorithm, the authentication size (i.e., truncating
the output of the authentication algorithm), the encryption algorithm,
and the encryption key length.  Both the size field and the key length
field are in bytes.  For example, AES-128 with SHA1-HMAC would be
represented by

	authenc(hmac(sha1), 12, cbc(aes), 16)

The key for the authenc algorithm is the concatenation of the keys for
the authentication algorithm with the encryption algorithm.  For the
above example, if a key of length 36 bytes is given, then hmac(sha1)
would receive the first 20 bytes while the last 16 would be given to
cbc(aes).
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent b16c3a2e
......@@ -483,6 +483,14 @@ config CRYPTO_TEST
help
Quick & dirty crypto test module.
config CRYPTO_AUTHENC
tristate "Authenc support"
select CRYPTO_AEAD
select CRYPTO_MANAGER
help
Authenc: Combined mode wrapper for IPsec.
This is required for IPSec.
source "drivers/crypto/Kconfig"
endif # if CRYPTO
......@@ -50,6 +50,7 @@ obj-$(CONFIG_CRYPTO_SEED) += seed.o
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
......
......@@ -470,9 +470,8 @@ int crypto_check_attr_type(struct rtattr **tb, u32 type)
}
EXPORT_SYMBOL_GPL(crypto_check_attr_type);
struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask)
struct crypto_alg *crypto_attr_alg(struct rtattr *rta, u32 type, u32 mask)
{
struct rtattr *rta = tb[1];
struct crypto_attr_alg *alga;
if (!rta)
......@@ -487,7 +486,25 @@ struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask)
return crypto_alg_mod_lookup(alga->name, type, mask);
}
EXPORT_SYMBOL_GPL(crypto_get_attr_alg);
EXPORT_SYMBOL_GPL(crypto_attr_alg);
int crypto_attr_u32(struct rtattr *rta, u32 *num)
{
struct crypto_attr_u32 *nu32;
if (!rta)
return -ENOENT;
if (RTA_PAYLOAD(rta) < sizeof(*nu32))
return -EINVAL;
if (rta->rta_type != CRYPTOA_U32)
return -EINVAL;
nu32 = RTA_DATA(rta);
*num = nu32->num;
return 0;
}
EXPORT_SYMBOL_GPL(crypto_attr_u32);
struct crypto_instance *crypto_alloc_instance(const char *name,
struct crypto_alg *alg)
......
This diff is collapsed.
......@@ -112,7 +112,8 @@ struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb);
int crypto_check_attr_type(struct rtattr **tb, u32 type);
struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask);
struct crypto_alg *crypto_attr_alg(struct rtattr *rta, u32 type, u32 mask);
int crypto_attr_u32(struct rtattr *rta, u32 *num);
struct crypto_instance *crypto_alloc_instance(const char *name,
struct crypto_alg *alg);
......@@ -171,6 +172,26 @@ 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_ablkcipher *crypto_spawn_ablkcipher(
struct crypto_spawn *spawn)
{
u32 type = CRYPTO_ALG_TYPE_BLKCIPHER;
u32 mask = CRYPTO_ALG_TYPE_MASK;
return __crypto_ablkcipher_cast(crypto_spawn_tfm(spawn, type, mask));
}
static inline struct crypto_blkcipher *crypto_spawn_blkcipher(
struct crypto_spawn *spawn)
{
......@@ -257,5 +278,26 @@ 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)
{
return crypto_attr_alg(tb[1], type, mask);
}
#endif /* _CRYPTO_ALGAPI_H */
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