Skip to content

Commit 9f6035a

Browse files
nhukcherbertx
authored andcommitted
crypto: x86/polyval - Fix crashes when keys are not 16-byte aligned
crypto_tfm::__crt_ctx is not guaranteed to be 16-byte aligned on x86-64. This causes crashes due to movaps instructions in clmul_polyval_update. Add logic to align polyval_tfm_ctx to 16 bytes. Cc: <[email protected]> Fixes: 34f7f6c ("crypto: x86/polyval - Add PCLMULQDQ accelerated implementation of POLYVAL") Reported-by: Bruno Goncalves <[email protected]> Signed-off-by: Nathan Huckleberry <[email protected]> Reviewed-by: Eric Biggers <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 9abf231 commit 9f6035a

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

arch/x86/crypto/polyval-clmulni_glue.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,17 @@
2727
#include <asm/cpu_device_id.h>
2828
#include <asm/simd.h>
2929

30+
#define POLYVAL_ALIGN 16
31+
#define POLYVAL_ALIGN_ATTR __aligned(POLYVAL_ALIGN)
32+
#define POLYVAL_ALIGN_EXTRA ((POLYVAL_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1))
33+
#define POLYVAL_CTX_SIZE (sizeof(struct polyval_tfm_ctx) + POLYVAL_ALIGN_EXTRA)
3034
#define NUM_KEY_POWERS 8
3135

3236
struct polyval_tfm_ctx {
3337
/*
3438
* These powers must be in the order h^8, ..., h^1.
3539
*/
36-
u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE];
40+
u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE] POLYVAL_ALIGN_ATTR;
3741
};
3842

3943
struct polyval_desc_ctx {
@@ -45,6 +49,11 @@ asmlinkage void clmul_polyval_update(const struct polyval_tfm_ctx *keys,
4549
const u8 *in, size_t nblocks, u8 *accumulator);
4650
asmlinkage void clmul_polyval_mul(u8 *op1, const u8 *op2);
4751

52+
static inline struct polyval_tfm_ctx *polyval_tfm_ctx(struct crypto_shash *tfm)
53+
{
54+
return PTR_ALIGN(crypto_shash_ctx(tfm), POLYVAL_ALIGN);
55+
}
56+
4857
static void internal_polyval_update(const struct polyval_tfm_ctx *keys,
4958
const u8 *in, size_t nblocks, u8 *accumulator)
5059
{
@@ -72,7 +81,7 @@ static void internal_polyval_mul(u8 *op1, const u8 *op2)
7281
static int polyval_x86_setkey(struct crypto_shash *tfm,
7382
const u8 *key, unsigned int keylen)
7483
{
75-
struct polyval_tfm_ctx *tctx = crypto_shash_ctx(tfm);
84+
struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(tfm);
7685
int i;
7786

7887
if (keylen != POLYVAL_BLOCK_SIZE)
@@ -102,7 +111,7 @@ static int polyval_x86_update(struct shash_desc *desc,
102111
const u8 *src, unsigned int srclen)
103112
{
104113
struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
105-
const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
114+
const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
106115
u8 *pos;
107116
unsigned int nblocks;
108117
unsigned int n;
@@ -143,7 +152,7 @@ static int polyval_x86_update(struct shash_desc *desc,
143152
static int polyval_x86_final(struct shash_desc *desc, u8 *dst)
144153
{
145154
struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
146-
const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
155+
const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
147156

148157
if (dctx->bytes) {
149158
internal_polyval_mul(dctx->buffer,
@@ -167,7 +176,7 @@ static struct shash_alg polyval_alg = {
167176
.cra_driver_name = "polyval-clmulni",
168177
.cra_priority = 200,
169178
.cra_blocksize = POLYVAL_BLOCK_SIZE,
170-
.cra_ctxsize = sizeof(struct polyval_tfm_ctx),
179+
.cra_ctxsize = POLYVAL_CTX_SIZE,
171180
.cra_module = THIS_MODULE,
172181
},
173182
};

0 commit comments

Comments
 (0)