mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-12 11:20:10 +01:00
Add crypt_wipe unit test.
It uses simple C wrapper aroung crypt_wipe() libcryptsetup and then bash test scripts wipung simple file and block device.
This commit is contained in:
@@ -22,6 +22,7 @@ TESTS = 00modules-test \
|
|||||||
bitlk-compat-test \
|
bitlk-compat-test \
|
||||||
run-all-symbols \
|
run-all-symbols \
|
||||||
unit-utils-crypt-test \
|
unit-utils-crypt-test \
|
||||||
|
unit-wipe-test \
|
||||||
reencryption-compat-test \
|
reencryption-compat-test \
|
||||||
luks2-reencryption-test \
|
luks2-reencryption-test \
|
||||||
luks2-reencryption-mangle-test
|
luks2-reencryption-mangle-test
|
||||||
@@ -129,6 +130,12 @@ unit_utils_crypt_test_LDFLAGS = $(AM_LDFLAGS) -static
|
|||||||
unit_utils_crypt_test_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib
|
unit_utils_crypt_test_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib
|
||||||
unit_utils_crypt_test_CPPFLAGS = $(AM_CPPFLAGS) -include config.h
|
unit_utils_crypt_test_CPPFLAGS = $(AM_CPPFLAGS) -include config.h
|
||||||
|
|
||||||
|
unit_wipe_SOURCES = unit-wipe.c
|
||||||
|
unit_wipe_LDADD = ../libcryptsetup.la
|
||||||
|
unit_wipe_LDFLAGS = $(AM_LDFLAGS) -static
|
||||||
|
unit_wipe_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib
|
||||||
|
unit_wipe_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
|
||||||
BUILT_SOURCES = test-symbols-list.h
|
BUILT_SOURCES = test-symbols-list.h
|
||||||
|
|
||||||
test-symbols-list.h: $(top_srcdir)/lib/libcryptsetup.sym generate-symbols-list
|
test-symbols-list.h: $(top_srcdir)/lib/libcryptsetup.sym generate-symbols-list
|
||||||
@@ -141,7 +148,7 @@ all_symbols_test_LDFLAGS = $(AM_LDFLAGS) -ldl
|
|||||||
all_symbols_test_CFLAGS = $(AM_CFLAGS)
|
all_symbols_test_CFLAGS = $(AM_CFLAGS)
|
||||||
all_symbols_test_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE
|
all_symbols_test_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE
|
||||||
|
|
||||||
check_PROGRAMS = api-test api-test-2 differ vectors-test unit-utils-io unit-utils-crypt-test all-symbols-test
|
check_PROGRAMS = api-test api-test-2 differ vectors-test unit-utils-io unit-utils-crypt-test unit-wipe all-symbols-test
|
||||||
|
|
||||||
check-programs: test-symbols-list.h $(check_PROGRAMS) fake_token_path.so
|
check-programs: test-symbols-list.h $(check_PROGRAMS) fake_token_path.so
|
||||||
|
|
||||||
|
|||||||
@@ -2041,6 +2041,25 @@ static void IntegrityTest(void)
|
|||||||
CRYPT_FREE(cd);
|
CRYPT_FREE(cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WipeTest(void)
|
||||||
|
{
|
||||||
|
OK_(crypt_init(&cd, NULL));
|
||||||
|
FAIL_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 4096, 0, 0, NULL, NULL), "No device");
|
||||||
|
FAIL_(crypt_wipe(cd, DEVICE_WRONG, CRYPT_WIPE_ZERO, 0, 4096, 0, 0, NULL, NULL), "Wrong device");
|
||||||
|
OK_(crypt_wipe(cd, DEVICE_1, CRYPT_WIPE_ZERO, 0, 4096, 0, 0, NULL, NULL));
|
||||||
|
OK_(crypt_wipe(cd, DEVICE_1, CRYPT_WIPE_RANDOM, 0, 4096, 0, 0, NULL, NULL));
|
||||||
|
OK_(crypt_wipe(cd, DEVICE_1, CRYPT_WIPE_RANDOM, 0, 4096, 0, CRYPT_WIPE_NO_DIRECT_IO, NULL, NULL));
|
||||||
|
CRYPT_FREE(cd);
|
||||||
|
|
||||||
|
OK_(crypt_init(&cd, DEVICE_1));
|
||||||
|
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 4096, 0, 0, NULL, NULL));
|
||||||
|
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_RANDOM, 0, 4096, TST_SECTOR_SIZE, 0, NULL, NULL));
|
||||||
|
FAIL_(crypt_wipe(cd, NULL, CRYPT_WIPE_RANDOM, 0, 4096, TST_SECTOR_SIZE-1, 0, NULL, NULL), "Sector size");
|
||||||
|
FAIL_(crypt_wipe(cd, NULL, CRYPT_WIPE_RANDOM, 0, 4096 - 1, 0, 0, NULL, NULL), "Length size not aligned");
|
||||||
|
FAIL_(crypt_wipe(cd, NULL, CRYPT_WIPE_RANDOM, 1, 4096, 0, 0, NULL, NULL), "Offset not aligned");
|
||||||
|
CRYPT_FREE(cd);
|
||||||
|
}
|
||||||
|
|
||||||
// Check that gcrypt is properly initialised in format
|
// Check that gcrypt is properly initialised in format
|
||||||
static void NonFIPSAlg(void)
|
static void NonFIPSAlg(void)
|
||||||
{
|
{
|
||||||
@@ -2134,6 +2153,7 @@ int main(int argc, char *argv[])
|
|||||||
RUN_(IntegrityTest, "Integrity API");
|
RUN_(IntegrityTest, "Integrity API");
|
||||||
RUN_(ResizeIntegrity, "Integrity raw resize");
|
RUN_(ResizeIntegrity, "Integrity raw resize");
|
||||||
RUN_(ResizeIntegrityWithKey, "Integrity raw resize with key");
|
RUN_(ResizeIntegrityWithKey, "Integrity raw resize with key");
|
||||||
|
RUN_(WipeTest, "Wipe device");
|
||||||
|
|
||||||
_cleanup();
|
_cleanup();
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
164
tests/unit-wipe-test
Executable file
164
tests/unit-wipe-test
Executable file
@@ -0,0 +1,164 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
WIPE_UNIT=./unit-wipe
|
||||||
|
FILE=./wipe_localfile
|
||||||
|
FILE_RAND=./wipe_random_localfile
|
||||||
|
MB_BYTES=$((1024*1024))
|
||||||
|
DEVSIZEMB=8
|
||||||
|
DEVSIZE=$((DEVSIZEMB*$MB_BYTES))
|
||||||
|
|
||||||
|
HASH_EMPTY=2daeb1f36095b44b318410b3f4e8b5d989dcc7bb023d1426c492dab0a3053e74
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
rm -f $FILE $FILE_RAND 2> /dev/null
|
||||||
|
sleep 1
|
||||||
|
rmmod scsi_debug >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail()
|
||||||
|
{
|
||||||
|
if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi
|
||||||
|
echo "FAILED backtrace:"
|
||||||
|
while caller $frame; do ((frame++)); done
|
||||||
|
cleanup
|
||||||
|
exit 100
|
||||||
|
}
|
||||||
|
|
||||||
|
function skip()
|
||||||
|
{
|
||||||
|
echo "TEST SKIPPED: $1"
|
||||||
|
cleanup
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_device()
|
||||||
|
{
|
||||||
|
rmmod scsi_debug >/dev/null 2>&1
|
||||||
|
if [ -d /sys/module/scsi_debug ] ; then
|
||||||
|
echo "Cannot use scsi_debug module (in use or compiled-in), test skipped."
|
||||||
|
exit 77
|
||||||
|
fi
|
||||||
|
modprobe scsi_debug dev_size_mb=$DEVSIZEMB num_tgts=1 delay=0 >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
echo "This kernel seems to not support proper scsi_debug module, test skipped."
|
||||||
|
exit 77
|
||||||
|
fi
|
||||||
|
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
|
||||||
|
DEV="/dev/$DEV"
|
||||||
|
[ -b $DEV ] || fail "Cannot find $DEV."
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_hash() # $1 dev, $2 hash
|
||||||
|
{
|
||||||
|
local HASH=$(sha256sum $1 | cut -d' ' -f 1)
|
||||||
|
[ $HASH == "$2" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
function init_hash_dd() # $1 dev, $dev orig
|
||||||
|
{
|
||||||
|
dd if=/dev/urandom of=$2 bs=1M count=$DEVSIZEMB conv=notrunc 2> /dev/null
|
||||||
|
dd if=$2 of=$1 bs=1M conv=notrunc 2> /dev/null
|
||||||
|
HASH_0=$(sha256sum $1 | cut -d' ' -f 1)
|
||||||
|
# second MB wiped
|
||||||
|
dd if=/dev/zero of=$1 bs=1M seek=1 count=1 conv=notrunc 2> /dev/null
|
||||||
|
HASH_1=$(sha256sum $1 | cut -d' ' -f 1)
|
||||||
|
# 4,5,6 MB wiped
|
||||||
|
dd if=/dev/zero of=$1 bs=1M seek=4 count=3 conv=notrunc 2> /dev/null
|
||||||
|
HASH_2=$(sha256sum $1 | cut -d' ' -f 1)
|
||||||
|
dd if=$2 of=$1 bs=1M conv=notrunc 2> /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_file()
|
||||||
|
{
|
||||||
|
dd if=/dev/zero of=$FILE bs=1M count=$DEVSIZEMB 2> /dev/null || fial
|
||||||
|
dd if=/dev/zero of=$FILE_RAND bs=1M count=$DEVSIZEMB 2> /dev/null || fail
|
||||||
|
check_hash $FILE $HASH_EMPTY || fail
|
||||||
|
check_hash $FILE_RAND $HASH_EMPTY || fail
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_wipe_full() # $1 dev, $2 block size, [$3 flags]
|
||||||
|
{
|
||||||
|
# wipe random and back to zero
|
||||||
|
$WIPE_UNIT $1 random 0 $DEVSIZE $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_EMPTY && fail "Failed random wipe"
|
||||||
|
$WIPE_UNIT $1 zero 0 $DEVSIZE $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_EMPTY || fail "Failed zero wipe"
|
||||||
|
}
|
||||||
|
|
||||||
|
# wipe MB blocks, with zero, random and special and back to original
|
||||||
|
function test_wipe_blocks() # $1 dev $2 block sizem [$3 flags]
|
||||||
|
{
|
||||||
|
init_hash_dd $1 $FILE_RAND
|
||||||
|
check_hash $1 $HASH_0 || fail
|
||||||
|
|
||||||
|
$WIPE_UNIT $1 zero $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_1 || fail
|
||||||
|
$WIPE_UNIT $1 random $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_1 && fail
|
||||||
|
$WIPE_UNIT $1 special $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_1 && fail
|
||||||
|
$WIPE_UNIT $1 zero $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_1 || fail
|
||||||
|
|
||||||
|
$WIPE_UNIT $1 zero $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_2 || fail
|
||||||
|
$WIPE_UNIT $1 random $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_2 && fail
|
||||||
|
$WIPE_UNIT $1 special $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_2 && fail
|
||||||
|
$WIPE_UNIT $1 zero $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail
|
||||||
|
check_hash $1 $HASH_2 || fail
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "$CRYPTSETUP_PATH" ] && skip "Cannot run this test with CRYPTSETUP_PATH set."
|
||||||
|
|
||||||
|
test -x $WIPE_UNIT || skip "Run \"make `basename $WIPE_UNIT`\" first"
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
add_file
|
||||||
|
|
||||||
|
echo -n "[1] Wipe full file "
|
||||||
|
for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do
|
||||||
|
echo -n [$bs/DIO]
|
||||||
|
test_wipe_full $FILE $bs
|
||||||
|
echo -n [$bs]
|
||||||
|
test_wipe_full $FILE $bs no-dio
|
||||||
|
done
|
||||||
|
echo "[OK]"
|
||||||
|
|
||||||
|
echo -n "[2] Wipe blocks in file "
|
||||||
|
for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do
|
||||||
|
echo -n [$bs/DIO]
|
||||||
|
test_wipe_blocks $FILE $bs
|
||||||
|
echo -n [$bs]
|
||||||
|
test_wipe_blocks $FILE $bs no-dio
|
||||||
|
done
|
||||||
|
echo "[OK]"
|
||||||
|
|
||||||
|
[ $(id -u) -eq 0 ] || {
|
||||||
|
echo "WARNING: You must be root to run remaining tests."
|
||||||
|
cleanup
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
add_device
|
||||||
|
|
||||||
|
echo -n "[3] Wipe full block device "
|
||||||
|
for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do
|
||||||
|
echo -n [$bs/DIO]
|
||||||
|
test_wipe_full $DEV $bs
|
||||||
|
echo -n [$bs]
|
||||||
|
test_wipe_full $DEV $bs no-dio
|
||||||
|
done
|
||||||
|
echo "[OK]"
|
||||||
|
|
||||||
|
echo -n "[4] Wipe blocks in block device "
|
||||||
|
for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do
|
||||||
|
echo -n [$bs/DIO]
|
||||||
|
test_wipe_blocks $DEV $bs
|
||||||
|
echo -n [$bs]
|
||||||
|
test_wipe_blocks $DEV $bs no-dio
|
||||||
|
done
|
||||||
|
echo "[OK]"
|
||||||
|
|
||||||
|
cleanup
|
||||||
131
tests/unit-wipe.c
Normal file
131
tests/unit-wipe.c
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* unit test helper for crypt_wipe API call
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Milan Broz
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "libcryptsetup.h"
|
||||||
|
|
||||||
|
const char *test_file;
|
||||||
|
uint64_t test_offset, test_length, test_block;
|
||||||
|
uint32_t flags;
|
||||||
|
crypt_wipe_pattern pattern;
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Use:\tunit-wipe file/device zero|random|special offset length bsize [no-dio].\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse_u64(const char *arg, uint64_t *u64)
|
||||||
|
{
|
||||||
|
unsigned long long ull;
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
ull = strtoull(arg, &end, 10);
|
||||||
|
if (*end || !*arg || errno == ERANGE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ull % 512)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*u64 = ull;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse_input_params(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (argc < 6 || argc > 7) {
|
||||||
|
usage();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(argv[1], &st)) {
|
||||||
|
fprintf(stderr, "File/device %s is missing?\n", argv[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
test_file = argv[1];
|
||||||
|
|
||||||
|
if (!strcmp(argv[2], "random"))
|
||||||
|
pattern = CRYPT_WIPE_RANDOM;
|
||||||
|
else if (!strcmp(argv[2], "zero"))
|
||||||
|
pattern = CRYPT_WIPE_ZERO;
|
||||||
|
else if (!strcmp(argv[2], "special"))
|
||||||
|
pattern = CRYPT_WIPE_SPECIAL;
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Wrong pattern specification.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_u64(argv[3], &test_offset)) {
|
||||||
|
fprintf(stderr, "Wrong offset specification.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_u64(argv[4], &test_length)) {
|
||||||
|
fprintf(stderr, "Wrong length specification.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_u64(argv[5], &test_block)) {
|
||||||
|
fprintf(stderr, "Wrong block length specification.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 6) {
|
||||||
|
if (!strcmp(argv[6], "no-dio"))
|
||||||
|
flags = CRYPT_WIPE_NO_DIRECT_IO;
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Wrong flags specification.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct crypt_device *cd;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!parse_input_params(argc, argv))
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
r = crypt_init(&cd, NULL);
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "Context init failure %i.\n", r);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = crypt_wipe(cd, test_file, pattern, test_offset, test_length,
|
||||||
|
test_block, flags, NULL, NULL);
|
||||||
|
crypt_free(cd);
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
fprintf(stderr, "Failure %i\n", r);
|
||||||
|
|
||||||
|
return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user