Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
    • Switch to GitLab Next
  • Sign in / Register
C
cryptsetup
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 41
    • Issues 41
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 3
    • Merge Requests 3
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • cryptsetup
  • cryptsetup
  • Issues
  • #617

Closed
Open
Opened Dec 20, 2020 by Patrick Schleizer@adrelanos

cryptsetup luksFormat slowdown of factor ~ 6 when using hardened memory allocator Hardened Malloc

Issue description

cryptsetup luksFormat gets slower by approximately factor ~ 6 when using hardened memory allocator Hardened Malloc.

Without Hardened Malloc:

time sudo ./test 
+ set -e
+ rm -f /tmp/test
+ dd if=/dev/zero bs=1M count=50 of=/tmp/test
50+0 records in
50+0 records out
52428800 bytes (52 MB, 50 MiB) copied, 0.0258572 s, 2.0 GB/s
+ echo test
+ cryptsetup --batch-mode luksFormat /tmp/test

real	0m7.925s
user	0m10.994s
sys	0m0.867s

With Hardened Malloc:

time sudo ./test
+ set -e
+ rm -f /tmp/test
+ dd if=/dev/zero bs=1M count=50 of=/tmp/test
50+0 records in
50+0 records out
52428800 bytes (52 MB, 50 MiB) copied, 0.0261877 s, 2.0 GB/s
+ cryptsetup --batch-mode luksFormat /tmp/test
+ echo test

real	0m40.255s
user	0m9.943s
sys	0m33.331s

Steps for reproducing the issue

  1. run some benchmark using cryptsetup luksFormat without hardened malloc installed
  2. install hardened malloc
  3. re-run benchmark
  4. compare benchmarks

Additional info

Debian buster

My test script.

#!/bin/bash
set -x
set -e

rm -f /tmp/test

dd if=/dev/zero bs=1M count=50 of=/tmp/test

echo test | cryptsetup --debug --batch-mode luksFormat /tmp/test

//cc @thestinger, developer of Hardened Malloc

Debug log

Without hardened malloc.

+ set -e
+ rm -f /tmp/test
+ dd if=/dev/zero bs=1M count=50 of=/tmp/test
50+0 records in
50+0 records out
52428800 bytes (52 MB, 50 MiB) copied, 0.0256035 s, 2.0 GB/s
+ echo test
+ cryptsetup --debug --batch-mode luksFormat /tmp/test
# cryptsetup 2.1.0 processing "cryptsetup --debug --batch-mode luksFormat /tmp/test"
# Running command luksFormat.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating context for crypt device /tmp/test.
# Trying to open and read device /tmp/test with direct-io.
# Initialising device-mapper backend library.
# STDIN descriptor passphrase entry requested.
# Crypto backend (OpenSSL 1.1.1d  10 Sep 2019) initialized in cryptsetup library version 2.1.0.
# Detected kernel Linux 4.19.125-1.pvops.qubes.x86_64 x86_64.
# Only 2 active CPUs detected, PBKDF threads decreased from 4 to 2.
# Not enough physical memory detected, PBKDF max memory decreased from 1048576kB to 339862kB.
# PBKDF argon2i, hash sha256, time_ms 2000 (iterations 0), max_memory_kb 339862, parallel_threads 2.
# Formatting device /tmp/test as type LUKS2.
# Topology info for /tmp/test not supported, using default offset 1048576 bytes.
# Checking if cipher aes-xts-plain64 is usable.
# Using userspace crypto wrapper to access keyslot area.
# Formatting LUKS2 with JSON metadata area 12288 bytes and keyslots area 16744448 bytes.
# Creating new digest 0 (pbkdf2).
# Setting PBKDF2 type key digest 0.
# Running pbkdf2(sha256) benchmark.
# PBKDF benchmark: memory cost = 0, iterations = 840205, threads = 0 (took 39 ms)
# PBKDF benchmark: memory cost = 0, iterations = 846991, threads = 0 (took 619 ms)
# Benchmark returns pbkdf2(sha256) 846991 iterations, 0 memory, 0 threads (for 512-bits key).
# Segment 0 assigned to digest 0.
# Wiping LUKS areas (0x000000 - 0x1000000) with zeroes.
# Wiping keyslots area (0x008000 - 0x1000000) with random data.
# Device size 52428800, offset 16777216.
# Acquiring write lock for device /tmp/test.
# Verifying write lock handle for device /tmp/test.
# Device /tmp/test WRITE lock taken.
# Trying to write LUKS2 header (16384 bytes) at offset 0.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Checksum:5929c7ee2ee79c2a4e204bab27891c5e1e6104e84c12d12506871c2ac16d2306 (in-memory)
# Trying to write LUKS2 header (16384 bytes) at offset 16384.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Checksum:8c04b8fd64c488e4f1725cedca059f8b10e4ac434204e233a73fa691e25b79a4 (in-memory)
# Device /tmp/test WRITE lock released.
# Adding new keyslot -1 using volume key.
# Adding new keyslot -1 with volume key assigned to a crypt segment.
# Selected keyslot 0.
# Verifying key digest 0.
# Keyslot 0 assigned to digest 0.
# Trying to allocate LUKS2 keyslot 0.
# Found area 32768 -> 290816
# Running argon2i() benchmark.
# PBKDF benchmark: memory cost = 32, iterations = 4, threads = 2 (took 5 ms)
# PBKDF benchmark: memory cost = 512, iterations = 4, threads = 2 (took 1 ms)
# PBKDF benchmark: memory cost = 8192, iterations = 4, threads = 2 (took 29 ms)
# PBKDF benchmark: memory cost = 70620, iterations = 4, threads = 2 (took 201 ms)
# PBKDF benchmark: memory cost = 87835, iterations = 4, threads = 2 (took 194 ms)
# PBKDF benchmark: memory cost = 113189, iterations = 4, threads = 2 (took 259 ms)
# PBKDF benchmark: memory cost = 339862, iterations = 10, threads = 2 (took 1976 ms)
# Benchmark returns argon2i() 10 iterations, 339862 memory, 2 threads (for 512-bits key).
# Calculating attributes for LUKS2 keyslot 0.
# Updating keyslot area [0x8000].
# Acquiring write lock for device /tmp/test.
# Verifying write lock handle for device /tmp/test.
# Device /tmp/test WRITE lock taken.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Device /tmp/test WRITE lock released.
# Device size 52428800, offset 16777216.
# Acquiring write lock for device /tmp/test.
# Verifying write lock handle for device /tmp/test.
# Device /tmp/test WRITE lock taken.
# Trying to write LUKS2 header (16384 bytes) at offset 0.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Checksum:e45303cf0534fbf492aaa8ebf0d92c106b21b2e64024f36ddb6163cde5e75ad4 (in-memory)
# Trying to write LUKS2 header (16384 bytes) at offset 16384.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Checksum:f6353f870a36ecb747a37e65181d861bd565b8b6aba036f867e7786e793f003e (in-memory)
# Device /tmp/test WRITE lock released.
Key slot 0 created.
# Releasing crypt device /tmp/test context.
# Releasing device-mapper backend.
# Unlocking memory.
Command successful.

real	0m7.581s
user	0m9.869s
sys	0m0.930s

With hardened malloc.

time sudo ./test
+ set -e
+ rm -f /tmp/test
+ dd if=/dev/zero bs=1M count=50 of=/tmp/test
50+0 records in
50+0 records out
52428800 bytes (52 MB, 50 MiB) copied, 0.0251046 s, 2.1 GB/s
+ echo test
+ cryptsetup --debug --batch-mode luksFormat /tmp/test
# cryptsetup 2.1.0 processing "cryptsetup --debug --batch-mode luksFormat /tmp/test"
# Running command luksFormat.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating context for crypt device /tmp/test.
# Trying to open and read device /tmp/test with direct-io.
# Initialising device-mapper backend library.
# STDIN descriptor passphrase entry requested.
# Crypto backend (OpenSSL 1.1.1d  10 Sep 2019) initialized in cryptsetup library version 2.1.0.
# Detected kernel Linux 4.19.125-1.pvops.qubes.x86_64 x86_64.
# Only 2 active CPUs detected, PBKDF threads decreased from 4 to 2.
# Not enough physical memory detected, PBKDF max memory decreased from 1048576kB to 341210kB.
# PBKDF argon2i, hash sha256, time_ms 2000 (iterations 0), max_memory_kb 341210, parallel_threads 2.
# Formatting device /tmp/test as type LUKS2.
# Topology info for /tmp/test not supported, using default offset 1048576 bytes.
# Checking if cipher aes-xts-plain64 is usable.
# Using userspace crypto wrapper to access keyslot area.
# Formatting LUKS2 with JSON metadata area 12288 bytes and keyslots area 16744448 bytes.
# Creating new digest 0 (pbkdf2).
# Setting PBKDF2 type key digest 0.
# Running pbkdf2(sha256) benchmark.
# PBKDF benchmark: memory cost = 0, iterations = 840205, threads = 0 (took 39 ms)
# PBKDF benchmark: memory cost = 0, iterations = 852500, threads = 0 (took 615 ms)
# Benchmark returns pbkdf2(sha256) 852500 iterations, 0 memory, 0 threads (for 512-bits key).
# Segment 0 assigned to digest 0.
# Wiping LUKS areas (0x000000 - 0x1000000) with zeroes.
# Wiping keyslots area (0x008000 - 0x1000000) with random data.
# Device size 52428800, offset 16777216.
# Acquiring write lock for device /tmp/test.
# Verifying write lock handle for device /tmp/test.
# Device /tmp/test WRITE lock taken.
# Trying to write LUKS2 header (16384 bytes) at offset 0.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Checksum:d0ecc71988d93df516431a9babe6ba2e1d98bcb8163082f83f0eab25b97d9206 (in-memory)
# Trying to write LUKS2 header (16384 bytes) at offset 16384.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Checksum:3874184ad27bd0cdc48e1688c973a68d68fc6b3b380c03ee1b9c95ab10173329 (in-memory)
# Device /tmp/test WRITE lock released.
# Adding new keyslot -1 using volume key.
# Adding new keyslot -1 with volume key assigned to a crypt segment.
# Selected keyslot 0.
# Verifying key digest 0.
# Keyslot 0 assigned to digest 0.
# Trying to allocate LUKS2 keyslot 0.
# Found area 32768 -> 290816
# Running argon2i() benchmark.
# PBKDF benchmark: memory cost = 32, iterations = 4, threads = 2 (took 4 ms)
# PBKDF benchmark: memory cost = 512, iterations = 4, threads = 2 (took 1 ms)
# PBKDF benchmark: memory cost = 8192, iterations = 4, threads = 2 (took 21 ms)
# PBKDF benchmark: memory cost = 97523, iterations = 4, threads = 2 (took 204 ms)
# PBKDF benchmark: memory cost = 119513, iterations = 4, threads = 2 (took 269 ms)
# PBKDF benchmark: memory cost = 341210, iterations = 10, threads = 2 (took 2092 ms)
# Benchmark returns argon2i() 10 iterations, 341210 memory, 2 threads (for 512-bits key).
# Calculating attributes for LUKS2 keyslot 0.
# Updating keyslot area [0x8000].
# Acquiring write lock for device /tmp/test.
# Verifying write lock handle for device /tmp/test.
# Device /tmp/test WRITE lock taken.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Device /tmp/test WRITE lock released.
# Device size 52428800, offset 16777216.
# Acquiring write lock for device /tmp/test.
# Verifying write lock handle for device /tmp/test.
# Device /tmp/test WRITE lock taken.
# Trying to write LUKS2 header (16384 bytes) at offset 0.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Checksum:a280edc63729a53b1fffa92d6a8e3e73ad957ec6a3b3931206bab0f9435b3e6e (in-memory)
# Trying to write LUKS2 header (16384 bytes) at offset 16384.
# Opening locked device /tmp/test
# Veryfing locked device handle (regular file)
# Checksum:501335fa4afcef24700fbeabb4089ad9fc0fd53ae5fe6273a69210e6c037c148 (in-memory)
# Device /tmp/test WRITE lock released.
Key slot 0 created.
# Releasing crypt device /tmp/test context.
# Releasing device-mapper backend.
# Unlocking memory.
Command successful.

real	0m39.775s
user	0m9.513s
sys	0m32.816s
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: cryptsetup/cryptsetup#617