From: Eric Biggers <[email protected]>

Make _require_scratch_encryption() and
_require_encryption_policy_support() support the new '-s' option to
set_encpolicy to specify a custom value of log2_data_unit_size.

Likewise, make _verify_ciphertext_for_encryption_policy() accept an
argument "log2_dusize=*" to cause it to use the specified data unit size
for the test and verify that the file contents are encrypted as expected
for that data unit size.

Signed-off-by: Eric Biggers <[email protected]>
---
 common/encrypt | 38 ++++++++++++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/common/encrypt b/common/encrypt
index 5688745c..d90a566a 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -1,32 +1,41 @@
 ##/bin/bash
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (c) 2016 Google, Inc.  All Rights Reserved.
 #
 # Functions for setting up and testing file encryption
 
 #
 # _require_scratch_encryption [-c CONTENTS_MODE] [-n FILENAMES_MODE]
 #                            [-f POLICY_FLAGS] [-v POLICY_VERSION]
+#                            [-s LOG2_DUSIZE]
 #
 # Require encryption support on the scratch device.
 #
 # This checks for support for the default type of encryption policy (v1 with
 # AES-256-XTS and AES-256-CTS).  Options can be specified to also require
 # support for a different type of encryption policy.
 #
 _require_scratch_encryption()
 {
-       _require_scratch
+       local arg
 
+       _require_scratch
        _require_xfs_io_command "set_encpolicy"
 
+       for arg; do
+               if [ "$arg" = "-s" ]; then
+                       # -s option was added later.  Make sure it's available.
+                       _require_xfs_io_command "set_encpolicy" "-s"
+               fi
+       done
+
        # The 'test_dummy_encryption' mount option interferes with trying to use
        # encryption for real, even if we are just trying to get/set policies
        # and never put any keys in the keyring.  So skip the real encryption
        # tests if the 'test_dummy_encryption' mount option was specified.
        _exclude_scratch_mount_option "test_dummy_encryption"
 
        # Make a filesystem on the scratch device with the encryption feature
        # enabled.  If this fails then probably the userspace tools (e.g.
        # e2fsprogs or f2fs-tools) are too old to understand encryption.
        if ! _scratch_mkfs_encrypted &>>$seqres.full; then
@@ -67,35 +76,35 @@ _require_scratch_encryption()
 _require_encryption_policy_support()
 {
        local mnt=$1
        local dir=$mnt/tmpdir
        local set_encpolicy_args=""
        local policy_flags=0
        local policy_version=1
        local c
 
        OPTIND=2
-       while getopts "c:n:f:v:" c; do
+       while getopts "c:n:f:s:v:" c; do
                case $c in
-               c|n)
+               c|n|s)
                        set_encpolicy_args+=" -$c $OPTARG"
                        ;;
                f)
                        set_encpolicy_args+=" -$c $OPTARG"
                        policy_flags=$OPTARG
                        ;;
                v)
                        set_encpolicy_args+=" -$c $OPTARG"
                        policy_version=$OPTARG
                        ;;
                *)
-                       _fail "Unrecognized option '$c'"
+                       _fail "${FUNCNAME[0]}: unrecognized option '$c'"
                        ;;
                esac
        done
        set_encpolicy_args=${set_encpolicy_args# }
 
        echo "Checking whether kernel supports encryption policy: 
$set_encpolicy_args" \
                >> $seqres.full
 
        if (( policy_flags & (FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 |
                              FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) )); then
@@ -756,28 +765,27 @@ _do_verify_ciphertext_for_encryption_policy()
 
        # Now unmount the filesystem and verify the ciphertext we just wrote.
        _scratch_unmount
 
        echo "Verifying encrypted file contents" >> $seqres.full
        for f in "${test_contents_files[@]}"; do
                read -r src inode blocklist <<< "$f"
                nonce=$(_get_encryption_nonce $SCRATCH_DEV $inode)
                _dump_ciphertext_blocks $SCRATCH_DEV $blocklist > 
$tmp.actual_contents
                $crypt_contents_cmd $contents_encryption_mode $raw_key_hex \
-                       --file-nonce=$nonce --data-unit-size=$blocksize \
-                       --inode-number=$inode < $src > $tmp.expected_contents
+                       --file-nonce=$nonce --inode-number=$inode \
+                        < $src > $tmp.expected_contents
                if ! cmp $tmp.expected_contents $tmp.actual_contents; then
                        _fail "Expected encrypted contents != actual encrypted 
contents.  File: $f"
                fi
                $crypt_contents_cmd $contents_encryption_mode $raw_key_hex \
-                       --decrypt --file-nonce=$nonce \
-                        --data-unit-size=$blocksize --inode-number=$inode \
+                       --decrypt --file-nonce=$nonce --inode-number=$inode \
                        < $tmp.actual_contents > $tmp.decrypted_contents
                if ! cmp $src $tmp.decrypted_contents; then
                        _fail "Contents decryption sanity check failed.  File: 
$f"
                fi
        done
 
        echo "Verifying encrypted file names" >> $seqres.full
        for f in "${test_filenames_files[@]}"; do
                read -r name inode dir_inode padding <<< "$f"
                nonce=$(_get_encryption_nonce $SCRATCH_DEV $dir_inode)
@@ -837,28 +845,30 @@ _fscrypt_mode_name_to_num()
 # policy of the specified type is used.
 #
 # The first two parameters are the contents and filenames encryption modes to
 # test.  The following optional parameters are also accepted to further modify
 # the type of encryption policy that is tested:
 #
 #      'v2':                   test a v2 encryption policy
 #      'direct':               test the DIRECT_KEY policy flag
 #      'iv_ino_lblk_64':       test the IV_INO_LBLK_64 policy flag
 #      'iv_ino_lblk_32':       test the IV_INO_LBLK_32 policy flag
+#      'log2_dusize=N':        test the log2_data_unit_size field
 #
 _verify_ciphertext_for_encryption_policy()
 {
        local contents_encryption_mode=$1
        local filenames_encryption_mode=$2
        local opt
        local policy_version=1
        local policy_flags=0
+       local log2_dusize=0
        local set_encpolicy_args=""
        local crypt_util_args=""
        local crypt_util_contents_args=""
        local crypt_util_filename_args=""
        local expected_identifier
 
        shift 2
        for opt; do
                case "$opt" in
                v2)
@@ -870,30 +880,36 @@ _verify_ciphertext_for_encryption_policy()
                                _fail "For direct key mode, contents and 
filenames modes must match"
                        fi
                        (( policy_flags |= FSCRYPT_POLICY_FLAG_DIRECT_KEY ))
                        ;;
                iv_ino_lblk_64)
                        (( policy_flags |= FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 ))
                        ;;
                iv_ino_lblk_32)
                        (( policy_flags |= FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 ))
                        ;;
+               log2_dusize=*)
+                       log2_dusize=$(echo "$opt" | sed 's/^log2_dusize=//')
+                       ;;
                *)
                        _fail "Unknown option '$opt' passed to ${FUNCNAME[0]}"
                        ;;
                esac
        done
        local contents_mode_num=$(_fscrypt_mode_name_to_num 
$contents_encryption_mode)
        local filenames_mode_num=$(_fscrypt_mode_name_to_num 
$filenames_encryption_mode)
 
        set_encpolicy_args+=" -c $contents_mode_num"
        set_encpolicy_args+=" -n $filenames_mode_num"
+       if (( log2_dusize != 0 )); then
+               set_encpolicy_args+=" -s $log2_dusize"
+       fi
        crypt_util_contents_args+=" --mode-num=$contents_mode_num"
        crypt_util_filename_args+=" --mode-num=$filenames_mode_num"
 
        if (( policy_version > 1 )); then
                set_encpolicy_args+=" -v 2"
                crypt_util_args+=" --kdf=HKDF-SHA512"
                if (( policy_flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY )); then
                        crypt_util_args+=" --direct-key"
                elif (( policy_flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 )); 
then
                        crypt_util_args+=" --iv-ino-lblk-64"
@@ -923,20 +939,26 @@ _verify_ciphertext_for_encryption_policy()
 
        echo "Creating encryption-capable filesystem" >> $seqres.full
        if (( policy_flags & (FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 |
                              FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) )); then
                _scratch_mkfs_stable_inodes_encrypted &>> $seqres.full
        else
                _scratch_mkfs_encrypted &>> $seqres.full
        fi
        _scratch_mount
 
+       if (( log2_dusize != 0 )); then
+               crypt_util_contents_args+=" --data-unit-size=$((1 << 
log2_dusize))"
+       else
+               crypt_util_contents_args+=" --data-unit-size=$(_get_block_size 
$SCRATCH_MNT)"
+       fi
+
        crypt_util_args+=" --fs-uuid=$(blkid -s UUID -o value $SCRATCH_DEV | tr 
-d -)"
 
        crypt_util_contents_args+="$crypt_util_args"
        crypt_util_filename_args+="$crypt_util_args"
 
        echo "Generating encryption key" >> $seqres.full
        local raw_key=$(_generate_raw_encryption_key)
        if (( policy_version > 1 )); then
                local keyspec=$(_add_enckey $SCRATCH_MNT "$raw_key" \
                                | awk '{print $NF}')
-- 
2.42.1


Reply via email to