aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2018-07-13 04:12:32 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2018-07-20 01:47:42 -0400
commit46d8c4b28652d35dc6cfb5adf7f54e102fc04384 (patch)
tree3c1d6b4111feb002b39f27cea7039a9d8090ffb0 /drivers
parent2546da99212f22034aecf279da9c47cbfac6c981 (diff)
crypto: padlock-aes - Fix Nano workaround data corruption
This was detected by the self-test thanks to Ard's chunking patch. I finally got around to testing this out on my ancient Via box. It turns out that the workaround got the assembly wrong and we end up doing count + initial cycles of the loop instead of just count. This obviously causes corruption, either by overwriting the source that is yet to be processed, or writing over the end of the buffer. On CPUs that don't require the workaround only ECB is affected. On Nano CPUs both ECB and CBC are affected. This patch fixes it by doing the subtraction prior to the assembly. Fixes: a76c1c23d0c3 ("crypto: padlock-aes - work around Nano CPU...") Cc: <stable@vger.kernel.org> Reported-by: Jamie Heilman <jamie@audible.transient.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/crypto/padlock-aes.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 1c6cbda56afe..09d823d36d3a 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -266,6 +266,8 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
266 return; 266 return;
267 } 267 }
268 268
269 count -= initial;
270
269 if (initial) 271 if (initial)
270 asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ 272 asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
271 : "+S"(input), "+D"(output) 273 : "+S"(input), "+D"(output)
@@ -273,7 +275,7 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
273 275
274 asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ 276 asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
275 : "+S"(input), "+D"(output) 277 : "+S"(input), "+D"(output)
276 : "d"(control_word), "b"(key), "c"(count - initial)); 278 : "d"(control_word), "b"(key), "c"(count));
277} 279}
278 280
279static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, 281static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
@@ -284,6 +286,8 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
284 if (count < cbc_fetch_blocks) 286 if (count < cbc_fetch_blocks)
285 return cbc_crypt(input, output, key, iv, control_word, count); 287 return cbc_crypt(input, output, key, iv, control_word, count);
286 288
289 count -= initial;
290
287 if (initial) 291 if (initial)
288 asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ 292 asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */
289 : "+S" (input), "+D" (output), "+a" (iv) 293 : "+S" (input), "+D" (output), "+a" (iv)
@@ -291,7 +295,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
291 295
292 asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ 296 asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */
293 : "+S" (input), "+D" (output), "+a" (iv) 297 : "+S" (input), "+D" (output), "+a" (iv)
294 : "d" (control_word), "b" (key), "c" (count-initial)); 298 : "d" (control_word), "b" (key), "c" (count));
295 return iv; 299 return iv;
296} 300}
297 301