mbox series

[v2,0/4] crypto: switch to crypto API for ESSIV generation

Message ID 20190618212749.8995-1-ard.biesheuvel@linaro.org (mailing list archive)
Headers show
Series crypto: switch to crypto API for ESSIV generation | expand

Message

Ard Biesheuvel June 18, 2019, 9:27 p.m. UTC
This series creates an ESSIV template that produces a skcipher or AEAD
transform based on a tuple of the form '<skcipher>,<cipher>,<shash>'
(or '<aead>,<cipher>,<shash>' for the AEAD case). It exposes the
encapsulated sync or async skcipher/aead by passing through all operations,
while using the cipher/shash pair to transform the input IV into an ESSIV
output IV.

This matches what both users of ESSIV in the kernel do, and so it is proposed
as a replacement for those, in patches #2 and #4.

This code has been tested using the fscrypt test suggested by Eric
(generic/549), as well as the mode-test script suggested by Milan for
the dm-crypt case. I also tested the aead case in a virtual machine,
but it definitely needs some wider testing from the dm-crypt experts.

Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Eric Biggers <ebiggers@google.com>
Cc: dm-devel@redhat.com
Cc: linux-fscrypt@vger.kernel.org
Cc: Gilad Ben-Yossef <gilad@benyossef.com>
Cc: Milan Broz <gmazyland@gmail.com>

Ard Biesheuvel (4):
  crypto: essiv - create wrapper template for ESSIV generation
  fs: crypto: invoke crypto API for ESSIV handling
  md: dm-crypt: infer ESSIV block cipher from cipher string directly
  md: dm-crypt: switch to ESSIV crypto API template

 crypto/Kconfig              |   4 +
 crypto/Makefile             |   1 +
 crypto/essiv.c              | 624 ++++++++++++++++++++
 drivers/md/Kconfig          |   1 +
 drivers/md/dm-crypt.c       | 237 ++------
 fs/crypto/Kconfig           |   1 +
 fs/crypto/crypto.c          |   5 -
 fs/crypto/fscrypt_private.h |   9 -
 fs/crypto/keyinfo.c         |  88 +--
 9 files changed, 675 insertions(+), 295 deletions(-)
 create mode 100644 crypto/essiv.c

Comments

Milan Broz June 19, 2019, 6:56 a.m. UTC | #1
On 18/06/2019 23:27, Ard Biesheuvel wrote:
> This series creates an ESSIV template that produces a skcipher or AEAD
> transform based on a tuple of the form '<skcipher>,<cipher>,<shash>'
> (or '<aead>,<cipher>,<shash>' for the AEAD case). It exposes the
> encapsulated sync or async skcipher/aead by passing through all operations,
> while using the cipher/shash pair to transform the input IV into an ESSIV
> output IV.
> 
> This matches what both users of ESSIV in the kernel do, and so it is proposed
> as a replacement for those, in patches #2 and #4.
> 
> This code has been tested using the fscrypt test suggested by Eric
> (generic/549), as well as the mode-test script suggested by Milan for
> the dm-crypt case. I also tested the aead case in a virtual machine,
> but it definitely needs some wider testing from the dm-crypt experts.

Well, I just run "make check" on cyptsetup upstream (32bit VM, Linus' tree
with this patcheset applied), and get this on the first api test...

Just try
cryptsetup open --type plain -c aes-cbc-essiv:sha256 /dev/sdd test

kernel: alg: No test for essiv(cbc(aes),aes,sha256) (essiv(cbc-aes-aesni,aes-aesni,sha256-generic))
kernel: BUG: unable to handle page fault for address: 00c14578
kernel: #PF: supervisor read access in kernel mode
kernel: #PF: error_code(0x0000) - not-present page
kernel: *pde = 00000000 
kernel: Oops: 0000 [#1] PREEMPT SMP
kernel: CPU: 2 PID: 15611 Comm: kworker/u17:2 Not tainted 5.2.0-rc5+ #519
kernel: Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/13/2018
kernel: Workqueue: kcryptd/253:2 kcryptd_crypt [dm_crypt]
kernel: EIP: essiv_skcipher_decrypt+0x3/0x20
kernel: Code: 5f 5d c3 90 90 90 90 55 8b 48 0c 89 e5 8d 41 10 ff 51 18 5d c3 66 90 55 8b 40 0c 89 e5 ff 50 08 5d c3 8d 74 26 00 90 8b 50 58 <f6> 02 01 75 10 55 83 c0 38 89 e5 ff 52 f0 5d c3 8d 74 26 00 90 b8
kernel: EAX: ee87fc08 EBX: ee87fd40 ECX: ee87fdc4 EDX: 00c14578
kernel: ESI: ee87fb78 EDI: f0a70800 EBP: ef7a9ed8 ESP: ef7a9e3c
kernel: DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010246
kernel: CR0: 80050033 CR2: 00c14578 CR3: 01b87000 CR4: 00140690
kernel: Call Trace:
kernel:  ? crypt_convert+0x864/0xe50 [dm_crypt]
kernel:  ? static_obj+0x32/0x50
kernel:  ? lockdep_init_map+0x34/0x1b0
kernel:  ? __init_waitqueue_head+0x29/0x40
kernel:  kcryptd_crypt+0xca/0x3b0 [dm_crypt]
kernel:  ? process_one_work+0x1a6/0x5a0
kernel:  process_one_work+0x214/0x5a0
kernel:  worker_thread+0x134/0x3e0
kernel:  ? process_one_work+0x5a0/0x5a0
kernel:  kthread+0xd4/0x100
kernel:  ? process_one_work+0x5a0/0x5a0
kernel:  ? kthread_park+0x90/0x90
kernel:  ret_from_fork+0x19/0x24
kernel: Modules linked in: dm_zero dm_integrity async_xor xor async_tx dm_verity reed_solomon dm_bufio dm_crypt loop dm_mod pktcdvd crc32_pclmul crc32c_intel aesni_intel aes_i586 crypto_simd cryptd ata_piix
kernel: CR2: 0000000000c14578
kernel: ---[ end trace 8a651b067b7b6a10 ]---
kernel: EIP: essiv_skcipher_decrypt+0x3/0x20
kernel: Code: 5f 5d c3 90 90 90 90 55 8b 48 0c 89 e5 8d 41 10 ff 51 18 5d c3 66 90 55 8b 40 0c 89 e5 ff 50 08 5d c3 8d 74 26 00 90 8b 50 58 <f6> 02 01 75 10 55 83 c0 38 89 e5 ff 52 f0 5d c3 8d 74 26 00 90 b8
kernel: EAX: ee87fc08 EBX: ee87fd40 ECX: ee87fdc4 EDX: 00c14578
kernel: ESI: ee87fb78 EDI: f0a70800 EBP: ef7a9ed8 ESP: c1b8b45c
kernel: DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010246
kernel: CR0: 80050033 CR2: 00c14578 CR3: 01b87000 CR4: 00140690

Milan
Ard Biesheuvel June 19, 2019, 7:11 a.m. UTC | #2
On Wed, 19 Jun 2019 at 08:56, Milan Broz <gmazyland@gmail.com> wrote:
>
> On 18/06/2019 23:27, Ard Biesheuvel wrote:
> > This series creates an ESSIV template that produces a skcipher or AEAD
> > transform based on a tuple of the form '<skcipher>,<cipher>,<shash>'
> > (or '<aead>,<cipher>,<shash>' for the AEAD case). It exposes the
> > encapsulated sync or async skcipher/aead by passing through all operations,
> > while using the cipher/shash pair to transform the input IV into an ESSIV
> > output IV.
> >
> > This matches what both users of ESSIV in the kernel do, and so it is proposed
> > as a replacement for those, in patches #2 and #4.
> >
> > This code has been tested using the fscrypt test suggested by Eric
> > (generic/549), as well as the mode-test script suggested by Milan for
> > the dm-crypt case. I also tested the aead case in a virtual machine,
> > but it definitely needs some wider testing from the dm-crypt experts.
>
> Well, I just run "make check" on cyptsetup upstream (32bit VM, Linus' tree
> with this patcheset applied), and get this on the first api test...
>

Ugh. Thanks for trying. I will have a look today.


> Just try
> cryptsetup open --type plain -c aes-cbc-essiv:sha256 /dev/sdd test
>
> kernel: alg: No test for essiv(cbc(aes),aes,sha256) (essiv(cbc-aes-aesni,aes-aesni,sha256-generic))
> kernel: BUG: unable to handle page fault for address: 00c14578
> kernel: #PF: supervisor read access in kernel mode
> kernel: #PF: error_code(0x0000) - not-present page
> kernel: *pde = 00000000
> kernel: Oops: 0000 [#1] PREEMPT SMP
> kernel: CPU: 2 PID: 15611 Comm: kworker/u17:2 Not tainted 5.2.0-rc5+ #519
> kernel: Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/13/2018
> kernel: Workqueue: kcryptd/253:2 kcryptd_crypt [dm_crypt]
> kernel: EIP: essiv_skcipher_decrypt+0x3/0x20
> kernel: Code: 5f 5d c3 90 90 90 90 55 8b 48 0c 89 e5 8d 41 10 ff 51 18 5d c3 66 90 55 8b 40 0c 89 e5 ff 50 08 5d c3 8d 74 26 00 90 8b 50 58 <f6> 02 01 75 10 55 83 c0 38 89 e5 ff 52 f0 5d c3 8d 74 26 00 90 b8
> kernel: EAX: ee87fc08 EBX: ee87fd40 ECX: ee87fdc4 EDX: 00c14578
> kernel: ESI: ee87fb78 EDI: f0a70800 EBP: ef7a9ed8 ESP: ef7a9e3c
> kernel: DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010246
> kernel: CR0: 80050033 CR2: 00c14578 CR3: 01b87000 CR4: 00140690
> kernel: Call Trace:
> kernel:  ? crypt_convert+0x864/0xe50 [dm_crypt]
> kernel:  ? static_obj+0x32/0x50
> kernel:  ? lockdep_init_map+0x34/0x1b0
> kernel:  ? __init_waitqueue_head+0x29/0x40
> kernel:  kcryptd_crypt+0xca/0x3b0 [dm_crypt]
> kernel:  ? process_one_work+0x1a6/0x5a0
> kernel:  process_one_work+0x214/0x5a0
> kernel:  worker_thread+0x134/0x3e0
> kernel:  ? process_one_work+0x5a0/0x5a0
> kernel:  kthread+0xd4/0x100
> kernel:  ? process_one_work+0x5a0/0x5a0
> kernel:  ? kthread_park+0x90/0x90
> kernel:  ret_from_fork+0x19/0x24
> kernel: Modules linked in: dm_zero dm_integrity async_xor xor async_tx dm_verity reed_solomon dm_bufio dm_crypt loop dm_mod pktcdvd crc32_pclmul crc32c_intel aesni_intel aes_i586 crypto_simd cryptd ata_piix
> kernel: CR2: 0000000000c14578
> kernel: ---[ end trace 8a651b067b7b6a10 ]---
> kernel: EIP: essiv_skcipher_decrypt+0x3/0x20
> kernel: Code: 5f 5d c3 90 90 90 90 55 8b 48 0c 89 e5 8d 41 10 ff 51 18 5d c3 66 90 55 8b 40 0c 89 e5 ff 50 08 5d c3 8d 74 26 00 90 8b 50 58 <f6> 02 01 75 10 55 83 c0 38 89 e5 ff 52 f0 5d c3 8d 74 26 00 90 b8
> kernel: EAX: ee87fc08 EBX: ee87fd40 ECX: ee87fdc4 EDX: 00c14578
> kernel: ESI: ee87fb78 EDI: f0a70800 EBP: ef7a9ed8 ESP: c1b8b45c
> kernel: DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010246
> kernel: CR0: 80050033 CR2: 00c14578 CR3: 01b87000 CR4: 00140690
>
> Milan
Ard Biesheuvel June 19, 2019, 9:14 a.m. UTC | #3
On Wed, 19 Jun 2019 at 09:11, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Wed, 19 Jun 2019 at 08:56, Milan Broz <gmazyland@gmail.com> wrote:
> >
> > On 18/06/2019 23:27, Ard Biesheuvel wrote:
> > > This series creates an ESSIV template that produces a skcipher or AEAD
> > > transform based on a tuple of the form '<skcipher>,<cipher>,<shash>'
> > > (or '<aead>,<cipher>,<shash>' for the AEAD case). It exposes the
> > > encapsulated sync or async skcipher/aead by passing through all operations,
> > > while using the cipher/shash pair to transform the input IV into an ESSIV
> > > output IV.
> > >
> > > This matches what both users of ESSIV in the kernel do, and so it is proposed
> > > as a replacement for those, in patches #2 and #4.
> > >
> > > This code has been tested using the fscrypt test suggested by Eric
> > > (generic/549), as well as the mode-test script suggested by Milan for
> > > the dm-crypt case. I also tested the aead case in a virtual machine,
> > > but it definitely needs some wider testing from the dm-crypt experts.
> >
> > Well, I just run "make check" on cyptsetup upstream (32bit VM, Linus' tree
> > with this patcheset applied), and get this on the first api test...
> >
>
> Ugh. Thanks for trying. I will have a look today.
>
>
> > Just try
> > cryptsetup open --type plain -c aes-cbc-essiv:sha256 /dev/sdd test
> >

Apologies, this was a rebase error on my part.

Could you please apply the hunk below and try again?

diff --git a/crypto/essiv.c b/crypto/essiv.c
index 029a65afb4d7..5dc2e592077e 100644
--- a/crypto/essiv.c
+++ b/crypto/essiv.c
@@ -243,6 +243,8 @@ static int essiv_aead_encrypt(struct aead_request *req)
 static int essiv_skcipher_decrypt(struct skcipher_request *req)
 {
        struct essiv_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
+
+       essiv_skcipher_prepare_subreq(req);
        return crypto_skcipher_decrypt(&rctx->blockcipher_req);
 }
Milan Broz June 19, 2019, 11:01 a.m. UTC | #4
On 19/06/2019 11:14, Ard Biesheuvel wrote:
> Apologies, this was a rebase error on my part.
> 
> Could you please apply the hunk below and try again?
> 
> diff --git a/crypto/essiv.c b/crypto/essiv.c
> index 029a65afb4d7..5dc2e592077e 100644
> --- a/crypto/essiv.c
> +++ b/crypto/essiv.c
> @@ -243,6 +243,8 @@ static int essiv_aead_encrypt(struct aead_request *req)
>  static int essiv_skcipher_decrypt(struct skcipher_request *req)
>  {
>         struct essiv_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
> +
> +       essiv_skcipher_prepare_subreq(req);
>         return crypto_skcipher_decrypt(&rctx->blockcipher_req);
>  }

That helps, but now the null cipher is broken...
(We use it for debugging and during reencryption from non-encrypted device)

Try
  cryptsetup open --type plain -c null /dev/sdd test -q
or
  dmsetup create test --table " 0 417792 crypt cipher_null-ecb - 0 /dev/sdd 0"

(or just run full cryptsetup testsuite)

kernel: BUG: kernel NULL pointer dereference, address: 00000000
kernel: #PF: supervisor read access in kernel mode
kernel: #PF: error_code(0x0000) - not-present page
kernel: *pde = 00000000 
kernel: Oops: 0000 [#1] PREEMPT SMP
kernel: CPU: 2 PID: 2261 Comm: cryptsetup Not tainted 5.2.0-rc5+ #521
kernel: Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/13/2018
kernel: EIP: strcmp+0x9/0x20
kernel: Code: 00 55 89 c1 89 e5 57 89 c7 56 89 d6 ac aa 84 c0 75 fa 5e 89 c8 5f 5d c3 8d b4 26 00 00 00 00 66 90 55 89 e5 57 89 d7 56 89 c6 <ac> ae 75 08 84 c0 75 f8 31 c0 eb 04 19 c0 0c 01 5e 5f 5d c3 8d 76
kernel: EAX: 00000000 EBX: ef51016c ECX: 0000000c EDX: f78e585e
kernel: ESI: 00000000 EDI: f78e585e EBP: f238dcb0 ESP: f238dca8
kernel: DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00210282
kernel: CR0: 80050033 CR2: 00000000 CR3: 30a28000 CR4: 00140690
kernel: Call Trace:
kernel:  crypt_ctr+0x473/0xf4e [dm_crypt]
kernel:  dm_table_add_target+0x15f/0x340 [dm_mod]
kernel:  table_load+0xe9/0x280 [dm_mod]
kernel:  ? retrieve_status+0x200/0x200 [dm_mod]
kernel:  ctl_ioctl+0x1c8/0x400 [dm_mod]
kernel:  ? retrieve_status+0x200/0x200 [dm_mod]
kernel:  ? ctl_ioctl+0x400/0x400 [dm_mod]
kernel:  dm_ctl_ioctl+0x8/0x10 [dm_mod]
kernel:  do_vfs_ioctl+0x3dd/0x790
kernel:  ? trace_hardirqs_on+0x4a/0xf0
kernel:  ? ksys_old_semctl+0x27/0x30
kernel:  ksys_ioctl+0x2e/0x60
kernel:  ? mpihelp_add_n+0x39/0x50
kernel:  sys_ioctl+0x11/0x20
kernel:  do_int80_syscall_32+0x4b/0x1a0
kernel:  ? mpihelp_add_n+0x39/0x50
kernel:  entry_INT80_32+0xcf/0xcf
kernel: EIP: 0xb7f5bbf2
kernel: Code: de 01 00 05 ed 73 02 00 83 ec 14 8d 80 0c ac ff ff 50 6a 02 e8 5f 12 01 00 c7 04 24 7f 00 00 00 e8 ce cd 01 00 66 90 90 cd 80 <c3> 8d b6 00 00 00 00 8d bc 27 00 00 00 00 8b 1c 24 c3 8d b6 00 00
kernel: EAX: ffffffda EBX: 00000005 ECX: c138fd09 EDX: 00511080
kernel: ESI: b7b83d40 EDI: b7b785af EBP: 0050dda0 ESP: bf9e1c34
kernel: DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00200286
kernel:  ? mpihelp_add_n+0x39/0x50
kernel: Modules linked in: dm_crypt loop dm_mod pktcdvd crc32_pclmul crc32c_intel aesni_intel aes_i586 crypto_simd cryptd ata_piix
kernel: CR2: 0000000000000000
kernel: ---[ end trace 0d32231f952fd372 ]---

m.
Ard Biesheuvel June 19, 2019, 11:16 a.m. UTC | #5
On Wed, 19 Jun 2019 at 13:01, Milan Broz <gmazyland@gmail.com> wrote:
>
> On 19/06/2019 11:14, Ard Biesheuvel wrote:
> > Apologies, this was a rebase error on my part.
> >
> > Could you please apply the hunk below and try again?
> >
> > diff --git a/crypto/essiv.c b/crypto/essiv.c
> > index 029a65afb4d7..5dc2e592077e 100644
> > --- a/crypto/essiv.c
> > +++ b/crypto/essiv.c
> > @@ -243,6 +243,8 @@ static int essiv_aead_encrypt(struct aead_request *req)
> >  static int essiv_skcipher_decrypt(struct skcipher_request *req)
> >  {
> >         struct essiv_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
> > +
> > +       essiv_skcipher_prepare_subreq(req);
> >         return crypto_skcipher_decrypt(&rctx->blockcipher_req);
> >  }
>
> That helps, but now the null cipher is broken...
> (We use it for debugging and during reencryption from non-encrypted device)
>

I guess that would be the cipher parsing change in the first patch.
I'll have a look.

> Try
>   cryptsetup open --type plain -c null /dev/sdd test -q
> or
>   dmsetup create test --table " 0 417792 crypt cipher_null-ecb - 0 /dev/sdd 0"
>
> (or just run full cryptsetup testsuite)
>

Is that your mode-test script?

I saw some errors about the null cipher, but tbh, it looked completely
unrelated to me, so i skipped those for the moment. But now, it looks
like it is related after all.


> kernel: BUG: kernel NULL pointer dereference, address: 00000000
> kernel: #PF: supervisor read access in kernel mode
> kernel: #PF: error_code(0x0000) - not-present page
> kernel: *pde = 00000000
> kernel: Oops: 0000 [#1] PREEMPT SMP
> kernel: CPU: 2 PID: 2261 Comm: cryptsetup Not tainted 5.2.0-rc5+ #521
> kernel: Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/13/2018
> kernel: EIP: strcmp+0x9/0x20
> kernel: Code: 00 55 89 c1 89 e5 57 89 c7 56 89 d6 ac aa 84 c0 75 fa 5e 89 c8 5f 5d c3 8d b4 26 00 00 00 00 66 90 55 89 e5 57 89 d7 56 89 c6 <ac> ae 75 08 84 c0 75 f8 31 c0 eb 04 19 c0 0c 01 5e 5f 5d c3 8d 76
> kernel: EAX: 00000000 EBX: ef51016c ECX: 0000000c EDX: f78e585e
> kernel: ESI: 00000000 EDI: f78e585e EBP: f238dcb0 ESP: f238dca8
> kernel: DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00210282
> kernel: CR0: 80050033 CR2: 00000000 CR3: 30a28000 CR4: 00140690
> kernel: Call Trace:
> kernel:  crypt_ctr+0x473/0xf4e [dm_crypt]
> kernel:  dm_table_add_target+0x15f/0x340 [dm_mod]
> kernel:  table_load+0xe9/0x280 [dm_mod]
> kernel:  ? retrieve_status+0x200/0x200 [dm_mod]
> kernel:  ctl_ioctl+0x1c8/0x400 [dm_mod]
> kernel:  ? retrieve_status+0x200/0x200 [dm_mod]
> kernel:  ? ctl_ioctl+0x400/0x400 [dm_mod]
> kernel:  dm_ctl_ioctl+0x8/0x10 [dm_mod]
> kernel:  do_vfs_ioctl+0x3dd/0x790
> kernel:  ? trace_hardirqs_on+0x4a/0xf0
> kernel:  ? ksys_old_semctl+0x27/0x30
> kernel:  ksys_ioctl+0x2e/0x60
> kernel:  ? mpihelp_add_n+0x39/0x50
> kernel:  sys_ioctl+0x11/0x20
> kernel:  do_int80_syscall_32+0x4b/0x1a0
> kernel:  ? mpihelp_add_n+0x39/0x50
> kernel:  entry_INT80_32+0xcf/0xcf
> kernel: EIP: 0xb7f5bbf2
> kernel: Code: de 01 00 05 ed 73 02 00 83 ec 14 8d 80 0c ac ff ff 50 6a 02 e8 5f 12 01 00 c7 04 24 7f 00 00 00 e8 ce cd 01 00 66 90 90 cd 80 <c3> 8d b6 00 00 00 00 8d bc 27 00 00 00 00 8b 1c 24 c3 8d b6 00 00
> kernel: EAX: ffffffda EBX: 00000005 ECX: c138fd09 EDX: 00511080
> kernel: ESI: b7b83d40 EDI: b7b785af EBP: 0050dda0 ESP: bf9e1c34
> kernel: DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00200286
> kernel:  ? mpihelp_add_n+0x39/0x50
> kernel: Modules linked in: dm_crypt loop dm_mod pktcdvd crc32_pclmul crc32c_intel aesni_intel aes_i586 crypto_simd cryptd ata_piix
> kernel: CR2: 0000000000000000
> kernel: ---[ end trace 0d32231f952fd372 ]---
>
> m.
Milan Broz June 19, 2019, 11:33 a.m. UTC | #6
On 19/06/2019 13:16, Ard Biesheuvel wrote:
>> Try
>>   cryptsetup open --type plain -c null /dev/sdd test -q
>> or
>>   dmsetup create test --table " 0 417792 crypt cipher_null-ecb - 0 /dev/sdd 0"
>>
>> (or just run full cryptsetup testsuite)
>>
> 
> Is that your mode-test script?
> 
> I saw some errors about the null cipher, but tbh, it looked completely
> unrelated to me, so i skipped those for the moment. But now, it looks
> like it is related after all.

This was triggered by align-test, mode-test fails the same though.

It is definitely related, I think you just changed the mode parsing in dm-crypt.
(cipher null contains only one dash I guess).

m.


> 
> 
>> kernel: BUG: kernel NULL pointer dereference, address: 00000000
>> kernel: #PF: supervisor read access in kernel mode
>> kernel: #PF: error_code(0x0000) - not-present page
>> kernel: *pde = 00000000
>> kernel: Oops: 0000 [#1] PREEMPT SMP
>> kernel: CPU: 2 PID: 2261 Comm: cryptsetup Not tainted 5.2.0-rc5+ #521
>> kernel: Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/13/2018
>> kernel: EIP: strcmp+0x9/0x20
>> kernel: Code: 00 55 89 c1 89 e5 57 89 c7 56 89 d6 ac aa 84 c0 75 fa 5e 89 c8 5f 5d c3 8d b4 26 00 00 00 00 66 90 55 89 e5 57 89 d7 56 89 c6 <ac> ae 75 08 84 c0 75 f8 31 c0 eb 04 19 c0 0c 01 5e 5f 5d c3 8d 76
>> kernel: EAX: 00000000 EBX: ef51016c ECX: 0000000c EDX: f78e585e
>> kernel: ESI: 00000000 EDI: f78e585e EBP: f238dcb0 ESP: f238dca8
>> kernel: DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00210282
>> kernel: CR0: 80050033 CR2: 00000000 CR3: 30a28000 CR4: 00140690
>> kernel: Call Trace:
>> kernel:  crypt_ctr+0x473/0xf4e [dm_crypt]
>> kernel:  dm_table_add_target+0x15f/0x340 [dm_mod]
>> kernel:  table_load+0xe9/0x280 [dm_mod]
>> kernel:  ? retrieve_status+0x200/0x200 [dm_mod]
>> kernel:  ctl_ioctl+0x1c8/0x400 [dm_mod]
>> kernel:  ? retrieve_status+0x200/0x200 [dm_mod]
>> kernel:  ? ctl_ioctl+0x400/0x400 [dm_mod]
>> kernel:  dm_ctl_ioctl+0x8/0x10 [dm_mod]
>> kernel:  do_vfs_ioctl+0x3dd/0x790
>> kernel:  ? trace_hardirqs_on+0x4a/0xf0
>> kernel:  ? ksys_old_semctl+0x27/0x30
>> kernel:  ksys_ioctl+0x2e/0x60
>> kernel:  ? mpihelp_add_n+0x39/0x50
>> kernel:  sys_ioctl+0x11/0x20
>> kernel:  do_int80_syscall_32+0x4b/0x1a0
>> kernel:  ? mpihelp_add_n+0x39/0x50
>> kernel:  entry_INT80_32+0xcf/0xcf
>> kernel: EIP: 0xb7f5bbf2
>> kernel: Code: de 01 00 05 ed 73 02 00 83 ec 14 8d 80 0c ac ff ff 50 6a 02 e8 5f 12 01 00 c7 04 24 7f 00 00 00 e8 ce cd 01 00 66 90 90 cd 80 <c3> 8d b6 00 00 00 00 8d bc 27 00 00 00 00 8b 1c 24 c3 8d b6 00 00
>> kernel: EAX: ffffffda EBX: 00000005 ECX: c138fd09 EDX: 00511080
>> kernel: ESI: b7b83d40 EDI: b7b785af EBP: 0050dda0 ESP: bf9e1c34
>> kernel: DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00200286
>> kernel:  ? mpihelp_add_n+0x39/0x50
>> kernel: Modules linked in: dm_crypt loop dm_mod pktcdvd crc32_pclmul crc32c_intel aesni_intel aes_i586 crypto_simd cryptd ata_piix
>> kernel: CR2: 0000000000000000
>> kernel: ---[ end trace 0d32231f952fd372 ]---
>>
>> m.
Ard Biesheuvel June 19, 2019, 12:36 p.m. UTC | #7
On Wed, 19 Jun 2019 at 13:33, Milan Broz <gmazyland@gmail.com> wrote:
>
> On 19/06/2019 13:16, Ard Biesheuvel wrote:
> >> Try
> >>   cryptsetup open --type plain -c null /dev/sdd test -q
> >> or
> >>   dmsetup create test --table " 0 417792 crypt cipher_null-ecb - 0 /dev/sdd 0"
> >>
> >> (or just run full cryptsetup testsuite)
> >>
> >
> > Is that your mode-test script?
> >
> > I saw some errors about the null cipher, but tbh, it looked completely
> > unrelated to me, so i skipped those for the moment. But now, it looks
> > like it is related after all.
>
> This was triggered by align-test, mode-test fails the same though.
>
> It is definitely related, I think you just changed the mode parsing in dm-crypt.
> (cipher null contains only one dash I guess).
>

On my unpatched 4.19 kernel, mode-test gives me

$ sudo ./mode-test
aes                            PLAIN:[table OK][status OK]
LUKS1:[table OK][status OK] CHECKSUM:[OK]
aes-plain                      PLAIN:[table OK][status OK]
LUKS1:[table OK][status OK] CHECKSUM:[OK]
null                           PLAIN:[table OK][status OK]
LUKS1:[table OK][status OK] CHECKSUM:[OK]
cipher_null                    PLAIN:[table FAIL]
 Expecting cipher_null-ecb got cipher_null-cbc-plain.
FAILED at line 64 ./mode-test

which is why I commented out those tests in the first place.

I can reproduce the crash after I re-enable them again, so I will need
to look into that. But something seems to be broken already.
Note that this is running on arm64 using a kconfig based on the Debian kernel.
Ard Biesheuvel June 19, 2019, 12:49 p.m. UTC | #8
On Wed, 19 Jun 2019 at 14:36, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Wed, 19 Jun 2019 at 13:33, Milan Broz <gmazyland@gmail.com> wrote:
> >
> > On 19/06/2019 13:16, Ard Biesheuvel wrote:
> > >> Try
> > >>   cryptsetup open --type plain -c null /dev/sdd test -q
> > >> or
> > >>   dmsetup create test --table " 0 417792 crypt cipher_null-ecb - 0 /dev/sdd 0"
> > >>
> > >> (or just run full cryptsetup testsuite)
> > >>
> > >
> > > Is that your mode-test script?
> > >
> > > I saw some errors about the null cipher, but tbh, it looked completely
> > > unrelated to me, so i skipped those for the moment. But now, it looks
> > > like it is related after all.
> >
> > This was triggered by align-test, mode-test fails the same though.
> >
> > It is definitely related, I think you just changed the mode parsing in dm-crypt.
> > (cipher null contains only one dash I guess).
> >
>
> On my unpatched 4.19 kernel, mode-test gives me
>
> $ sudo ./mode-test
> aes                            PLAIN:[table OK][status OK]
> LUKS1:[table OK][status OK] CHECKSUM:[OK]
> aes-plain                      PLAIN:[table OK][status OK]
> LUKS1:[table OK][status OK] CHECKSUM:[OK]
> null                           PLAIN:[table OK][status OK]
> LUKS1:[table OK][status OK] CHECKSUM:[OK]
> cipher_null                    PLAIN:[table FAIL]
>  Expecting cipher_null-ecb got cipher_null-cbc-plain.
> FAILED at line 64 ./mode-test
>
> which is why I commented out those tests in the first place.
>
> I can reproduce the crash after I re-enable them again, so I will need
> to look into that. But something seems to be broken already.
> Note that this is running on arm64 using a kconfig based on the Debian kernel.

Actually, could this be an issue with cryptsetup being out of date? On
another arm64 system with a more recent distro, it works fine
Milan Broz June 19, 2019, 1:08 p.m. UTC | #9
On 19/06/2019 14:49, Ard Biesheuvel wrote:
> On Wed, 19 Jun 2019 at 14:36, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>>
>> On Wed, 19 Jun 2019 at 13:33, Milan Broz <gmazyland@gmail.com> wrote:
>>>
>>> On 19/06/2019 13:16, Ard Biesheuvel wrote:
>>>>> Try
>>>>>   cryptsetup open --type plain -c null /dev/sdd test -q
>>>>> or
>>>>>   dmsetup create test --table " 0 417792 crypt cipher_null-ecb - 0 /dev/sdd 0"
>>>>>
>>>>> (or just run full cryptsetup testsuite)
>>>>>
>>>>
>>>> Is that your mode-test script?
>>>>
>>>> I saw some errors about the null cipher, but tbh, it looked completely
>>>> unrelated to me, so i skipped those for the moment. But now, it looks
>>>> like it is related after all.
>>>
>>> This was triggered by align-test, mode-test fails the same though.
>>>
>>> It is definitely related, I think you just changed the mode parsing in dm-crypt.
>>> (cipher null contains only one dash I guess).
>>>
>>
>> On my unpatched 4.19 kernel, mode-test gives me
>>
>> $ sudo ./mode-test
>> aes                            PLAIN:[table OK][status OK]
>> LUKS1:[table OK][status OK] CHECKSUM:[OK]
>> aes-plain                      PLAIN:[table OK][status OK]
>> LUKS1:[table OK][status OK] CHECKSUM:[OK]
>> null                           PLAIN:[table OK][status OK]
>> LUKS1:[table OK][status OK] CHECKSUM:[OK]
>> cipher_null                    PLAIN:[table FAIL]
>>  Expecting cipher_null-ecb got cipher_null-cbc-plain.
>> FAILED at line 64 ./mode-test
>>
>> which is why I commented out those tests in the first place.
>>
>> I can reproduce the crash after I re-enable them again, so I will need
>> to look into that. But something seems to be broken already.
>> Note that this is running on arm64 using a kconfig based on the Debian kernel.
> 
> Actually, could this be an issue with cryptsetup being out of date? On
> another arm64 system with a more recent distro, it works fine

Ah yes, it was changed because we hardened dm-crypt mode validation in kernel
https://gitlab.com/cryptsetup/cryptsetup/commit/aeea93fa9553ad70ed57f273aecb233113b204d6#f40cab3037a50bf28ce20d8aae52bfa6a0c0e2c4_137_137

So either use test form the released version of cryptsetup (all version are here)
https://mirrors.edge.kernel.org/pub/linux/utils/cryptsetup/

Or better use upstream git, we added a lot of tests anyway.

Milan
Ard Biesheuvel June 19, 2019, 1:13 p.m. UTC | #10
On Wed, 19 Jun 2019 at 14:49, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Wed, 19 Jun 2019 at 14:36, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> >
> > On Wed, 19 Jun 2019 at 13:33, Milan Broz <gmazyland@gmail.com> wrote:
> > >
> > > On 19/06/2019 13:16, Ard Biesheuvel wrote:
> > > >> Try
> > > >>   cryptsetup open --type plain -c null /dev/sdd test -q
> > > >> or
> > > >>   dmsetup create test --table " 0 417792 crypt cipher_null-ecb - 0 /dev/sdd 0"
> > > >>
> > > >> (or just run full cryptsetup testsuite)
> > > >>
> > > >
> > > > Is that your mode-test script?
> > > >
> > > > I saw some errors about the null cipher, but tbh, it looked completely
> > > > unrelated to me, so i skipped those for the moment. But now, it looks
> > > > like it is related after all.
> > >
> > > This was triggered by align-test, mode-test fails the same though.
> > >
> > > It is definitely related, I think you just changed the mode parsing in dm-crypt.
> > > (cipher null contains only one dash I guess).
> > >
> >
> > On my unpatched 4.19 kernel, mode-test gives me
> >
> > $ sudo ./mode-test
> > aes                            PLAIN:[table OK][status OK]
> > LUKS1:[table OK][status OK] CHECKSUM:[OK]
> > aes-plain                      PLAIN:[table OK][status OK]
> > LUKS1:[table OK][status OK] CHECKSUM:[OK]
> > null                           PLAIN:[table OK][status OK]
> > LUKS1:[table OK][status OK] CHECKSUM:[OK]
> > cipher_null                    PLAIN:[table FAIL]
> >  Expecting cipher_null-ecb got cipher_null-cbc-plain.
> > FAILED at line 64 ./mode-test
> >
> > which is why I commented out those tests in the first place.
> >
> > I can reproduce the crash after I re-enable them again, so I will need
> > to look into that. But something seems to be broken already.
> > Note that this is running on arm64 using a kconfig based on the Debian kernel.
>
> Actually, could this be an issue with cryptsetup being out of date? On
> another arm64 system with a more recent distro, it works fine

This should fix the crash you are seeing

diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 89efd7d249fd..12d28880ec34 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -2357,7 +2357,7 @@ static int crypt_ctr_cipher_old(struct dm_target
*ti, char *cipher_in, char *key
        if (!cipher_api)
                goto bad_mem;

-       if (!strcmp(*ivmode, "essiv")) {
+       if (*ivmode && !strcmp(*ivmode, "essiv")) {
                if (!*ivopts) {
                        ti->error = "Digest algorithm missing for ESSIV mode";
                        return -EINVAL;

Apologies for the sloppiness - this is a check that I had added and
then removed again, given that *ivmode was assigned unconditionally,
but i didn't realize tmp could be NULL.

With these two changes applied, mode-test successfully runs to completion.

Can you recommend another test suite I could run?