Commit f9dc9f2e authored by Eric Biggers's avatar Eric Biggers Committed by Herbert Xu

crypto: cmac - remove unnecessary alignment logic

The cmac template is setting its alignmask to that of its underlying
'cipher'.  Yet, it doesn't care itself about how its inputs and outputs
are aligned, which is ostensibly the point of the alignmask.  Instead,
cmac actually just uses its alignmask itself to runtime-align certain
fields in its tfm and desc contexts appropriately for its underlying
cipher.  That is almost entirely pointless too, though, since cmac is
already using the cipher API functions that handle alignment themselves,
and few ciphers set a nonzero alignmask anyway.  Also, even without
runtime alignment, an alignment of at least 4 bytes can be guaranteed.

Thus, at best this code is optimizing for the rare case of ciphers that
set an alignmask >= 7, at the cost of hurting the common cases.

Therefore, this patch removes the manual alignment code from cmac and
makes it stop setting an alignmask.
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 21415bfe
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
*/ */
struct cmac_tfm_ctx { struct cmac_tfm_ctx {
struct crypto_cipher *child; struct crypto_cipher *child;
u8 ctx[]; __be64 consts[];
}; };
/* /*
...@@ -44,17 +44,15 @@ struct cmac_tfm_ctx { ...@@ -44,17 +44,15 @@ struct cmac_tfm_ctx {
*/ */
struct cmac_desc_ctx { struct cmac_desc_ctx {
unsigned int len; unsigned int len;
u8 ctx[]; u8 odds[];
}; };
static int crypto_cmac_digest_setkey(struct crypto_shash *parent, static int crypto_cmac_digest_setkey(struct crypto_shash *parent,
const u8 *inkey, unsigned int keylen) const u8 *inkey, unsigned int keylen)
{ {
unsigned long alignmask = crypto_shash_alignmask(parent);
struct cmac_tfm_ctx *ctx = crypto_shash_ctx(parent); struct cmac_tfm_ctx *ctx = crypto_shash_ctx(parent);
unsigned int bs = crypto_shash_blocksize(parent); unsigned int bs = crypto_shash_blocksize(parent);
__be64 *consts = PTR_ALIGN((void *)ctx->ctx, __be64 *consts = ctx->consts;
(alignmask | (__alignof__(__be64) - 1)) + 1);
u64 _const[2]; u64 _const[2];
int i, err = 0; int i, err = 0;
u8 msb_mask, gfmask; u8 msb_mask, gfmask;
...@@ -104,10 +102,9 @@ static int crypto_cmac_digest_setkey(struct crypto_shash *parent, ...@@ -104,10 +102,9 @@ static int crypto_cmac_digest_setkey(struct crypto_shash *parent,
static int crypto_cmac_digest_init(struct shash_desc *pdesc) static int crypto_cmac_digest_init(struct shash_desc *pdesc)
{ {
unsigned long alignmask = crypto_shash_alignmask(pdesc->tfm);
struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc); struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
int bs = crypto_shash_blocksize(pdesc->tfm); int bs = crypto_shash_blocksize(pdesc->tfm);
u8 *prev = PTR_ALIGN((void *)ctx->ctx, alignmask + 1) + bs; u8 *prev = &ctx->odds[bs];
ctx->len = 0; ctx->len = 0;
memset(prev, 0, bs); memset(prev, 0, bs);
...@@ -119,12 +116,11 @@ static int crypto_cmac_digest_update(struct shash_desc *pdesc, const u8 *p, ...@@ -119,12 +116,11 @@ static int crypto_cmac_digest_update(struct shash_desc *pdesc, const u8 *p,
unsigned int len) unsigned int len)
{ {
struct crypto_shash *parent = pdesc->tfm; struct crypto_shash *parent = pdesc->tfm;
unsigned long alignmask = crypto_shash_alignmask(parent);
struct cmac_tfm_ctx *tctx = crypto_shash_ctx(parent); struct cmac_tfm_ctx *tctx = crypto_shash_ctx(parent);
struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc); struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
struct crypto_cipher *tfm = tctx->child; struct crypto_cipher *tfm = tctx->child;
int bs = crypto_shash_blocksize(parent); int bs = crypto_shash_blocksize(parent);
u8 *odds = PTR_ALIGN((void *)ctx->ctx, alignmask + 1); u8 *odds = ctx->odds;
u8 *prev = odds + bs; u8 *prev = odds + bs;
/* checking the data can fill the block */ /* checking the data can fill the block */
...@@ -165,14 +161,11 @@ static int crypto_cmac_digest_update(struct shash_desc *pdesc, const u8 *p, ...@@ -165,14 +161,11 @@ static int crypto_cmac_digest_update(struct shash_desc *pdesc, const u8 *p,
static int crypto_cmac_digest_final(struct shash_desc *pdesc, u8 *out) static int crypto_cmac_digest_final(struct shash_desc *pdesc, u8 *out)
{ {
struct crypto_shash *parent = pdesc->tfm; struct crypto_shash *parent = pdesc->tfm;
unsigned long alignmask = crypto_shash_alignmask(parent);
struct cmac_tfm_ctx *tctx = crypto_shash_ctx(parent); struct cmac_tfm_ctx *tctx = crypto_shash_ctx(parent);
struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc); struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
struct crypto_cipher *tfm = tctx->child; struct crypto_cipher *tfm = tctx->child;
int bs = crypto_shash_blocksize(parent); int bs = crypto_shash_blocksize(parent);
u8 *consts = PTR_ALIGN((void *)tctx->ctx, u8 *odds = ctx->odds;
(alignmask | (__alignof__(__be64) - 1)) + 1);
u8 *odds = PTR_ALIGN((void *)ctx->ctx, alignmask + 1);
u8 *prev = odds + bs; u8 *prev = odds + bs;
unsigned int offset = 0; unsigned int offset = 0;
...@@ -191,7 +184,7 @@ static int crypto_cmac_digest_final(struct shash_desc *pdesc, u8 *out) ...@@ -191,7 +184,7 @@ static int crypto_cmac_digest_final(struct shash_desc *pdesc, u8 *out)
} }
crypto_xor(prev, odds, bs); crypto_xor(prev, odds, bs);
crypto_xor(prev, consts + offset, bs); crypto_xor(prev, (const u8 *)tctx->consts + offset, bs);
crypto_cipher_encrypt_one(tfm, out, prev); crypto_cipher_encrypt_one(tfm, out, prev);
...@@ -241,7 +234,6 @@ static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb) ...@@ -241,7 +234,6 @@ static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb)
struct shash_instance *inst; struct shash_instance *inst;
struct crypto_cipher_spawn *spawn; struct crypto_cipher_spawn *spawn;
struct crypto_alg *alg; struct crypto_alg *alg;
unsigned long alignmask;
u32 mask; u32 mask;
int err; int err;
...@@ -273,23 +265,14 @@ static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb) ...@@ -273,23 +265,14 @@ static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb)
if (err) if (err)
goto err_free_inst; goto err_free_inst;
alignmask = alg->cra_alignmask;
inst->alg.base.cra_alignmask = alignmask;
inst->alg.base.cra_priority = alg->cra_priority; inst->alg.base.cra_priority = alg->cra_priority;
inst->alg.base.cra_blocksize = alg->cra_blocksize; inst->alg.base.cra_blocksize = alg->cra_blocksize;
inst->alg.base.cra_ctxsize = sizeof(struct cmac_tfm_ctx) +
alg->cra_blocksize * 2;
inst->alg.digestsize = alg->cra_blocksize; inst->alg.digestsize = alg->cra_blocksize;
inst->alg.descsize = inst->alg.descsize = sizeof(struct cmac_desc_ctx) +
ALIGN(sizeof(struct cmac_desc_ctx), crypto_tfm_ctx_alignment()) alg->cra_blocksize * 2;
+ (alignmask & ~(crypto_tfm_ctx_alignment() - 1))
+ alg->cra_blocksize * 2;
inst->alg.base.cra_ctxsize =
ALIGN(sizeof(struct cmac_tfm_ctx), crypto_tfm_ctx_alignment())
+ ((alignmask | (__alignof__(__be64) - 1)) &
~(crypto_tfm_ctx_alignment() - 1))
+ alg->cra_blocksize * 2;
inst->alg.init = crypto_cmac_digest_init; inst->alg.init = crypto_cmac_digest_init;
inst->alg.update = crypto_cmac_digest_update; inst->alg.update = crypto_cmac_digest_update;
inst->alg.final = crypto_cmac_digest_final; inst->alg.final = crypto_cmac_digest_final;
......
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