Support empty salt for verity, support no superblock.
authorMilan Broz <gmazyland@gmail.com>
Sat, 9 Jun 2012 11:12:04 +0000 (13:12 +0200)
committerMilan Broz <gmazyland@gmail.com>
Sat, 9 Jun 2012 11:12:04 +0000 (13:12 +0200)
lib/libdevmapper.c
lib/setup.c
lib/verity/verity.c
src/veritysetup.c
tests/verity-compat-test

index e7d4a07..c82c0f5 100644 (file)
@@ -334,10 +334,13 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
                goto out;
        hex_key(hexroot, dmd->u.verity.root_hash_size, dmd->u.verity.root_hash);
 
-       hexsalt = crypt_safe_alloc(vp->salt_size * 2 + 1);
+       hexsalt = crypt_safe_alloc(vp->salt_size ? vp->salt_size * 2 + 1 : 2);
        if (!hexsalt)
                goto out;
-       hex_key(hexsalt, vp->salt_size, vp->salt);
+       if (vp->salt_size)
+               hex_key(hexsalt, vp->salt_size, vp->salt);
+       else
+               strncpy(hexsalt, "-", 2);
 
        max_size = strlen(hexroot) + strlen(hexsalt) +
                   strlen(dmd->data_device) +
index 32b39e0..87afb6f 100644 (file)
@@ -654,6 +654,9 @@ static int _crypt_load_verity(struct crypt_device *cd, struct crypt_params_verit
        if (r < 0)
                return r;
 
+       if (params->flags & CRYPT_VERITY_NO_HEADER)
+               return -EINVAL;
+
        if (params)
                sb_offset = params->hash_area_offset;
 
@@ -1076,11 +1079,12 @@ static int _crypt_format_verity(struct crypt_device *cd,
        if (r)
                goto out;
 
-       log_dbg("Creating verity hash on device %s.", mdata_device(cd));
-       r = VERITY_create(cd, &cd->verity_hdr, cd->device, mdata_device(cd),
-                         cd->verity_root_hash, cd->verity_root_hash_size);
-       if (r)
-               goto out;
+       if (params->flags & CRYPT_VERITY_CREATE_HASH) {
+               r = VERITY_create(cd, &cd->verity_hdr, cd->device, mdata_device(cd),
+                                 cd->verity_root_hash, cd->verity_root_hash_size);
+               if (r)
+                       goto out;
+       }
 
        if (!(params->flags & CRYPT_VERITY_NO_HEADER))
                r = VERITY_write_sb(cd, mdata_device(cd),
index afe261e..3991a81 100644 (file)
@@ -61,7 +61,7 @@ int VERITY_read_sb(struct crypt_device *cd,
                sizeof(struct verity_sb), device, sb_offset);
 
        if (params->flags & CRYPT_VERITY_NO_HEADER) {
-               log_err(cd, _("Verity don't use on-disk header.\n"), device);
+               log_err(cd, _("Verity device doesn't use on-disk header.\n"), device);
                return -EINVAL;
        }
 
@@ -130,7 +130,7 @@ int VERITY_write_sb(struct crypt_device *cd,
                sizeof(struct verity_sb), device, sb_offset);
 
        if (params->flags & CRYPT_VERITY_NO_HEADER) {
-               log_err(cd, _("Verity don't use on-disk header.\n"), device);
+               log_err(cd, _("Verity device doesn't use on-disk header.\n"), device);
                return -EINVAL;
        }
 
index bf0bbc1..e672537 100644 (file)
  */
 
 /* TODO:
- * - support device without superblock
  * - extend superblock (UUID)
  * - add api tests
- * - salt string "-"
  * - report in-kernel status outside libcryptsetup (extend api)
  */
 
@@ -118,37 +116,52 @@ static void _log(int level, const char *msg, void *usrptr __attribute__((unused)
        }
 }
 
+static int _prepare_format(struct crypt_params_verity *params,
+                          const char *data_device,
+                          uint32_t flags)
+{
+       static char salt_bytes[512];
+
+       params->hash_name = hash_algorithm ?: DEFAULT_VERITY_HASH;
+       params->data_device = data_device;
+
+       if (salt_string && !strcmp(salt_string, "-")) {
+               params->salt_size = 0;
+               params->salt = NULL;
+       } else if (salt_string) {
+               params->salt_size = strlen(salt_string) / 2;
+               if (hex_to_bytes(salt_string, salt_bytes) != params->salt_size)
+                       return -EINVAL;
+               params->salt = salt_bytes;
+       } else
+               params->salt_size = DEFAULT_VERITY_SALT_SIZE;
+
+       params->data_block_size = data_block_size;
+       params->hash_block_size = hash_block_size;
+       params->data_size = data_blocks;
+       params->hash_area_offset = hash_start;
+       params->version = version;
+       params->flags = flags;
+
+       return 0;
+}
+
 static int action_format(int arg)
 {
        struct crypt_device *cd = NULL;
        struct crypt_params_verity params = {};
-       char salt_bytes[512];
+       uint32_t flags = CRYPT_VERITY_CREATE_HASH;
        int r;
 
        if ((r = crypt_init(&cd, action_argv[1])))
                goto out;
 
-       params.hash_name = hash_algorithm ?: DEFAULT_VERITY_HASH;
-       params.data_device = action_argv[0];
-
-       if (salt_string) {
-               params.salt_size = strlen(salt_string) / 2;
-               if (hex_to_bytes(salt_string, salt_bytes) != params.salt_size) {
-                       r = -EINVAL;
-                       goto out;
-               }
-               params.salt = salt_bytes;
-       } else
-               params.salt_size = DEFAULT_VERITY_SALT_SIZE;
-
-       params.data_block_size = data_block_size;
-       params.hash_block_size = hash_block_size;
-       params.data_size = data_blocks;
-       params.hash_area_offset = hash_start;
-       params.version = version;
-       params.flags = CRYPT_VERITY_CREATE_HASH;
        if (!use_superblock)
-               params.flags |= CRYPT_VERITY_NO_HEADER;
+               flags |= CRYPT_VERITY_NO_HEADER;
+
+       r = _prepare_format(&params, action_argv[0], flags);
+       if (r < 0)
+               goto out;
 
        r = crypt_format(cd, CRYPT_VERITY, NULL, NULL, NULL, NULL, 0, &params);
        if (!r)
@@ -173,25 +186,15 @@ static int _activate(const char *dm_device,
        if ((r = crypt_init(&cd, hash_device)))
                goto out;
 
-       params.flags |= flags;
-
        if (use_superblock) {
+               params.flags = flags;
                params.hash_area_offset = hash_start;
                r = crypt_load(cd, CRYPT_VERITY, &params);
-       } else {/*
-               params.hash_name = hash_algorithm;
-               params.salt = salt_bytes;
-               params.salt_size = salt_size;
-               params.data_block_size = data_block_size;
-               params.hash_block_size = hash_block_size;
-
-               params.data_size = data_blocks * data_block_size / 512;
-               params.version = version;
-               params.flags |= CRYPT_VERITY_NO_HEADER;
-               r = crypt_load(cd, CRYPT_VERITY, &params);
-               crypt_format(); */
-               r = -EINVAL;
-               goto out;
+       } else {
+               r = _prepare_format(&params, data_device, flags | CRYPT_VERITY_NO_HEADER);
+               if (r < 0)
+                       goto out;
+               r = crypt_format(cd, CRYPT_VERITY, NULL, NULL, NULL, NULL, 0, &params);
        }
        if (r < 0)
                goto out;
index ce71b3c..b8156d7 100755 (executable)
@@ -78,22 +78,28 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
                DEV_PARAMS="$LOOPDEV1 $LOOPDEV2"
        fi
 
+       for sb in yes no; do
+       FORMAT_PARAMS="--format=$4 --data-block-size=$1 --hash-block-size=$1 --hash=$5 --salt=$3"
+       if [ $sb == yes ] ; then
+               VERIFY_PARAMS=""
+       else
+               FORMAT_PAFAMS="$FORMAT_PARAMS --no-superlock"
+               VERIFY_PARAMS=$FORMAT_PARAMS
+       fi
+
        for fail in data hash; do
        wipe
-       echo -n "V$4 $5 block size $1: "
-       $VERITYSETUP format $DEV_PARAMS --format=$4 \
-               --data-block-size=$1 --hash-block-size=$1 \
-               --hash=$5 --salt=$3 \
-               >$DEV_OUT || fail
+       echo -n "V$4(sb=$sb) $5 block size $1: "
+       $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >$DEV_OUT || fail
 
        echo -n "[root hash]"
        compare_out "root hash" $2
-       compare_out "alt" "$3"
+       compare_out "salt" "$3"
 
-       $VERITYSETUP verify $DEV_PARAMS $2 >>$DEV_OUT 2>&1 || fail
+       $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 || fail
        echo -n "[verify]"
 
-       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $2  >>$DEV_OUT 2>&1 || fail
+       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $2  >>$DEV_OUT 2>&1 || fail
        check_exists
        echo -n "[activate]"
 
@@ -118,9 +124,9 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
                ;;
        esac
 
-       $VERITYSETUP verify $DEV_PARAMS $2 >>$DEV_OUT 2>&1 && \
+       $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 && \
                fail "userspace check for $TXT corruption"
-       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $2 >>$DEV_OUT 2>&1 || \
+       $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 || \
                fail "activation"
        dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=$1 2>/dev/null
        dmsetup status $DEV_NAME | grep "verity V" >/dev/null && \
@@ -128,6 +134,7 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6
        $VERITYSETUP remove $DEV_NAME || fail "deactivation"
        echo "[$TXT corruption]"
        done
+       done
 }
 
 function valgrind_setup()
@@ -158,6 +165,8 @@ check_root_hash 1024 54d92778750495d1f80832b486ebd007617d746271511bbf0e295e143da
 check_root_hash 4096 e522df0f97da4febb882ac40f30b37dc0b444bf6df418929463fa25280f09d5c $SALT 1 sha256
 # version 0
 check_root_hash 4096 cbbf4ebd004ef65e29b935bb635a39cf754d677f3fa10b0126da725bbdf10f7d $SALT 0 sha256
+# no salt
+check_root_hash 4096 ef29c902d87350f1da4bfa536e16cebc162a909bf89abe448b81ec500d4fb9bf - 1 sha256
 # sha1
 check_root_hash 1024 d0e9163ca8844aaa2e88fe5265a8c5d9ee494a99 $SALT 1 sha1
 check_root_hash 1024 73509e8e868be6b8ac939817a98a3d35121413b2 dadada 1 sha1
@@ -169,6 +178,8 @@ check_root_hash 1024 54d92778750495d1f80832b486ebd007617d746271511bbf0e295e143da
 check_root_hash 4096 e522df0f97da4febb882ac40f30b37dc0b444bf6df418929463fa25280f09d5c $SALT 1 sha256 16384
 # version 0
 check_root_hash 4096 cbbf4ebd004ef65e29b935bb635a39cf754d677f3fa10b0126da725bbdf10f7d $SALT 0 sha256 16384
+# no salt
+check_root_hash 4096 ef29c902d87350f1da4bfa536e16cebc162a909bf89abe448b81ec500d4fb9bf - 1 sha256 16384
 # sha1
 check_root_hash 1024 d0e9163ca8844aaa2e88fe5265a8c5d9ee494a99 $SALT 1 sha1 16384
 check_root_hash 1024 73509e8e868be6b8ac939817a98a3d35121413b2 dadada 1 sha1 16384