On systems with OpenSSL sha1 disabled, the sign-verify.test fails:
- openssl dgst -sha1 sha1.txt
- openssl dgst -sha1 -sign test-rsa1024.key -hex sha1.txt
Error setting context
804BD5CF787F0000:error:03000098:digital envelope routines:do_sigver_init:invalid digest:crypto/evp/m_sigver.c:343:
sha1 (test-rsa1024.key) test is skipped (openssl is unable to sign)
Instead of enabling sha1 support on these systems by setting the environment
variable OPENSSL_ENABLE_SHA1_SIGNATURES, generate a sha256 certificate.
Reported-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Tested-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
Add tests to ensure that, after applying the kernel patch 'ima: Align
ima_file_mmap() parameters with mmap_file LSM hook', the MMAP_CHECK hook
checks the protections applied by the kernel and not those requested by the
application.
Also ensure that after applying 'ima: Introduce MMAP_CHECK_REQPROT hook',
the MMAP_CHECK_REQPROT hook checks the protections requested by the
application.
Test both with the test_mmap application that by default requests the
PROT_READ protection flag. Its syntax is:
test_mmap <file> <mode>
where mode can be:
- exec: adds the PROT_EXEC protection flag to mmap()
- read_implies_exec: calls the personality() system call with
READ_IMPLIES_EXEC as the first argument before mmap()
- mprotect: adds the PROT_EXEC protection flag to a memory area in addition
to PROT_READ
- exec_on_writable: calls mmap() with PROT_EXEC on a file which has a
writable mapping
Check the different combinations of hooks/modes and ensure that a
measurement entry is found in the IMA measurement list only when it is
expected. No measurement entry should be found when only the PROT_READ
protection flag is requested or the matching policy rule has the
MMAP_CHECK_REQPROT hook and the personality() system call was called with
READ_IMPLIES_EXEC.
mprotect() with PROT_EXEC on an existing memory area protected with
PROT_READ should be denied (with an appraisal rule), regardless of the MMAP
hook specified in the policy. The same applies for mmap() with PROT_EXEC on
a file with a writable mapping.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Add ima_policy_check.awk to check for possible overlapping of a rule being
added by a test with the existing IMA policy (policy replacement by IMA at
the first policy load is not taken into account).
ima_policy_check.awk expects as input the rule to be added, followed by the
IMA policy.
It returns a bit mask with the following values:
- 1: invalid new rule;
- 2: overlap of the new rule with an existing rule in the IMA policy;
- 4: new rule exists in the IMA policy.
Values can be individually checked by the test executing the awk script, to
determine what to do (abort loading, print a warning in case of overlap,
avoid adding an existing rule).
The bit mask allows the test to see multiple statements regarding the new
rule. For example, if the test added anyway an overlapping rule, it could
also see that the policy already contains it at the next test execution,
and does not add it again.
Since ima_policy_check.awk uses GNU extensions (such as the or() function,
or the fourth argument of split()), add gawk as dependency for the CI.
Finally add ima_policy_check.test, to ensure that the awk script behaves as
expected.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Introduce these functions to let the developer specify which kernel patches
are required for the tests to be successful (either pass or fail). If a
test is not successful, print those patches in the test result summary.
First, the developer should declare an array, named PATCHES, with the list
of all kernel patches that are required by the tests. For example:
PATCHES=(
'patch 1 title'
...
'patch N title'
)
Second, the developer could replace the existing expect_pass() and
expect_fail() respectively with expect_pass_if() and expect_fail_if(), and
add the indexes in the PATCHES array as the first argument, enclosed with
quotes. The other parameters of expect_pass() and expect_fail() remain the
same.
In the following example, the PATCHES array has been added to a new test
script, tests/mmap_check.test:
PATCHES=(
'ima: Align ima_file_mmap() parameters with mmap_file LSM hook'
'ima: Introduce MMAP_CHECK_REQPROT hook'
)
Then, expect_pass() has been replaced with expect_pass_if():
expect_pass_if '0' check_mmap "MMAP_CHECK" "read_implies_exec"
The resulting output when a test fails (if the required patch is not
applied) is:
Test: check_mmap (hook="MMAP_CHECK", test_mmap arg: "read_implies_exec")
Result (expect found): not found
Possibly missing patches:
- ima: Align ima_file_mmap() parameters with mmap_file LSM hook
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Prior to the support for reading the TPM 2.0 PCRs via the sysfs
interface, based on environment variables the userspace application read
either the physical or software TPM's PCRs.
With the support for reading the exported TPM 2.0 PCRs via the sysfs
interface, the physical TPM's PCRs are always read. Define a new evmctl
option named '--hwtpm' to limit reading the TPM 2.0 PCRs via the sysfs
interface.
Fixes: a141bd594263 ("add support for reading per bank TPM 2.0 PCRs via sysfs")
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
At least on Tumbleweed build fails due openSSL 3.0.7
being installed from package.
Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Unlike the original ima-evm-utils ima_hash.test and sign_verify.test
selftests, kernel tests may fail for any number of reasons (e.g. kernel
config, permissions, missing applications, test infrastructure). For
these tests, the full test log is needed to analyze the failure.
Create a phony target in tests/Makefile.am named "check-logs". Based on
test name, output different amounts of the test log.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Instead of making changes to the system, use in-place built fsverity binary
by adding ../fsverity-utils to the PATH variable, so that the binary can be
found with the 'command -v' command.
Don't delete the fsverity-utils directory, so that the built binary is
available. Not deleting should not be a problem, as the script is meant to
be executed in a CI environment, where cleanup is done by the CI
infrastructure itself.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Adapt fsverity.test by adding calls to the testing environment API in
functions.sh. If TST_ENV is set, create a new environment and run the
kernel specified with the TST_KERNEL environment variable. Otherwise, keep
the current behavior.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Verify that operations on files with EVM portable signatures succeed and
that the new kernel patch set does not break the existing kernel integrity
expectations. Build and install mount-idmapped for ci/fedora.sh, to
additionally test idmapped mounts.
To run the tests, pass the path of the kernel private key with the
TST_KEY_PATH environment variable. If not provided, search first in the
ima-evm-utils top directory, and then in
/lib/modules/$(uname -r)/source/certs/signing_key.pem and
/lib/modules/$(uname -r)/build/certs/signing_key.pem.
Root privileges are required to mount the image, configure IMA/EVM and set
xattrs.
Set TST_ENV to 'um', to relaunch the script in a new environment after
booting an UML kernel. The UML kernel path must be specified with the
TST_KERNEL environment variable.
Alternatively, set the TST_EVM_CHANGE_MODE variable to 1, to change the
current EVM mode, if a test needs a different one. Otherwise, execute only
the tests compatible with the current EVM mode.
Also set the EVM_ALLOW_METADATA_WRITES flag in the EVM mode, before
launching the script, to run the check_evm_revalidate() test. Execute:
echo 4 > /sys/kernel/security/evm
The last two environment variables above affect which tests will run the
next time the script is executed. Without setting TST_ENV, changes to the
current EVM mode will be irreversibly done in the host. Next time, unless
the host is rebooted, only tests compatible with the last EVM mode set will
run. The others will be skipped.
By setting TST_ENV, this problem does not arise as, every time the
environment is created, it will be clean with no flags set in the EVM mode.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
It might be desirable, due to restrictions in the testing environment, to
execute tests individually. Introduce the TST_LIST variable, which can be
set with the name of the test to execute. If the variable is set,
expect_pass and expect_fail automatically skip the tests when the first
argument of those functions does not match the value of TST_LIST.
TST_LIST can be also used in new environments, to execute a subset of
defined tests for each environment. It is sufficient to add the variable
and its value to the kernel command line.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Add the new functions _run_env(), _exit_env(), _init_env() and
_cleanup_env() to run the tests inside a new environment specified with the
TST_ENV environment variable.
A typical structure of a script with tests is:
trap '_report_exit_and_cleanup _cleanup_env cleanup' \
SIGINT SIGTERM SIGSEGV EXIT
cleanup() {
<test cleanup>
}
<tests implementations>
_run_env "$TST_KERNEL" "$PWD/$(basename "$0")" "env_var1=$env_var1 ..."
_exit_env "$TST_KERNEL"
_init_env
<tests init>
<tests call>
If TST_ENV is not set or empty, don't create a new testing environment and
perform the cleanup in the current environment. Don't create a new testing
environment also if the script is already executed in a new environment, to
avoid loops. Instead, for cleanup, do it in the new environment and skip it
in the host environment (if the cleanup function is passed to
_cleanup_env()).
Signal to the creator of the environment failures of tests or of the script
itself run in the new environment (if the exit code is 1 ($FAIL) or 99
($HARDFAIL)) with an unclean shutdown of the system.
Add haveged and systemd as dependencies for the tests in ci/fedora.sh,
respectively for initializing the random number generator and for shutting
down the system in the new environment.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
If an error occurs before any test is executed, _report_exit_and_cleanup()
returns 77 ($SKIP) as exit code, which might not reflect the real exit code
at the time the script terminated its execution.
If the function registered in the shell trap() is a cleanup function
calling _report_exit_and_cleanup() inside, the latter will not have access
to the exit code at the time of the trap but instead to the exit code of
the cleanup function.
To solve this issue, pass the cleanup function and its arguments to
_report_exit_and_cleanup(), so that the latter can first get the script
exit code and then can execute the cleanup function.
Finally, if no test was executed, return the exit code at the time of the
trap() instead of 77.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This does not make fsverity.test working on GA CI, though.
- `--device /dev/loop-control' is required for losetup(8) to work.
- `--privileged' is required foo mount(8) to work, and this makes
`--security-opt seccomp=unconfined' redundant.
- GA container does not have `/sys/kernel/security' mounted which is
needed for `/sys/kernel/security/integrity/ima/policy'.
- Enable `set -x` in CI as the logs is everything we have to analyze on
failures.
Update: with these changes and the UML kernel support, the fsverity.test
is working properly.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
[zohar@linux.ibm.com: updated patch description]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Test IMA support for including fs-verity enabled file measurements
in the IMA measurement list based on the ima-ngv2 and ima-sigv2
records.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Fix COMPILE_SSL to build for the proper architecture, link with the
appropriate library, and set up library path for evmctl.
Compile OpenSSL with "no-engine" and "no-dynamic-engine" support.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Since the distros are now shipping with OpenSSL 3, no need
to build it. Limit the sm2/sm3 test to OpenSSL 3.
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
The original IMA file signatures were based on a SHA1 hash. Kernel
support for other hash algorithms was subsequently upstreamed. Deprecate
"--rsa" support.
Define "--enable-sigv1" option to configure signature v1 support.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Extend the sign_verify test with a pkcs11-specific test.
Since the openssl command line tool now needs to use a key provided by
an engine, extend some command lines with the additional parameters
'--keyform engine'. These parameters are passed using the global variable
OPENSSL_KEYFORM, which is only set when pkcs11 URIs are used.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Import softhsm_setup script from my swtpm project and contribute
it to this project under dual license BSD 3-clause and GPL 2.0.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Keep in sync with the kernel IMA, IMA signature tool supports SM2/3
algorithm combination. Because in the current version of OpenSSL 1.1.1,
the SM2 algorithm and the public key using the EC algorithm share the
same ID 'EVP_PKEY_EC', and the specific algorithm can only be
distinguished by the curve name used. This patch supports this feature.
Secondly, the openssl 1.1.1 tool does not fully support the signature
of SM2/3 algorithm combination, so the openssl3 tool is used in the
test case, and there is no this problem with directly calling the
openssl 1.1.1 API in evmctl.
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
[zohar@linux.ibm.com: "COMPILE_SSL: " -> "COMPILE_SSL=" in .travis.yml
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Allow to have certificate appended to the private key of `--key'
specified (PEM) file (for v2 signing) to facilitate reading of keyid
from the associated cert. This will allow users to have private and
public key as a single file and avoid the need of manually specifying
keyid. There is no check that public key form the cert matches
associated private key.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Allow user to specify `--keyid-from-cert cert.pem' to extract keyid from
SKID of the certificate file. PEM or DER format is auto-detected.
This commit creates ABI change for libimaevm, due to adding new function
ima_read_keyid(). Newer clients cannot work with older libimaevm.
Together with previous commit it creates backward-incompatible ABI
change, thus soname should be incremented on release.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Allow user to set signature's keyid using `--keyid' option. Keyid should
correspond to SKID in certificate, when keyid is calculated using SHA-1
in libimaevm it may mismatch keyid extracted by the kernel from SKID of
certificate (the way public key is presented to the kernel), thus making
signatures not verifiable. This may happen when certificate is using non
SHA-1 SKID (see rfc7093) or just 'unique number' (see rfc5280 4.2.1.2).
As a last resort user may specify arbitrary keyid using the new option.
This commit creates ABI change for libimaevm, because of adding
additional parameter to imaevm_params - newer libimaevm cannot work
with older clients.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Reported-by: Elvira Khabirova <lineprinter0@gmail.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Some distributions, such as ALT, cannot use sudo under root by default.
Error message will appear:
root is not in the sudoers file. This incident will be reported.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
to workaround running out of subuids/subgids when using podman:
tar: ./LICENSE: Cannot change ownership to uid 339315, gid 578953: Invalid argument
(run script under sudo would also work, but this does not require it)
Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Add test cases that test the signing and signature verification with the
elliptic curves prime192v1 and prime256v1, also known as NIST P192 and
P256. These curves will soon be supported by Linux. If OpenSSL cannot
generate prime192v1 keys, as is the case on Fedora, where this curve is
not supported, the respective tests will be skipped automatically.
The r and s integer components of the signature can have varying size.
Therefore we do the size checks for the entire signature with a regular
expression that accounts for the varying size. The most typical cases
are supported following hours of running the tests with varying keys.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Older distros, such as Ubuntu Xenial or Centos 7, fail to calculate the
keyid properly in the bash script. Adding 'tail -n1' into the pipe fixes
the issue since we otherwise have two numbers in 'id' due to two
'BIT STRING's.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This is required, because when TPM HW available (i.e. -c /dev/tpm0),
evmctl ima_boot_aggregate returns sha1:xxxx.
skip requires to move cleanup().
Signed-off-by: Petr Vorel <petr.vorel@gmail.com>
[zohar@linux.ibm.com: move test so it works with sample logs]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
The existing variable names swtpm and swtpm1 is confusing. Rename
"swtpm" to "tpm_server" and "swtpm1" as "swtpm".
Suggested-by: Ken Goldman <kgoldman@us.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
The software TPM might not be listening for commands yet. Try re-sending
the tssstartup.
Reported-by: Ken Goldman <kgoldman@us.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
The default value raw is appropriate for 'swtpm'. tpm_server
uses the Microsoft packet encapsulation, so the env variable
must have the value mssim.
Signed-off-by: Ken Goldman <kgoldman@us.ibm.com>
Fixes: f831508297cd ("Install the swtpm package, if available")
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
The "boot_aggregate.test" requires either a hardware or software TPM.
Support using the swtpm, if packaged for the distro, in addition to
tpm_server.
Note: Some travis/<distro>.sh scripts are links to other scripts.
Don't fail the build of the linked script if the swtpm package doesn't
exist.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Acked-by: Bruno Meneguele <bmeneg@redhat.com>
cmp is not by default installed on some containers
(unlike other tools e.g. cut, tr from coreutils or grep).
Also cmp implementation from busybox doesn't support -b, thus detect it.
Signed-off-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Bruno Meneguele <bmeneg@redhat.com>(Fedora,CentOS 8(RHEL actually))
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
tpm2-software is being packaged in major distros nowadays.
Signed-off-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Bruno Meneguele <bmeneg@redhat.com>(Fedora,CentOS 8(RHEL actually))
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Some distros in Travis CI (e.g. Debian and Ubuntu) have problems with
downloading from sourceforge.net due unknown certificate issuer:
--2020-08-11 14:47:51-- https://sourceforge.net/projects/ibmswtpm2/files/ibmtpm1332.tar.gz/download
Resolving sourceforge.net (sourceforge.net)... 216.105.38.13
Connecting to sourceforge.net (sourceforge.net)|216.105.38.13|:443... connected.
ERROR: The certificate of 'sourceforge.net' is not trusted.
ERROR: The certificate of 'sourceforge.net' doesn't have a known issuer.
This is a preparation for future commit (moving to docker based Travis CI).
Signed-off-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Bruno Meneguele <bmeneg@redhat.com>(Fedora,CentOS 8(RHEL actually))
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Running the "boot_aggregate" test without a physical TPM, requires
installing and initializing a software TPM. For now, use the same
method of initializing the TPM, based on the IBM tss, for both the
IBM and Intel's tss.
Build both the IBM and INTEL's tss.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Verifying the "boot_aggregate" requires reading the TPM PCRs for each of
the TPM banks. In test environments without a physical TPM, a software
TPM may be used, but requires initializing the TPM PCRs. By walking and
replaying the TPM event log, a software TPM may be properly initialized.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Verifying the "boot_aggregate" requires reading the TPM PCRs for each of
the TPM banks. In test environments without a physical TPM, a software
TPM may be used.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
boot_aggregate test make use of a software TPM 2.0 in case it doesn't find
any /dev/tpm0 in the system or if the test is ran as a normal user. However,
when the system has a discrete TPM 1.2 and the user runs the test with a
non-root user evmctl fails to return the software TPM 2.0 boot aggregate
value because it tries to access TPM 1.2 the sysfs PCRs file and,
consequently, the test fails. Thus TPM 2.0 log test is not supported on
systems with a discrete TPM 1.2
Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Searching for the last "boot_aggregate" record in the measurement list
could inadvertently match a filename containing the string
"boot_aggregate". Prevent this from happening.
Reviewed-by: Bruno Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
display_pcrs() should include PCRS 8 - 9 as they are non-zeros on some
systems. boot_aggregate may span PCRs 0 - 9 so check()'s info message
should be fixed accordingly.
Signed-off-by: Maurizio Drocco <maurizio.drocco@ibm.com>
Use the "functions.sh" tty color scheme, which defines SKIP as CYAN.
FAILURE: RED (31)
SUCCESS: GREEN (32)
SKIP: CYAN (36)
Should VERBOSE or informational messages be color coded?
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
For each kexec, an additional "boot_aggregate" will appear in the
measurement list, assuming the previous measurement list is carried
across kexec.
Verify that the last "boot_aggregate" record in the IMA measurement list
matches. The "boot_aggregate" is either the last field (e.g. "ima-ng")
or the second to last field (e.g. "ima-sig") in the measurement list
record.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>