aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-01-25 06:34:01 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2006-03-21 04:14:08 -0500
commitf10b7897ee29649fa7f0ccdc8d859ccd6ce7dbfd (patch)
tree345a25e1e1b2bcd647074844003d61b7d27e4e39
parenta5f8c473052bc693cdbe2f9ae4b424b993886ff5 (diff)
[CRYPTO] api: Align tfm context as wide as possible
Since tfm contexts can contain arbitrary types we should provide at least natural alignment (__attribute__ ((__aligned__))) for them. In particular, this is needed on the Xscale which is a 32-bit architecture with a u64 type that requires 64-bit alignment. This problem was reported by Ronen Shitrit. The crypto_tfm structure's size was 44 bytes on 32-bit architectures and 80 bytes on 64-bit architectures. So adding this requirement only means that we have to add an extra 4 bytes on 32-bit architectures. On i386 the natural alignment is 16 bytes which also benefits the VIA Padlock as it no longer has to manually align its context structure to 128 bits. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/api.c2
-rw-r--r--drivers/crypto/padlock-aes.c6
-rw-r--r--include/linux/crypto.h10
3 files changed, 15 insertions, 3 deletions
diff --git a/crypto/api.c b/crypto/api.c
index e26156f71839..34e02caffc2a 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -165,7 +165,7 @@ static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags)
165 break; 165 break;
166 } 166 }
167 167
168 return len + alg->cra_alignmask; 168 return len + (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1));
169} 169}
170 170
171struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) 171struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 0c08c58252be..5158a9db4bc5 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -284,7 +284,11 @@ aes_hw_extkey_available(uint8_t key_len)
284 284
285static inline struct aes_ctx *aes_ctx(void *ctx) 285static inline struct aes_ctx *aes_ctx(void *ctx)
286{ 286{
287 return (struct aes_ctx *)ALIGN((unsigned long)ctx, PADLOCK_ALIGNMENT); 287 unsigned long align = PADLOCK_ALIGNMENT;
288
289 if (align <= crypto_tfm_ctx_alignment())
290 align = 1;
291 return (struct aes_ctx *)ALIGN((unsigned long)ctx, align);
288} 292}
289 293
290static int 294static int
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index d88bf8aa8b47..0ab1bc1152ca 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -229,6 +229,8 @@ struct crypto_tfm {
229 } crt_u; 229 } crt_u;
230 230
231 struct crypto_alg *__crt_alg; 231 struct crypto_alg *__crt_alg;
232
233 char __crt_ctx[] __attribute__ ((__aligned__));
232}; 234};
233 235
234/* 236/*
@@ -301,7 +303,13 @@ static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm)
301 303
302static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) 304static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
303{ 305{
304 return (void *)&tfm[1]; 306 return tfm->__crt_ctx;
307}
308
309static inline unsigned int crypto_tfm_ctx_alignment(void)
310{
311 struct crypto_tfm *tfm;
312 return __alignof__(tfm->__crt_ctx);
305} 313}
306 314
307/* 315/*