#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright 2019 Google LLC # # FS QA Test generic/577 # # Test the fs-verity built-in signature verification support. # seq=`basename $0` seqres=$RESULT_DIR/$seq echo "QA output created by $seq" here=`pwd` tmp=/tmp/$$ status=1 # failure is the default! trap "_cleanup; exit \$status" 0 1 2 3 15 _cleanup() { cd / _restore_fsverity_signatures rm -f $tmp.* } # get standard environment, filters and checks . ./common/rc . ./common/filter . ./common/verity # remove previous $seqres.full before test rm -f $seqres.full # real QA test starts here _supported_fs generic _supported_os Linux _require_scratch_verity _require_fsverity_builtin_signatures _require_command "$OPENSSL_PROG" openssl _require_command "$KEYCTL_PROG" keyctl _scratch_mkfs_verity &>> $seqres.full _scratch_mount fsv_file=$SCRATCH_MNT/file.fsv fsv_orig_file=$SCRATCH_MNT/file keyfile=$tmp.key.pem certfile=$tmp.cert.pem certfileder=$tmp.cert.der sigfile=$tmp.sig otherfile=$SCRATCH_MNT/otherfile othersigfile=$tmp.othersig # Setup echo -e "\n# Generating certificates and private keys" for suffix in '' '.2'; do if ! $OPENSSL_PROG req -newkey rsa:4096 -nodes -batch -x509 \ -keyout $keyfile$suffix -out $certfile$suffix \ &>> $seqres.full; then _fail "Failed to generate certificate and private key (see $seqres.full)" fi $OPENSSL_PROG x509 -in $certfile$suffix -out $certfileder$suffix \ -outform der done echo -e "\n# Clearing fs-verity keyring" $KEYCTL_PROG clear %keyring:.fs-verity echo -e "\n# Loading first certificate into fs-verity keyring" $KEYCTL_PROG padd asymmetric '' %keyring:.fs-verity \ < $certfileder >> $seqres.full echo -e "\n# Enabling fs.verity.require_signatures" _enable_fsverity_signatures echo -e "\n# Generating file and signing it for fs-verity" head -c 100000 /dev/zero > $fsv_orig_file for suffix in '' '.2'; do _fsv_sign $fsv_orig_file $sigfile$suffix --key=$keyfile$suffix \ --cert=$certfile$suffix | _filter_scratch done echo -e "\n# Signing a different file for fs-verity" head -c 100000 /dev/zero | tr '\0' 'X' > $otherfile _fsv_sign $otherfile $othersigfile --key=$keyfile --cert=$certfile \ | _filter_scratch # Actual tests reset_fsv_file() { rm -f $fsv_file cp $fsv_orig_file $fsv_file } echo -e "\n# Enabling verity with valid signature (should succeed)" reset_fsv_file _fsv_enable $fsv_file --signature=$sigfile cmp $fsv_file $fsv_orig_file echo -e "\n# Enabling verity without signature (should fail)" reset_fsv_file _fsv_enable $fsv_file |& _filter_scratch echo -e "\n# Opening verity file without signature (should fail)" reset_fsv_file _disable_fsverity_signatures _fsv_enable $fsv_file _enable_fsverity_signatures _scratch_cycle_mount md5sum $fsv_file |& _filter_scratch echo -e "\n# Enabling verity with untrusted signature (should fail)" reset_fsv_file _fsv_enable $fsv_file --signature=$sigfile.2 |& _filter_scratch echo -e "\n# Enabling verity with wrong file's signature (should fail)" reset_fsv_file _fsv_enable $fsv_file --signature=$othersigfile |& _filter_scratch echo -e "\n# Enabling verity with malformed signature (should fail)" echo foobarbaz > $tmp.malformed_sig reset_fsv_file _fsv_enable $fsv_file --signature=$tmp.malformed_sig |& _filter_scratch echo -e "\n# Testing salt" reset_fsv_file _fsv_sign $fsv_orig_file $sigfile.salted --key=$keyfile --cert=$certfile \ --salt=abcd | _filter_scratch _fsv_enable $fsv_file --signature=$sigfile.salted --salt=abcd cmp $fsv_file $fsv_orig_file echo -e "\n# Testing non-default hash algorithm" if _fsv_have_hash_algorithm sha512 $fsv_file; then reset_fsv_file _fsv_sign $fsv_orig_file $sigfile.sha512 --key=$keyfile \ --cert=$certfile --hash-alg=sha512 > /dev/null _fsv_enable $fsv_file --signature=$sigfile.sha512 --hash-alg=sha512 cmp $fsv_file $fsv_orig_file fi echo -e "\n# Testing empty file" echo -n > $fsv_file _fsv_sign $fsv_file $sigfile.emptyfile --key=$keyfile --cert=$certfile | \ _filter_scratch _fsv_enable $fsv_file --signature=$sigfile.emptyfile # success, all done status=0 exit