diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2014-07-25 19:40:20 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-07-28 10:01:02 -0400 |
commit | f960d2093f29f0bc4e1df1fcefb993455620c0b5 (patch) | |
tree | 3f30e4258e76c6fe1a0feabdb54372e9602b9a1b /arch/arm64 | |
parent | e052dbf554610e2104c5a7518c4d8374bed701bb (diff) |
crypto: arm64-aes - fix encryption of unaligned data
cryptsetup fails on arm64 when using kernel encryption via AF_ALG socket.
See https://bugzilla.redhat.com/show_bug.cgi?id=1122937
The bug is caused by incorrect handling of unaligned data in
arch/arm64/crypto/aes-glue.c. Cryptsetup creates a buffer that is aligned
on 8 bytes, but not on 16 bytes. It opens AF_ALG socket and uses the
socket to encrypt data in the buffer. The arm64 crypto accelerator causes
data corruption or crashes in the scatterwalk_pagedone.
This patch fixes the bug by passing the residue bytes that were not
processed as the last parameter to blkcipher_walk_done.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'arch/arm64')
-rw-r--r-- | arch/arm64/crypto/aes-glue.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index 60f2f4c12256..79cd911ef88c 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c | |||
@@ -106,7 +106,7 @@ static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
106 | for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) { | 106 | for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) { |
107 | aes_ecb_encrypt(walk.dst.virt.addr, walk.src.virt.addr, | 107 | aes_ecb_encrypt(walk.dst.virt.addr, walk.src.virt.addr, |
108 | (u8 *)ctx->key_enc, rounds, blocks, first); | 108 | (u8 *)ctx->key_enc, rounds, blocks, first); |
109 | err = blkcipher_walk_done(desc, &walk, 0); | 109 | err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE); |
110 | } | 110 | } |
111 | kernel_neon_end(); | 111 | kernel_neon_end(); |
112 | return err; | 112 | return err; |
@@ -128,7 +128,7 @@ static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
128 | for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) { | 128 | for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) { |
129 | aes_ecb_decrypt(walk.dst.virt.addr, walk.src.virt.addr, | 129 | aes_ecb_decrypt(walk.dst.virt.addr, walk.src.virt.addr, |
130 | (u8 *)ctx->key_dec, rounds, blocks, first); | 130 | (u8 *)ctx->key_dec, rounds, blocks, first); |
131 | err = blkcipher_walk_done(desc, &walk, 0); | 131 | err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE); |
132 | } | 132 | } |
133 | kernel_neon_end(); | 133 | kernel_neon_end(); |
134 | return err; | 134 | return err; |
@@ -151,7 +151,7 @@ static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
151 | aes_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr, | 151 | aes_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr, |
152 | (u8 *)ctx->key_enc, rounds, blocks, walk.iv, | 152 | (u8 *)ctx->key_enc, rounds, blocks, walk.iv, |
153 | first); | 153 | first); |
154 | err = blkcipher_walk_done(desc, &walk, 0); | 154 | err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE); |
155 | } | 155 | } |
156 | kernel_neon_end(); | 156 | kernel_neon_end(); |
157 | return err; | 157 | return err; |
@@ -174,7 +174,7 @@ static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
174 | aes_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr, | 174 | aes_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr, |
175 | (u8 *)ctx->key_dec, rounds, blocks, walk.iv, | 175 | (u8 *)ctx->key_dec, rounds, blocks, walk.iv, |
176 | first); | 176 | first); |
177 | err = blkcipher_walk_done(desc, &walk, 0); | 177 | err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE); |
178 | } | 178 | } |
179 | kernel_neon_end(); | 179 | kernel_neon_end(); |
180 | return err; | 180 | return err; |
@@ -243,7 +243,7 @@ static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
243 | aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr, | 243 | aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr, |
244 | (u8 *)ctx->key1.key_enc, rounds, blocks, | 244 | (u8 *)ctx->key1.key_enc, rounds, blocks, |
245 | (u8 *)ctx->key2.key_enc, walk.iv, first); | 245 | (u8 *)ctx->key2.key_enc, walk.iv, first); |
246 | err = blkcipher_walk_done(desc, &walk, 0); | 246 | err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE); |
247 | } | 247 | } |
248 | kernel_neon_end(); | 248 | kernel_neon_end(); |
249 | 249 | ||
@@ -267,7 +267,7 @@ static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
267 | aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr, | 267 | aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr, |
268 | (u8 *)ctx->key1.key_dec, rounds, blocks, | 268 | (u8 *)ctx->key1.key_dec, rounds, blocks, |
269 | (u8 *)ctx->key2.key_enc, walk.iv, first); | 269 | (u8 *)ctx->key2.key_enc, walk.iv, first); |
270 | err = blkcipher_walk_done(desc, &walk, 0); | 270 | err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE); |
271 | } | 271 | } |
272 | kernel_neon_end(); | 272 | kernel_neon_end(); |
273 | 273 | ||