aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2014-03-27 13:14:40 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2014-04-01 05:22:47 -0400
commit8ceee72808d1ae3fb191284afc2257a2be964725 (patch)
tree30112eda2dac48ea04c9bd035dd918b82a47c2af /arch
parent37b28947170ebe55cb4f689ded5857d943c6578e (diff)
crypto: ghash-clmulni-intel - use C implementation for setkey()
The GHASH setkey() function uses SSE registers but fails to call kernel_fpu_begin()/kernel_fpu_end(). Instead of adding these calls, and then having to deal with the restriction that they cannot be called from interrupt context, move the setkey() implementation to the C domain. Note that setkey() does not use any particular SSE features and is not expected to become a performance bottleneck. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Acked-by: H. Peter Anvin <hpa@linux.intel.com> Fixes: 0e1227d356e9b (crypto: ghash - Add PCLMULQDQ accelerated implementation) Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/crypto/ghash-clmulni-intel_asm.S29
-rw-r--r--arch/x86/crypto/ghash-clmulni-intel_glue.c14
2 files changed, 11 insertions, 32 deletions
diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S b/arch/x86/crypto/ghash-clmulni-intel_asm.S
index 586f41aac361..185fad49d86f 100644
--- a/arch/x86/crypto/ghash-clmulni-intel_asm.S
+++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S
@@ -24,10 +24,6 @@
24.align 16 24.align 16
25.Lbswap_mask: 25.Lbswap_mask:
26 .octa 0x000102030405060708090a0b0c0d0e0f 26 .octa 0x000102030405060708090a0b0c0d0e0f
27.Lpoly:
28 .octa 0xc2000000000000000000000000000001
29.Ltwo_one:
30 .octa 0x00000001000000000000000000000001
31 27
32#define DATA %xmm0 28#define DATA %xmm0
33#define SHASH %xmm1 29#define SHASH %xmm1
@@ -134,28 +130,3 @@ ENTRY(clmul_ghash_update)
134.Lupdate_just_ret: 130.Lupdate_just_ret:
135 ret 131 ret
136ENDPROC(clmul_ghash_update) 132ENDPROC(clmul_ghash_update)
137
138/*
139 * void clmul_ghash_setkey(be128 *shash, const u8 *key);
140 *
141 * Calculate hash_key << 1 mod poly
142 */
143ENTRY(clmul_ghash_setkey)
144 movaps .Lbswap_mask, BSWAP
145 movups (%rsi), %xmm0
146 PSHUFB_XMM BSWAP %xmm0
147 movaps %xmm0, %xmm1
148 psllq $1, %xmm0
149 psrlq $63, %xmm1
150 movaps %xmm1, %xmm2
151 pslldq $8, %xmm1
152 psrldq $8, %xmm2
153 por %xmm1, %xmm0
154 # reduction
155 pshufd $0b00100100, %xmm2, %xmm1
156 pcmpeqd .Ltwo_one, %xmm1
157 pand .Lpoly, %xmm1
158 pxor %xmm1, %xmm0
159 movups %xmm0, (%rdi)
160 ret
161ENDPROC(clmul_ghash_setkey)
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
index 6759dd1135be..d785cf2c529c 100644
--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
+++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
@@ -30,8 +30,6 @@ void clmul_ghash_mul(char *dst, const be128 *shash);
30void clmul_ghash_update(char *dst, const char *src, unsigned int srclen, 30void clmul_ghash_update(char *dst, const char *src, unsigned int srclen,
31 const be128 *shash); 31 const be128 *shash);
32 32
33void clmul_ghash_setkey(be128 *shash, const u8 *key);
34
35struct ghash_async_ctx { 33struct ghash_async_ctx {
36 struct cryptd_ahash *cryptd_tfm; 34 struct cryptd_ahash *cryptd_tfm;
37}; 35};
@@ -58,13 +56,23 @@ static int ghash_setkey(struct crypto_shash *tfm,
58 const u8 *key, unsigned int keylen) 56 const u8 *key, unsigned int keylen)
59{ 57{
60 struct ghash_ctx *ctx = crypto_shash_ctx(tfm); 58 struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
59 be128 *x = (be128 *)key;
60 u64 a, b;
61 61
62 if (keylen != GHASH_BLOCK_SIZE) { 62 if (keylen != GHASH_BLOCK_SIZE) {
63 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 63 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
64 return -EINVAL; 64 return -EINVAL;
65 } 65 }
66 66
67 clmul_ghash_setkey(&ctx->shash, key); 67 /* perform multiplication by 'x' in GF(2^128) */
68 a = be64_to_cpu(x->a);
69 b = be64_to_cpu(x->b);
70
71 ctx->shash.a = (__be64)((b << 1) | (a >> 63));
72 ctx->shash.b = (__be64)((a << 1) | (b >> 63));
73
74 if (a >> 63)
75 ctx->shash.b ^= cpu_to_be64(0xc2);
68 76
69 return 0; 77 return 0;
70} 78}