From bb8e0853786f0430cbe28b6c9909b42d251c7bb3 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Tue, 26 Oct 2010 14:34:47 +0000 Subject: [PATCH] Add utils_crypt file and test for supported modes presentation. git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@348 36d66b0a-2a48-0410-832c-cd162a569da5 --- lib/Makefile.am | 2 + lib/internal.h | 5 +-- lib/setup.c | 27 +----------- lib/utils_crypt.c | 42 ++++++++++++++++++ lib/utils_crypt.h | 9 ++++ src/Makefile.am | 1 + src/cryptsetup.c | 8 ++-- src/cryptsetup.h | 3 +- tests/Makefile.am | 2 +- tests/mode-test | 110 ++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 172 insertions(+), 37 deletions(-) create mode 100644 lib/utils_crypt.c create mode 100644 lib/utils_crypt.h create mode 100755 tests/mode-test diff --git a/lib/Makefile.am b/lib/Makefile.am index be97c0b2..c9503772 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -38,6 +38,8 @@ libcryptsetup_la_SOURCES = \ blockdev.h \ libcryptsetup.h \ utils.c \ + utils_crypt.c \ + utils_crypt.h \ utils_debug.c \ backends.c \ libdevmapper.c \ diff --git a/lib/internal.h b/lib/internal.h index 8e445f69..a06d558d 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -11,6 +11,7 @@ #include #include "nls.h" +#include "utils_crypt.h" #define SECTOR_SHIFT 9 #define SECTOR_SIZE (1 << SECTOR_SHIFT) @@ -73,8 +74,6 @@ int hash(const char *backend_name, const char *hash_name, char *result, size_t size, const char *passphrase, size_t sizep); -void hexprint(char *d, int n); - /* Device mapper backend */ const char *dm_get_dir(void); int dm_init(struct crypt_device *context, int check_kernel); @@ -114,8 +113,6 @@ void get_key(char *prompt, char **key, unsigned int *passLen, int key_size, const char *key_file, int timeout, int how2verify, struct crypt_device *cd); -int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode); - void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...); #define log_dbg(x...) logger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x) #define log_std(c, x...) logger(c, CRYPT_LOG_NORMAL, __FILE__, __LINE__, x) diff --git a/lib/setup.c b/lib/setup.c index 444f4ecf..6da952f8 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -126,31 +126,6 @@ static char *process_key(struct crypt_device *cd, const char *hash_name, return key; } -int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode) -{ -/* Token content stringification, see info cpp/stringification */ -#define str(s) #s -#define xstr(s) str(s) -#define scanpattern1 "%" xstr(LUKS_CIPHERNAME_L) "[^-]-%" xstr(LUKS_CIPHERMODE_L) "s" -#define scanpattern2 "%" xstr(LUKS_CIPHERNAME_L) "[^-]" - - int r; - - if(sscanf(nameAndMode,scanpattern1, name, mode) != 2) { - if((r = sscanf(nameAndMode,scanpattern2,name)) == 1) - strncpy(mode,"cbc-plain",10); - else - return -EINVAL; - } - - return 0; - -#undef scanpattern1 -#undef scanpattern2 -#undef str -#undef xstr -} - static int isPLAIN(const char *type) { return (type && !strcmp(CRYPT_PLAIN, type)); @@ -751,7 +726,7 @@ int crypt_luksFormat(struct crypt_options *options) }; int r; - r = parse_into_name_and_mode(options->cipher, cipherName, cipherMode); + r = crypt_parse_name_and_mode(options->cipher, cipherName, cipherMode); if(r < 0) { log_err(cd, _("No known cipher specification pattern detected.\n")); return r; diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c new file mode 100644 index 00000000..0c47fa21 --- /dev/null +++ b/lib/utils_crypt.c @@ -0,0 +1,42 @@ +#include +#include +#include + +#include "internal.h" + +int crypt_parse_name_and_mode(const char *s, char *cipher, char *cipher_mode) +{ + if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s", + cipher, cipher_mode) == 2) { + return 0; + } + + if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]", cipher) == 1) { + strncpy(cipher_mode, "cbc-plain", 9); + return 0; + } + + return -EINVAL; +} + +#if 0 +/* Token content stringification, see info cpp/stringification */ +#define str(s) #s +#define xstr(s) str(s) +#define scanpattern1 "%" xstr(MAX_CIPHER_LEN) "[^-]-%" xstr(MAX_CIPHER_LEN) "s" +#define scanpattern2 "%" xstr(MAX_CIPHER_LEN) "[^-]" + + if(sscanf(nameAndMode,scanpattern1, name, mode) != 2) { + if((r = sscanf(nameAndMode,scanpattern2,name)) == 1) + strncpy(mode,"cbc-plain",10); + else + return -EINVAL; + } + + return 0; + +#undef scanpattern1 +#undef scanpattern2 +#undef str +#undef xstr +#endif diff --git a/lib/utils_crypt.h b/lib/utils_crypt.h new file mode 100644 index 00000000..10ed36e6 --- /dev/null +++ b/lib/utils_crypt.h @@ -0,0 +1,9 @@ +#ifndef _UTILS_CRYPT_H +#define _UTILS_CRYPT_H + +#define MAX_CIPHER_LEN 32 +#define MAX_CIPHER_LEN_STR "32" + +int crypt_parse_name_and_mode(const char *s, char *cipher, char *cipher_mode); + +#endif /* _UTILS_CRYPT_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 2e61b8dc..29eb840f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,6 +10,7 @@ INCLUDES = \ -D_GNU_SOURCE cryptsetup_SOURCES = \ + $(top_builddir)/lib/utils_crypt.c \ cryptsetup.c \ cryptsetup.h diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 2b48e418..16e0b82d 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -348,11 +348,11 @@ static int _action_luksFormat_useMK() .data_alignment = opt_align_payload, }; - if (sscanf(opt_cipher ?: DEFAULT_CIPHER(LUKS1), - "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s", - cipher, cipher_mode) != 2) { + r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1), + cipher, cipher_mode); + if (r < 0) { log_err("No known cipher specification pattern detected.\n"); - return -EINVAL; + return r; } keysize = (opt_key_size ?: DEFAULT_LUKS1_KEYBITS) / 8; diff --git a/src/cryptsetup.h b/src/cryptsetup.h index 6b4ec0b9..56e17c38 100644 --- a/src/cryptsetup.h +++ b/src/cryptsetup.h @@ -6,9 +6,8 @@ #endif #include "lib/nls.h" +#include "lib/utils_crypt.h" -#define MAX_CIPHER_LEN 32 -#define MAX_CIPHER_LEN_STR "32" #define DEFAULT_CIPHER(type) (DEFAULT_##type##_CIPHER "-" DEFAULT_##type##_MODE) #define log_dbg(x...) clogger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x) diff --git a/tests/Makefile.am b/tests/Makefile.am index da9ee2ea..98df3698 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -TESTS = api-test compat-test align-test +TESTS = api-test compat-test align-test mode-test EXTRA_DIST = compatimage.img.bz2 align-test compat-test diff --git a/tests/mode-test b/tests/mode-test new file mode 100755 index 00000000..e65be1d8 --- /dev/null +++ b/tests/mode-test @@ -0,0 +1,110 @@ +#!/bin/bash + +# +# Test mode compatibility, check input + kernel and cryptsetup cipher status +# +# FIXME: add checkum test of data +# + +CRYPTSETUP="../src/cryptsetup.static" +DEV_NAME=dmc_test +LOOPDEV=/dev/loop5 +HEADER_IMG=mode-test.img +PASSWORD=3xrododenron + +# cipher-chainmode-ivopts:ivmode +CIPHERS="aes twofish serpent" +MODES="cbc lrw xts" +IVMODES="null benbi plain plain64 essiv:sha256" + +cleanup() { + for dev in $(dmsetup status --target crypt | sed s/\:\ .*// | grep "^$DEV_NAME"_); do + dmsetup remove $dev + done + udevadm settle 2>/dev/null 2>&1 + sleep 2 + [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME + losetup -d $LOOPDEV >/dev/null 2>&1 + rm -f $HEADER_IMG >/dev/null 2>&1 +} + +fail() +{ + [ -n "$1" ] && echo "$1" + cleanup + exit 100 +} + +add_device() { + dd if=/dev/zero of=$HEADER_IMG bs=1M count=6 >/dev/null 2>&1 + sync + losetup $LOOPDEV $HEADER_IMG >/dev/null 2>&1 + dmsetup create $DEV_NAME --table "0 10240 linear $LOOPDEV 8" >/dev/null 2>&1 +} + +dmcrypt_check() # device outstring +{ + X=$(dmsetup table $1 2>/dev/null | cut -d' ' -f 4) + if [ $X = $2 ] ; then + echo -n "OK]" + else + echo -n "FAIL]" + echo " Expecting $2 got $X." + fail + fi + + X=$($CRYPTSETUP status $1 | grep cipher | sed s/\.\*cipher:\\s*//) + if [ $X = $2 ] ; then + echo " [OK]" + else + echo " [FAIL]" + echo " Expecting $2 got $X." + fail + fi +} + +dmcrypt() +{ + OUT=$2 + [ -z "$OUT" ] && OUT=$1 + + echo -n -e "TESTING(PLAIN): $1 [" + echo $PASSWORD | $CRYPTSETUP create -c $1 -s 256 "$DEV_NAME"_"$1" /dev/mapper/$DEV_NAME >/dev/null 2>&1 + if [ $? -eq 0 ] ; then + dmcrypt_check "$DEV_NAME"_"$1" $OUT + dmsetup remove "$DEV_NAME"_"$1" >/dev/null 2>&1 + else + echo "SKIPPED]" + fi + + echo -n -e "TESTING(LUKS): $1 [" + echo $PASSWORD | $CRYPTSETUP luksFormat -i 1 -c $1 -s 256 /dev/mapper/$DEV_NAME >/dev/null 2>&1 + if [ $? -eq 0 ] ; then + echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_"$1" >/dev/null 2>&1 + dmcrypt_check "$DEV_NAME"_"$1" $OUT + dmsetup remove "$DEV_NAME"_"$1" >/dev/null 2>&1 + else + echo "SKIPPED]" + fi +} + +add_device + +# compatibility modes +dmcrypt aes aes-cbc-plain +dmcrypt aes-plain aes-cbc-plain + +# codebook doesn't support IV at all +for cipher in $CIPHERS ; do + dmcrypt "$cipher-ecb" +done + +for cipher in $CIPHERS ; do + for mode in $MODES ; do + for ivmode in $IVMODES ; do + dmcrypt "$cipher-$mode-$ivmode" + done + done +done + +cleanup