1
0
mirror of https://git.code.sf.net/p/linux-ima/ima-evm-utils synced 2025-07-02 05:33:15 +02:00

361 Commits
v0.1.1 ... v1.4

Author SHA1 Message Date
318a3e6b2d Release version 1.4
Updated both the release and library (ABI change) versions.  See the
NEWS file for a short summary and the git history for details.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-11-03 14:07:21 -04:00
f9b805fabc travis: use alt:sisyphus from docker.io
Instead of returning an image, it prompts for a response.  Hardcode
to use docker.io.

 Please select an image:
  ▸ docker.io/library/alt:sisyphus
    quay.io/alt:sisyphus

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-11-03 14:07:21 -04:00
1a9472a09c travis: Fix fedora:latest, alpine:latest, and alt:sisyphus
As expected, for the same reasons as commit 6287cb76d1 ("travis: Fix
openSUSE Tumbleweed"), replace using docker with podman, but now use
crun.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-11-01 14:23:38 -04:00
4dab8558fc ci: upgrade to glibc-2.34 uses clone3 causing CI to fail
Both opensuse/tumbleweed and Alt Linux have upgraded to glibc-2.34,
causing the CI testing to fail.  Disable seccomp (which is not needed
anyway, since GA uses throwable virtual environments anyway).

options: --security-opt seccomp=unconfined

Suggested-by: Vitaly Chikunov <vt@altlinux.org>
Acked-by: Petr Vorel <petr.vorel@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-10-28 16:07:43 -04:00
9171c1ce43 travis: switch to using crun for podman
Fix for:

"container_linux.go:367: starting container process caused: error
adding seccomp filter rule for syscall bdflush: permission denied":
OCI permission denied"

Reviewed-by: Petr Vorel <petr.vorel@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-10-28 16:07:23 -04:00
ba366f0b41 Merge branch 'default-hash-algo' into next
Due to SHA1 weaknesses, define a configuration option to set the default
hash algorithm. The set of permitted hash algorithms is defined in the
hash_info.h header file.  At the same time, change the default hash
algorithm from SHA1 to SHA256.
2021-09-14 08:57:24 -04:00
3328f6efed make SHA-256 the default hash algorithm
The SHA-1 algorithm is considered a weak hash algorithm and there has been
some movement within certain distros to drop its support completely or at
least drop it from the default behavior. ima-evm-utils uses it as the
default algorithm in case the user doesn't explicitly ask for another
through the --with-default-hash configuration time option or --hashalgo/-a
runtime option. With that, make SHA-256 the default hash algorithm instead.

Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 19:20:17 -04:00
80bb310152 set default hash algorithm in configuration time
The default hash algorithm for evmctl is today hardcoded in the libimaevm.c
file. To facilitate package maintainers across different distributions to
set their own default hash algorithm, this patch adds the
--with-default-hash=<algo> option to the configuration script.

The chosen algorithm will then be checked by its available in the kernel,
otherwise IMA won't be able to verify files hashed by the user. For that,
the kernel header hash_info.h used as the source of supported hashes. In
case the hash_info.h header is not present, the configuration script warns
about it, but uses whatever the user specified in the option.

Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 19:19:31 -04:00
5356b0487a Merge branch 'pkcs11-support-v4' into next
From the cover letter:
Add support for signing with pkcs11 URIs so that pkcs11-enabled devices
can also be used for file signing.

Extend the existing sign_verify.test with tests for the new pkcs11 URI support.
Use SoftHSM, when available, as a pkcs11 device for testing.
2021-09-13 18:56:22 -04:00
ebcdbfe91e tests: Get the packages for pkcs11 testing on the CI/CD system
Get the packages for pkcs11 testing on the CI/CD system, where available.
On those system where it is not available, skip the two tests.

The following distros cannot run the pkcs11 tests:

- Alpine: package with pkcs11 engine not available
- CentOS7: softhsm 2.1.0 is too old for tests to work; tests also fail when
           trying to sign with pkcs11 URI using openssl command line tool
- OpenSuSE Leap: softhsm package not available in main repo

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 18:48:41 -04:00
e5b3097821 tests: Extend sign_verify test with pkcs11-specific test
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>
2021-09-13 18:42:50 -04:00
4a977c8d23 tests: Import softhsm_setup script to enable pkcs11 test case
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>
2021-09-13 18:42:20 -04:00
6350e014a8 libimaevm: Add support for pkcs11 private keys for signing a v2 hash
Add support for pkcs11 private keys for signing a v2 hash.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 18:39:38 -04:00
3b32acbc7d evmctl: use the pkcs11 engine for pkcs11: prefixed URIs
If the key has the pkcs11: URI prefix then setup the pkcs11 engine
if the user hasn't chosen a specific engine already.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 18:39:38 -04:00
1de1e3c8ce evmctl: Define and use an ENGINE field in libimaevm_params
Extend the global libimaevm_params structure with an ENGINE field 'eng'
and use it in place of the local ENGINE variable in main().

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 18:39:38 -04:00
29aa7465d5 evmctl: Implement function for setting up an OpenSSL engine
Move the code that sets up an OpenSSL engine into its own function.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 18:39:38 -04:00
47510a1050 evmctl: Handle failure to initialize the openssl engine
Handle failure to initialize the openssl engine. For example,

$ ./src/evmctl --engine foo
engine foo isn't available
140322992015168:error:25066067:DSO support routines:dlfcn_load:could not load the shared library:crypto/dso/dso_dlfcn.c:118:filename(/usr/lib64/engines-1.1/foo.so): /usr/lib64/engines-1.1/foo.so: cannot open shared object file: No such file or directory
140322992015168:error:25070067:DSO support routines:DSO_load:could not load the shared library:crypto/dso/dso_lib.c:162:
140322992015168:error:260B6084:engine routines:dynamic_load:dso not found:crypto/engine/eng_dyn.c:414:
140322992015168:error:2606A074:engine routines:ENGINE_by_id:no such engine:crypto/engine/eng_list.c:334:id=foo
Segmentation fault (core dumped)

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 18:39:38 -04:00
6fbb2a305b evmctl: Implement support for EVMCTL_KEY_PASSWORD environment variable
If the user did not use the --pass option to provide a key password,
get the key password from the EVMCTL_KEY_PASSWORD environment variable.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-09-13 18:39:38 -04:00
fa2ba9a6e9 evmctl: fix memory leak in get_password
The variable "password" is not freed nor returned in case get_password()
succeeds. Return it instead of the intermediary variable "pwd". Issue found
by Coverity scan tool.

src/evmctl.c:2565: leaked_storage: Variable "password" going out of scope
    leaks the storage it points to.

Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-08-19 17:17:06 -04:00
b1818c1113 Create alternative tpm2_pcr_read() that uses IBM TSS
Use the IBM TSS to implement the functions as an alternative to the
command line tools.

The algorithm_string_to_algid() function supports only the digest
algorithms in use.  The table has place holders for other algorithms
as they are needed and the C strings are defined.

The table can also be used for an algorithm ID to string function if
it's ever needed.

When using the IBM TSS, link in its library.

Signed-off-by: Ken Goldman <kgoldman@us.ibm.com>
[zohar@linux.ibm.com: updated configure.ac, replaced license with SPDX,
added comment before TSS_Delete and modified rc1 testing.]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-08-11 10:57:27 -04:00
e52fc1d330 Change PCR iterator from int to uint32_t
PCR numbers are naturally unsigned values.  Further, they are
32 bits, even on 64-bit machines. This change eliminates the
need for negative value and overflow tests.

The parameter name is changed from j and idx to pcr_handle, which is
more descriptive and is similar to the parameter name used in the TPM
2.0 specification.

Signed-off-by: Ken Goldman <kgoldman@us.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-08-10 11:22:15 -04:00
efacc1f396 Expand the INSTALL instructions
Add some of the less obvious package, TPM, and TSS prerequisites.

autoreconf -i is required before ./configure

Signed-off-by: Ken Goldman <kgoldman@us.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-08-10 11:22:15 -04:00
2a7658bf0e ima-evm-utils: Fix incorrect algorithm name in hash_info.gen
There is no such an algorithm name as sm3-256. This is an ambiguity
caused by the definition of the macro HASH_ALGO_SM3_256. The sed
command is only a special case of sm3, so sm3 is used to replace
the sm3-256 algorithm name.

Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-26 17:35:51 -04:00
a5f5dd7c8e ima-evm-utils: Support SM2/3 algorithm for sign and verify
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>
2021-07-21 13:15:02 -04:00
40621b2259 Read keyid from the cert appended to the key file
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>
2021-07-16 17:10:33 -04:00
0e7a00e26b Allow manual setting keyid from a cert file
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>
2021-07-16 17:10:33 -04:00
51b694bfea Allow manual setting keyid for signing
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>
2021-07-16 17:10:33 -04:00
6ecb883528 evmctl: Remove left-over check S_ISDIR() for directory signing
Since we are not signing directory entries, remove the left-over check
with S_ISDIR().

Suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-16 16:58:30 -04:00
6cdbd2d49f Remove unnecessary NULL pointer test
Remove the "Logically dead code (DEADCODE)" as reported by Coverity.

Fixes: 9c79b7de72 ("ima-evm-utils: support verifying the measurement list using multiple keys")
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-16 09:38:01 -04:00
84a423d5a1 Address "ignoring number of bytes read" messages
Coverity complains about the existing "if (!fread(....))" and inverse
syntax.  Change it to make Coverity happy.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-16 09:38:01 -04:00
ad1d5e3f67 Fix out-of-bounds read
Coverity reported "overrunning an array".  Properly clear only the
remaining unused buffer memory.

Fixes: 874c0fd45c ("EVM hmac calculation")
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-16 09:38:01 -04:00
996435d2d6 CI: list crypto algorithm tests skipped
Include the list and number of crypto tests skipped in the CI output.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-16 09:37:44 -04:00
79ff634f7e Fix NULL pointer warning
Static analysis reported an "invalid operation involving NULL pointer"
warning.  Although the code properly exits the loop without ever
using the variable, test the pointer isn't NULL before incrementing
it.

Fixes: 80d3fda608 ("ima-evm-utils: Check for tsspcrread in runtime")
Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-16 07:43:42 -04:00
58a84044fd CI: Add support for ALT Linux
Build on Sisyphus branch which is bleeding edge repository.
Package manager is apt-rpm (not APT as it may look from the scripts).

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-16 07:43:37 -04:00
aef36466c9 CI: Do not use sudo when not needed
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>
2021-07-14 10:29:21 -04:00
a7dd075ef7 CI: Do not install swtpm if it cannot work anyway
Do not need to waste CPU cycles and time to install swtpm in CI
container if distribution does not have tssstartup, because we will
be not able to start it.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-13 21:02:29 -04:00
fd40ff5dd5 libimaevm: Remove calculation of a digest over a symbolic link
Signature verification on symbolic links is not supported by IMA in the
kernel, so remove the calculation of digests over symbolic links.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-12 14:07:10 -04:00
a5a03d5454 libimaevm: Remove calculation of a digest over a directory
Signature verification on directories is not supported by IMA in the
kernel, so remove the calculation of digests over directories.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-12 14:07:07 -04:00
75b65e8618 libimaevm: Remove calculation of a digest over a device file
Signature verification on device files is not supported by IMA in the
kernel, so remove calculation of digests over devices files.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-12 14:07:03 -04:00
3f806e1100 evmctl: Remove filtering support for file types unsupported by IMA
Remove support for filtering on file types unsupported by IMA from evmctl.
This now prevents func(de->d_name) to be invoked on symlinks, block device
files, etc. since signature verification on those file types is not
supported by IMA in the kernel.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-09 17:33:37 -04:00
309d3369bb libimaevm: Use function parameter algo for name of hash
Instead of using the global variable imaevm_params.hash_algo as the
hash algo to use, use the algo parameter passed into the function.
Existing code in this function already uses 'algo' for writing the
hash into the header:

        hdr->hash_algo = imaevm_get_hash_algo(algo);

Fixes: 07e623b608 ("ima-evm-utils: Convert sign_hash_v2 to EVP_PKEY API").
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-07-09 17:28:41 -04:00
3feccd45a8 libimaevm: Report unsupported filetype using log_err
There's no errno set at this point so that using log_errno would
display something useful. Instead use log_error().

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-06-25 15:31:17 -04:00
d22cf0b005 libimaevm: Rename variable from cr to newline
Rename function variable from cr (carriage return, '\r') to
newline, because this is what it is.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-06-25 15:31:10 -04:00
3a28dd2721 libimaevm: Rename variable returned from readlink to len
The variable returned from readlink is a length indicator of the
number of bytes placed into a buffer, not only an error. Leave
a note in the code that a zero-length link is also treated as an
error, besides the usual -1.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-06-25 15:30:53 -04:00
837591b81b libimaevm: Remove unused off variable
The 'off' variable was unused in add_dir_hash(), so remove it.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-06-25 15:30:47 -04:00
161a4a5026 libimaevm: Properly check for error returned by EVP_DigestUpdate
The error checking in add_dir_hash was wrong. EVP_DigestUpdate returns 1
on success and 0 on error, so we cannot just accumulate it using or'ing.

>From the man page:
       EVP_DigestInit_ex(), EVP_DigestUpdate(), EVP_DigestFinal_ex()
           Returns 1 for success and 0 for failure.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-06-25 15:30:32 -04:00
81478c5667 CI: Introduce GitHub Actions setup
Travis is unreliable due "pull rate limit" issue, workaround does not
work any more. Also GitHub Actions is a recommended way for projects
hosted on GitHub.

Nice bonus is that manual podman activation for distros using glibc >=
2.33 (e.g. openSUSE Tumbleweed, Fedora) it's not needed in GitHub.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-06-24 10:39:22 -04:00
487a078cd3 CI/openSUSE: Fix tpm_server symlink creation
This symlink is missing only on openSUSE Tumbleweed,
it exists on openSUSE Leap, thus build failed.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-06-24 10:39:22 -04:00
28dd7d4b06 CI: Rename travis script directory
This is a preparation for adding GitHub Actions support.

Also run from root directory. It's a bit confusing to run from
travis directory.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-06-24 10:39:22 -04:00
8e0b3f00be tests/install-swtpm.sh: Add tar option --no-same-owner
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>
2021-04-15 11:17:51 -04:00
6287cb76d1 travis: Fix openSUSE Tumbleweed
openSUSE Tumbleweed build fails due broken permission detection due
faccessat2() incompatibility in libseccomp/runc used in old docker with
old kernel on Ubuntu Focal on hosts in Travis CI together with guests
with the newest glibc 2.33.

Fixing Tumbleweed required switch to podman and downloading newest runc
release (v1.0.0-rc93) which contains the fix [1], because proposed glibc
fix [2] aren't going to merged to upstream [3] nor to Tumbleweed
downstream glibc [4].

Sooner or later it will be required for more distros (Fedora, Debian
Ubuntu), but don't waste build time until required.

[1] https://github.com/opencontainers/runc/pull/2750
[2] https://sourceware.org/pipermail/libc-alpha/2020-November/119955.html
[3] https://sourceware.org/pipermail/libc-alpha/2020-November/119978.html
[4] https://bugzilla.opensuse.org/1182451

Signed-off-by: Petr Vorel <pvorel@suse.cz>
[zohar@linux.ibm.com: actually remove sudo, as per Changelog]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-04-15 11:16:56 -04:00
74ea78d4f2 ima-evm-utils: Prevent crash if pcr is invalid
If the pcr is invalid, evmctl will crash while accessing
an invalid memory address.  Verify the pcr is in the
expected range.

Also, correct range of an existing check.

Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-02-12 13:38:53 -05:00
8cbf05fcde Limit comparing the calculated PCR value to just a single bank
TPM 2.0 banks may be extended either with a padded SHA1 hash or more
recently with a per TPM bank calculated hash.  If the measurement list
is carried across kexec, the original kernel might extend the TPM
differently than the new kernel.

Support for verifying a mixed IMA measurement list is not supported.  To
permit verifying just the SHA1 bank, specify "--verify-bank=sha1" on the
command line.

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-02-09 11:46:08 -05:00
d80b6d5a7d ima-evm-utils: Improve ima_measurement matching on busy system with >1 banks
When a system is very busy with IMA taking measurements into more than
one bank, then we often do not get the PCR 10 values of the sha1 bank
that represents the same log entry as the reading of the PCR value of
the sha256 bank. In other words, the reading of the PCR 10 value from
the sha1 bank may represent the PCR 10 state at the time of the
n-th entry in the log while the reading of the PCR 10 value from the
sha256 bank may represent the state at the time of a later-than-n entry.
The result currently is that the PCR measurements do not match and
on a busy system the tool may not easily report a successful match.

This patch fixes this issue by separating the TPM bank comparison for
each one of the banks being looked and using a bit mask for checking
which banks have already been matched. Once the mask has become 0
all PCR banks have been successfully matched.

A run on a busy system may result in the output as follows indicating
PCR bank matches at the n-th entry for the sha1 bank and at a later
entry, possibly n + 1 or n + 2 or so, for the sha256 bank. The
output is interleaved with a match of the sha1 bank against 'padded
matching'.

$ evmctl ima_measurement --ignore-violations /sys/kernel/security/ima/binary_runtime_measurements -v
sha1: PCRAgg  10: 381cc6139e2fbda76037ec0946089aeccaaa5374
sha1: TPM PCR-10: 381cc6139e2fbda76037ec0946089aeccaaa5374
sha1 PCR-10: succeed at entry 4918
sha1: PCRAgg  10: 381cc6139e2fbda76037ec0946089aeccaaa5374
sha1: TPM PCR-10: 381cc6139e2fbda76037ec0946089aeccaaa5374
sha1 PCR-10: succeed at entry 4918
[...]
sha256: PCRAgg  10: c21dcb7098b3d7627f7aaeddf8aff68a65209027274d82af52be2fd302193eb7
sha256: TPM PCR-10: c21dcb7098b3d7627f7aaeddf8aff68a65209027274d82af52be2fd302193eb7
sha256 PCR-10: succeed at entry 4922
Matched per TPM bank calculated digest(s).

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-02-09 07:36:59 -05:00
9473e3c887 ima_evm_utils: Add testing with elliptic curves prime192v1 and 256v1
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>
2021-02-04 12:44:30 -05:00
cbbe31e1ca ima_evm_utils: Fix calculation of keyid for older distros
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>
2021-02-04 12:44:30 -05:00
056a7d284c travis: Use Ubuntu 20.10 groovy
Eoan is failing:

E: The repository 'http://security.ubuntu.com/ubuntu eoan-security Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

And 20.04 LTS focal in Travis is still fails on debconf issue
("debconf: unable to initialize frontend: Dialog")

Old 16.04 LTS xenial is still supported and working in Travis,
thus move to new groovy gives us good coverage both old and new releases.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-01-06 08:41:44 -05:00
57f0ffd8d9 pcr_tsspcrread: Add missing new line
Fixes: 80d3fda ("ima-evm-utils: Check for tsspcrread in runtime")

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-12-15 16:36:31 -05:00
097c81a1a5 tests: add test to verify EVM portable and immutable signatures
Now that evmctl supports verifying EVM portable and immutable signatures,
add the test.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-12-08 08:24:58 -05:00
f4b901d081 Add support for verifying portable EVM signatures
Commit 4928548d9d ("Add support for portable EVM format") added
support for generating portable and immutable signatures.  Support
verifying them, using either the security.ima or the user.ima.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-12-08 08:00:00 -05:00
00a0e66a14 Release version 1.3.2
Refer to the NEWS file for a short summary and the git history for
details.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-10-28 13:18:08 -04:00
155c139d30 boot_aggregate.test: Skip if CONFIG_IMA not enabled
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>
2020-10-23 08:35:41 -04:00
2d03bdbdde travis: properly kill the software TPM
Send "tsstpmcmd -stop" to properly stop the tpm_server.  Send SIGTERM
to stop the swtpm process.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-10-21 19:32:45 -04:00
f3fb7c5de0 travis: rename the software tpm variables
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>
2020-10-21 19:32:35 -04:00
54d07e3aaf travis: retry sending tssstartup
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>
2020-10-19 19:15:11 -04:00
0ecfd590c2 ima-evm-utils: Correct spelling errors
In comments and error messages.  No impact to code.

Signed-off-by: Ken Goldman <kgoldman@us.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-10-19 19:15:11 -04:00
05c03be98b travis: Change env variable TPM_SERVER_TYPE for tpm_server
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: f831508297 ("Install the swtpm package, if available")
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-10-19 19:15:11 -04:00
9980149f95 travis: Fix Tumbleweed installation
to prevent fail the job when /usr/lib/ibmtss/tpm_server does not exist.

Fixes: 6c78911 travis: Switch to docker based builds

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-10-19 19:15:11 -04:00
2fb79b9c3e help: Add missing new line for --ignore-violations
Fixes: 62534f2 ("Rename "--validate" to "--ignore-violations"")

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-10-19 19:15:11 -04:00
2b2a3623c1 ima-evm-utils: Add test for sigfile reading
Test reading of detached IMA signature (--sigfile).

Suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-10-19 19:15:11 -04:00
19b77c8667 ima-evm-utils: Fix reading of sigfile
Fix reading of detached IMA signature (--sigfile). Error message:

  Reading to sha1.txt.sig
  Failed to fread 147 bytes: sha1.txt.sig
  Failed reading: sha1.txt

Reported-by: Mimi Zohar <zohar@linux.ibm.com>
Fixes: 08a51e7460 ("ima-evm-utils: Fix file2bin stat and fopen relations")
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-10-19 19:14:56 -04:00
7fd8c13b64 Merge branch 'docker-travis'
Support docker based travis to test on different distro releases.
2020-08-19 10:25:45 -04:00
f831508297 Install the swtpm package, if available
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>
2020-08-18 17:22:03 -04:00
6c78911350 travis: Switch to docker based builds
This requires to have distro specific install scripts and build.sh
script.

For now ibmswtpm2 is compiled just for native builds (depends on gcc,
compiled natively). libtmps/swtpm could be used.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Bruno Meneguele <bmeneg@redhat.com>(Fedora,CentOS 8(RHEL actually))
[zohar@linux.ibm.com: removed debugging in travis/fedora.sh]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-08-18 17:21:39 -04:00
851f8c7907 tests: Require cmp
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>
2020-08-18 17:21:31 -04:00
ccbac508b5 autogen.sh: Cleanup
m4 directory exists, force parameter is not needed.
Remove commented out "old way".

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>
2020-08-18 17:21:24 -04:00
83e7925cbe Remove install-tpm2-tss.sh
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>
2020-08-18 17:21:15 -04:00
60e1535438 install-swtpm.sh: Update ibmtpm to version 1637
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>
2020-08-18 17:21:00 -04:00
5b764057f3 install-swtpm.sh: Ignore certificate for download
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>
2020-08-18 17:20:48 -04:00
4a67103e9d man: Generate doc targets only when XSL found
As requiring manpages/docbook.xsl breaks build if not found.

Also rewrite the check to add more debug info.

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>
2020-08-18 17:20:34 -04:00
9620d8b70d man: Fix xmlcatalog path detection
for catalogs which return plain file path (e.g.
/usr/.../manpages/docbook.xsl) instead of URI which starts
with file://). In that case sed printed empty string.

Fixes: 5fa7d35 ("autotools: Try to find correct manpage stylesheet
path")

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>
2020-08-18 17:20:03 -04:00
3b70893edf configure: Fix tss2-esys check
Check tss2-esys with Esys_Free() instead of Esys_PCR_Read().
That should be the newest dependency.

That means we depend on tss2-esys >= 2.1.0 instead of 2.0.0.

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>
2020-08-18 17:18:52 -04:00
97b912a727 Release version 1.3.1
Releasing v1.3.1 so quickly after v1.3 is to address a couple of distro
build issues.  A few additional changes, that were not quite ready for
the 1.3 release, are included as well.  Refer to "NEWS" for a summary of
these changes.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-08-11 07:19:04 -04:00
b51487be67 Merge branch 'travis'
Support for multiple TSS and crypto libraries resulted in needing to
test different software package combinations.  Although this is a
first attempt at using travis matrix, include it.  This will be replaced
with docker based travis support.
2020-08-10 15:39:07 -04:00
1b5146db99 travis: define dist as "bionic"
Default to using "bionic".

Mimi Zohar <zohar@linux.ibm.com>
2020-08-10 15:35:36 -04:00
3ff5d99edc travis: support tpm2-tss
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>
2020-08-04 13:53:07 -04:00
f2fe592907 travis: dependency on TSS for initializing software TPM
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>
2020-08-04 13:53:07 -04:00
9cd7edf1e0 travis: download, compile, and install a swTPM
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>
2020-08-04 13:53:07 -04:00
d5aed92be4 travis: define travis.yml
Initial travis.yml file without the "boot_aggregate" test.

Signed-off-by: Mimi Zohar <zoahr@linux.ibm.com>
2020-08-04 13:53:07 -04:00
62534f2127 Rename "--validate" to "--ignore-violations"
IMA records file "Time of Measure, Time of Use (ToMToU)" and "open
writers" integrity violations by adding a record to the measurement
list containing one value (0x00's), but extending the TPM with a
different value (0xFF's).

To avoid known file integrity violations, the builtin "tcb" measurement
policy should be replaced with a custom policy as early as possible.
This patch renames the existing "--validate" option to
"--ignore-violations".

Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-08-04 08:17:50 -04:00
fbd96c98c5 Update the ima_boot_aggregate apsects of the "README" and "help" files
Add the missing "evmctl ima_boot_aggregate" info to the README.  Update
the "help" to include the new "--pcrs" option.  In addition, replace
the "file" option with "TPM 1.2 BIOS event log".  The new format is:

ima_boot_aggregate [--pcrs hash-algorithm,file] [TPM 1.2 BIOS event log]

Reminder: calculating the TPM PCRs based on the BIOS event log and
comparing them with the TPM PCRs should be done prior to calculating the
possible boot_aggregate value(s).

For TPM 1.2, the TPM 1.2 BIOS event log may be provided as an option
when calculating the ima_boot_aggregate.  For TPM 2.0, "tsseventextend
-sim -if <binary_bios_measurements> -ns -v", may be used to validate
the TPM 2.0 event log.

(Note: some TPM 2.0's export the BIOS event log in the TPM 1.2 format.)

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-08-04 08:17:50 -04:00
5b58f47570 Drop the ima_measurement "--verify" option
While walking the IMA measurement list re-calculating the PCRS,
ima_measurement should always re-calculate the template data digest
and verify it against the measurement list value.

This patch removes the "--verify" option.

On success, return 0.

Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-08-04 08:17:50 -04:00
8e2738dd44 extend ima_measurement --pcrs option to support per-bank pcr files
Extend the ima_measurement --pcrs option to support per-bank pcr files.
The extended syntax is "--pcrs algorithm,pathname".  If no algorithm
is specified, it defaults to sha1 as before.  Multiple --pcrs options
are now supported, one per bank of PCRs. The file format remains
unchanged.  If --pcrs is specified, only try to read PCRs from the
specified file(s); do not fall back to trying to read from sysfs
or the TPM itself in this case since the user requested use of
the files.

Create per-bank pcr files, depends on "tpm: add sysfs exports for all
banks of PCR registers" kernel patch:
$ cat tpm2pcrread.sh
for alg in sha1 sha256
do
  rm -f pcr-$alg
  pcr=0;
  while [ $pcr -lt 24 ];
  do
    printf "PCR-%02d: " $pcr >> pcr-$alg;
    cat /sys/class/tpm/tpm0/pcr-$alg/$pcr >> pcr-$alg;
    pcr=$[$pcr+1];
  done
done
$ sh ./tpm2pcrread.sh

Pass only the sha1 PCRs to evmctl defaulting to sha1:
$ sudo evmctl ima_measurement --pcrs pcr-sha1 /sys/kernel/security/integrity/ima/binary_runtime_measurements

Pass only the sha1 PCRs to evmctl with explicit selection of sha1:
$ sudo evmctl ima_measurement --pcrs sha1,pcr-sha1 /sys/kernel/security/integrity/ima/binary_runtime_measurements

Pass both sha1 and sha256 PCRs to evmctl:
$ sudo evmctl ima_measurement --pcrs sha1,pcr-sha1 --pcrs sha256,pcr-sha256 /sys/kernel/security/integrity/ima/binary_runtime_measurements

Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[zohar@linux.ibm.com: although support for exporting TPM 2.0 PCRs has
not yet been upstreamed, add support for the file format anyway.]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-08-04 08:17:32 -04:00
79ab82f55f Rename "Changelog" to "NEWS"
autoconfig requires the existence of a "NEWS" file.  "git log" is a better
changelog, and "ChangeLog" is really condensed and suitable to be NEWS.
After renaming ChangeLog to NEWS, autoconfig complains about the missing
"ChangeLog" file.

Replacing the default automake GNU flavor with "foreign" removes the
requirement for defining the NEWS, COPYING, AUTHORS, ChangeLog, and
README files.

Reported-by: Petr Vorel <pvorel@suse.cz>
Suggested-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-22 22:14:11 -04:00
7f9a59c6c6 Fix missing {u,g}id_t typedef on musl
Fixes: 273701a ("evmctl - IMA/EVM control tool")

Signed-off-by: Petr Vorel <petr.vorel@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-22 17:20:14 -04:00
1f4e423e7c pcr_tss: Fix compilation for old compilers
pcr_tss.c: In function 'pcr_selections_match':
pcr_tss.c:73:2: error: 'for' loop initial declarations are only allowed in C99 mode
  for (int i = 0; i < a->count; i++) {
  ^
pcr_tss.c:73:2: note: use option -std=c99 or -std=gnu99 to compile your code
pcr_tss.c:78:3: error: 'for' loop initial declarations are only allowed in C99 mode
   for (int j = 0; j < a->pcrSelections[i].sizeofSelect; j++) {
   ^

Fixes: 03f99ea ("ima-evm-utils: Add support for Intel TSS2 for PCR
reading")

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-22 07:01:12 -04:00
f01c449a0c ima-evm-utils: Release version 1.3
Updated both the release and library (ABI change) versions.  See the
"Changelog" for a list of the new features, bug fixes, and code cleanup.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-21 18:39:17 -04:00
5f26c40779 ima_evm_utils: indicate "--verify" template data digest failures
Helps to indicate when the template data digest verification fails.
Indicate the problematic record in the measurement list based on
log level and fail verification.

fixes: ff26f9704e ("ima-evm-utils: calculate and verify the template
data digest")

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
2020-07-20 07:44:47 -04:00
ee43312f74 ima-evm-utils: output specific "unknown keyid" file msg based on log level
When the IMA measurement list contains file signatures, the file
signatures are verified either by calculating the local file data hash
or based on the file hash contained in the measurement list.  In either
case a list of trusted public keys needs to be provided.

In addition to the list of known/unknown public keys needed to verify
the measurement list being output, the specific files signed by an
unknown public key are output as well.

Output the individual "unknown keyid" file messages based on log level.

Example 1: "ima_measurement" list of known/unknown public keys

Verify the provided IMA measurement list against the provided TPM 1.2
PCRs.
--validate: ignore measurement violations.
--verify: calculate and verify the template digest against the template
data.
--verify-sig: verify the file signature against the file hash stored
in the template data.

$ evmctl ima_measurement /tmp/local_binary_runtime_measurements --pcrs
/tmp/local_pcrs_new --validate --verify --verify-sig
key 1: 14c2d147 /etc/keys/x509_evm.der
key 2: 6e6c1046 (unknown keyid)
key 3: c4e2426e (unknown keyid)
Matched per TPM bank calculated digest(s).

Example 2: verbose mode (-v) includes specific unknown files.

/usr/bin/evmctl: verification failed: unknown keyid 6e6c1046

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
2020-07-20 07:44:37 -04:00
9b5a1e7b1d ima-evm-utils: similarly add sanity check for file parameter of TPM 1.2 PCRs
Parameter expects to be a copy of /sys/class/tpm/tpm0/device/pcrs (i.e.
regular file, not a directory, block or character device, socket, ...)

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
2020-07-20 07:44:29 -04:00
aa636ee486 Add sanity check for file parameter of ima_boot_aggregate
Parameter expects to be a copy of
/sys/kernel/security/tpm0/binary_bios_measurements (i.e. regular file,
not a directory, block or character device, socket, ...)

Fixes: f49e982 ("ima-evm-utils: read the TPM 1.2 binary_bios_measurements")

Signed-off-by: Petr Vorel <pvorel@suse.cz>
[zohar@linux.ibm.com: updated to check stat result]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-19 09:45:55 -04:00
3e7d575816 ima-evm-utils: fix overflow on printing boot_aggregate
There was no room for placing the '\0' at the end of boot_aggregate value,
thus printf() was reading 1 byte beyond the array limit.

Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 21:49:58 -04:00
dbbaccc781 ima-evm-utils: fix memory leak in case of error
OpenSSL context should be freed in case of versions >= 1.1 before leaving
the function in case EVP_DigestUpdate() returns any error.

Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 21:49:58 -04:00
02d976a3df ima-evm-utils: fix empty label at end of function.
Distros running older OpenSSL versions (<= 1.1) fail to build due to the
empty label at the end of calc_bootaggr(). For these, that label is no-op.

Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 21:49:58 -04:00
4780eae3e3 ima-evm-utils: add missing license info
src/utils.c contains some common functions.

Fixes: 03f99ea6d0 ("ima-evm-utils: Add support for Intel TSS2 for PCR reading")

Reported-by: Petr Vorel <pvorel@suse.cz>
Cc: Patrick Uiterwijk <patrick@puiterwijk.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 21:49:58 -04:00
229e9e3cee ima-evm-utils: reading public keys
Not being able to read the public key is not necessarily an error.
Emit a message based on log level.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 21:49:58 -04:00
0911c60fb5 ima-evm-utils: address new compiler complaints
Address the new compiler complaints:
- while reading the template data
- while reading the exported TPM 1.2 PCRs
- while reading the TPM event log

Reported-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 21:49:58 -04:00
80d3fda608 ima-evm-utils: Check for tsspcrread in runtime
instead of checking in build time as it's runtime dependency.
Also log when tsspcrread not found to make debugging easier.

We search for tsspcrread unless there is tss2-esys with Esys_PCR_Read(),
thus pcr_none.c was dropped as unneeded.

file_exist(), tst_get_path() and MIN() taken from LTP project.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
[zohar@linux.ibm.com: added USE_FPRINTF definitions]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 21:49:26 -04:00
1bf51afb46 ima-evm-utils: update README to reflect "--pcrs", "--verify" and "--validate"
"--pcrs" compares the re-calculate PCRs against a file containing TPM 1.2 pcrs.
"--validate" ignores ToMToU measurement violations.
"--verify" verifies the template data digest based on the template data.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 16:25:32 -04:00
4a96edb6e8 ima-evm-utils: verify the template data file signature
The file signature stored in the ima_measurement list is verified based
on the file hash.  Instead of reading the file data to calculate the
file hash, compare with the file hash stored in the template data.  In
both cases, the set of public keys need to be specified.

This patch renames the "--list" option to "verify-sig" option.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 16:25:32 -04:00
1816644727 ima-evm-utils: the IMA measurement list may have too many measurements
Reading the TPM PCRs before walking the measurement list guarantees
the measurement list contains all the records, possibly too many records.
Compare the re-calculated hash after each extend with both the per bank
TPM PCR digests and the SHA1 paddeded TPM PCR digests.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 16:25:32 -04:00
6baaf7f876 ima-evm-utils: guarantee the measurement list contains all the records
Reading the TPM PCRs before walking the measurement list guarantees
the measurement list contains all the records.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 16:25:32 -04:00
36aa7be850 ima-evm-utils: emit "ima_measurement" messages based on log level
"ima_measurement" emits quite a few messages.  Only a few messages
belong at the default log level.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 16:25:32 -04:00
354510fa50 ima-evm-utils: support providing the TPM 1.2 PCRs as a file
"evmctl ima_measurement" walks the IMA measurement list calculating the
PCRs and verifies the calculated values against the system's PCRs.
Instead of reading the system's PCRs, provide the PCRs as a file.  For
TPM 1.2 the PCRs are exported via a securityfs file.

Verifying the IMA measurement list against the exported TPM 1.2 PCRs
file may be used remotely for regression testing.  If used in a
production environment, the provided TPM PCRs must be compared with
those included in the TPM 1.2 quote as well.

This patch defines an evmctl ima_measurement "--pcrs <filename>" option.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 16:25:31 -04:00
d5b24fa18e ima_evm_utils: support extending TPM 2.0 banks w/original SHA1 padded digest
Initially the sha1 digest, including violations, was padded with zeroes
before being extended into the other TPM banks.  Support walking the
IMA measurement list, calculating the per TPM bank SHA1 padded
digest(s).

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 16:25:31 -04:00
b102db4180 ima-evm-utils: improve reading TPM 1.2 PCRs
Instead of reading the TPM 1.2 PCRs one at a time, opening and closing
the securityfs file each time, read all of PCRs at once.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-15 16:25:24 -04:00
663dfd5efb ima-evm-utils: mixed "ima" and other template formats not supported
An IMA measurement list may not contain "ima" and other template
formats.  Fail verifying the ima_measurement test.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:44 -04:00
f49e982627 ima-evm-utils: read the TPM 1.2 binary_bios_measurements
Instead of just calculating the "boot_aggregate" based on the current
TPM PCRs, the original LTP and standalone ima_boot_aggregate test walked
the TPM 1.2 event log, calculating the PCRs.

If the TPM 1.2 event log is provided as an option on the "evmctl
ima_boot_aggregate" command, read the event log, calculate the sha1
PCRs, and calculate the "boot_aggregate" based on these PCRs.

The code for walking the IMA measurement list is based on the LTP and
standalone ima_boot_aggregate tests.  Similar support for reading the
TPM 2.0 event log to calculate the PCRs requires the TPM 2.0 event log
to be exported or a TSS to read the event log.  Parsing the TPM 2.0
event log is not supported here.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:44 -04:00
81aa698c70 ima-evm-utils: support the original "ima" template
The original "ima" template digest included just a SHA1 file data hash
and a fixed 255 character pathname in the hash calculation.  Two main
differences exist between the "ima" template and other template formats.
The other template data formats are prefixed with the template data
length and each field is prefixed with the field length,

These differences simplify verifying the other template formats against
the TPM PCRs without necessarily understanding each and every template
field.

Support for the original "ima" templat formate is based on the original
LTP and IMA standalone versions.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:44 -04:00
590966cb7f ima-evm-utils: define a basic hash_info.h file
Some older system kernel header packages don't necessarily include
hash_info.h.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:21 -04:00
d9f015035a ima-evm-utils: use uint32_t for template length
The template length should never be less than zero.  Replace "int" with
"uint32_t".

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:21 -04:00
ff26f9704e ima-evm-utils: calculate and verify the template data digest
Validating a TPM quote of PCR-10, the default IMA PCR, requires not only
sending the quote to the verifier, but the IMA measurement list as well.
The attestation server can verify the IMA measurement list simply by
walking the measurement list and re-calculating the PCRs based on the
template data digest.  In addition, the attestation server could verify
the template data digest based on the template data.

The LTP and standalone "ima_measure" test optionally verify the template
data digest.  Similarly add "--verify" support to conditionally verify
the template data digest against the template data.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:21 -04:00
bb62a7115e ima-evm-utils: don't hardcode validating the IMA measurement list
File time of measure, time of use (ToMToU) violations are annotated in
the measurement list by including a template data digest of zeroes, but
extending the TPM with 0xFF's.  This causes validating the measurement
against the TPM PCRs to fail.  To validate the measurement list against
the PCRs requires replacing the zero template data digest with OxFF's.

The default behavior, unless specifically requested, should be to fail
the measurement list verification.  Support validating the measurement
list based on a "--validate" option.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:21 -04:00
747bf9e890 ima-evm-utils: fix measurement violation checking
The template data digest for file measurement time of measure, time of
use (ToMToU) violations is zero.  Don't calculate the template data
digest for the different banks.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:21 -04:00
8b49f0c01c ima-evm-utils: fix PCRAggr error message
Display the correct TPM PCR value.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 11:00:21 -04:00
ceecb28d3b ima-evm-utils: add SM3 to pkey_hash_algo algorithm list
SM3 was published by State Encryption Management Bureau, China.
It has been well supported in the kernel and openssl.
This patch allows SM3 to be used smoothly by specifying the
parameter `-a sm3` or `--hashalgo sm3`.

Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 10:59:59 -04:00
15659747eb ima-evm-utils: beautify the code to make it more readable
Use enum type instead of hard-coded numbers to improve code readability.

Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-09 10:59:59 -04:00
fb19ae86db ima-evm-utils: Fix mismatched type checking
Even if imaevm_get_hash_algo() returns an error value of -1, it is
forced to be converted to uint8_t type here, resulting in this error
not being checked by the if condition. This patch fixes this error.

Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-07-06 17:42:05 -04:00
c9e99f0a21 ima-evm-utils: skip test for discrete TPM 1.2 and exec'd as normal user
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>
2020-06-24 20:37:50 -04:00
c396c5a4bf ima-evm-utils: logging: Print also LOG_INFO messages
as some errors are using it, e.g. in previous fix
just errno would be printed:

./src/evmctl ima_boot_aggregate
Failed to read any TPM PCRs
errno: No such file or directory (2)

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-06-24 20:37:50 -04:00
89eee0f883 ima-evm-utils: tests: fix finding the "boot_aggregate" value
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>
2020-06-24 20:37:09 -04:00
48cb564567 ima_evm_utils: tests: boot_aggregate.test spans PCRs 0-9
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>
2020-06-24 20:36:25 -04:00
319fb19caa ima_evm_utils: extended calc_bootaggr to PCRs 8 - 9
cal_bootaggr() should include PCRs 8-9 in non-SHA1 digests.

Signed-off-by: Maurizio Drocco <maurizio.drocco@ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-06-24 20:36:05 -04:00
39f1dbeaa4 ima_evm_utils: tests: color boot_aggregate.test tty output
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>
2020-06-23 21:45:17 -04:00
5404aa8397 ima-evm-utils: tests: verify the last "boot_aggregate" record
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>
2020-06-23 21:45:17 -04:00
c5732b6d95 ima-evm-utils: tests: verify boot_aggregate
Calculate the boot_aggregate for each TPM bank and verify that the
boot_aggregate in the IMA measurement list matches one of them.

A software TPM may be used to verify the boot_aggregate.  If a
software TPM is not already running on the system, this test
starts one and initializes the TPM PCR banks by walking the sample
binary_bios_measurements event log, included in this directory, and
extending the TPM PCRs.  The associated ascii_runtime_measurements
for verifying the calculated boot_aggregate is included in this
directory as well.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-06-23 21:45:17 -04:00
917317a8ea ima_evm_utils: emit the per TPM PCR bank "boot_aggregate" values
Instead of emitting the per TPM PCR bank "boot_aggregate" values one
at a time, store them in a buffer and emit them all at once.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-06-11 17:14:57 -04:00
d3faeb19ad ima-evm-utils: Add sign/verify tests for evmctl
This commit adds (evm) sign, (evm) verify, ima_sign, and
ima_verify tests for different algos.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:30:00 -04:00
b6ff60e4fa ima-evm-utils: Add some tests for evmctl
Run `make check' to execute the tests.
This commit only adds ima_hash test.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:29:59 -04:00
dc00c92adf ima-evm-utils: calculate the per TPM bank boot_aggregate
The IMA measurement list boot_aggregate is the link between the preboot
event log and the IMA measurement list.  Read and calculate all the
possible per TPM bank boot_aggregate digests based on PCRs 0 - 7.

Reading the TPM PCRs requires root permission, unless access to the
device (/dev/tpm0 or /dev/tpmrm0) has been granted.

Prior to calculating the boot_aggregate, the TPM PCRs themselves should
be validated by walking the TPM event log and re-calculating the PCRs.
(Such a test should be included as part of the TSS regression testsuites.)

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:29:59 -04:00
03f99ea6d0 ima-evm-utils: Add support for Intel TSS2 for PCR reading
This patch makes it possible to use the Intel TSS2 for getting
PCR values from the SHA1/SHA256 banks on a TPM2.
It is somewhat naive as it doesn't use the multi-PCR selection
that TSS2 is capable of, that is for a future patch.

Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
[zohar@linux.ibm.com: added missing "stdint.h" in pcr_tsspcrread.c]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:28:00 -04:00
e532fb65fd ima-evm-utils: remove TPM 1.2 specific code
Now that read_tpm_banks() reads the TPM 1.2 PCRs, remove the TPM 1.2
specific code for reading and verifying the SHA1 PCRs.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:25:13 -04:00
040c693b8b ima-evm-utils: use a common bank variable for TPM 1.2 and TPM 2.0
Extend read_tpm_banks() to support TPM 1.2, by reading TPM 1.2 SHA1 PCRs
into the first bank and mark the other banks as disabled.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:25:11 -04:00
acf2ac7559 ima-evm-utils: compare re-calculated PCRs with the TPM values
After walking the measurement list, re-calculating and extending the TPM
PCRs with the appropriate template digest for each bank, compare the
re-calculated PCR values for each TPM bank with the actual TPM values.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:25:09 -04:00
3472f9ba9c ima-evm-utils: read the PCRs for the requested TPM banks
Read and store the PCRs for the requested banks to compare with the
re-calculated PCR values.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:25:01 -04:00
2f482a6989 ima-evm-utils: add support in tpm2_read_pcrs to read different TPM banks
tpm2_read_pcrs() reads the sha1 PCRs in order to verify the measurmeent
list.  This patch adds support for reading other TPM banks.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:24:59 -04:00
696bf0b108 ima-evm-utils: calculate the digests for multiple TPM banks
IMA currently extends the different TPM banks by padding/truncating the
SHA1 template digest.  Although the IMA measurement list only includes
the SHA1 template digest, the template digest could be re-calculated
properly for each bank.

This patch adds support for properly calculating the template hash for
multiple TPM banks - "sha1" and "sha256".

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:24:55 -04:00
bdc94c9b49 ima-evm-utils: increase the size of "zero" and "fox" variables
Opening a file for write when it is already opened for read, results in
a time of measure, time of use (ToMToU) error.  Similarly, when opening
a file for read, when it is already opened for write, results in a file
measurement error.  These violations are flagged by including 0x00's as
the template digest in the measurement list, but extending the TPM with
0xFF's.

In preparation of extending the TPM banks with bank specific digest
values, increase the "zero" and "fox" variable sizes.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:24:48 -04:00
dc3897f011 ima-evm-utils: treat unallocated banks as an error
The TPM spec differentiates between an unknown bank and an unallocated
bank.  In terms of re-calculating the PCR, treat them as equivalent.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:24:44 -04:00
9c2298c367 ima-evm-utils: Never exit with -1 code
Change main() return code from -1 to 125 as -1 is not really valid exit
code. 125 is choosen because exit codes for signals start from 126.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-05-19 17:24:37 -04:00
fbba18c477 ima-evm-utils: include file name on failure to verify signature
Include file name on warning/error indication on signature verification.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2020-02-20 18:10:44 -05:00
cf1b8fda8d ima-evm-utils: Allow EVM verify to determine hash algo
Previously for EVM verify you should specify `--hashalgo' option while
for IMA ima_verify you didn't.

Allow EVM verify to determine hash algo from signature.

Also, this makes two previously static functions to become exportable
and renamed:

  get_hash_algo_from_sig -> imaevm_hash_algo_from_sig
  get_hash_algo_by_id    -> imaevm_hash_algo_by_id

This is needed because EVM hash is calculated (in calc_evm_hash) outside
of library.

imaevm_hash_algo_by_id() will now return NULL if algo is not found.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-30 13:32:28 -04:00
90176e835a ima-evm-utils: Do not load keys from x509 certs if user pass --rsa
If user wants to verify v1 signature and specify RSA public key in `-k'
option, this key will be attempted to be loaded as x509 certificate and
this process will output errors.

Do not load a key as a x509 cert if user pass `--rsa'.

This is not perfect solution. As now it's possible to specify `-k' and
`--rsa' and v2 signatures will not verify, because of no keys.

This improvement is not added into ima_measurement().

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-30 13:32:28 -04:00
2b491be5e2 ima-evm-utils: Fix ima_verify return value on multiple files
If any tested file results in failure produce failure exit code.
Previously exit code affected only by the last file tested.

Fixes: "Allow multiple files in ima_verify"
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-30 07:33:56 -04:00
bd8b503206 ima-evm-utils: limit OPENSSL_init_crypto calls
OPENSSL_init_crypto() was introduced in version 1.1.  When using an
older version of openssl, don't call OPENSSL_init_crypto.  Partially
revert commit 782224f33c ("ima-evm-utils: Rework openssl init").

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-30 07:15:18 -04:00
d8e7d63feb ima-evm-utils: Fix ima_verify for v1 signatures
Use user supplied key in verify_hash for DIGSIG_VERSION_1.
Otherwise v1 signatures don't pass verification.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-30 07:15:10 -04:00
e1bd9c9887 ima-evm-utils: fix trailing chars from configure script
Two chars were left in a AC_DEFINE() in configure.ac, leading to an error
message during ./configure call:

checking for tsspcrread... yes
./configure: line 9894: ],: command not found

Signed-off-by: Bruno E. O. Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-30 07:14:18 -04:00
515c99856e ima-evm-utils: Release version 1.2
Updated both the release and library (ABI change) versions.  See the
"Changelog" for a short list of the new features, bug fixes, and code
cleanup.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-26 07:42:17 -04:00
28cbfa1769 ima-evm-utils: functions/arrays define as static
Make sign_hash_v1(), sign_hash_v2(), get_hash_algo_by_id, and
 pkey_hash_algo[] and pkey_hash_algo_kern[] static.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-25 12:14:21 -04:00
c317d4618f ima-evm-utils: Namespace some too generic object names
Prefix `dump', `do_dump', and `params' with `imaevm_' to avoid colliding
with other global symbols.
Also, rename `libevm_' to `libimaevm_`, only used with `params'.
Additionally, rename `dump' into `hexdump'.
Finally, rename `get_hash_algo' to `imaevm_get_hash_algo' as suggested by
Mimi Zohar.

Lines that became too long are split, indent corrected. No code changes.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Reviewed-by: Bruno E. O. Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-25 12:14:21 -04:00
a1b149bda4 ima-evm-utils: Show used hash algo in verbose mode
This could be useful for users.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-25 12:14:10 -04:00
25fce6e76a ima-evm-utils: Do not allow fallback and unknown hash algos
Falling back and permissiveness could have security implications.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-25 12:14:01 -04:00
31ceff7eb6 ima-evm-utils: use tsspcrread to read the TPM 2.0 PCRs
The kernel does not expose the crypto agile TPM 2.0 PCR banks to
userspace like it exposes PCRs for TPM 1.2.  As a result, a userspace
application is required to read PCRs.

This patch adds tsspcrread support for reading the TPM 2.0 PCRs.
tsspcrread is one application included in the ibmtss package.

Sample error messages:
Failed to read PCRs: (tsspcrread failed: No such file or directory)
Failed to read PCRs: (TSS_Dev_Open: Error opening /dev/tpmrm0)

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Bruno E. O. Meneguele <bmeneg@redhat.com>
2019-07-24 06:09:17 -04:00
340f7eb7dd ima-evm-utils: Remove ERR_load_crypto_strings from read_priv_pkey
ERR_load_crypto_strings() is already called in other place.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-23 20:27:41 -04:00
3eac3710a9 ima-evm-utils: log unknown keyid's as errors
Each tima a new unknown key is encountered, emit a message of the format
"key #: <keyid> (unknown keyid)".  The individual files using unknown
keys are then only logged in verbose mode.  Also update the message
emitted to be consistent with other "verification failed" messages.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>

Changlog:
- Incorporated Vitaly's fix to prevent a null dereference in `tail->next`
2019-07-23 20:24:58 -04:00
15afdbeae7 ima-evm-utils: Improve OpenSSL error reporting
Previously OpenSSL errors was delayed until evmctl exit (sometimes not).
Since we try to make libimaevm more robust, there could be many errors
accumulated, so it's useful to output OpenSSL errors as they happen.
This will also make output more understandable as you can see which
openssl error correspond to which libimaevm error.

Additionally, change spelling of read_pub_pkey and read_priv_pkey to
include key file name.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-18 21:09:32 -04:00
42d1636f52 ima-evm-utils: Remove not needed argument from verify_hash_v2
Since we now always call verify_hash_v2() with NULL keyfile (assuming
all keys are already loaded into public_keys list), remove keyfile
argument and its handling from verify_hash_v2().

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
[zohar@linux.ibm.com: make verify_hash_v1() and verify_hash_v2() static.]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-18 21:09:32 -04:00
3359563dbe ima-evm-utils: Remove indirect call to subfunctions in verify_hash
This is more human understandable and also will improve handling of
the sources by cscope.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-18 21:09:32 -04:00
388f807a0f ima_evm_utils: erroneous "verification failed: 0 (invalid padding)" message
When public keys are specified on the boot command line (--key "<public
key file>,[<public key file>,...]"), the appropriate public key is used
to verify EVM or file signatures.  If no keys are specified, the default
x509_evm.der or pubkey_evm.pem file is used to verify the DIGSIG_VERSION_2
or DIGSIG_VERSION_1 signatures respectively, without first checking the
keyids.  Instead of emitting a "verification failed: 0 (invalid
padding)" message, an "unknown keyid" message would be clearer.

To address this problem, when no public keys are specified, this patch
loads the x509_evm.der default public key onto the "public_keys" list,
while the pubkey_evm.pem continues to be passed to verify_hash_v1()

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-18 21:07:48 -04:00
a225728550 ima-evm-utils: Add more error checking in add_file_hash
Check return value of fstat(2) in add_file_hash() and remove
now unused get_fdsize().

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-16 14:14:10 -04:00
08a51e7460 ima-evm-utils: Fix file2bin stat and fopen relations
Check stat(2) return value, use fstat(2) to avoid race between
stat() and fopen(), remove now unused get_filesize().

Fixes: CID 229889.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-16 14:14:03 -04:00
9d52489bd3 ima-evm-utils: Fix memory leak in get_password
Free allocated password buffer when returning NULL.

Fixes: CID 229894 (partially).
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-16 14:13:50 -04:00
4b7a74cc41 ima-evm-utils: Fix possible xattr_value overflows in calc_evm_hash
`selinux_str',`caps_str', and `ima_str' are passed from the command line
but copied into the fixed-size buffer.

Yes, length of `selinux_str' is calculated differently than of `caps_str'.

Fixes: CID 229895.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-16 14:13:39 -04:00
d47951c6e1 ima-evm-utils: Fix null dereference from file2bin to memcpy
file2bin() may return NULL, which is set to tmp, which is passed to
memcpy. Add explicit check for it.

Fixes: CID 229904.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-16 14:12:47 -04:00
164c51ff2b ima-evm-utils: support template "buf" field
Other than the "boot-aggregate" measurement entry in the IMA
measuremeent list, all other measurements are of file data.  Kernel
support was recently added to support measuring the kexec boot command
line buffer, which is stored in a new template field named 'buf'.

This patch adds support for a new template named "ima-buf", defined as
"d-ng|n-ng|buf".

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
4ec7c1d028 ima-evm-utils: limit "remain unprocessed data" messages
New, unknown template formats containing unknown fields are not
processed, resulting in "remain unprocessed data" messages.  Processing
these unknown fields is unnecessary for walking the measurement list to
re-calculate the PCRs.

The "remain unproccessed data" may also be emitted for malformed, known
template records.

This patch limits the number of messages emitted to once per template
format and includes the template name in the message.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
40c842ace3 ima-evm-utils: Fix clang warning about possible unaligned pointer for hdr->keyid
Struct signature_v2_hdr is packed so clang complains that taking address
of packed member may result in an unaligned pointer value:

libimaevm.c:481:21: warning: taking address of packed member 'keyid' of class or structure 'signature_v2_hdr' may result in an unaligned pointer value
      [-Waddress-of-packed-member]
                                __be32_to_cpup(&hdr->keyid));
                                                ^~~~~~~~~~

libimaevm.c:905:17: warning: taking address of packed member 'keyid' of class or structure 'signature_v2_hdr' may result in an unaligned pointer value
      [-Waddress-of-packed-member]
        calc_keyid_v2(&hdr->keyid, name, pkey);
                       ^~~~~~~~~~

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
ae57a3e1e4 ima-evm-utils: Allow multiple files in ima_verify
This allows testing multiple verify in a row, similar to ima_measurement.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
556f2fc66d ima-evm-utils: Preload public keys for ima_verify
This allows testing verify_hash_v2() with multiple public keys.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
bb35e696df ima-evm-utils: Fix memory leak in init_public_keys
strdup'ed string should be freed. Found with ASan.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
faea7ca2b1 ima-evm-utils: Fix EVP_MD_CTX leak in ima_calc_hash
When pctx is allocated using EVP_MD_CTX_new() it should be freed.
Found with ASan.

Fixes: 81010f0 ("ima-evm-utils: Add backward compatible support for openssl 1.1")
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
30add9c2eb ima-evm-utils: Log hash_algo with hash value in verbose mode
It's useful to know not just a hash value but also which algorithm is
used.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
5f126d1d25 ima-evm-utils: Pass status codes from sign and hash functions to the callers
Move sign_hash()/ima_calc_hash()/calc_evm_hmac()/calc_evm_hash() status
checking before assert()'ing of their return values, so it can be passed
to the upper level callers. Especially useful for showing errors.

Fixes: 1d9c279279 ("Define hash and sig buffer sizes and add asserts")
Fixes: 9643544701 ("Fix hash buffer overflow in verify_evm and hmac_evm")
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>

ima-evm-utils: Fix assert after ima_calc_hash
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:13 -04:00
28d3a1b293 ima-evm-utils: Remove RSA_ASN1_templates
RSA_ASN1_templates[] are not needed anymore, because we switched to the
generic EVP_PKEY OpenSSL API to generate v2 signatures instead of
constructing PKCS1 ourselves.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 10:00:06 -04:00
13d4521dbf ima-evm-utils: Replace calc_keyid_v2 with calc_pkeyid_v2
Finish conversion of calc keyid v2 to EVP_PKEY API. After sign_hash_v2()
is switched to EVP_PKEY API (in previous commit), older RSA-specific
calc_keyid_v2() does not needed anymore and can be replaced with
calc_pkeyid_v2().

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 09:59:59 -04:00
07e623b608 ima-evm-utils: Convert sign_hash_v2 to EVP_PKEY API
Convert sign_hash_v2() to use more generic EVP_PKEY API instead of RSA
API. This enables generation of more signatures out of the box, such as
EC-RDSA (GOST) and any other that OpenSSL supports. This conversion also
fixes generation of MD4 signatures, because it didn't have proper
RSA_ASN1_template.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 09:59:53 -04:00
e0d778c608 ima-evm-utils: Convert verify_hash_v2 and find_keyid to EVP_PKEY API
Rely on OpenSSL API to verify v2 signatures instead of manual PKCS1
decoding. Also, convert find_keyid() to return EVP_PKEY because
verify_hash_v2() is sole user of it.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 09:59:45 -04:00
af4e3c06bb ima-evm-utils: Convert cmd_import and calc keyid v2 to EVP_PKEY API
Introduce calc_pkeyid_v2() (which accepts EVP_PKEY) to replace
calc_keyid_v2() (which accepts RSA) in the future and use it in
cmd_import().

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 09:59:14 -04:00
3df7b5d779 ima-evm-utils: Convert read_priv_key to EVP_PKEY API
Introduce read_priv_pkey() to read keys using EVP_PKEY, and change
read_priv_key() to be wrapper for it.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 09:59:07 -04:00
71c1be47e7 ima-evm-utils: Convert read_pub_key to EVP_PKEY API
Introduce read_pub_pkey() to read keys using EVP_PKEY, and change
read_pub_key() to be wrapper for it.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-07-08 09:58:49 -04:00
2308132957 ima-evm-utils: update .gitignore files
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-05-23 10:07:27 -04:00
103b90d27c ima-evm-utils: include hash-info.gen into distribution
Include hash-info.gen into tarball and call it from the sourcedir to fix
out-of-tree build (and thus 'make distcheck').

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-05-23 10:07:27 -04:00
8acbae598b ima-evm-utils: replace INCLUDES with AM_CPPFLAGS
Replace INCLUDES variable with AM_CPPFLAGS to stop Automake from warning
about deprecated variable usage.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-05-23 10:07:27 -04:00
b09a25690f ima-evm-utils: link to libcrypto instead of OpenSSL
There is no need to link to full libssl. evmctl uses functions from
libcrypto, so let's link only against that library.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-05-23 10:07:27 -04:00
782224f33c ima-evm-utils: Rework openssl init
Remove deprecated call to OpenSSL_add_all_algorithms().
Allow to disable openssl config loading by evmctl via configure
`--disable-openssl-conf' option. Show status of that in configure.
Move config loading from libimaevm to evmctl.
Finish engine initialization properly by calling ENGINE_set_default(),
as suggested by James Bottomley.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-05-21 10:41:29 -04:00
ebbfc41ad6 ima-evm-utils: try to load digest by its alias
Primary names of the algorithms are different for OpenSSL and Kernel.
"Streebog" is a name of the hash algorithm in the Kernel Crypto API.
"md_gost12_X" is the name used by most versions of OpenSSL, it's
placed in pkey_hash_algo[] so that algo IDs are resolved to them.
Allow to use both names.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
[zohar@linux.ibm.com: updated patch description based input from Vitaly]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-05-21 10:41:02 -04:00
b628d8bfdb ima-evm-utils: Extract digest algorithms from hash_info.h
If configured with "--with-kernel-headers=PATH" try to extract hash
algorithms from "hash_info.h" from the kernel source tree or
kernel-headers package located in the specified path. (Otherwise, it
will be tried to get from the installed kernel.)

This also introduces two algorithm lists, one is built-in and another is
from the kernel source. (They should never contain conflicting algorithm
IDs by their append-only nature.) If the digest is not found in the
built-in list it will be searched in the list from kernel's
"hash_info.h".

This patch will allow evmctl to be just recompiled to work with digest
algorithms introduced in the newer kernels.

Suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2019-04-03 16:47:37 -04:00
07d799cb6c ima-evm-utils: Preload OpenSSL engine via '--engine' option
Another method of using GOST algorithms (and cryptographic accelerators)
is via direct preloading of appropriate engine using '--engine' option.
For the gost-engine it should be '--engine gost'.

Usage example:

1. Install gost-engine appropriately. (No need to edit openssl.cnf).

2. Then GOST algorithms should work:

  # cp /dev/null a
  # evmctl -v ima_hash --engine gost -a streebog256 a
  hash: 04123f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2018-12-03 06:08:36 -05:00
7e2a7840a7 ima-evm-utils: Allow using Streebog hash function
This patch will allow using GOST algorithms from OpenSSL's
gost-engine[1] via config extension (which is the usual way).

[1] https://github.com/gost-engine/engine

Full usage example:

1. Install the gost-engine package for your distro, this could be
libengine-gost-openssl1.1, openssl-gost-engine, or openssl-engines.

2. Edit openssl.cnf appropriately. Reference INSTALL.md of gost-engine
for the detailed instructions.

3. Then GOST algorithms should work:

  $ cp /dev/null a
  $ openssl dgst -streebog256 a
  md_gost12_256(a)= 3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb
  $ evmctl -v ima_hash -a streebog256 --xattr-user a
  hash: 04123f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb
  $ getfattr -d -m. -ehex a
  # file: a
  user.ima=0x04123f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2018-12-03 06:08:36 -05:00
b853b7ba93 ima-evm-utils: Define the '--xattr-user' option for testing
The IMA/EVM attributes are currently stored in the "security" namespace,
which requires root privileges. Storing the ima/evm attributes in the
"user" namespace, instead of the "security" namespace, would be useful
for debugging and testing purposes, and because "--sigfile" does not
work for evm signatures.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2018-12-03 06:08:36 -05:00
1d9c279279 ima-evm-utils: Define hash and sig buffer sizes and add asserts
To prevent hash and sig buffers size mismatch, define their maximum
sizes and add sanity checking asserts.

Suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2018-12-03 06:08:36 -05:00
9643544701 ima-evm-utils: Fix hash buffer overflow in verify_evm and hmac_evm
Commit ae1319eeab ("Remove hardcoding of SHA1 in EVM signatures")
introduces overflow of 20 byte buffer on the stack while calculating
hash. Also, invalid hash length is passed to the underlying verification
function in verify_evm. This prevents any non-SHA1 hashes from being
properly validated using evmctl.

Fixes: ae1319eeab ("Remove hardcoding of SHA1 in EVM signatures")
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2018-12-03 06:08:36 -05:00
15410695c7 ima-evm-utils: libimaevm: get key description out of verbose condition
Key description in keyring is being filled with memory garbage during
import process if the LOG_LEVEL is not satisfied (using '-vv').

Testing in kernels without trusted keyring support, and importing a v1
(RSA) key pair, the kernel fails to find the key since it looks for the
key description, which is not found due to this issue:

    "digsig: key not found, id: DD0558FEB7DDBD26"

Looking at:
    # keyctl show
    Session Keyring
     635748007 --alswrv      0     0  keyring: _ses
     673181018 --alswrv      0 65534   \_ keyring: _uid.0
     360651479 --alswrv      0     0       \_ keyring: _ima
     499360916 --alswrv      0     0       |   \_ user: .N=
     266933436 --alswrv      0     0       |   \_ user: B641632DA94DEE26

Key id 499360916 and 266933436 are both the same key, but the first was added
without '-vv' in the command line, while the second one was using it.

Signed-off-by: Bruno E. O. Meneguele <bmeneg@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2018-12-02 11:16:23 -05:00
8c8f29e870 ima-evm-utils: check the return code from tpm_pcr_read() in ima_measurement()
Don't log garbage when neither /sys/class/tpm/tpm0/device/pcrs nor
/sys/class/misc/tpm0/device/pcrs can be read and exit nicely with a
value of 1.

Signed-off-by: George Wilson <gcwilson@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-07-01 14:55:19 -04:00
9119f771a2 Add security.apparmor to the set of extended attributes used by EVM
The kernel is taking security.apparmor into account when validating EVM,
so evmctl should be doing the same.

Signed-off-by: Matthew Garrett <mjg59@google.com>
Signed-off-by: Mimi Zohar <zoahr@linux.vnet.ibm.com>

Changelog:
- Prevent compilation from failing due to XATTR_NAME_APPARMOR not being
included in the kernel-headers package.
2018-07-01 14:48:51 -04:00
ae1319eeab Remove hardcoding of SHA1 in EVM signatures
EVM signatures are always being generated with SHA1 even if the -a
argument has been provided to evmctl. Fix this so the provided hash
algorithm is used instead.

Signed-off-by: Matthew Garrett <mjg59@google.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Changelog:
- Like for cmd_sign_hash() and sign_ima(), the hash size for sign_evm()
should now be 64.
2018-07-01 14:48:51 -04:00
6aea54d2ad evmctl: use correct include for xattr.h
The xattr API/ABI is provided by both the c-library, as well as by the
libattr package. The c-library's header file is sys/xattr.h, whereas
libattr's header file can be found in attr/xattr.h.

Given none of the code here *links* against the libattr.so shared library, it
is wrong to *compile* against libattr's API (header file).

Doing so avoids confusion as to which xattr.h is used as the least problem,
and potential ABI differences as the worst problem due the mismatching header
file used.

So make sure we compile and link against the same thing, the c-library in
both cases.

Signed-off-by: André Draszik <git@andred.net>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-07-01 14:47:17 -04:00
5fa7d35de5 autotools: Try to find correct manpage stylesheet path
xslt docbook styles differ across distributions, which requires some
workarounds [1]. Try to check the manpage stylesheet path with
xmlcatalog and fallback to the original one.

Add option --with-xml-catalog to use non-default catalog.

+ remove trailing whitespace

[1] https://github.com/CESNET/ipfixcol/blob/master/base/m4/lbr_check_xsltproc.m4

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-05-07 07:51:32 -04:00
c860e0d9bb ima-evm-utils: Release version 1.1
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-02-15 08:02:19 -05:00
360655f059 Support different levels of output for "ima_measurement"
Instead of always displaying the entire measurement list, the default
behavior is just to return an error.  Verbose (-v) displays the key ids
used in validating the measurement list, the PCR aggregate and TPM PCR
values.  Verbose+ (-v -v) also displays the measurement list.

Signed-of-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-02-06 07:50:31 -05:00
057efc397d Include the file name in "ima_measurement" verification result
When displaying the measurement list, include the filename in the result.

Signed-of-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-02-06 07:50:01 -05:00
c2ef2aabe2 ima-evm-utils: sysfs pathname change
Commit 313d21e "tpm: device class for tpm" moved the TPM sysfs location
from /sys/class/misc/tpmX/device/ to /sys/class/tpm/tpmX/device/.

Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-01-29 14:24:03 -05:00
81010f0d87 ima-evm-utils: Add backward compatible support for openssl 1.1
Openssl 1.1 is really annoying in that it made certain objects opaque
and added accessors for the necessary componenets, but these accessors
often don't exist in 1.0 and before, so there's no way to create clean
code that will compile with both 1.0 and 1.1; instead you have to
compiled with both code bases to make sure everything is working).

The other problem is that since the structures are opaque, their size
isn't known, so having a structure declared as a variable is no longer
possible.

This change switches all uses of EVP_MD_CTX to be pointers initialised
with the correct EVP_MD_CTX_new() (not available in 1.0), does the
same for HMAC_CTX, and uses the 1.1 only primitve RSA_get0_key() to
extract the public modulus and exponent from an RSA key.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Tested-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-01-28 13:47:54 -05:00
6921833477 ima-evm-utils: add support for validating multiple pcrs
The IMA measurement list may contain records for different PCRs.  This
patch walks the measurement list, calculating a PCR aggregate value for
each PCR.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-01-28 10:02:18 -05:00
1a69e42ac1 ima-evm-utils: verify the measurement list signature based on the list digest
Instead of verifying file signatures included in the measurement list,
by calculating the local file hash, verify the file signature based on the
digest contained in the measurement list.

This patch defines a new option named "--list".

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-01-28 09:57:34 -05:00
9c79b7de72 ima-evm-utils: support verifying the measurement list using multiple keys
On a running system, different software packages might be signed by
different parties.  Support verifying signatures in the measurement
list using multiple public keys(eg.  -k "key1, key2, ...").

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-01-28 09:57:34 -05:00
838b08b449 ima-evm-utils: fix spelling error
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-01-28 09:57:34 -05:00
ba92e44719 ima-evm-utils: fix "ima_measurement" template fields length
The template data field length is uint32_t, not uint8_t.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2018-01-28 08:37:08 -05:00
4928548d9d Add support for portable EVM format
Add a --portable argument that generates EVM signatures without using
the inode number and generation or fs UUID.

Signed-off-by: Matthew Garrett <mjg59@google.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Changelog:
- immutable and portable flags are exclusive, prevent enabling both.
2017-11-16 15:02:40 -05:00
233dedffe9 Write out .sig file as security.ima xattr
To write the .sig file as security.ima xattr using setfattr first
requires converting the .sig file from binary to ascii-hex.  Although
this conversion can be done using hexdump, it is unnecessary when
calling setxattr.  This patch defines a new command called
"ima_setxattr", which calls lsetxattr() to write the .sig file as
the security.ima xattr.

Changelog:
- remove unnecessary copy
- fixed --sigfile option

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2016-03-06 07:55:04 -05:00
3e2a67bdb0 script to build static evmctl version
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
2015-10-01 22:42:45 +03:00
839a674580 Supply file attributes values on command line
Can be used by Android filesystem image creation tool.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
2015-09-20 23:28:20 +03:00
e55d286ad6 Use single flag to indicate 'no'flag
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
2015-09-20 23:15:32 +03:00
28d99354de Use byte range values
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
2015-09-20 22:22:06 +03:00
ea5ccdf38f Newer kernels requires at least 64 byte keys
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
2015-09-20 22:22:00 +03:00
b0d13ba557 calc_evm_hmac/hash: avoid fd leak when ioctl fails
When opening the file succeeds but ioctl() then fails, the file must
be closed before returning.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
2015-09-09 23:02:01 +03:00
199311e6a5 ima_verify: ignore -n flag
"evmutil ima_verify -n <some file>" disabled using xattrs without enabling
using a signature file, resulting in the use of uninitialized memory in
ima_verify_signature() and thus unpredictable results.

Such a mode of operation makes no sense, so interpret -n as
documented ("print result to stdout instead of setting xattr") and ignore it
during ima_verify. Instead, switch between the two verification modes only
via the global sigfile variable.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
2015-09-09 22:50:45 +03:00
453d3db8a5 tpm_pcr_read: close file when returning early
When return from inside the for() loop, the open file was not
closed.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
2015-09-09 22:50:35 +03:00
fa0b30b15e add_dir_hash: fix DIR leak in case of failure
When bailing out of the function due to EVP_DigestUpdate()
failing, the DIR resources allocated with opendir() were
not freed.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
2015-09-09 22:50:18 +03:00
4b56112c09 Release version 1.0
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
2015-07-30 21:28:53 +03:00
9c8a67a209 Prompt for the password
Supplying the password on the command line is not safe.  This patch
adds support for prompting the user to enter the password.  At some
point, supplying the pasword on the command line should be deprecated.

Prior to this patch, the password could be specified with a blank in
between the '-p' option and the password.  With this patch, the
password now must be adjacent

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2015-07-28 21:42:35 +03:00
96e55082c2 Must use 'const char*'
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
2015-07-24 22:51:39 +03:00
6a712b3b38 Add support for passing the private key password to sign_hash()
evmctl defines the "--pass | -p" command line option for providing
the private key's password.  The password is then stored in a global
variable accessible by the sign_hash_XXXX() functions.

This patch modifies the arguments to the library sign_hash()
function to include the password, allowing callers to specify the
private key password.

Changelog:
- add library init to call OpenSSL_add_all_algorithms

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2015-07-24 22:51:27 +03:00
17f49a1881 Add "ima_clear" command to remove IMA/EVM xattrs
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-10-29 21:38:03 +02:00
4d7d2c71a5 Define common function for recursive scanning
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-10-29 21:31:58 +02:00
92033dc404 Produce immutable EVM signature
'evmctl sign -i <file>' generates immutable EVM signature.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-10-29 13:00:43 +02:00
f805d4d0fe Fix typo
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-10-29 12:33:58 +02:00
8558dc5250 Add recursive hashing
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-10-02 19:22:19 +03:00
3d9bdc1de2 Release version 0.9
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-23 15:09:05 +03:00
f4fe504f98 Add 'evmctl --version' version reporting
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-23 14:40:18 +03:00
05d1f74559 Update README/man page documentation
Add more info on:
* introduction
* EVM formats
* Signature and keys formats
* IMA trusted keys and keyrings
* EVM trusted keys
* Updated scripts and examples

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-23 14:40:14 +03:00
a99a8a517c Provide command parameter to include extra SMACK xattrs for EVM signature
Latest versions of smack uses additional xattrs. This patch adds them to
EVM protection. Linux kernel configuration option CONFIG_EVM_EXTRA_SMACK_XATTRS
has to be enabled.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-17 16:02:22 +03:00
6261753e1e Use <linux/xattr.h> for security xattrs
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-17 16:01:12 +03:00
47d3048ce1 Make error and help messages more understandable
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-17 15:16:59 +03:00
14a90aa87c Make evmctl.1 as part of distribution and release
Do not require to re-build man file at the build process.
It will require less build dependencies.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-11 16:50:30 +03:00
635288f70f Update README to produce initial evmctl.1 man page
Update README with additional information to produce initial
evmctl.1 man page. Sligtly reformat it for that purpose as well.

Requires asciidoc, xslproc, docbook-xsl packages to build man page.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-11 16:50:30 +03:00
d5891ad96d Include example scripts to distribution and installation
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-11 16:50:30 +03:00
dede7cf850 Fix checkpatch errors
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-11 16:50:30 +03:00
8f04d131ac Move sign hash functions to library
This patch enables package managers, such as rpm, to include IMA signatures in
packages.

To do this, sign_hash and some helper functions were moved from evmctl to
libimaevm. These functions used global variables that belong to evmctl, sigdump
and keypass. The variable sigdump is a flag that file signatures should be
printed to stdout, so the signature dump is now handled by functions that call
sign_hash. The variable keypass is a passphrase for an encrypted key, so it was
added to 'struct libevm_params'.

v2: Uses 'struct libevm_params' to minimize sign_hash parameters
v3: Export single sign_hash function that selects _v1 or _v2 internally based
on params.x509. Moved parameter checks and explicitly return -1 for failures.

Signed-off-by: Fionnuala Gunter <fin@linux.vnet.ibm.com>
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-09-11 16:50:20 +03:00
29adc34d35 Remove local ioctl definitions and use <linux/fs.h>
Use standard flags, supported by ext2/3/4

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-06-25 18:54:55 +03:00
0636083acd Remove code duplication
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-06-25 18:54:55 +03:00
02594d3003 Switch to HMAC attribute mask
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-06-25 18:54:41 +03:00
c958062023 Fix setting correct hash header
'ima_hash -a sha256' and 'sign -a sha256 --imahash' commands did set
incorrect xattr header for hash algos other than sha1.

Fix it.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-06-24 15:54:37 +03:00
9bc24ee556 Use defined xattr types
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-06-24 15:54:37 +03:00
c5a2992bc8 Fix resource leak
Signed-off-by: Zbigniew Jasinski <z.jasinski@samsung.com>
2014-06-24 15:54:37 +03:00
dddef9172e make it possible to provide keyring id in hexadecimal format
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-06-13 12:59:14 +03:00
24c9e6adc7 add extra auto built files to .gitignore
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-06-13 12:58:16 +03:00
1a4c9ed2d6 Fix memory leak
Signed-off-by: Zbigniew Jasinski <z.jasinski@samsung.com>
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-05-30 17:58:46 +03:00
3a1ef5f5c7 Use proper loff_t type for file size
Signed-off-byL Zbigniew Jasinski <z.jasinski@samsung.com>
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-05-30 17:46:43 +03:00
7ece92b4e1 Release version 0.8
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-05-05 10:01:26 +03:00
dde9e21a4a Fix parameter name in help output
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-05-02 18:51:15 +03:00
6ec61ab9cb Remove unused 'x' parameter
'-x' option was removed a while ago, but 'x' was not removed
from getopt_long() parameter. Remove it.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-05-02 18:43:45 +03:00
77986c80ac Add Mimi to AUTHORS list
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-05-02 17:49:42 +03:00
2b893135be Update license text with OpenSSL exception clause
Ubuntu/Debian requires to provide OpenSSL exception clause.
This patch fixes it.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-05-02 17:19:47 +03:00
8feba3f462 Add support for signing a file hash
In a number of situations, the file hash has already been calculated.
Instead of reading a file to calculate the file hash, read the file hash
from stdin; and instead of writing the signature as an xattr or creating
a .sig file, output the signature as ascii-hex to stdout.

For example, piping the output of sha256sum <pathname> to evmctl would
display the original sha256 output with the file signature appended.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2014-03-26 14:50:20 +02:00
b0da7e69e0 Define symbolic keyring name
Currently evmctl supports importing keys onto a particular keyring
based on a numeric keyring identifier.  This patch adds support
for importing keys based special values as defined by keyctl.

   Thread keyring: @t (-1)
   Process keyring: @p (-2)
   Session keyring: @s (-3)
   User specific keyring: @u (-4)
   User default session keyring: @us (-5)
   Group specific keyring: @g (-6)

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2014-03-05 13:03:36 +02:00
bed3cc06f1 Release new version v0.7
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-02-17 16:29:20 +02:00
bddbd31a15 Provide random KMK example instead of fixed testing123
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-02-17 16:21:52 +02:00
c7042472e8 Limit includes in imaevm.h
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-02-17 15:56:07 +02:00
12af148131 Rename library, header file and export it.
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-02-17 15:56:07 +02:00
ca6b42ab17 Use --m32 and --m64 parameters also in HMAC signing code
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-02-17 15:56:07 +02:00
5e8564d155 Provide target architecture size parameter
'--m32|--m64' parameter can be specified to label images for different
architecture size than host.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-02-17 15:56:07 +02:00
f3cef2c047 Provide additional debug info for hmac_misc
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-02-17 15:56:07 +02:00
ef46876b10 Include only libraries to the package
Prevent including debug stuff to the main package.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-02-17 15:56:07 +02:00
5f30ed1da6 Remove experimental module signing functionality
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 16:04:47 +02:00
86a605eb10 Remove verify_hash parameter
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 15:59:24 +02:00
fd7e949c29 Remove x509 library parameter
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 15:37:54 +02:00
e92cbe4756 Remove user_hash_algo
Use always hash algo from signature like kernel does.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 15:27:49 +02:00
86d8772653 Use EVM v2 HMAC format by default
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 15:25:05 +02:00
317fa60467 Do use x509 by default
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 15:20:54 +02:00
f9a3d7c378 Select signing function in single place
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 15:01:17 +02:00
454350d294 Select verification function version in the library code
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 14:57:16 +02:00
4578679081 Remove user_sig_type flag
Always use signature type from signature header - like kernel does.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 14:54:59 +02:00
ff5f07e171 Use verify_hash() for EVM verification as well
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 14:50:09 +02:00
3299fba40d Move signature version checking to verify_hash()
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 14:48:02 +02:00
906861a308 Move hash verification to separate function
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 14:42:22 +02:00
6aabda5b65 Move signature verification implementation to the library
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-24 13:59:18 +02:00
018495c87f Initial library skeleton
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 18:43:44 +02:00
3dc656bc6f Implement recursive IMA signing
Recursive signing is needed when doing filesystem image signing.
Using script is very slow due to multiple forking and executing.
C-based implementation provides about 7 times performance improvements.
It is very significant when doing large image signing.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 15:27:20 +02:00
5b852c0fbb Rename de_type to search_type
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 15:27:20 +02:00
e4e0cabc21 Move file type checking to separate function
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 15:27:20 +02:00
51dbb77c4f Implement recursive EVM signing
Recursive signing is needed when doing filesystem image signing.
Using script is very slow due to multiple forking and executing.
C-based implementation provides about 7 times performance improvements.
It is very significant when doing large image signing.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 15:27:12 +02:00
eda8a164e0 Export find() declaration for the following patches
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 14:56:19 +02:00
6c0ebe2be6 Prevent reading of inode generation for special files in HMAC signing
Kernel API does not support at the momement reading of inode generation
number of special files, so do not do it also when do HMAC signing.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 14:56:19 +02:00
fd08fdeeb5 Prevent reading of inode generation for special files
Kernel API does not support at the momement reading of
generation number of special files, so do not do it.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 14:56:19 +02:00
05017f3e98 Use lgetxattr() instead of getxattr()
IMA/EVM extended attributes should be get for symbolic links themselves,
not to the entries pointed by them. setxattr() dereference symbolic links.
It is necessary to use lgetxattr().

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 14:56:19 +02:00
33ff9595e5 Use lsetxattr() instead of setxattr()
IMA/EVM extended attributes should be set for symbolic links themselves,
not to the entries pointed by them. setxattr() dereference symbolic links.
It is necessary to use lsetxattr().

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 12:47:47 +02:00
7045d70a1e Implement recursive efficient IMA fixing
Using scripts which do many forking and execution is very slow on
embedded/mobile devices. C based implementation is about 7 times faster.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-17 12:43:03 +02:00
323d81777d Script for generating self-signed certificate
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-16 13:36:18 +02:00
73f10810c0 Provide spec file for gbs build system
GBS build system requires specfile before configuring the package.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-16 13:35:22 +02:00
504e1d4013 Move spec file to packaging directory
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-16 13:34:48 +02:00
08043fc800 IMA measurement list verification (experimental)
PCR aggregate value is reconstructed using IMA measurement list and is compared
against TPM PCR-10. It also performs signature verification if it is available in
the measurement list. ima_measurement_new.c (Mimi Zohar) was used as an example.

Example:
  evmctl ima_measurement /sys/kernel/security/ima/binary_runtime_measurements

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2014-01-15 18:19:35 +02:00
afcef2b493 Define __packed
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-11-12 19:27:36 +02:00
20f1837d51 Provide hexdump functions without new line
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-11-12 19:20:58 +02:00
6918bfbf20 split signature verification function for passing signature as an argument
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-11-12 18:35:16 +02:00
092d5cc15d scripts to generate ca and keys
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-11-01 01:30:40 +02:00
78ccd56afe License changed from LGPL to GPL as in COPYING
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-09-04 16:51:44 +03:00
f1ba3e7b45 Version 0.6 release
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-08-28 16:37:52 +03:00
d7d74e5648 Fix cleanup in the case of errors
Proper memory cleanup is not really necessary for command line
utility because all memory is cleaned up when it quits. But as
code does it most of the cases, fix other places.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-08-28 15:20:16 +03:00
15dab873b5 fix the crash when key file is not found
Error in error handling caused crash when key file is not found.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-08-27 15:44:18 +03:00
971b286169 make --imahash or --imasig optional for EVM signing
One might not want to change/set IMA xattr value when performing
EVM signing.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-08-13 16:55:14 +03:00
2406322914 perform uuid format checking and error handling
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-08-13 16:55:14 +03:00
b3a5fcbca2 make argument for '-u' option as optional
-u required to provide uuid or '-', which was confusing.
Now -u does not require '-' argument to read uuid automatically.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-08-13 16:55:10 +03:00
59ef0a0b99 Save full security.ima attribute to a file
Right now if -f option is passed in, we only save the actual signature to
a file and not the full security.ima attribute.

I think it makes more sense to save full security.ima attribute so that
it can act as detached signatures and one can install signature later.
That is signing can take place on build server and detached signatures
can be generated and these signatures can be installed later on target.

One can use following steps.

evmctl ima_sign -f -x -a sha256 /tmp/data.txt

hexdump -v -e '1/1 "%02x"' /tmp/data.txt.sig > /tmp/data.txt.sig.hex
printf "# file: /tmp/data.txt\nsecurity.ima=0x" | cat - /tmp/data.txt.sig.hex | setfattr --restore -

evmctl ima_verify /tmp/data.txt

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-08-09 15:57:26 +03:00
ab18c60ec1 Get signature version from the header
Currently we assume signature version is v1 until and unless -x is
specified on kernel command line. Given the fact that signature version
information is available in signature itself, it is much better to get
it from there and not require user to pass -x during verification phase.

If user passed -x on command line, then honor it.

Now one can do following.

	evmctl ima_sign -x /tmp/data.txt
	evmctl ima_verify /tmp/data.txt

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-08-09 15:57:26 +03:00
d9678295b9 Move key file selection to later phase
Following patch reads signature version from header and based
on that key file needs to be selected.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-08-09 15:57:18 +03:00
0df73005a3 Use enums for signature versions
Using enums for fixed values looks cleaner. Also I am planning to use
version field in more places in next patch. So use enums intead of
numbers like 1 and 2.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-08-09 15:55:53 +03:00
b49e2251a0 Let user specified hash algo take precedence
After applying previous patch, we will always get hash algo info from
signature and if user specified one on command line, that will be overridden.

This is like breaking old behavior. So keep track whether user specified
hash algo on command line or not. If user did not specify one then get
hash algo info from signature otherwise use the one user provided.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-08-09 15:55:49 +03:00
fa3c365cce Get hash algorithm info from the signature
If one signs a file using hash algo -sha256 then one needs to specify
signature during verification also. Otherwise evmctl using default sha1
for calculating hash and signature verification fails. One needs to
specify -a sha256 on command line even during signature verification
phase to make sure file is signed right.

I think that's completely unnecessary. A user is not always supposed
to know what algorithm was used to generate signature. User is only
concered with whether this signature is valid or not.

So retrieve hash algorithm info from signature and use that.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-07-15 18:02:02 +03:00
00caa1d5ba Put right hash algo info in digital signature version 1 header
hdr->hash for signature version 1 contains the info about what hash
algorithm has been used for signing the file. Currently we always set
hdr->hash to DIGEST_ALGO_SHA1. But one can sign file using SHA256 using
option "-a sha256". In that case we should put right hash algo info
in signature header. Fix it.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-07-15 18:01:05 +03:00
b48f4f9c7e Fix hash array size in verify_ima()
Now evmctl supports different hash algorithms and sha512 will produce
64 byte digest. verify_ima() still allocates only 20bytes to store hash.
This does not work with larger hashes.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-07-15 18:00:32 +03:00
16d40dbdf6 evmctl: Fix signature verification code for V2 digital signature
For V2 of digital signature we store signature at hdr->sig and not at
hdr->sig + 2. That's the property of V1 of signature.

Fix the verification code otherwise it fails with following message.

RSA_public_decrypt() failed: -1
error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01
error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
2013-07-10 16:45:38 +01:00
3f0c0a3c84 Fix verification using signature file
Signature file does not contain xattr prefix.
Add signature xattr prefix manually.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
2013-07-10 16:00:53 +01:00
076fd302bb support for asymmetric crypto keys and new signature format
Asymmetric keys were introduced in linux-3.7 to verify the signature on
signed kernel modules. The asymmetric keys infrastructure abstracts the
signature verification from the crypto details. Asymmetric crypto keys
support allows to import X509 public key certificate in a DER format
into the kernel keyring. Asymmetric keys require a new signature format.
'evmctl -x' or 'evmctl --x509' option can be used to utilize new
signature format.

Using of key filename after the file name for signing and verification commands
is a bit odd. This patch add '--key' parameter to specify non-default key file.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2013-02-11 16:12:08 +02:00
1d24a94bb5 added uuid support for EVM
Latest version of EVM uses file system UUID as part of an HMAC
calculation to prevent pasting of inode metadata from other file
systems. This patch adds support for adding file system UUID
to HMAC calculation. It is necessary to specify '-u -' or '--uuid -'
on evmctl command line.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2013-02-11 16:07:30 +02:00
5be54eaca4 Update README
README updated.
Module signing info has been removed. Module signing is done now in kernel
source tree and uses appended signatures. No need to create sig files or
set extended attributes. Information about test scripts has been removed.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-10 15:37:40 +03:00
a58cd9f4af Remove test scripts
Test scripts are not used at all.
All needed information is in README.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-10 15:17:42 +03:00
c8b4f34fd4 remove directory entry list sorting
Directory entries list sorting is not needed.
Entries are read always in the same order.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:54 +03:00
c171931236 added ima signature verification support
For debugging puporse it is usefull to have signature verification
functionality. It supports use of xattrs and .sig files.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:54 +03:00
ba07c9d4b1 do not output type prefix for sig files
sig files do not need type prefix as they are contain only signatures.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:54 +03:00
203f058903 added support for kernel module signature
Kernel module signature is appended to the kernel module.
Kernel signature also contains signature length and magic.
Added --modsig parameter to generate kernel module signature.

Signature can be added to the module like: cat module.sig >> module.ko

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:54 +03:00
72ad26c3be disable printing signature when using sigfiles
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:54 +03:00
f41d43026b Remove tag creation
Better to create tag manually when release is done.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:54 +03:00
4ae323778e Version 0.3
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
1001b9f992 Added hash calculation for special files
New IMA kernel patches support appraisal of special files,
such as links, device nodes, fifos.

This patch adds support to calculate hash for special files
to be set to security.ima extended attribute.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
307f8162eb Refactored to remove redundant hash initialization code
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
ef74ed1ab2 Do not search for algorithm as it is known
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
588cbb7492 Some files updated
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
bcaadb1205 Use libexec for programs and scripts
Newer automake does not like to put programs and scripts
to lib directory. Use libexec instead.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
f60ffc2109 Remove forced tag creation
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
9c4d793034 inline block variable renamed
err shadows function lever err.
Renamed it to error.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
42e40570e6 Added entry type to directory hash calculation
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
13571ace6b llistxattr returns 0 if there are no xattrs and it is valid
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
76f3496455 evm-utils renamed to ima-evm-utils.
Version set to 0.2.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
dc36ed86d3 Added RPM and TAR building rules
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
de89119dbf added command options description
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
04e3ff3ef5 removed unused parameter
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
5769fb1833 import functions combined
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
52960f8b93 updated error handling
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
e576ac9771 read list of existing extended attributes
getxattr() might return runtime value which does not really exist
on file system. It happens for SMACK LSM. Reading the list of existing
attributes allows to prevent such to happen.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
d61b9c0be7 added HMAC API error handling
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
1e2934d9a3 version 0.1.0 2012-09-06 14:08:53 +03:00
c13fce4028 remove unused parameter
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
aa2f6e9b63 Changed time_t timestamp type to uint32_t
time_t is actually long and is different on 32 and 64 bit architectures.
Format of the signatures should not depend on the architecture and should
be the same. Changed timestamp to uint32_t like in GPG.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:53 +03:00
ff071501d0 Added missing CFLAGS
Added missing CFLAGS

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:52 +03:00
f2b486e053 Added signature write to .sig file
To enable module signature verification working on file systems
without extended attributes, or to be able to copy modules by methods,
which does not support extended attribute copying, it is necessary
to store signature in the file. This patch provides command line parameter
for storing signature in .sig file.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:52 +03:00
e3f11d343a Change set_xattr to xattr.
set_xattr changed to xattr.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:52 +03:00
7e89de565e Changed to conform Linux kernel coding style
Changed to conform Linux kernel coding style, except 80 characters
line length limit.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:52 +03:00
e91cb01e9a added password parameter for using encrypted keys
Added password parameter for using encrypted keys.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:52 +03:00
b0966fd243 added openssl initialization and error reporting
Added openssl initialization and error reporting.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:52 +03:00
0b197c4d30 minor fixes
- error message
- command info

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
2012-09-06 14:08:52 +03:00
67 changed files with 7898 additions and 931 deletions

137
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,137 @@
# Copyright (c) 2021 Petr Vorel <pvorel@suse.cz>
name: "distros"
on: [push, pull_request]
jobs:
job:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
# 32bit build
- container: "debian:stable"
env:
CC: gcc
ARCH: i386
TSS: tpm2-tss
VARIANT: i386
COMPILE_SSL: openssl-3.0.0-beta1
# cross compilation builds
- container: "debian:stable"
env:
ARCH: ppc64el
CC: powerpc64le-linux-gnu-gcc
TSS: ibmtss
VARIANT: cross-compile
- container: "debian:stable"
env:
ARCH: arm64
CC: aarch64-linux-gnu-gcc
TSS: tpm2-tss
VARIANT: cross-compile
- container: "debian:stable"
env:
ARCH: s390x
CC: s390x-linux-gnu-gcc
TSS: ibmtss
VARIANT: cross-compile
# musl (native)
- container: "alpine:latest"
env:
CC: gcc
TSS: tpm2-tss
# glibc (gcc/clang)
- container: "opensuse/tumbleweed"
env:
CC: clang
TSS: ibmtss
COMPILE_SSL: openssl-3.0.0-beta1
- container: "opensuse/leap"
env:
CC: gcc
TSS: tpm2-tss
- container: "ubuntu:groovy"
env:
CC: gcc
TSS: ibmtss
COMPILE_SSL: openssl-3.0.0-beta1
- container: "ubuntu:xenial"
env:
CC: clang
TSS: tpm2-tss
- container: "fedora:latest"
env:
CC: clang
TSS: ibmtss
- container: "centos:7"
env:
CC: gcc
TSS: tpm2-tss
- container: "centos:latest"
env:
CC: gcc
TSS: tpm2-tss
- container: "debian:testing"
env:
CC: clang
TSS: tpm2-tss
- container: "debian:stable"
env:
CC: clang
TSS: ibmtss
- container: "alt:sisyphus"
env:
CC: gcc
TSS: libtpm2-tss-devel
container:
image: ${{ matrix.container }}
env: ${{ matrix.env }}
options: --security-opt seccomp=unconfined
steps:
- name: Show OS
run: cat /etc/os-release
- name: Git checkout
uses: actions/checkout@v1
- name: Install additional packages
run: |
INSTALL=${{ matrix.container }}
INSTALL="${INSTALL%%:*}"
INSTALL="${INSTALL%%/*}"
if [ "$VARIANT" ]; then ARCH="$ARCH" ./ci/$INSTALL.$VARIANT.sh; fi
ARCH="$ARCH" CC="$CC" TSS="$TSS" ./ci/$INSTALL.sh
if [ "$COMPILE_SSL" ]; then COMPILE_SSL="$COMPILE_SSL" ./tests/install-openssl3.sh; fi
- name: Build swtpm
run: |
if [ ! "$VARIANT" ]; then
which tpm_server || which swtpm || \
if which tssstartup; then
./tests/install-swtpm.sh;
fi
fi
- name: Compiler version
run: $CC --version
- name: Compile
run: CC="$CC" VARIANT="$VARIANT" ./build.sh

6
.gitignore vendored
View File

@ -2,6 +2,8 @@
*~
# Generated by autotools
.libs
m4
.deps
aclocal.m4
autom4te.cache
@ -19,10 +21,13 @@ missing
compile
libtool
ltmain.sh
test-driver
# Compiled executables
*.o
*.a
*.lo
*.la
src/evmctl
tests/openclose
config.h
@ -40,6 +45,7 @@ cscope.*
ncscope.*
# Generated documentation
*.1
*.8
*.5
manpage.links

98
.travis.yml Normal file
View File

@ -0,0 +1,98 @@
# Copyright (c) 2017-2021 Petr Vorel <pvorel@suse.cz>
dist: bionic
language: C
services:
- docker
matrix:
include:
# 32 bit build
- os: linux
env: DISTRO=debian:stable VARIANT=i386 ARCH=i386 TSS=tpm2-tss COMPILE_SSL=openssl-3.0.0-beta1
compiler: gcc
# cross compilation builds
- os: linux
env: DISTRO=debian:stable VARIANT=cross-compile ARCH=ppc64el TSS=ibmtss
compiler: powerpc64le-linux-gnu-gcc
- os: linux
env: DISTRO=debian:stable VARIANT=cross-compile ARCH=arm64 TSS=tpm2-tss
compiler: aarch64-linux-gnu-gcc
- os: linux
env: DISTRO=debian:stable VARIANT=cross-compile ARCH=s390x TSS=ibmtss
compiler: s390x-linux-gnu-gcc
# musl
- os: linux
env: DISTRO=alpine:latest TSS=tpm2-tss CONTAINER=podman CONTAINER_ARGS="--runtime=/usr/bin/crun --network=host"
compiler: gcc
# glibc (gcc/clang)
- os: linux
env: DISTRO=opensuse/tumbleweed TSS=ibmtss CONTAINER=podman CONTAINER_ARGS="--runtime=/usr/bin/crun --network=host" COMPILE_SSL=openssl-3.0.0-beta1
compiler: clang
- os: linux
env: DISTRO=opensuse/leap TSS=tpm2-tss
compiler: gcc
- os: linux
env: DISTRO=ubuntu:groovy TSS=ibmtss COMPILE_SSL=openssl-3.0.0-beta1
compiler: gcc
- os: linux
env: DISTRO=ubuntu:xenial TSS=tpm2-tss
compiler: clang
- os: linux
env: DISTRO=fedora:latest TSS=ibmtss CONTAINER=podman CONTAINER_ARGS="--runtime=/usr/bin/crun --network=host"
compiler: clang
- os: linux
env: DISTRO=centos:7 TSS=tpm2-tss
compiler: gcc
- os: linux
env: DISTRO=centos:latest TSS=tpm2-tss
compiler: clang
- os: linux
env: DISTRO=debian:testing TSS=tpm2-tss
compiler: clang
- os: linux
env: DISTRO=debian:stable TSS=ibmtss
compiler: gcc
- os: linux
env: REPO="docker.io/library/" DISTRO=${REPO}alt:sisyphus TSS=libtpm2-tss-devel CONTAINER=podman CONTAINER_ARGS="--runtime=/usr/bin/crun --network=host"
compiler: gcc
before_install:
# Tumbleweed requires podman due docker incompatible with glibc 2.33
# (faccessat2) and crun (for clone3).
- CONTAINER="${CONTAINER:-docker}"
- >
if [ "$CONTAINER" = "podman" ]; then
# podman
. /etc/os-release
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/xUbuntu_${VERSION_ID}/Release.key -O- | sudo apt-key add -
sudo apt update
sudo apt -y install podman slirp4netns crun
fi
- $CONTAINER info
- DIR="/usr/src/ima-evm-utils"
- printf "FROM $DISTRO\nRUN mkdir -p $DIR\nWORKDIR $DIR\nCOPY . $DIR\n" > Dockerfile
- cat Dockerfile
- $CONTAINER build $CONTAINER_ARGS -t ima-evm-utils .
script:
- INSTALL="${DISTRO#${REPO}}"
- INSTALL="${INSTALL%%:*}"
- INSTALL="${INSTALL%%/*}"
- $CONTAINER run $CONTAINER_ARGS -t ima-evm-utils /bin/sh -c "if [ \"$VARIANT\" ]; then ARCH=\"$ARCH\" ./ci/$INSTALL.$VARIANT.sh; fi && ARCH=\"$ARCH\" CC=\"$CC\" TSS=\"$TSS\" ./ci/$INSTALL.sh && if [ "$COMPILE_SSL" ]; then COMPILE_SSL="$COMPILE_SSL" ./tests/install-openssl3.sh; fi && if [ ! \"$VARIANT\" ]; then which tpm_server || which swtpm || if which tssstartup; then ./tests/install-swtpm.sh; fi; fi && CC=\"$CC\" VARIANT=\"$VARIANT\" ./build.sh"

View File

@ -1,2 +1,6 @@
Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Dmitry Kasatkin <d.kasatkin@samsung.com>
CONTRIBUTORS:
Vivek Goyal <vgoyal@redhat.com>
Mimi Zohar <zohar@linux.vnet.ibm.com>

339
COPYING
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -1,10 +0,0 @@
2012-04-02 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
version 0.1.0
* Fully functional version for lastest 3.x kernels
2011-08-24 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
version 0.1
* Initial public version.

42
INSTALL
View File

@ -1,18 +1,41 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Prerequisites
=============
This project has the following prerequisites:
(Ubuntu package names)
libkeyutils-dev
libtasn1-dev
libgmp-dev
libnspr4-dev
libnss3-dev
These software TPMs are supported:
https://sourceforge.net/projects/ibmswtpm2/
https://github.com/stefanberger/swtpm
swtpm depends upon
https://github.com/stefanberger/libtpms
Supported TSSes include these. Both are included in some distros.
IBM TSS https://sourceforge.net/projects/ibmtpm20tss/
Intel TSS
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
Briefly, the shell commands `autoreconf -i; ./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
@ -51,7 +74,7 @@ of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
`autoreconf -i' and then `./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
@ -226,6 +249,11 @@ order to use an ANSI C compiler:
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
@ -304,9 +332,10 @@ causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
an Autoconf limitation. Until the limitation is lifted, you can use
this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
@ -362,4 +391,3 @@ operates.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@ -1,6 +1,12 @@
SUBDIRS = src tests
if MANPAGE_DOCBOOK_XSL
dist_man_MANS = evmctl.1
endif
#EXTRA_DIST = LEGAL acinclude.m4 include
doc_DATA = examples/ima-genkey-self.sh examples/ima-genkey.sh examples/ima-gen-local-ca.sh
EXTRA_DIST = autogen.sh $(doc_DATA)
CLEANFILES = *.html *.xsl
ACLOCAL_AMFLAGS = -I m4
@ -11,8 +17,7 @@ pkgname = $(PACKAGE_NAME)-$(PACKAGE_VERSION)
tarname = $(pkgname).tar.gz
$(tarname):
git tag -f v$(PACKAGE_VERSION)
git archive --format=tar --prefix=$(pkgname)/ v$(PACKAGE_VERSION) $(FILES) | gzip >$@;
git archive --format=tar --prefix=$(pkgname)/ v$(PACKAGE_VERSION) $(FILES) | gzip >$@
tar: $(tarname)
@ -20,4 +25,19 @@ rpm: $(tarname)
cp $(tarname) $(SRCS)/
rpmbuild -ba --nodeps $(SPEC)
if MANPAGE_DOCBOOK_XSL
evmctl.1.html: README
@asciidoc -o $@ $<
evmctl.1:
asciidoc -d manpage -b docbook -o evmctl.1.xsl README
xsltproc --nonet -o $@ $(MANPAGE_DOCBOOK_XSL) evmctl.1.xsl
rm -f evmctl.1.xsl
rmman:
rm -f evmctl.1
doc: evmctl.1.html rmman evmctl.1
endif
.PHONY: $(tarname)

222
NEWS
View File

@ -0,0 +1,222 @@
2021-10-22 Mimi Zohar <zohar@linux.ibm.com>
version 1.4:
* Elliptic curve support and tests
* PKCS11 support and tests
* Ability to manually specify the keyid included in the IMA xattr
* Improve IMA measurement list per TPM bank verification
* Linking with IBM TSS
* Set default hash algorithm in package configuration
* (Minimal) support and test EVM portable signatures
* CI testing:
* Refresh and include new distros
* Podman support
* GitHub Actions
* Limit "sudo" usage
* Misc bug fixes and code cleanup
* Fix static analysis bug reports, memory leaks
* Remove experimental code that was never upstreamed in the kernel
* Use unsigned variable, remove unused variables, etc
2020-10-28 Mimi Zohar <zohar@linux.ibm.com>
version 1.3.2:
* Bugfixes: importing keys
* NEW: Docker based travis distro testing
* Travis bugfixes, code cleanup, software version update,
and script removal
* Initial travis testing
2020-08-11 Mimi Zohar <zohar@linux.ibm.com>
version 1.3.1:
* "--pcrs" support for per crypto algorithm
* Drop/rename "ima_measurement" options
* Moved this summary from "Changelog" to "NEWS", removing
requirement for GNU empty files
* Distro build fixes
2020-07-21 Mimi Zohar <zohar@linux.ibm.com>
version 1.3 new features:
* NEW ima-evm-utils regression test infrastructure with two initial
tests:
- ima_hash.test: calculate/verify different crypto hash algorithms
- sign_verify.test: EVM and IMA sign/verify signature tests
* TPM 2.0 support
- Calculate the new per TPM 2.0 bank template data digest
- Support original padding the SHA1 template data digest
- Compare ALL the re-calculated TPM 2.0 bank PCRs against the
TPM 2.0 bank PCR values
- Calculate the per TPM bank "boot_aggregate" values, including
PCRs 8 & 9 in calculation
- Support reading the per TPM 2.0 Bank PCRs using Intel's TSS
- boot_aggregate.test: compare the calculated "boot_aggregate"
values with the "boot_aggregate" value included in the IMA
measurement.
* TPM 1.2 support
- Additionally support reading the TPM 1.2 PCRs from a supplied file
("--pcrs" option)
* Based on original IMA LTP and standalone version support
- Calculate the TPM 1.2 "boot_aggregate" based on the exported
TPM 1.2 BIOS event log.
- In addition to verifying the IMA measurement list against the
the TPM PCRs, verify the IMA template data digest against the
template data. (Based on LTP "--verify" option.)
- Ignore file measurement violations while verifying the IMA
measurment list. (Based on LTP "--validate" option.)
- Verify the file data signature included in the measurement list
based on the file hash also included in the measurement list
(--verify-sig)
- Support original "ima" template (mixed templates not supported)
* Support "sm3" crypto name
Bug fixes and code cleanup:
* Don't exit with -1 on failure, exit with 125
* On signature verification failure, include pathname.
* Provide minimal hash_info.h file in case one doesn't exist, needed
by the ima-evm-utils regression tests.
* On systems with TPM 1.2, skip "boot_aggregate.test" using sample logs
* Fix hash_algo type comparison mismatch
* Simplify/clean up code
* Address compiler complaints and failures
* Fix memory allocations and leaks
* Sanity check provided input files are regular files
* Revert making "tsspcrread" a compile build time decision.
* Limit additional messages based on log level (-v)
2019-07-30 Mimi Zohar <zohar@linux.ibm.com>
version 1.2.1 Bug fixes:
* When verifying multiple file signatures, return correct status
* Don't automatically use keys from x509 certs if user supplied "--rsa"
* Fix verifying DIGSIG_VERSION_1 signatures
* autoconf, openssl fixes
2019-07-24 Mimi Zohar <zohar@linux.ibm.com>
version 1.2 new features:
* Generate EVM signatures based on the specified hash algorithm
* include "security.apparmor" in EVM signature
* Add support for writing & verifying "user.xxxx" xattrs for testing
* Support Strebog/Gost hash functions
* Add OpenSSL engine support
* Use of EVP_PKEY OpenSSL API to generate/verify v2 signatures
* Support verifying multiple signatures at once
* Support new template "buf" field and warn about other unknown fields
* Improve OpenSSL error reporting
* Support reading TPM 2.0 PCRs using tsspcrread
Bug fixes and code cleanup:
* Update manpage stylesheet detection
* Fix xattr.h include file
* On error when reading TPM PCRs, don't log gargabe
* Properly return keyid string to calc_keyid_v1/v2 callers, caused by
limiting keyid output to verbose mode
* Fix hash buffer overflow caused by EVM support for larger hashes,
defined MAX_DIGEST_SIZE and MAX_SIGNATURE_SIZE, and added "asserts".
* Linked with libcrypto instead of OpenSSL
* Updated Autotools, replacing INCLUDES with AM_CPPFLAGS
* Include new "hash-info.gen" in tar
* Log the hash algorithm, not just the hash value
* Fixed memory leaks in: EV_MD_CTX, init_public_keys
* Fixed other warnings/bugs discovered by clang, coverity
* Remove indirect calls in verify_hash() to improve code readability
* Don't fallback to using sha1
* Namespace some too generic object names
* Make functions/arrays static if possible
2018-01-28 Mimi Zohar <zohar@us.ibm.com>
version 1.1
* Support the new openssl 1.1 api
* Support for validating multiple pcrs
* Verify the measurement list signature based on the list digest
* Verify the "ima-sig" measurement list using multiple keys
* Fixed parsing the measurement template data field length
* Portable & immutable EVM signatures (new format)
* Multiple fixes that have been lingering in the next branch. Some
are for experimental features that are not yet supported in the
kernel.
2014-07-30 Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
version 1.0
* Recursive hashing
* Immutable EVM signatures (experimental)
* Command 'ima_clear' to remove xattrs
* Support for passing password to the library
* Support for asking password safely from the user
2014-09-23 Dmitry Kasatkin <d.kasatkin@samsung.com>
version 0.9
* Updated README
* man page generated and added to the package
* Use additional SMACK xattrs for EVM signature generation
* Signing functions moved to libimaevm for external use (RPM)
* Fixed setting of correct hash header
2014-05-05 Dmitry Kasatkin <d.kasatkin@samsung.com>
version 0.8
* Symbilic names for keyrings
* Hash list signing
* License text fix for using OpenSSL
* Help output fix
2014-02-17 Dmitry Kasatkin <d.kasatkin@samsung.com>
version 0.7
* Fix symbolic links related bugs
* Provide recursive fixing
* Provide recursive signing
* Move IMA verification to the library (first for LTP use)
* Support for target architecture data size
* Remove obsolete module signing code
* Code cleanup
2013-08-28 Dmitry Kasatkin <d.kasatkin@samsung.com>
version 0.6
* support for asymmetric crypto keys and new signature format (v2)
* fixes to set correct hash algo for digital signature v1
* uuid support for EVM
* signature verification support
* test scripts removed
* README updates
2012-05-18 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
version 0.3
* llistxattr returns 0 if there are no xattrs and it is valid
* Added entry type to directory hash calculation
* inline block variable renamed
* Remove forced tag creation
* Use libexec for programs and scripts
* Some files updated
* Do not search for algorithm as it is known
* Refactored to remove redundant hash initialization code
* Added hash calculation for special files
2012-04-05 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
version 0.2
* added RPM & TAR building makefile rules
* renamed evm-utils to ima-evm-utils
* added command options description
* updated error handling
* refactored redundant code
2012-04-02 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
version 0.1.0
* Fully functional version for lastest 3.x kernels
2011-08-24 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
version 0.1
* Initial public version.

467
README
View File

@ -1,52 +1,457 @@
EVMCTL(1)
=========
1. Generate private key
NAME
----
# plain key
openssl genrsa -out privkey_evm.pem 1024
evmctl - IMA/EVM signing utility
# encrypted key
openssl genrsa -des3 -out privkey_evm.pem 1024
# set password for the key
openssl rsa -in /etc/keys/privkey_evm.pem -out privkey_evm_enc.pem -des3
or
openssl pkcs8 -topk8 -in /etc/keys/privkey_evm.pem -out privkey_evm_enc.pem
SYNOPSIS
--------
2. Generate public key
evmctl [options] <command> [OPTIONS]
openssl rsa -pubout -in privkey_evm.pem -out pubkey_evm.pem
3. Copy public (+private if to sign on device) key to the device/qemu /etc/keys
DESCRIPTION
-----------
scp pubkey_evm.pem mad:/etc/keys
The evmctl utility can be used for producing and verifying digital signatures,
which are used by Linux kernel integrity subsystem (IMA/EVM). It can be also
used to import keys into the kernel keyring.
4. Load keys and enable EVM
COMMANDS
--------
evm_enable.sh
--version
help <command>
import [--rsa] pubkey keyring
sign [-r] [--imahash | --imasig ] [--portable] [--key key] [--pass password] file
verify file
ima_boot_aggregate [--pcrs hash-algorithm,file] [TPM 1.2 BIOS event log]
ima_sign [--sigfile] [--key key] [--pass password] file
ima_verify file
ima_hash file
ima_measurement [--ignore-violations] [--verify-sig [--key "key1, key2, ..."]] [--pcrs [hash-algorithm,]file [--pcrs hash-algorithm,file] ...] file
ima_fix [-t fdsxm] path
sign_hash [--key key] [--pass password]
hmac [--imahash | --imasig ] file
This should be done at early phase, before mounting root filesystem.
5. Sign EVM and use hash value for IMA - common case
OPTIONS
-------
evmctl sign --imahash test.txt
-a, --hashalgo sha1, sha224, sha256, sha384, sha512
-s, --imasig make IMA signature
-d, --imahash make IMA hash
-f, --sigfile store IMA signature in .sig file instead of xattr
--xattr-user store xattrs in user namespace (for testing purposes)
--rsa use RSA key type and signing scheme v1
-k, --key path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem)
or a pkcs11 URI
--keyid n overwrite signature keyid with a 32-bit value in hex (for signing)
--keyid-from-cert file
read keyid value from SKID of a x509 cert file
-o, --portable generate portable EVM signatures
-p, --pass password for encrypted signing key
-r, --recursive recurse into directories (sign)
-t, --type file types to fix 'fxm' (f: file)
x - skip fixing if both ima and evm xattrs exist (use with caution)
m - stay on the same filesystem (like 'find -xdev')
-n print result to stdout instead of setting xattr
-u, --uuid use custom FS UUID for EVM (unspecified: from FS, empty: do not use)
--smack use extra SMACK xattrs for EVM
--m32 force EVM hmac/signature for 32 bit target system
--m64 force EVM hmac/signature for 64 bit target system
--engine e preload OpenSSL engine e (such as: gost)
--pcrs file containing TPM pcrs, one per hash-algorithm/bank
--ignore-violations ignore ToMToU measurement violations
--verify-sig verify the file signature based on the file hash, both
stored in the template data.
-v increase verbosity level
-h, --help display this help and exit
6. Sign IMA and EVM - for immutable files and modules
Environment variables:
evmctl sign --imasig test.txt
EVMCTL_KEY_PASSWORD : Private key password to use; do not use --pass option
7. Sign whole filesystem
evm_sign_all.sh
or
find / \( -fstype rootfs -o -fstype ext3 -o -fstype ext4 \) ! -path "/lib/modules/*" -type f -uid 0 -exec evmctl sign --imahash '{}' \;
find /lib/modules ! -name "*.ko" -type f -uid 0 -exec evmctl sign --imahash '{}' \;
# security.ima needs to have signature for modules
find /lib/modules -name "*.ko" -type f -uid 0 -exec evmctl sign --imasig '{}' \;
INTRODUCTION
------------
# generate signatures in .sig files
find /lib/modules -name "*.ko" -type f -uid 0 -exec evmctl -n --sigfile ima_sign '{}' \;
Linux kernel integrity subsystem is comprised of a number of different components
including the Integrity Measurement Architecture (IMA), Extended Verification Module
(EVM), IMA-appraisal extension, digital signature verification extension and audit
measurement log support.
8. Label filesystem in fix mode...
The evmctl utility is used for producing and verifying digital signatures, which
are used by the Linux kernel integrity subsystem. It is also used for importing keys
into the kernel keyring.
ima_fix_dir.sh <dir>
Linux integrity subsystem allows to use IMA and EVM signatures. EVM signature
protects file metadata, such as file attributes and extended attributes. IMA
signature protects file content.
For more detailed information about integrity subsystem it is recommended to follow
resources in RESOURCES section.
EVM HMAC and signature metadata
-------------------------------
EVM protects file metadata by including following attributes into HMAC and signature
calculation: inode number, inode generation, UID, GID, file mode, security.selinux,
security.SMACK64, security.ima, security.capability.
EVM HMAC and signature in may also include additional file and file system attributes.
Currently supported additional attributes are filesystem UUID and extra SMACK
extended attributes.
Kernel configuration option CONFIG_EVM_ATTR_FSUUID controls whether to include
filesystem UUID into HMAC and enabled by default. Therefore evmctl also includes
fsuuid by default. Providing '--uuid' option without parameter allows to disable
usage of fs uuid. Providing '--uuid=UUID' option with parameter allows to use
custom UUID. Providing the '--portable' option will disable usage of the fs uuid
and also the inode number and generation.
Kernel configuration option CONFIG_EVM_EXTRA_SMACK_XATTRS controls whether to
include additional SMACK extended attributes into HMAC. They are following:
security.SMACK64EXEC, security.SMACK64TRANSMUTE and security.SMACK64MMAP.
evmctl '--smack' options enables that.
Key and signature formats
-------------------------
Linux integrity subsystem supports two type of signature and respectively two
key formats.
First key format (v1) is pure RSA key encoded in PEM a format and uses own signature
format. It is now non-default format and requires to provide evmctl '--rsa' option
for signing and importing the key.
Second key format uses X509 DER encoded public key certificates and uses asymmetric key support
in the kernel (since kernel 3.9). CONFIG_INTEGRITY_ASYMMETRIC_KEYS must be enabled (default).
For v2 signatures x509 certificate (containing the public key) could be appended to the
private key (they both are in PEM format) to automatically extract keyid from its Subject
Key Identifier (SKID).
Integrity keyrings
----------------
Integrity subsystem uses dedicated IMA/EVM keyrings to search for signature verification
keys - '_ima' and '_evm' respectively.
Since 3.13 IMA allows to declare IMA keyring as trusted. It allows only to load keys,
signed by a key from the system keyring (.system). It means self-signed keys are not
allowed. This is a default behavior unless CONFIG_IMA_TRUSTED_KEYRING is undefined.
IMA trusted keyring is has different name '.ima'. Trusted keyring requires X509
public key certificates. Old version RSA public keys are not compatible with trusted
keyring.
Generate EVM encrypted keys
---------------------------
EVM encrypted key is used for EVM HMAC calculation:
# create and save the key kernel master key (user type)
# LMK is used to encrypt encrypted keys
keyctl add user kmk "`dd if=/dev/urandom bs=1 count=32 2>/dev/null`" @u
keyctl pipe `keyctl search @u user kmk` > /etc/keys/kmk
# create the EVM encrypted key
keyctl add encrypted evm-key "new user:kmk 64" @u
keyctl pipe `keyctl search @u encrypted evm-key` >/etc/keys/evm-key
Generate EVM trusted keys (TPM based)
-------------------------------------
Trusted EVM keys are keys which a generate with the help of TPM.
They are not related to integrity trusted keys.
# create and save the key kernel master key (user type)
keyctl add trusted kmk "new 32" @u
keyctl pipe `keyctl search @u trusted kmk` >kmk
# create the EVM trusted key
keyctl add encrypted evm-key "new trusted:kmk 32" @u
keyctl pipe `keyctl search @u encrypted evm-key` >evm-key
Generate signing and verification keys
--------------------------------------
Generate private key in plain text format:
openssl genrsa -out privkey_evm.pem 1024
Generate encrypted private key:
openssl genrsa -des3 -out privkey_evm.pem 1024
Make encrypted private key from unencrypted:
openssl rsa -in /etc/keys/privkey_evm.pem -out privkey_evm_enc.pem -des3
Generate self-signed X509 public key certificate and private key for using kernel
asymmetric keys support:
openssl req -new -nodes -utf8 -sha1 -days 36500 -batch \
-x509 -config x509_evm.genkey \
-outform DER -out x509_evm.der -keyout privkey_evm.pem
Configuration file x509_evm.genkey:
# Begining of the file
[ req ]
default_bits = 1024
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts
[ req_distinguished_name ]
O = Magrathea
CN = Glacier signing key
emailAddress = slartibartfast@magrathea.h2g2
[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
# EOF
Generate public key for using RSA key format:
openssl rsa -pubout -in privkey_evm.pem -out pubkey_evm.pem
Copy keys to /etc/keys:
cp pubkey_evm.pem /etc/keys
scp pubkey_evm.pem target:/etc/keys
or
cp x509_evm.pem /etc/keys
scp x509_evm.pem target:/etc/keys
Generate trusted keys
---------------------
Generation of trusted keys is a bit more complicated process and involves
following steps:
* Creation of local IMA certification authority (CA).
It consist of private and public key certificate which are used
to sign and verify other keys.
* Build Linux kernel with embedded local IMA CA X509 certificate.
It is used to verify other keys added to the '.ima' trusted keyring
* Generate IMA private signing key and verification public key certificate,
which is signed using local IMA CA private key.
Configuration file ima-local-ca.genkey:
# Begining of the file
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = v3_ca
[ req_distinguished_name ]
O = IMA-CA
CN = IMA/EVM certificate signing key
emailAddress = ca@ima-ca
[ v3_ca ]
basicConstraints=CA:TRUE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# keyUsage = cRLSign, keyCertSign
# EOF
Generate private key and X509 public key certificate:
openssl req -new -x509 -utf8 -sha1 -days 3650 -batch -config $GENKEY \
-outform DER -out ima-local-ca.x509 -keyout ima-local-ca.priv
Produce X509 in DER format for using while building the kernel:
openssl x509 -inform DER -in ima-local-ca.x509 -out ima-local-ca.pem
Configuration file ima.genkey:
# Begining of the file
[ req ]
default_bits = 1024
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = v3_usr
[ req_distinguished_name ]
O = `hostname`
CN = `whoami` signing key
emailAddress = `whoami`@`hostname`
[ v3_usr ]
basicConstraints=critical,CA:FALSE
#basicConstraints=CA:FALSE
keyUsage=digitalSignature
#keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
#authorityKeyIdentifier=keyid,issuer
# EOF
Generate private key and X509 public key certificate signing request:
openssl req -new -nodes -utf8 -sha1 -days 365 -batch -config $GENKEY \
-out csr_ima.pem -keyout privkey_ima.pem
Sign X509 public key certificate signing request with local IMA CA private key:
openssl x509 -req -in csr_ima.pem -days 365 -extfile $GENKEY -extensions v3_usr \
-CA ima-local-ca.pem -CAkey ima-local-ca.priv -CAcreateserial \
-outform DER -out x509_ima.der
Sign file data and metadata
---------------------------
Default key locations:
Private RSA key: /etc/keys/privkey_evm.pem
Public RSA key: /etc/keys/pubkey_evm.pem
X509 certificate: /etc/keys/x509_evm.der
Options to remember: '-k', '-r', '--rsa', '--uuid', '--smack'.
Sign file with EVM signature and calculate hash value for IMA:
evmctl sign --imahash test.txt
Sign file with both IMA and EVM signatures:
evmctl sign --imasig test.txt:
Sign file with IMA signature:
evmctl ima_sign test.txt
Sign recursively whole filesystem:
evmctl -r sign --imahash /
Fix recursively whole filesystem:
evmctl -r ima_fix /
Sign filesystem selectively using 'find' command:
find / \( -fstype rootfs -o -fstype ext4 \) -exec evmctl sign --imahash '{}' \;
Fix filesystem selectively using 'find' command:
find / \( -fstype rootfs -o -fstype ext4 \) -exec sh -c "< '{}'" \;
Initialize IMA/EVM at early boot
--------------------------------
IMA/EVM initialization should be normally done from initial RAM file system
before mounting root filesystem.
Here is Ubuntu initramfs example script (/etc/initramfs-tools/scripts/local-top/ima.sh)
# mount securityfs if not mounted
SECFS=/sys/kernel/security
grep -q $SECFS /proc/mounts || mount -n -t securityfs securityfs $SECFS
# search for IMA trusted keyring, then for untrusted
ima_id="`awk '/\.ima/ { printf "%d", "0x"$1; }' /proc/keys`"
if [ -z "$ima_id" ]; then
ima_id=`keyctl search @u keyring _ima 2>/dev/null`
if [ -z "$ima_id" ]; then
ima_id=`keyctl newring _ima @u`
fi
fi
# import IMA X509 certificate
evmctl import /etc/keys/x509_ima.der $ima_id
# search for EVM keyring
evm_id=`keyctl search @u keyring _evm 2>/dev/null`
if [ -z "$evm_id" ]; then
evm_id=`keyctl newring _evm @u`
fi
# import EVM X509 certificate
evmctl import /etc/keys/x509_evm.der $evm_id
# a) import EVM encrypted key
cat /etc/keys/kmk | keyctl padd user kmk @u
keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u
# OR
# b) import EVM trusted key
keyctl add trusted kmk "load `cat /etc/keys/kmk`" @u
keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u
# enable EVM
echo "1" > /sys/kernel/security/evm
Optionally it is possible also to forbid adding, removing of new public keys
and certificates into keyrings and revoking keys using 'keyctl setperm' command:
# protect EVM keyring
keyctl setperm $evm_id 0x0b0b0000
# protect IMA keyring
keyctl setperm $ima_id 0x0b0b0000
# protecting IMA key from revoking (against DoS)
ima_key=`evmctl import /etc/keys/x509_ima.der $ima_id`
keyctl setperm $ima_key 0x0b0b0000
When using plain RSA public keys in PEM format, use 'evmctl import --rsa' for importing keys:
evmctl import --rsa /etc/keys/pubkey_evm.pem $evm_id
Latest version of keyctl allows to import X509 public key certificates:
cat /etc/keys/x509_ima.der | keyctl padd asymmetric '' $ima_id
FILES
-----
Examples of scripts to generate X509 public key certificates:
/usr/share/doc/ima-evm-utils/ima-genkey-self.sh
/usr/share/doc/ima-evm-utils/ima-genkey.sh
/usr/share/doc/ima-evm-utils/ima-gen-local-ca.sh
AUTHOR
------
Written by Dmitry Kasatkin, <dmitry.kasatkin at gmail.com> and others.
RESOURCES
---------
http://sourceforge.net/p/linux-ima/wiki/Home
http://sourceforge.net/p/linux-ima/ima-evm-utils
COPYING
-------
Copyright \(C) 2012 - 2014 Linux Integrity Project. Free use of this software is granted under
the terms of the GNU Public License (GPL).

View File

@ -1,16 +1,4 @@
#! /bin/sh
set -e
# new way
# strange, but need this for Makefile.am, because it has -I m4
test -d m4 || mkdir m4
autoreconf -f -i
# old way
#libtoolize --automake --copy --force
#aclocal
#autoconf --force
#autoheader --force
#automake --add-missing --copy --force-missing --gnu
autoreconf -i

4
build-static.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
gcc -static -o evmctl.static -include config.h src/evmctl.c src/libimaevm.c -lcrypto -lkeyutils -ldl

105
build.sh Executable file
View File

@ -0,0 +1,105 @@
#!/bin/sh
# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
set -e
CC="${CC:-gcc}"
CFLAGS="${CFLAGS:--Wformat -Werror=format-security -Werror=implicit-function-declaration -Werror=return-type -fno-common}"
PREFIX="${PREFIX:-$HOME/ima-evm-utils-install}"
export LD_LIBRARY_PATH="$PREFIX/lib64:$PREFIX/lib:/usr/local/lib64:/usr/local/lib"
export PATH="$PREFIX/bin:/usr/local/bin:$PATH"
title()
{
echo "===== $1 ====="
}
log_exit()
{
local ret="${3:-$?}"
local log="$1"
local msg="$2"
local prefix
echo "=== $log ==="
[ $ret -eq 0 ] || prefix="FAIL: "
cat $log
echo
echo "$prefix$msg, see output of $log above"
exit $ret
}
cd `dirname $0`
case "$VARIANT" in
i386)
echo "32-bit compilation"
export CFLAGS="-m32 $CFLAGS" LDFLAGS="-m32 $LDFLAGS"
export PKG_CONFIG_LIBDIR=/usr/lib/i386-linux-gnu/pkgconfig
;;
cross-compile)
host="${CC%-gcc}"
export CROSS_COMPILE="${host}-"
host="--host=$host"
echo "cross compilation: $host"
echo "CROSS_COMPILE: '$CROSS_COMPILE'"
;;
*)
if [ "$VARIANT" ]; then
echo "Wrong VARIANT: '$VARIANT'" >&2
exit 1
fi
echo "native build"
;;
esac
title "compiler version"
$CC --version
echo "CFLAGS: '$CFLAGS'"
echo "LDFLAGS: '$LDFLAGS'"
echo "PREFIX: '$PREFIX'"
title "configure"
./autogen.sh
./configure --prefix=$PREFIX $host || log_exit config.log "configure failed"
title "make"
make -j$(nproc)
make install
title "test"
if [ "$VARIANT" = "cross-compile" ]; then
echo "skip make check on cross compilation"
exit 0
fi
ret=0
VERBOSE=1 make check || ret=$?
title "logs"
if [ $ret -eq 0 ]; then
if [ -f tests/ima_hash.log ]; then
tail -3 tests/ima_hash.log
grep "skipped" tests/ima_hash.log && \
grep "skipped" tests/ima_hash.log | wc -l
fi
if [ -f tests/sign_verify.log ]; then
tail -3 tests/sign_verify.log
grep "skipped" tests/sign_verify.log && \
grep "skipped" tests/sign_verify.log | wc -l
fi
tail -20 tests/boot_aggregate.log
exit 0
fi
cat tests/test-suite.log
if [ $ret -eq 77 ]; then
msg="WARN: some tests skipped"
ret=0
else
msg="FAIL: tests exited: $ret"
fi
log_exit tests/test-suite.log "$msg" $ret

50
ci/alpine.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/sh
# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
set -ex
if [ -z "$CC" ]; then
echo "missing \$CC!" >&2
exit 1
fi
case "$TSS" in
ibmtss) echo "No IBM TSS package, will be installed from git" >&2; TSS=;;
tpm2-tss) TSS="tpm2-tss-dev";;
'') echo "Missing TSS!" >&2; exit 1;;
*) echo "Unsupported TSS: '$TSS'!" >&2; exit 1;;
esac
# ibmswtpm2 requires gcc
[ "$CC" = "gcc" ] || CC="gcc $CC"
apk update
apk add \
$CC $TSS \
asciidoc \
attr \
attr-dev \
autoconf \
automake \
diffutils \
docbook-xml \
docbook-xsl \
keyutils-dev \
libtool \
libxslt \
linux-headers \
make \
musl-dev \
openssl \
openssl-dev \
pkgconfig \
procps \
sudo \
wget \
which \
xxd
if [ ! "$TSS" ]; then
apk add git
../tests/install-tss.sh
fi

27
ci/alt.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh -ex
# SPDX-License-Identifier: GPL-2.0-only
#
# Install build env for ALT Linux
apt-get update -y
# rpm-build brings basic build environment with gcc, make, autotools, etc.
apt-get install -y \
$CC \
$TSS \
asciidoc \
attr \
docbook-style-xsl \
gnutls-utils \
libattr-devel \
libkeyutils-devel \
libp11 \
libssl-devel \
openssl \
openssl-gost-engine \
rpm-build \
softhsm \
wget \
xsltproc \
xxd \
&& control openssl-gost enabled

1
ci/centos.sh Symbolic link
View File

@ -0,0 +1 @@
fedora.sh

23
ci/debian.cross-compile.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/sh
# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
set -ex
if [ -z "$ARCH" ]; then
echo "missing \$ARCH!" >&2
exit 1
fi
case "$ARCH" in
arm64) gcc_arch="aarch64";;
ppc64el) gcc_arch="powerpc64le";;
s390x) gcc_arch="$ARCH";;
*) echo "unsupported arch: '$ARCH'!" >&2; exit 1;;
esac
dpkg --add-architecture $ARCH
apt update
apt install -y --no-install-recommends \
dpkg-dev \
gcc-${gcc_arch}-linux-gnu \
libc6-dev-${ARCH}-cross

11
ci/debian.i386.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
set -ex
dpkg --add-architecture i386
apt update
apt install -y --no-install-recommends \
linux-libc-dev:i386 \
gcc-multilib \
pkg-config:i386

55
ci/debian.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/sh
# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
set -ex
if [ -z "$CC" ]; then
echo "missing \$CC!" >&2
exit 1
fi
# debian.*.sh must be run first
if [ "$ARCH" ]; then
ARCH=":$ARCH"
unset CC
else
apt update
fi
# ibmswtpm2 requires gcc
[ "$CC" = "gcc" ] || CC="gcc $CC"
case "$TSS" in
ibmtss) TSS="libtss-dev";;
tpm2-tss) TSS="libtss2-dev";;
'') echo "Missing TSS!" >&2; exit 1;;
*) [ "$TSS" ] && echo "Unsupported TSS: '$TSS'!" >&2; exit 1;;
esac
apt="apt install -y --no-install-recommends"
$apt \
$CC $TSS \
asciidoc \
attr \
autoconf \
automake \
diffutils \
debianutils \
docbook-xml \
docbook-xsl \
gzip \
libattr1-dev$ARCH \
libkeyutils-dev$ARCH \
libssl-dev$ARCH \
libtool \
make \
openssl \
pkg-config \
procps \
sudo \
wget \
xsltproc
$apt xxd || $apt vim-common
$apt libengine-gost-openssl1.1$ARCH || true
$apt softhsm gnutls-bin libengine-pkcs11-openssl1.1$ARCH || true

52
ci/fedora.sh Executable file
View File

@ -0,0 +1,52 @@
#!/bin/sh
# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
set -e
if [ -z "$CC" ]; then
echo "missing \$CC!" >&2
exit 1
fi
case "$TSS" in
ibmtss) TSS="tss2-devel";;
tpm2-tss) TSS="tpm2-tss-devel";;
'') echo "Missing TSS!" >&2; exit 1;;
*) echo "Unsupported TSS: '$TSS'!" >&2; exit 1;;
esac
# ibmswtpm2 requires gcc
[ "$CC" = "gcc" ] || CC="gcc $CC"
yum -y install \
$CC $TSS \
asciidoc \
attr \
autoconf \
automake \
diffutils \
docbook-xsl \
gnutls-utils \
gzip \
keyutils-libs-devel \
libattr-devel \
libtool \
libxslt \
make \
openssl \
openssl-devel \
openssl-pkcs11 \
pkg-config \
procps \
sudo \
vim-common \
wget \
which
yum -y install docbook5-style-xsl || true
yum -y install swtpm || true
# SoftHSM is available via EPEL on CentOS
if [ -f /etc/centos-release ]; then
yum -y install epel-release
fi
yum -y install softhsm || true

1
ci/opensuse.sh Symbolic link
View File

@ -0,0 +1 @@
tumbleweed.sh

50
ci/tumbleweed.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/sh
# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
set -ex
if [ -z "$CC" ]; then
echo "missing \$CC!" >&2
exit 1
fi
case "$TSS" in
ibmtss) TSS="ibmtss-devel";;
tpm2-tss) TSS="tpm2-0-tss-devel";;
'') echo "Missing TSS!" >&2; exit 1;;
*) echo "Unsupported TSS: '$TSS'!" >&2; exit 1;;
esac
# clang has some gcc dependency
[ "$CC" = "gcc" ] || CC="gcc $CC"
zypper --non-interactive install --force-resolution --no-recommends \
$CC $TSS \
asciidoc \
attr \
autoconf \
automake \
diffutils \
docbook_5 \
docbook5-xsl-stylesheets \
gzip \
ibmswtpm2 \
keyutils-devel \
libattr-devel \
libopenssl-devel \
libtool \
make \
openssl \
pkg-config \
procps \
sudo \
vim \
wget \
which \
xsltproc
zypper --non-interactive install --force-resolution --no-recommends \
gnutls openssl-engine-libp11 softhsm || true
if [ -f /usr/lib/ibmtss/tpm_server -a ! -e /usr/local/bin/tpm_server ]; then
ln -s /usr/lib/ibmtss/tpm_server /usr/local/bin
fi

1
ci/ubuntu.sh Symbolic link
View File

@ -0,0 +1 @@
debian.sh

View File

@ -1,12 +1,13 @@
# autoconf script
AC_PREREQ([2.65])
AC_INIT(ima-evm-utils, 0.1.1, dmitry.kasatkin@intel.com)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
AC_INIT(ima-evm-utils, 1.4, zohar@linux.ibm.com)
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_HOST
AC_USE_SYSTEM_EXTENSIONS
# Checks for programs.
AC_PROG_CC
@ -24,12 +25,34 @@ LT_INIT
# Checks for header files.
AC_HEADER_STDC
PKG_CHECK_MODULES(OPENSSL, [ openssl >= 0.9.8 ])
AC_SUBST(OPENSSL_CFLAGS)
AC_SUBST(OPENSSL_LIBS)
PKG_CHECK_MODULES(LIBCRYPTO, [libcrypto >= 0.9.8 ])
AC_SUBST(KERNEL_HEADERS)
AC_CHECK_HEADER(unistd.h)
AC_CHECK_HEADERS(openssl/conf.h)
# Intel TSS
AC_CHECK_LIB([tss2-esys], [Esys_Free])
AC_CHECK_LIB([tss2-rc], [Tss2_RC_Decode])
AM_CONDITIONAL([USE_PCRTSS], [test "x$ac_cv_lib_tss2_esys_Esys_Free" = "xyes"])
# IBM TSS include files
AC_CHECK_HEADER(ibmtss/tss.h, [], [], [[#define TPM_POSIX]])
AM_CONDITIONAL([USE_IBMTSS], [test "x$ac_cv_header_ibmtss_tss_h" = "xyes"])
AC_CHECK_HEADERS(sys/xattr.h, , [AC_MSG_ERROR([sys/xattr.h header not found. You need the c-library development package.])])
AC_CHECK_HEADERS(keyutils.h, , [AC_MSG_ERROR([keyutils.h header not found. You need the libkeyutils development package.])])
AC_ARG_WITH(kernel_headers, [AS_HELP_STRING([--with-kernel-headers=PATH],
[specifies the Linux kernel-headers package location or kernel root directory you want to use])],
[KERNEL_HEADERS="$withval"],
[KERNEL_HEADERS=/lib/modules/$(uname -r)/source])
AC_ARG_ENABLE([openssl_conf],
[AS_HELP_STRING([--disable-openssl-conf], [disable loading of openssl config by evmctl])],
[if test "$enable_openssl_conf" = "no"; then
AC_DEFINE(DISABLE_OPENSSL_CONF, 1, [Define to disable loading of openssl config by evmctl.])
fi], [enable_openssl_conf=yes])
#debug support - yes for a while
PKG_ARG_ENABLE(debug, "yes", DEBUG, [Enable Debug support])
if test $pkg_cv_enable_debug = yes; then
@ -38,6 +61,9 @@ else
CFLAGS="$CFLAGS -Wall -Wstrict-prototypes -pipe -fomit-frame-pointer"
fi
EVMCTL_MANPAGE_DOCBOOK_XSL
AX_DEFAULT_HASH_ALGO([$KERNEL_HEADERS])
# for gcov
#CFLAGS="$CFLAGS -Wall -fprofile-arcs -ftest-coverage"
#CXXFLAGS="$CXXFLAGS -Wall -fprofile-arcs -ftest-coverage"
@ -47,14 +73,19 @@ fi
AC_CONFIG_FILES([Makefile
src/Makefile
tests/Makefile
ima-evm-utils.spec
packaging/ima-evm-utils.spec
])
AC_OUTPUT
# Give some feedback
echo
echo
echo "Configuration:"
echo " debug: $pkg_cv_enable_debug"
echo "Configuration:"
echo " debug: $pkg_cv_enable_debug"
echo " default-hash: $HASH_ALGO"
echo " openssl-conf: $enable_openssl_conf"
echo " tss2-esys: $ac_cv_lib_tss2_esys_Esys_Free"
echo " tss2-rc-decode: $ac_cv_lib_tss2_rc_Tss2_RC_Decode"
echo " ibmtss: $ac_cv_header_ibmtss_tss_h"
echo " doc: $have_doc"
echo

29
examples/ima-gen-local-ca.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/sh
GENKEY=ima-local-ca.genkey
cat << __EOF__ >$GENKEY
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = v3_ca
[ req_distinguished_name ]
O = IMA-CA
CN = IMA/EVM certificate signing key
emailAddress = ca@ima-ca
[ v3_ca ]
basicConstraints=CA:TRUE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# keyUsage = cRLSign, keyCertSign
__EOF__
openssl req -new -x509 -utf8 -sha1 -days 3650 -batch -config $GENKEY \
-outform DER -out ima-local-ca.x509 -keyout ima-local-ca.priv
openssl x509 -inform DER -in ima-local-ca.x509 -out ima-local-ca.pem

29
examples/ima-genkey-self.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/sh
GENKEY=x509_evm.genkey
cat << __EOF__ >$GENKEY
[ req ]
default_bits = 1024
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts
[ req_distinguished_name ]
O = `hostname`
CN = `whoami` signing key
emailAddress = `whoami`@`hostname`
[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
__EOF__
openssl req -x509 -new -nodes -utf8 -sha1 -days 3650 -batch -config $GENKEY \
-outform DER -out x509_evm.der -keyout privkey_evm.pem
openssl rsa -pubout -in privkey_evm.pem -out pubkey_evm.pem

33
examples/ima-genkey.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/sh
GENKEY=ima.genkey
cat << __EOF__ >$GENKEY
[ req ]
default_bits = 1024
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = v3_usr
[ req_distinguished_name ]
O = `hostname`
CN = `whoami` signing key
emailAddress = `whoami`@`hostname`
[ v3_usr ]
basicConstraints=critical,CA:FALSE
#basicConstraints=CA:FALSE
keyUsage=digitalSignature
#keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
#authorityKeyIdentifier=keyid,issuer
__EOF__
openssl req -new -nodes -utf8 -sha1 -days 365 -batch -config $GENKEY \
-out csr_ima.pem -keyout privkey_ima.pem
openssl x509 -req -in csr_ima.pem -days 365 -extfile $GENKEY -extensions v3_usr \
-CA ima-local-ca.pem -CAkey ima-local-ca.priv -CAcreateserial \
-outform DER -out x509_ima.der

36
m4/default-hash-algo.m4 Normal file
View File

@ -0,0 +1,36 @@
dnl Copyright (c) 2021 Bruno Meneguele <bmeneg@redhat.com>
dnl Check hash algorithm availability in the kernel
dnl
dnl $1 - $KERNEL_HEADERS
AC_DEFUN([AX_DEFAULT_HASH_ALGO], [
HASH_INFO_HEADER="$1/include/uapi/linux/hash_info.h"
AC_ARG_WITH([default_hash],
AS_HELP_STRING([--with-default-hash=ALGORITHM], [specifies the default hash algorithm to be used]),
[HASH_ALGO=$withval],
[HASH_ALGO=sha256])
AC_PROG_SED()
HASH_ALGO="$(echo $HASH_ALGO | $SED 's/\(.*\)/\L\1\E/')"
AC_CHECK_HEADER([$HASH_INFO_HEADER],
[HAVE_HASH_INFO_HEADER=yes],
[AC_MSG_WARN([$HASH_INFO_HEADER not found.])])
if test "x$HAVE_HASH_INFO_HEADER" = "x"; then
AC_MSG_RESULT([using $HASH_ALGO algorithm as default hash algorith])
AC_DEFINE_UNQUOTED(DEFAULT_HASH_ALGO, "$HASH_ALGO", [Define default hash algorithm])
else
AC_PROG_GREP()
$SED -n 's/HASH_ALGO_\(.*\),/\L\1\E/p' $HASH_INFO_HEADER | $GREP -w $HASH_ALGO > /dev/null
have_hash=$?
if test $have_hash -ne 0; then
AC_MSG_ERROR([$HASH_ALGO algorithm specified, but not provided by the kernel], 1)
else
AC_MSG_NOTICE([using $HASH_ALGO as default hash algorithm])
AC_DEFINE_UNQUOTED(DEFAULT_HASH_ALGO, "$HASH_ALGO", [Define default hash algorithm])
fi
fi
])

48
m4/manpage-docbook-xsl.m4 Normal file
View File

@ -0,0 +1,48 @@
dnl Copyright (c) 2018-2020 Petr Vorel <pvorel@suse.cz>
dnl Find docbook manpage stylesheet
AC_DEFUN([EVMCTL_MANPAGE_DOCBOOK_XSL], [
DOCBOOK_XSL_URI="http://docbook.sourceforge.net/release/xsl/current"
DOCBOOK_XSL_PATH="manpages/docbook.xsl"
AC_PATH_PROGS(XMLCATALOG, xmlcatalog)
AC_ARG_WITH([xml-catalog],
AC_HELP_STRING([--with-xml-catalog=CATALOG],
[path to xml catalog to use]),,
[with_xml_catalog=/etc/xml/catalog])
XML_CATALOG_FILE="$with_xml_catalog"
AC_SUBST([XML_CATALOG_FILE])
if test "x${XMLCATALOG}" = "x"; then
AC_MSG_WARN([xmlcatalog not found, cannot search for $DOCBOOK_XSL_PATH])
else
AC_MSG_CHECKING([for XML catalog ($XML_CATALOG_FILE)])
if test -f "$XML_CATALOG_FILE"; then
have_xmlcatalog_file=yes
AC_MSG_RESULT([found])
else
AC_MSG_RESULT([not found, cannot search for $DOCBOOK_XSL_PATH])
fi
fi
if test "x${XMLCATALOG}" != "x" -a "x$have_xmlcatalog_file" = "xyes"; then
MANPAGE_DOCBOOK_XSL=$(${XMLCATALOG} ${XML_CATALOG_FILE} ${DOCBOOK_XSL_URI}/${DOCBOOK_XSL_PATH} | sed 's|^file:/\+|/|')
fi
if test "x${MANPAGE_DOCBOOK_XSL}" = "x"; then
MANPAGE_DOCBOOK_XSL="/usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl"
AC_MSG_WARN([trying a default path for $DOCBOOK_XSL_PATH])
fi
if test -f "$MANPAGE_DOCBOOK_XSL"; then
have_doc=yes
AC_MSG_NOTICE([using $MANPAGE_DOCBOOK_XSL for generating doc])
else
AC_MSG_WARN([$DOCBOOK_XSL_PATH not found, generating doc will be skipped])
MANPAGE_DOCBOOK_XSL=
have_doc=no
fi
AM_CONDITIONAL(MANPAGE_DOCBOOK_XSL, test "x$have_doc" = xyes)
AC_SUBST(MANPAGE_DOCBOOK_XSL)
])

View File

@ -0,0 +1,52 @@
Name: ima-evm-utils
Version: 1.4
Release: 1%{?dist}
Summary: ima-evm-utils - IMA/EVM control utility
Group: System/Libraries
License: GPLv2
#URL:
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: openssl-devel
BuildRequires: keyutils-libs-devel
%description
This package provide IMA/EVM control utility
%prep
%setup -q
%build
./autogen.sh
%configure --prefix=/usr
make
%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install
%clean
rm -rf %{buildroot}
%post
/sbin/ldconfig
exit 0
%preun -p /sbin/ldconfig
%postun
/sbin/ldconfig
%files
%defattr(-,root,root,-)
%{_bindir}/*
%{_libdir}/libimaevm.*
%{_includedir}/*
%changelog
* Thu Apr 05 2012 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
- Initial RPM spec file

View File

@ -3,7 +3,7 @@ Version: @PACKAGE_VERSION@
Release: 1%{?dist}
Summary: @PACKAGE_NAME@ - IMA/EVM control utility
Group: System/Libraries
License: LGPLv2
License: GPLv2
#URL:
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@ -11,7 +11,6 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: openssl-devel
BuildRequires: libattr-devel
BuildRequires: keyutils-libs-devel
%description
@ -44,7 +43,8 @@ exit 0
%files
%defattr(-,root,root,-)
%{_bindir}/*
%{_libdir}/*
%{_libdir}/libimaevm.*
%{_includedir}/*
%changelog
* Thu Apr 05 2012 Dmitry Kasatkin <dmitry.kasatkin@intel.com>

2
src/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
hash_info.h
tmp_hash_info.h

View File

@ -1,12 +1,45 @@
lib_LTLIBRARIES = libimaevm.la
libimaevm_la_SOURCES = libimaevm.c
libimaevm_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBCRYPTO_CFLAGS)
# current[:revision[:age]]
# result: [current-age].age.revision
libimaevm_la_LDFLAGS = -version-info 3:0:0
libimaevm_la_LIBADD = $(LIBCRYPTO_LIBS)
include_HEADERS = imaevm.h
nodist_libimaevm_la_SOURCES = hash_info.h
BUILT_SOURCES = hash_info.h
EXTRA_DIST = hash_info.gen
hash_info.h: Makefile
$(srcdir)/hash_info.gen $(KERNEL_HEADERS) >$@
bin_PROGRAMS = evmctl
evmctl_SOURCES = evmctl.c
evmctl_CPPFLAGS = $(OPENSSL_CFLAGS)
evmctl_SOURCES = evmctl.c utils.c
evmctl_CPPFLAGS = $(AM_CPPFLAGS) $(LIBCRYPTO_CFLAGS)
evmctl_LDFLAGS = $(LDFLAGS_READLINE)
evmctl_LDADD = $(OPENSSL_LIBS) -lkeyutils
evmctl_LDADD = $(LIBCRYPTO_LIBS) -lkeyutils libimaevm.la
INCLUDES = -I$(top_srcdir) -include config.h
# USE_PCRTSS uses the Intel TSS
if USE_PCRTSS
evmctl_SOURCES += pcr_tss.c
# USE_IBMTSS uses the IBM TSS
else
if USE_IBMTSS
evmctl_SOURCES += pcr_ibmtss.c
evmctl_LDADD += -libmtss
# uses the IBM TSS command line utilities
else
evmctl_SOURCES += pcr_tsspcrread.c
endif
endif
AM_CPPFLAGS = -I$(top_srcdir) -include config.h
CLEANFILES = hash_info.h tmp_hash_info.h
DISTCLEANFILES = @DISTCLEANFILES@

File diff suppressed because it is too large Load Diff

93
src/hash_info.gen Executable file
View File

@ -0,0 +1,93 @@
#!/bin/sh
#
# Generate hash_info.h from kernel headers
#
# Copyright (C) 2018 <vt@altlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
KERNEL_HEADERS=$1
HASH_INFO_H=uapi/linux/hash_info.h
HASH_INFO=$KERNEL_HEADERS/include/$HASH_INFO_H
TMPHASHINFO="./tmp_hash_info.h"
gen_hashinfo() {
cat << __EOF__ >$TMPHASHINFO
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* Hash Info: Hash algorithms information
*
* Copyright (c) 2013 Dmitry Kasatkin <d.kasatkin@samsung.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*/
enum hash_algo {
HASH_ALGO_MD4,
HASH_ALGO_MD5,
HASH_ALGO_SHA1,
HASH_ALGO_RIPE_MD_160,
HASH_ALGO_SHA256,
HASH_ALGO_SHA384,
HASH_ALGO_SHA512,
HASH_ALGO_SHA224,
HASH_ALGO_RIPE_MD_128,
HASH_ALGO_RIPE_MD_256,
HASH_ALGO_RIPE_MD_320,
HASH_ALGO_WP_256,
HASH_ALGO_WP_384,
HASH_ALGO_WP_512,
HASH_ALGO_TGR_128,
HASH_ALGO_TGR_160,
HASH_ALGO_TGR_192,
HASH_ALGO_SM3_256,
HASH_ALGO__LAST
};
__EOF__
}
# Allow to specify kernel-headers past include/
if [ ! -e $HASH_INFO ]; then
HASH_INFO2=$KERNEL_HEADERS/$HASH_INFO_H
if [ -e $HASH_INFO2 ]; then
HASH_INFO=$HASH_INFO2
else
gen_hashinfo
HASH_INFO="$TMPHASHINFO"
fi
fi
if [ ! -e $HASH_INFO ]; then
echo "/* $HASH_INFO is not found */"
HASH_INFO=/dev/null
else
echo "/* $HASH_INFO is found */"
fi
echo "enum hash_algo {"
grep HASH_ALGO_.*, $HASH_INFO
printf "\tHASH_ALGO__LAST\n"
echo "};"
echo "const char *const hash_algo_name[HASH_ALGO__LAST] = {"
sed -n 's/HASH_ALGO_\(.*\),/\1 \L\1\E/p' $HASH_INFO | \
while read a b; do
# Normalize text hash name: sm3 algorithm name is different from
# the macro definition, which is also the only special case of an
# underscore between digits. Remove all other underscores.
b=$(echo "$b" | sed "s/sm3_256/sm3/g;s/_//g")
printf '\t%-26s = "%s",\n' "[HASH_ALGO_$a]" "$b"
done
echo "};"

237
src/imaevm.h Normal file
View File

@ -0,0 +1,237 @@
/*
* ima-evm-utils - IMA/EVM support utilities
*
* Copyright (C) 2011 Nokia Corporation
* Copyright (C) 2011,2012,2013 Intel Corporation
* Copyright (C) 2013,2014 Samsung Electronics
*
* Authors:
* Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
* <dmitry.kasatkin@intel.com>
* <d.kasatkin@samsung.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU General Public License in all respects
* for all of the code used other than as permitted herein. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version. If you
* delete this exception statement from all source files in the program,
* then also delete it in the license file.
*
* File: imaevm.h
* IMA/EVM header file
*/
#ifndef _LIBIMAEVM_H
#define _LIBIMAEVM_H
#include <linux/fs.h>
#include <stdint.h>
#include <syslog.h>
#include <stdbool.h>
#include <errno.h>
#include <sys/types.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
#ifdef USE_FPRINTF
#define do_log(level, fmt, args...) \
({ if (level <= imaevm_params.verbose) fprintf(stderr, fmt, ##args); })
#define do_log_dump(level, p, len, cr) \
({ if (level <= imaevm_params.verbose) imaevm_do_hexdump(stderr, p, len, cr); })
#else
#define do_log(level, fmt, args...) syslog(level, fmt, ##args)
#define do_log_dump(level, p, len, cr)
#endif
#ifdef DEBUG
#define log_debug(fmt, args...) do_log(LOG_DEBUG, "%s:%d " fmt, __func__ , __LINE__ , ##args)
#define log_debug_dump(p, len) do_log_dump(LOG_DEBUG, p, len, true)
#define log_debug_dump_n(p, len) do_log_dump(LOG_DEBUG, p, len, false)
#else
#define log_debug(fmt, args...)
#define log_debug_dump(p, len)
#endif
#define log_dump(p, len) do_log_dump(LOG_INFO, p, len, true)
#define log_dump_n(p, len) do_log_dump(LOG_INFO, p, len, false)
#define log_info(fmt, args...) do_log(LOG_INFO, fmt, ##args)
#define log_err(fmt, args...) do_log(LOG_ERR, fmt, ##args)
#define log_errno(fmt, args...) do_log(LOG_ERR, fmt ": errno: %s (%d)\n", ##args, strerror(errno), errno)
#ifndef DEFAULT_HASH_ALGO
#define DEFAULT_HASH_ALGO "sha256"
#endif
#define DATA_SIZE 4096
#define SHA1_HASH_LEN 20
#define MAX_DIGEST_SIZE 64
#define MAX_SIGNATURE_SIZE 1024
#define __packed __attribute__((packed))
enum evm_ima_xattr_type {
IMA_XATTR_DIGEST = 0x01,
EVM_XATTR_HMAC,
EVM_IMA_XATTR_DIGSIG,
IMA_XATTR_DIGEST_NG,
EVM_XATTR_PORTABLE_DIGSIG,
};
struct h_misc {
unsigned long ino;
uint32_t generation;
uid_t uid;
gid_t gid;
unsigned short mode;
};
struct h_misc_32 {
uint32_t ino;
uint32_t generation;
uid_t uid;
gid_t gid;
unsigned short mode;
};
struct h_misc_64 {
uint64_t ino;
uint32_t generation;
uid_t uid;
gid_t gid;
unsigned short mode;
};
struct h_misc_digsig {
uid_t uid;
gid_t gid;
unsigned short mode;
};
enum pubkey_algo {
PUBKEY_ALGO_RSA,
PUBKEY_ALGO_MAX,
};
enum digest_algo {
DIGEST_ALGO_SHA1,
DIGEST_ALGO_SHA256,
DIGEST_ALGO_MAX
};
enum digsig_version {
DIGSIG_VERSION_1 = 1,
DIGSIG_VERSION_2
};
struct pubkey_hdr {
uint8_t version; /* key format version */
uint32_t timestamp; /* key made, always 0 for now */
uint8_t algo;
uint8_t nmpi;
char mpi[0];
} __packed;
struct signature_hdr {
uint8_t version; /* signature format version */
uint32_t timestamp; /* signature made */
uint8_t algo;
uint8_t hash;
uint8_t keyid[8];
uint8_t nmpi;
char mpi[0];
} __packed;
/* reflect enum hash_algo from include/uapi/linux/hash_info.h */
enum pkey_hash_algo {
PKEY_HASH_MD4,
PKEY_HASH_MD5,
PKEY_HASH_SHA1,
PKEY_HASH_RIPE_MD_160,
PKEY_HASH_SHA256,
PKEY_HASH_SHA384,
PKEY_HASH_SHA512,
PKEY_HASH_SHA224,
PKEY_HASH_RIPE_MD_128,
PKEY_HASH_RIPE_MD_256,
PKEY_HASH_RIPE_MD_320,
PKEY_HASH_WP_256,
PKEY_HASH_WP_384,
PKEY_HASH_WP_512,
PKEY_HASH_TGR_128,
PKEY_HASH_TGR_160,
PKEY_HASH_TGR_192,
PKEY_HASH_SM3_256,
PKEY_HASH_STREEBOG_256,
PKEY_HASH_STREEBOG_512,
PKEY_HASH__LAST
};
/*
* signature format v2 - for using with asymmetric keys
*/
struct signature_v2_hdr {
uint8_t version; /* signature format version */
uint8_t hash_algo; /* Digest algorithm [enum pkey_hash_algo] */
uint32_t keyid; /* IMA key identifier - not X509/PGP specific*/
uint16_t sig_size; /* signature size */
uint8_t sig[0]; /* signature payload */
} __packed;
struct libimaevm_params {
int verbose;
int x509;
const char *hash_algo;
const char *keyfile;
const char *keypass;
uint32_t keyid; /* keyid overriding value, unless 0. (Host order.) */
ENGINE *eng;
};
struct RSA_ASN1_template {
const uint8_t *data;
size_t size;
};
#define NUM_PCRS 24
#define DEFAULT_PCR 10
extern struct libimaevm_params imaevm_params;
void imaevm_do_hexdump(FILE *fp, const void *ptr, int len, bool cr);
void imaevm_hexdump(const void *ptr, int len);
int ima_calc_hash(const char *file, uint8_t *hash);
int imaevm_get_hash_algo(const char *algo);
RSA *read_pub_key(const char *keyfile, int x509);
EVP_PKEY *read_pub_pkey(const char *keyfile, int x509);
void calc_keyid_v1(uint8_t *keyid, char *str, const unsigned char *pkey, int len);
void calc_keyid_v2(uint32_t *keyid, char *str, EVP_PKEY *pkey);
int key2bin(RSA *key, unsigned char *pub);
uint32_t imaevm_read_keyid(const char *certfile);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
int verify_hash(const char *file, const unsigned char *hash, int size, unsigned char *sig, int siglen);
int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
void init_public_keys(const char *keyfiles);
int imaevm_hash_algo_from_sig(unsigned char *sig);
const char *imaevm_hash_algo_by_id(int algo);
#endif

1089
src/libimaevm.c Normal file

File diff suppressed because it is too large Load Diff

3
src/pcr.h Normal file
View File

@ -0,0 +1,3 @@
int tpm2_pcr_supported(void);
int tpm2_pcr_read(const char *algo_name, uint32_t pcr_handle, uint8_t *hwpcr,
int len, char **errmsg);

164
src/pcr_ibmtss.c Normal file
View File

@ -0,0 +1,164 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Support PCR reading implementation based on IBM TSS2
*
* Copyright (C) 2021 IBM Ken Goldman <kgoldman@us.ibm.com>
*/
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <openssl/sha.h>
#define USE_FPRINTF
#include "utils.h"
#include "imaevm.h"
#define TPM_POSIX /* use Posix, not Windows constructs in TSS */
#undef MAX_DIGEST_SIZE /* imaevm uses a different value than the TSS */
#include <ibmtss/tss.h>
#define CMD "tsspcrread"
static char path[PATH_MAX];
int tpm2_pcr_supported(void)
{
if (imaevm_params.verbose > LOG_INFO)
log_info("Using %s to read PCRs.\n", CMD);
if (get_cmd_path(CMD, path, sizeof(path))) {
log_debug("Couldn't find '%s' in $PATH\n", CMD);
return 0;
}
log_debug("Found '%s' in $PATH\n", CMD);
return 1;
}
/* Table mapping C strings to TCG algorithm identifiers */
typedef struct tdAlgorithm_Map {
const char *algorithm_string;
TPMI_ALG_HASH algid;
} Algorithm_Map;
Algorithm_Map algorithm_map[] = {
{ "sha1", TPM_ALG_SHA1},
{ "sha256", TPM_ALG_SHA256},
#if 0 /* uncomment as these digest algorithms are supported */
{ "", TPM_ALG_SHA384},
{ "", TPM_ALG_SHA512},
{ "", TPM_ALG_SM3_256},
{ "", TPM_ALG_SHA3_256},
{ "", TPM_ALG_SHA3_384},
{ "", TPM_ALG_SHA3_512},
#endif
};
/*
* algorithm_string_to_algid() converts a digest algorithm from a C string to a
* TCG algorithm identifier as defined in the TCG Algorithm Regisrty..
*
* Returns TPM_ALG_ERROR if the string has an unsupported value.
*/
static TPMI_ALG_HASH algorithm_string_to_algid(const char *algorithm_string)
{
size_t i;
for (i=0 ; i < sizeof(algorithm_map)/sizeof(Algorithm_Map) ; i++) {
if (strcmp(algorithm_string, algorithm_map[i].algorithm_string)
== 0) {
return algorithm_map[i].algid; /* if match */
}
}
return TPM_ALG_ERROR;
}
/*
* tpm2_pcr_read - read the PCR
*
* algo_name: PCR digest algorithm (the PCR bank) as a C string
* pcr_handle: PCR number to read
* hwpcr: buffer for the PCR output in binary
* len: allocated size of hwpcr and should match the digest algorithm
*/
int tpm2_pcr_read(const char *algo_name, uint32_t pcr_handle, uint8_t *hwpcr,
int len, char **errmsg)
{
int ret = 0; /* function return code */
TPM_RC rc = 0; /* TCG return code */
TPM_RC rc1 = 0; /* secondary return code */
PCR_Read_In pcr_read_in; /* command input */
PCR_Read_Out pcr_read_out; /* response output */
TSS_CONTEXT *tss_context = NULL;
TPMI_ALG_HASH alg_id; /* PCR algorithm */
alg_id = algorithm_string_to_algid(algo_name);
if (alg_id == TPM_ALG_ERROR) {
ret = asprintf(errmsg, "tpm2_pcr_read: unknown algorithm %s",
algo_name);
if (ret == -1) /* the contents of errmsg is undefined */
*errmsg = NULL;
rc = 1;
goto end;
}
rc = TSS_Create(&tss_context);
if (rc != 0)
goto end;
/* call TSS to execute the command */
pcr_read_in.pcrSelectionIn.count = 1;
pcr_read_in.pcrSelectionIn.pcrSelections[0].hash = alg_id;
pcr_read_in.pcrSelectionIn.pcrSelections[0].sizeofSelect = 3;
pcr_read_in.pcrSelectionIn.pcrSelections[0].pcrSelect[0] = 0;
pcr_read_in.pcrSelectionIn.pcrSelections[0].pcrSelect[1] = 0;
pcr_read_in.pcrSelectionIn.pcrSelections[0].pcrSelect[2] = 0;
pcr_read_in.pcrSelectionIn.pcrSelections[0].pcrSelect[pcr_handle / 8] =
1 << (pcr_handle % 8);
rc = TSS_Execute(tss_context,
(RESPONSE_PARAMETERS *)&pcr_read_out,
(COMMAND_PARAMETERS *)&pcr_read_in,
NULL,
TPM_CC_PCR_Read,
TPM_RH_NULL, NULL, 0);
if (rc != 0)
goto end;
/* nothing read, bank missing */
if (pcr_read_out.pcrValues.count == 0) {
ret = asprintf(errmsg, "tpm2_pcr_read: returned count 0 for %s",
algo_name);
if (ret == -1) /* the contents of errmsg is undefined */
*errmsg = NULL;
rc = 1;
goto end;
}
/* len parameter did not match the digest algorithm */
else if (pcr_read_out.pcrValues.digests[0].t.size != len) {
ret = asprintf(errmsg,
"tpm2_pcr_read: "
"expected length %d actual %u for %s",
len, pcr_read_out.pcrValues.digests[0].t.size,
algo_name);
if (ret == -1) /* the contents of errmsg is undefined */
*errmsg = NULL;
rc = 1;
goto end;
} else {
memcpy(hwpcr,
pcr_read_out.pcrValues.digests[0].t.buffer,
pcr_read_out.pcrValues.digests[0].t.size);
}
end:
/* Call delete even on errors to free context resources */
rc1 = TSS_Delete(tss_context);
/* map TCG return code to function return code */
if ((rc == 0) && (rc1 == 0))
return 0;
else
return -1;
}

192
src/pcr_tss.c Normal file
View File

@ -0,0 +1,192 @@
/*
* ima-evm-utils - IMA/EVM support utilities
*
* Copyright (C) 2011 Nokia Corporation
* Copyright (C) 2011,2012,2013 Intel Corporation
* Copyright (C) 2013,2014 Samsung Electronics
*
* Authors:
* Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
* <dmitry.kasatkin@intel.com>
* <d.kasatkin@samsung.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU General Public License in all respects
* for all of the code used other than as permitted herein. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version. If you
* delete this exception statement from all source files in the program,
* then also delete it in the license file.
*
* File: pcr_tss.c
* PCR reading implementation based on Intel TSS2
*/
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#ifdef HAVE_LIBTSS2_ESYS
# include <tss2/tss2_esys.h>
# ifdef HAVE_LIBTSS2_RC
# include <tss2/tss2_rc.h>
# define LIB "tss2-rc-decode"
# else
# define LIB "tss2-esys"
# endif
#endif /* HAVE_LIBTSS2_ESYS */
#define USE_FPRINTF
#include "imaevm.h"
int tpm2_pcr_supported(void)
{
if (imaevm_params.verbose > LOG_INFO)
log_info("Using %s to read PCRs.\n", LIB);
return 1;
}
static int pcr_selections_match(TPML_PCR_SELECTION *a, TPML_PCR_SELECTION *b)
{
int i, j;
if (a->count != b->count)
return 0;
for (i = 0; i < a->count; i++) {
if (a->pcrSelections[i].hash != b->pcrSelections[i].hash)
return 0;
if (a->pcrSelections[i].sizeofSelect != b->pcrSelections[i].sizeofSelect)
return 0;
for (j = 0; j < a->pcrSelections[i].sizeofSelect; j++) {
if (a->pcrSelections[i].pcrSelect[j] != b->pcrSelections[i].pcrSelect[j])
return 0;
}
}
return 1;
}
static inline int tpm2_set_errmsg(char **errmsg, const char *message, TSS2_RC ret)
{
#ifdef HAVE_LIBTSS2_RC
return asprintf(errmsg, "%s: %s", message, Tss2_RC_Decode(ret));
#else
return asprintf(errmsg, "%s: #%d", message, ret);
#endif
}
static TPM2_ALG_ID algo_to_tss2(const char *algo_name)
{
if (!strcmp(algo_name, "sha1"))
return TPM2_ALG_SHA1;
else if (!strcmp(algo_name, "sha256"))
return TPM2_ALG_SHA256;
return TPM2_ALG_ERROR;
}
int tpm2_pcr_read(const char *algo_name, uint32_t pcr_handle, uint8_t *hwpcr,
int len, char **errmsg)
{
TSS2_ABI_VERSION abi_version = {
.tssCreator = 1,
.tssFamily = 2,
.tssLevel = 1,
.tssVersion = 108,
};
ESYS_CONTEXT *ctx = NULL;
TSS2_RC ret = 0;
TPML_PCR_SELECTION *pcr_select_out;
TPML_DIGEST *pcr_digests;
UINT32 pcr_update_counter;
TPM2_ALG_ID algid = algo_to_tss2(algo_name);
if (algid == TPM2_ALG_ERROR) {
ret = asprintf(errmsg, "unsupported tss2 algorithm");
if (ret == -1) /* the contents of errmsg are undefined */
*errmsg = NULL;
return -1;
}
TPML_PCR_SELECTION pcr_select_in = {
.count = 1,
.pcrSelections = {
{
.hash = algid,
.sizeofSelect = 3,
.pcrSelect = { 0x00, 0x00, 0x00 },
}
}
};
pcr_select_in.pcrSelections[0].pcrSelect[pcr_handle / 8] =
(1 << (pcr_handle % 8));
ret = Esys_Initialize(&ctx, NULL, &abi_version);
if (ret != TPM2_RC_SUCCESS) {
ret = tpm2_set_errmsg(errmsg, "esys initialize failed", ret);
if (ret == -1) /* the contents of errmsg are undefined */
*errmsg = NULL;
return -1;
}
ret = Esys_PCR_Read(ctx,
ESYS_TR_NONE,
ESYS_TR_NONE,
ESYS_TR_NONE,
&pcr_select_in,
&pcr_update_counter,
&pcr_select_out,
&pcr_digests);
Esys_Finalize(&ctx);
if (ret != TPM2_RC_SUCCESS) {
ret = tpm2_set_errmsg(errmsg, "esys PCR reading failed", ret);
if (ret == -1) /* the contents of errmsg is undefined */
*errmsg = NULL;
return -1;
}
if (!pcr_selections_match(&pcr_select_in, pcr_select_out)) {
Esys_Free(pcr_select_out);
Esys_Free(pcr_digests);
ret = asprintf(errmsg, "TPM returned incorrect PCRs");
if (ret == -1) /* the contents of errmsg are undefined */
*errmsg = NULL;
return -1;
}
Esys_Free(pcr_select_out);
if (pcr_digests->count != 1 || pcr_digests->digests[0].size != len) {
Esys_Free(pcr_digests);
ret = asprintf(errmsg, "TPM returned incorrect digests");
if (ret == -1) /* the contents of errmsg is undefined */
*errmsg = NULL;
return -1;
}
memcpy(hwpcr, pcr_digests->digests[0].buffer, len);
Esys_Free(pcr_digests);
return 0;
}

111
src/pcr_tsspcrread.c Normal file
View File

@ -0,0 +1,111 @@
/*
* ima-evm-utils - IMA/EVM support utilities
*
* Copyright (C) 2011 Nokia Corporation
* Copyright (C) 2011,2012,2013 Intel Corporation
* Copyright (C) 2013,2014 Samsung Electronics
*
* Authors:
* Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
* <dmitry.kasatkin@intel.com>
* <d.kasatkin@samsung.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU General Public License in all respects
* for all of the code used other than as permitted herein. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version. If you
* delete this exception statement from all source files in the program,
* then also delete it in the license file.
*
* File: pcr_tsspcrread.c
* PCR reading implementation based on IBM TSS2
*/
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <openssl/sha.h>
#define USE_FPRINTF
#include "utils.h"
#include "imaevm.h"
#define CMD "tsspcrread"
static char path[PATH_MAX];
int tpm2_pcr_supported(void)
{
if (imaevm_params.verbose > LOG_INFO)
log_info("Using %s to read PCRs.\n", CMD);
if (get_cmd_path(CMD, path, sizeof(path))) {
log_debug("Couldn't find '%s' in $PATH\n", CMD);
return 0;
}
log_debug("Found '%s' in $PATH\n", CMD);
return 1;
}
int tpm2_pcr_read(const char *algo_name, uint32_t pcr_handle, uint8_t *hwpcr,
int len, char **errmsg)
{
FILE *fp;
char pcr[100]; /* may contain an error */
char cmd[PATH_MAX + 50];
int ret;
sprintf(cmd, "%s -halg %s -ha %u -ns 2> /dev/null",
path, algo_name, pcr_handle);
fp = popen(cmd, "r");
if (!fp) {
ret = asprintf(errmsg, "popen failed: %s", strerror(errno));
if (ret == -1) /* the contents of errmsg is undefined */
*errmsg = NULL;
return -1;
}
if (fgets(pcr, sizeof(pcr), fp) == NULL) {
ret = asprintf(errmsg, "tsspcrread failed: %s",
strerror(errno));
if (ret == -1) /* the contents of errmsg is undefined */
*errmsg = NULL;
ret = pclose(fp);
return -1;
}
/* get the popen "cmd" return code */
ret = pclose(fp);
/* Treat an unallocated bank as an error */
if (!ret && (strlen(pcr) < SHA_DIGEST_LENGTH))
ret = -1;
if (!ret)
hex2bin(hwpcr, pcr, len);
else
*errmsg = strndup(pcr, strlen(pcr) - 1); /* remove newline */
return ret;
}

115
src/utils.c Normal file
View File

@ -0,0 +1,115 @@
// SPDX-License-Identifier: GPL-2.0
/*
* utils: set of common functions
*
* Copyright (C) 2020 Patrick Uiterwijk <patrick@puiterwijk.org>
* Copyright (C) 2010 Cyril Hrubis <chrubis@suse.cz>
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "utils.h"
#ifndef MIN
# define MIN(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a < _b ? _a : _b; \
})
#endif /* MIN */
static int file_exist(const char *path)
{
struct stat st;
if (!access(path, R_OK) && !stat(path, &st) && S_ISREG(st.st_mode))
return 1;
return 0;
}
int get_cmd_path(const char *prog_name, char *buf, size_t buf_len)
{
const char *path = (const char *)getenv("PATH");
const char *start = path;
const char *end;
size_t size, ret;
if (path == NULL)
return -1;
do {
end = strchr(start, ':');
if (end != NULL)
snprintf(buf, MIN(buf_len, (size_t) (end - start + 1)),
"%s", start);
else
snprintf(buf, buf_len, "%s", start);
size = strlen(buf);
/*
* "::" inside $PATH, $PATH ending with ':' or $PATH starting
* with ':' should be expanded into current working directory.
*/
if (size == 0) {
snprintf(buf, buf_len, ".");
size = strlen(buf);
}
/*
* If there is no '/' ad the end of path from $PATH add it.
*/
if (buf[size - 1] != '/')
ret =
snprintf(buf + size, buf_len - size, "/%s",
prog_name);
else
ret =
snprintf(buf + size, buf_len - size, "%s",
prog_name);
if (buf_len - size > ret && file_exist(buf))
return 0;
if (end != NULL)
start = end + 1;
} while (end != NULL);
return -1;
}
int hex_to_bin(char ch)
{
if ((ch >= '0') && (ch <= '9'))
return ch - '0';
ch = tolower(ch);
if ((ch >= 'a') && (ch <= 'f'))
return ch - 'a' + 10;
return -1;
}
int hex2bin(void *dst, const char *src, size_t count)
{
int hi, lo;
while (count--) {
if (*src == ' ')
src++;
hi = hex_to_bin(*src++);
lo = hex_to_bin(*src++);
if ((hi < 0) || (lo < 0))
return -1;
*(uint8_t *)dst++ = (hi << 4) | lo;
}
return 0;
}

6
src/utils.h Normal file
View File

@ -0,0 +1,6 @@
#include <ctype.h>
#include <sys/types.h>
int get_cmd_path(const char *prog_name, char *buf, size_t buf_len);
int hex_to_bin(char ch);
int hex2bin(void *dst, const char *src, size_t count);

16
tests/.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
# Generated by test driver
*.log
*.trs
# Generated by tests
*.txt
*.out
*.sig
*.sig2
# Generated certs and keys (by gen-keys.sh)
*.cer
*.pub
*.key
*.conf

View File

@ -1,7 +1,12 @@
pkglib_PROGRAMS = openclose
check_SCRIPTS =
TESTS = $(check_SCRIPTS)
openclose_SOURCES = openclose.c
check_SCRIPTS += ima_hash.test sign_verify.test boot_aggregate.test
dist_pkglib_SCRIPTS = evm_enable.sh evm_genkey.sh evm_sign_all.sh evm_sign_modules.sh ima_fix_dir.sh \
evm_hmac_all.sh evm_hmac_modules.sh
clean-local:
-rm -f *.txt *.out *.sig *.sig2
distclean: distclean-keys
.PHONY: distclean-keys
distclean-keys:
./gen-keys.sh clean

197
tests/boot_aggregate.test Executable file
View File

@ -0,0 +1,197 @@
#!/bin/bash
#
# Calculate the boot_aggregate for each TPM bank, verifying that the
# boot_aggregate in the IMA measurement list matches one of them.
#
# A software TPM may be used to verify the boot_aggregate. If a
# software TPM is not already running on the system, this test
# starts one and initializes the TPM PCR banks by walking the sample
# binary_bios_measurements event log, included in this directory, and
# extending the TPM PCRs. The associated ascii_runtime_measurements
# for verifying the calculated boot_aggregate is included in this
# directory as well.
trap cleanup SIGINT SIGTERM EXIT
# Base VERBOSE on the environment variable, if set.
VERBOSE="${VERBOSE:-0}"
cd "$(dirname "$0")"
export PATH=../src:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
. ./functions.sh
_require evmctl
TSSDIR="$(dirname -- "$(which tssstartup)")"
PCRFILE="/sys/class/tpm/tpm0/device/pcrs"
MISC_PCRFILE="/sys/class/misc/tpm0/device/pcrs"
# Only stop this test's software TPM
cleanup() {
if [ -n "${SWTPM_PID}" ]; then
kill -SIGTERM "${SWTPM_PID}"
elif [ -n "${TPMSERVER_PID}" ]; then
"${TSSDIR}/tsstpmcmd" -stop
fi
}
# Try to start a software TPM if needed.
swtpm_start() {
local tpm_server swtpm
tpm_server="$(which tpm_server)"
swtpm="$(which swtpm)"
if [ -z "${tpm_server}" ] && [ -z "${swtpm}" ]; then
echo "${CYAN}SKIP: Software TPM (tpm_server and swtpm) not found${NORM}"
return "$SKIP"
fi
if [ -n "${swtpm}" ]; then
pgrep swtpm
if [ $? -eq 0 ]; then
echo "INFO: Software TPM (swtpm) already running"
return 114
else
echo "INFO: Starting software TPM: ${swtpm}"
mkdir -p ./myvtpm
${swtpm} socket --tpmstate dir=./myvtpm --tpm2 --ctrl type=tcp,port=2322 --server type=tcp,port=2321 --flags not-need-init > /dev/null 2>&1 &
SWTPM_PID=$!
fi
elif [ -n "${tpm_server}" ]; then
# tpm_server uses the Microsoft simulator encapsulated packet format
export TPM_SERVER_TYPE="mssim"
pgrep tpm_server
if [ $? -eq 0 ]; then
echo "INFO: Software TPM (tpm_server) already running"
return 114
else
echo "INFO: Starting software TPM: ${tpm_server}"
${tpm_server} > /dev/null 2>&1 &
TPMSERVER_PID=$!
fi
fi
return 0
}
# Initialize the software TPM using the sample binary_bios_measurements log.
swtpm_init() {
if [ ! -f "${TSSDIR}/tssstartup" ] || [ ! -f "${TSSDIR}/tsseventextend" ]; then
echo "${CYAN}SKIP: tssstartup and tsseventextend needed for test${NORM}"
return "$SKIP"
fi
echo "INFO: Sending software TPM startup"
"${TSSDIR}/tssstartup"
if [ $? -ne 0 ]; then
echo "INFO: Retry sending software TPM startup"
sleep 1
"${TSSDIR}/tssstartup"
fi
if [ $? -ne 0 ]; then
echo "INFO: Software TPM startup failed"
return "$SKIP"
fi
echo "INFO: Walking ${BINARY_BIOS_MEASUREMENTS} initializing the software TPM"
# $(${TSSDIR}/tsseventextend -tpm -if "${BINARY_BIOS_MEASUREMENTS}" -v) 2>&1 > /dev/null
"${TSSDIR}/tsseventextend" -tpm -if "${BINARY_BIOS_MEASUREMENTS}" -v > /dev/null 2>&1
}
# In VERBOSE mode, display the calculated TPM PCRs for the different banks.
display_pcrs() {
local PCRMAX=9
local banks=("sha1" "sha256")
local i;
for bank in "${banks[@]}"; do
echo "INFO: Displaying ${bank} TPM bank (PCRs 0 - 9)"
for i in $(seq 0 $PCRMAX); do
rc=0
pcr=$("${TSSDIR}/tsspcrread" -halg "${bank}" -ha "${i}" -ns)
if [ $rc -ne 0 ]; then
echo "INFO: tsspcrread failed: $pcr"
break
fi
echo "$i: $pcr"
done
done
}
# The first entry in the IMA measurement list is the "boot_aggregate".
# For each kexec, an additional "boot_aggregate" will appear in the
# measurement list, assuming the previous measurement list is carried
# across the kexec.
#
# Verify that the last "boot_aggregate" record in the IMA measurement
# list matches.
check() {
echo "INFO: Calculating the boot_aggregate (PCRs 0 - 9) for multiple banks"
bootaggr=$(evmctl ima_boot_aggregate)
if [ $? -ne 0 ]; then
echo "${CYAN}SKIP: evmctl ima_boot_aggregate: $bootaggr${NORM}"
exit "$SKIP"
fi
boot_aggr=( $bootaggr )
echo "INFO: Searching for the boot_aggregate in ${ASCII_RUNTIME_MEASUREMENTS}"
for hash in "${boot_aggr[@]}"; do
if [ "$VERBOSE" != "0" ]; then
echo "$hash"
fi
if grep -e " boot_aggregate$" -e " boot_aggregate.$" "${ASCII_RUNTIME_MEASUREMENTS}" | tail -n 1 | grep -q "${hash}"; then
echo "${GREEN}SUCCESS: boot_aggregate ${hash} found${NORM}"
return "$OK"
fi
done
echo "${RED}FAILURE: boot_aggregate not found${NORM}"
echo "$bootaggr"
return "$FAIL"
}
if [ "$(id -u)" = 0 ] && [ -c "/dev/tpm0" ]; then
ASCII_RUNTIME_MEASUREMENTS="/sys/kernel/security/ima/ascii_runtime_measurements"
if [ ! -d "/sys/kernel/security/ima" ]; then
echo "${CYAN}SKIP: CONFIG_IMA not enabled${NORM}"
exit "$SKIP"
fi
else
BINARY_BIOS_MEASUREMENTS="./sample-binary_bios_measurements-pcrs-8-9"
ASCII_RUNTIME_MEASUREMENTS="./sample-ascii_runtime_measurements-pcrs-8-9"
export TPM_INTERFACE_TYPE="socsim"
export TPM_COMMAND_PORT=2321
export TPM_PLATFORM_PORT=2322
export TPM_SERVER_NAME="localhost"
# swtpm uses the raw, unencapsulated packet format
export TPM_SERVER_TYPE="raw"
fi
# Start and initialize a software TPM as needed
if [ "$(id -u)" != 0 ] || [ ! -c "/dev/tpm0" ]; then
if [ -f "$PCRFILE" ] || [ -f "$MISC_PCRFILE" ]; then
echo "${CYAN}SKIP: system has discrete TPM 1.2, sample TPM 2.0 event log test not supported.${NORM}"
exit "$SKIP"
fi
swtpm_start
error=$?
if [ $error -eq "$SKIP" ]; then
echo "skip: swtpm not installed"
exit "$SKIP"
fi
if [ $error -eq 0 ]; then
swtpm_init
if [ $? -eq "$SKIP" ]; then
echo "testing boot_aggregate without entries"
exit "$SKIP"
fi
fi
if [ "$VERBOSE" != "0" ]; then
display_pcrs
fi
fi
expect_pass check

View File

@ -1,25 +0,0 @@
#!/bin/sh
# import EVM HMAC key
keyctl clear @u
keyctl add user kmk "testing123" @u
keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u
# import Moule public key
mod_id=`keyctl newring _module @u`
evmctl import /etc/keys/pubkey_evm.pem $mod_id
# import IMA public key
ima_id=`keyctl newring _ima @u`
evmctl import /etc/keys/pubkey_evm.pem $ima_id
# import EVM public key
evm_id=`keyctl newring _evm @u`
evmctl import /etc/keys/pubkey_evm.pem $evm_id
# enable EVM
echo "1" > /sys/kernel/security/evm
# enable module checking
echo "1" > /sys/kernel/security/ima/module_check

View File

@ -1,8 +0,0 @@
#!/bin/sh
keyctl add user kmk "testing123" @u
key=`keyctl add encrypted evm-key "new user:kmk 32" @u`
keyctl print $key >/etc/keys/evm-key
keyctl list @u

View File

@ -1,14 +0,0 @@
#!/bin/sh
verbose=""
if [ "$1" = "-v" ] ; then
verbose="-v"
shift 1
fi
dir=${1:-/}
echo "Label: $dir"
find $dir \( -fstype rootfs -o -fstype ext3 -o -fstype ext4 \) \( -type f -o -type d \) -exec evmctl hmac --imahash $verbose '{}' \;

View File

@ -1,14 +0,0 @@
#!/bin/sh
verbose=""
if [ "$1" = "-v" ] ; then
verbose="-v"
shift 1
fi
dir=${1:-/lib/modules}
echo "HMAC modules: $dir"
find $dir -name "*.ko" -type f -exec evmctl hmac --imasig $verbose '{}' \;

View File

@ -1,14 +0,0 @@
#!/bin/sh
verbose=""
if [ "$1" = "-v" ] ; then
verbose="-v"
shift 1
fi
dir=${1:-/}
echo "Label: $dir"
find $dir \( -fstype rootfs -o -fstype ext3 -o -fstype ext4 \) -type f -exec evmctl sign --imahash $verbose '{}' \;

View File

@ -1,14 +0,0 @@
#!/bin/sh
verbose=""
if [ "$1" = "-v" ] ; then
verbose="-v"
shift 1
fi
dir=${1:-/lib/modules}
echo "Signing modules: $dir"
find $dir -name "*.ko" -type f -exec evmctl sign --imasig $verbose '{}' \;

315
tests/functions.sh Executable file
View File

@ -0,0 +1,315 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# ima-evm-utils tests bash functions
#
# Copyright (C) 2020 Vitaly Chikunov <vt@altlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# Tests accounting
declare -i testspass=0 testsfail=0 testsskip=0
# Exit codes (compatible with automake)
declare -r OK=0
declare -r FAIL=1
declare -r HARDFAIL=99 # hard failure no matter testing mode
declare -r SKIP=77
# You can set env VERBOSE=1 to see more output from evmctl
VERBOSE=${VERBOSE:-0}
V=vvvv
V=${V:0:$VERBOSE}
V=${V:+-$V}
# Exit if env FAILEARLY is defined.
# Used in expect_{pass,fail}.
exit_early() {
if [ "$FAILEARLY" ]; then
exit "$1"
fi
}
# Require particular executables to be present
_require() {
ret=
for i; do
if ! type $i; then
echo "$i is required for test"
ret=1
fi
done
[ $ret ] && exit "$HARDFAIL"
}
# Non-TTY output is never colored
if [ -t 1 ]; then
RED=$'\e[1;31m'
GREEN=$'\e[1;32m'
YELLOW=$'\e[1;33m'
BLUE=$'\e[1;34m'
CYAN=$'\e[1;36m'
NORM=$'\e[m'
export RED GREEN YELLOW BLUE CYAN NORM
fi
# Test mode determined by TFAIL variable:
# undefined: to success testing
# defined: failure testing
TFAIL=
TMODE=+ # mode character to prepend running command in log
declare -i TNESTED=0 # just for sanity checking
# Run positive test (one that should pass) and account its result
expect_pass() {
local -i ret
if [ $TNESTED -gt 0 ]; then
echo $RED"expect_pass should not be run nested"$NORM
testsfail+=1
exit "$HARDFAIL"
fi
TFAIL=
TMODE=+
TNESTED+=1
[ "$VERBOSE" -gt 1 ] && echo "____ START positive test: $*"
"$@"
ret=$?
[ "$VERBOSE" -gt 1 ] && echo "^^^^ STOP ($ret) positive test: $*"
TNESTED+=-1
case $ret in
0) testspass+=1 ;;
77) testsskip+=1 ;;
99) testsfail+=1; exit_early 1 ;;
*) testsfail+=1; exit_early 2 ;;
esac
return $ret
}
# Eval negative test (one that should fail) and account its result
expect_fail() {
local ret
if [ $TNESTED -gt 0 ]; then
echo $RED"expect_fail should not be run nested"$NORM
testsfail+=1
exit "$HARDFAIL"
fi
TFAIL=yes
TMODE=-
TNESTED+=1
[ "$VERBOSE" -gt 1 ] && echo "____ START negative test: $*"
"$@"
ret=$?
[ "$VERBOSE" -gt 1 ] && echo "^^^^ STOP ($ret) negative test: $*"
TNESTED+=-1
case $ret in
0) testsfail+=1; exit_early 3 ;;
77) testsskip+=1 ;;
99) testsfail+=1; exit_early 4 ;;
*) testspass+=1 ;;
esac
# Restore defaults (as in positive tests)
# for tests to run without wrappers
TFAIL=
TMODE=+
return $ret
}
# return true if current test is positive
_test_expected_to_pass() {
[ ! $TFAIL ]
}
# return true if current test is negative
_test_expected_to_fail() {
[ $TFAIL ]
}
# Show blank line and color following text to red
# if it's real error (ie we are in expect_pass mode).
color_red_on_failure() {
if _test_expected_to_pass; then
echo "$RED"
COLOR_RESTORE=true
fi
}
# For hard errors
color_red() {
echo "$RED"
COLOR_RESTORE=true
}
color_restore() {
[ $COLOR_RESTORE ] && echo "$NORM"
COLOR_RESTORE=
}
ADD_DEL=
ADD_TEXT_FOR=
# _evmctl_run should be run as `_evmctl_run ... || return'
_evmctl_run() {
local op=$1 out=$1-$$.out
local text_for=${FOR:+for $ADD_TEXT_FOR}
# Additional parameters:
# ADD_DEL: additional files to rm on failure
# ADD_TEXT_FOR: append to text as 'for $ADD_TEXT_FOR'
cmd="evmctl $V $EVMCTL_ENGINE $*"
echo $YELLOW$TMODE "$cmd"$NORM
$cmd >"$out" 2>&1
ret=$?
# Shell special and signal exit codes (except 255)
if [ $ret -ge 126 ] && [ $ret -lt 255 ]; then
color_red
echo "evmctl $op failed hard with ($ret) $text_for"
sed 's/^/ /' "$out"
color_restore
rm "$out" $ADD_DEL
ADD_DEL=
ADD_TEXT_FOR=
return "$HARDFAIL"
elif [ $ret -gt 0 ]; then
color_red_on_failure
echo "evmctl $op failed" ${TFAIL:+properly} "with ($ret) $text_for"
# Show evmctl output only in verbose mode or if real failure.
if _test_expected_to_pass || [ "$VERBOSE" ]; then
sed 's/^/ /' "$out"
fi
color_restore
rm "$out" $ADD_DEL
ADD_DEL=
ADD_TEXT_FOR=
return "$FAIL"
elif _test_expected_to_fail; then
color_red
echo "evmctl $op wrongly succeeded $text_for"
sed 's/^/ /' "$out"
color_restore
else
[ "$VERBOSE" ] && sed 's/^/ /' "$out"
fi
rm "$out"
ADD_DEL=
ADD_TEXT_FOR=
return "$OK"
}
# Extract xattr $attr from $file into $out file skipping $pref'ix
_extract_xattr() {
local file=$1 attr=$2 out=$3 pref=$4
getfattr -n "$attr" -e hex "$file" \
| grep "^$attr=" \
| sed "s/^$attr=$pref//" \
| xxd -r -p > "$out"
}
# Test if xattr $attr in $file matches $prefix
# Show error and fail otherwise.
_test_xattr() {
local file=$1 attr=$2 prefix=$3
local text_for=${ADD_TEXT_FOR:+ for $ADD_TEXT_FOR}
if ! getfattr -n "$attr" -e hex "$file" | egrep -qx "$attr=$prefix"; then
color_red_on_failure
echo "Did not find expected hash$text_for:"
echo " $attr=$prefix"
echo ""
echo "Actual output below:"
getfattr -n "$attr" -e hex "$file" | sed 's/^/ /'
color_restore
rm "$file"
ADD_TEXT_FOR=
return "$FAIL"
fi
ADD_TEXT_FOR=
}
# Try to enable gost-engine if needed.
_enable_gost_engine() {
# Do not enable if it's already working (enabled by user)
if ! openssl md_gost12_256 /dev/null >/dev/null 2>&1 \
&& openssl engine gost >/dev/null 2>&1; then
export EVMCTL_ENGINE="--engine gost"
export OPENSSL_ENGINE="-engine gost"
fi
}
# Show test stats and exit into automake test system
# with proper exit code (same as ours). Do cleanups.
_report_exit_and_cleanup() {
if [ -n "${WORKDIR}" ]; then
rm -rf "${WORKDIR}"
fi
if [ $testsfail -gt 0 ]; then
echo "================================="
echo " Run with FAILEARLY=1 $0 $*"
echo " To stop after first failure"
echo "================================="
fi
[ $testspass -gt 0 ] && echo -n "$GREEN" || echo -n "$NORM"
echo -n "PASS: $testspass"
[ $testsskip -gt 0 ] && echo -n "$YELLOW" || echo -n "$NORM"
echo -n " SKIP: $testsskip"
[ $testsfail -gt 0 ] && echo -n "$RED" || echo -n "$NORM"
echo " FAIL: $testsfail"
echo "$NORM"
if [ $testsfail -gt 0 ]; then
exit "$FAIL"
elif [ $testspass -gt 0 ]; then
exit "$OK"
else
exit "$SKIP"
fi
}
# Setup SoftHSM for local testing by calling the softhsm_setup script.
# Use the provided workdir as the directory where SoftHSM will store its state
# into.
# Upon successfully setting up SoftHSM, this function sets the global variables
# OPENSSL_ENGINE and OPENSSL_KEYFORM so that the openssl command line tool can
# use SoftHSM. Also the PKCS11_KEYURI global variable is set to the test key's
# pkcs11 URI.
_softhsm_setup() {
local workdir="$1"
local msg
export SOFTHSM_SETUP_CONFIGDIR="${workdir}/softhsm"
export SOFTHSM2_CONF="${workdir}/softhsm/softhsm2.conf"
mkdir -p "${SOFTHSM_SETUP_CONFIGDIR}"
msg=$(./softhsm_setup setup 2>&1)
if [ $? -eq 0 ]; then
echo "softhsm_setup setup succeeded: $msg"
PKCS11_KEYURI=$(echo $msg | sed -n 's|^keyuri: \(.*\)|\1|p')
export EVMCTL_ENGINE="--engine pkcs11"
export OPENSSL_ENGINE="-engine pkcs11"
export OPENSSL_KEYFORM="-keyform engine"
else
echo "softhsm_setup setup failed: ${msg}"
fi
}
# Tear down the SoftHSM setup and clean up the environment
_softhsm_teardown() {
./softhsm_setup teardown &>/dev/null
rm -rf "${SOFTHSM_SETUP_CONFIGDIR}"
unset SOFTHSM_SETUP_CONFIGDIR SOFTHSM2_CONF PKCS11_KEYURI \
EVMCTL_ENGINE OPENSSL_ENGINE OPENSSL_KEYFORM
}

161
tests/gen-keys.sh Executable file
View File

@ -0,0 +1,161 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Generate keys for the tests
#
# Copyright (C) 2020 Vitaly Chikunov <vt@altlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
cd "$(dirname "$0")" || exit 1
PATH=../src:$PATH
type openssl
log() {
echo >&2 - "$*"
eval "$@"
}
if [ "$1" = clean ]; then
rm -f test-ca.conf
elif [ "$1" = force ] || [ ! -e test-ca.conf ] \
|| [ gen-keys.sh -nt test-ca.conf ]; then
cat > test-ca.conf <<- EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = v3_ca
[ req_distinguished_name ]
O = IMA-CA
CN = IMA/EVM certificate signing key
emailAddress = ca@ima-ca
[ v3_ca ]
basicConstraints=CA:TRUE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
[ skid ]
basicConstraints=CA:TRUE
subjectKeyIdentifier=12345678
authorityKeyIdentifier=keyid:always,issuer
EOF
fi
# RSA
# Second key will be used for wrong key tests.
for m in 1024 1024_skid 2048; do
if [ "$1" = clean ] || [ "$1" = force ] \
|| [ gen-keys.sh -nt test-rsa$m.key ]; then
rm -f test-rsa$m.cer test-rsa$m.key test-rsa$m.pub
fi
if [ "$1" = clean ]; then
continue
fi
if [ -z "${m%%*_*}" ]; then
# Add named extension.
bits=${m%_*}
ext="-extensions ${m#*_}"
else
bits=$m
ext=
fi
if [ ! -e test-rsa$m.key ]; then
log openssl req -verbose -new -nodes -utf8 -sha1 -days 10000 -batch -x509 $ext \
-config test-ca.conf \
-newkey rsa:$bits \
-out test-rsa$m.cer -outform DER \
-keyout test-rsa$m.key
# for v1 signatures
log openssl pkey -in test-rsa$m.key -out test-rsa$m.pub -pubout
if [ $m = 1024_skid ]; then
# Create combined key+cert.
log openssl x509 -inform DER -in test-rsa$m.cer >> test-rsa$m.key
fi
fi
done
for curve in prime192v1 prime256v1; do
if [ "$1" = clean ] || [ "$1" = force ]; then
rm -f test-$curve.cer test-$curve.key test-$curve.pub
fi
if [ "$1" = clean ]; then
continue
fi
if [ ! -e test-$curve.key ]; then
log openssl req -verbose -new -nodes -utf8 -sha1 -days 10000 -batch -x509 \
-config test-ca.conf \
-newkey ec \
-pkeyopt ec_paramgen_curve:$curve \
-out test-$curve.cer -outform DER \
-keyout test-$curve.key
if [ -s test-$curve.key ]; then
log openssl pkey -in test-$curve.key -out test-$curve.pub -pubout
fi
fi
done
# EC-RDSA
for m in \
gost2012_256:A \
gost2012_256:B \
gost2012_256:C \
gost2012_512:A \
gost2012_512:B; do
IFS=':' read -r algo param <<< "$m"
if [ "$1" = clean ] || [ "$1" = force ]; then
rm -f "test-$algo-$param.key" "test-$algo-$param.cer" "test-$algo-$param.pub"
fi
if [ "$1" = clean ]; then
continue
fi
[ -e "test-$algo-$param.key" ] && continue
log openssl req -nodes -x509 -utf8 -days 10000 -batch \
-config test-ca.conf \
-newkey "$algo" \
-pkeyopt "paramset:$param" \
-out "test-$algo-$param.cer" -outform DER \
-keyout "test-$algo-$param.key"
if [ -s "test-$algo-$param.key" ]; then
log openssl pkey -in "test-$algo-$param.key" -out "test-$algo-$param.pub" -pubout
fi
done
# SM2, If openssl 3.0 is installed, gen SM2 keys using
if [ -x /opt/openssl3/bin/openssl ]; then
(PATH=/opt/openssl3/bin:$PATH LD_LIBRARY_PATH=/opt/openssl3/lib
for curve in sm2; do
if [ "$1" = clean ] || [ "$1" = force ]; then
rm -f test-$curve.cer test-$curve.key test-$curve.pub
fi
if [ "$1" = clean ]; then
continue
fi
if [ ! -e test-$curve.key ]; then
log openssl req -verbose -new -nodes -utf8 -days 10000 -batch -x509 \
-sm3 -sigopt "distid:1234567812345678" \
-config test-ca.conf \
-copy_extensions copyall \
-newkey $curve \
-out test-$curve.cer -outform DER \
-keyout test-$curve.key
if [ -s test-$curve.key ]; then
log openssl pkey -in test-$curve.key -out test-$curve.pub -pubout
fi
fi
done)
fi
# This script leaves test-ca.conf, *.cer, *.pub, *.key files for sing/verify tests.
# They are never deleted except by `make distclean'.

View File

@ -1,8 +0,0 @@
#!/bin/sh
dir=${1:-/}
echo "Fixing dir: $dir"
find $dir \( -fstype rootfs -o -fstype ext3 -o -fstype ext4 \) -type f -exec openclose '{}' \;

79
tests/ima_hash.test Executable file
View File

@ -0,0 +1,79 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# evmctl ima_hash tests
#
# Copyright (C) 2020 Vitaly Chikunov <vt@altlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
cd "$(dirname "$0")" || exit 1
PATH=../src:$PATH
source ./functions.sh
_require evmctl openssl getfattr
trap _report_exit_and_cleanup EXIT
set -f # disable globbing
check() {
local alg=$1 prefix=$2 chash=$3 hash
local file=$alg-hash.txt
rm -f "$file"
touch "$file"
# Generate hash with openssl, if it failed skip test,
# unless it's negative test, then pass to evmctl
cmd="openssl dgst $OPENSSL_ENGINE -$alg $file"
echo - "$cmd"
hash=$(set -o pipefail; $cmd 2>/dev/null | cut -d' ' -f2)
if [ $? -ne 0 ] && _test_expected_to_pass; then
echo "${CYAN}$alg test is skipped$NORM"
rm "$file"
return "$SKIP"
fi
if [ "$chash" ] && [ "$chash" != "$hash" ]; then
color_red
echo "Invalid hash for $alg from openssl"
echo "Expected: $chash"
echo "Returned: $hash"
color_restore
rm "$file"
return "$HARDFAIL"
fi
ADD_TEXT_FOR=$alg ADD_DEL=$file \
_evmctl_run ima_hash --hashalgo "$alg" --xattr-user "$file" || return
ADD_TEXT_FOR=$alg \
_test_xattr "$file" user.ima "$prefix$hash" || return
rm "$file"
return "$OK"
}
# check args: algo hdr-prefix canonic-hash
expect_pass check md4 0x01 31d6cfe0d16ae931b73c59d7e0c089c0
expect_pass check md5 0x01 d41d8cd98f00b204e9800998ecf8427e
expect_pass check sha1 0x01 da39a3ee5e6b4b0d3255bfef95601890afd80709
expect_fail check SHA1 0x01 # uppercase
expect_fail check sha512-224 0x01 # valid for pkcs1
expect_fail check sha512-256 0x01 # valid for pkcs1
expect_fail check unknown 0x01 # nonexistent
expect_pass check sha224 0x0407 d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
expect_pass check sha256 0x0404 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
expect_pass check sha384 0x0405 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
expect_pass check sha512 0x0406 cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
expect_pass check rmd160 0x0403 9c1185a5c5e9fc54612808977ee8f548b2258d31
expect_pass check sm3 0x0411 1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b
_enable_gost_engine
expect_pass check md_gost12_256 0x0412 3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb
expect_pass check streebog256 0x0412 3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb
expect_pass check md_gost12_512 0x0413 8e945da209aa869f0455928529bcae4679e9873ab707b55315f56ceb98bef0a7362f715528356ee83cda5f2aac4c6ad2ba3a715c1bcd81cb8e9f90bf4c1c1a8a
expect_pass check streebog512 0x0413 8e945da209aa869f0455928529bcae4679e9873ab707b55315f56ceb98bef0a7362f715528356ee83cda5f2aac4c6ad2ba3a715c1bcd81cb8e9f90bf4c1c1a8a

23
tests/install-openssl3.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
set -ex
if [ -z "$COMPILE_SSL" ]; then
echo "Missing \$COMPILE_SSL!" >&2
exit 1
fi
version=${COMPILE_SSL}
wget --no-check-certificate https://github.com/openssl/openssl/archive/refs/tags/${version}.tar.gz
tar --no-same-owner -xzf ${version}.tar.gz
cd openssl-${version}
./Configure --prefix=/opt/openssl3 --openssldir=/opt/openssl3/ssl
make -j$(nproc)
# only install apps and library
sudo make install_sw
cd ..
rm -rf ${version}.tar.gz
rm -rf openssl-${version}

21
tests/install-swtpm.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh -ex
# No need to run via sudo if we already have permissions.
# Also, some distros do not have sudo configured for root:
# `root is not in the sudoers file. This incident will be reported.'
if [ -w /usr/local/bin ]; then
SUDO=
else
SUDO=sudo
fi
version=1637
wget --no-check-certificate https://sourceforge.net/projects/ibmswtpm2/files/ibmtpm${version}.tar.gz/download
mkdir ibmtpm$version
cd ibmtpm$version
tar --no-same-owner -xvzf ../download
cd src
make -j$(nproc)
$SUDO cp tpm_server /usr/local/bin/
cd ../..

8
tests/install-tss.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
set -ex
git clone https://git.code.sf.net/p/ibmtpm20tss/tss
cd tss
autoreconf -i && ./configure --disable-tpm-1.2 --disable-hwtpm && make -j$(nproc) && sudo make install
cd ..
rm -rf tss

View File

@ -1,20 +0,0 @@
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int fd;
fd = open(argv[1], O_RDONLY);
if (fd < 0) {
perror("open()");
exit(1);
}
close(fd);
return 0;
}

View File

@ -0,0 +1 @@
10 2e03b3fdb0014fc8bae2a07ca33ae67125b290f3 ima-ng sha256:83d19723ef3b3c05bb8ae70d86b3886c158f2408f1b71ed265886a7b79eb700e boot_aggregate

Binary file not shown.

View File

@ -0,0 +1,25 @@
pcrread: tsspcrread -halg sha1
0: 92c1850372e9493929aa9a2e9ea953e21ff1be45
1: 41c54039ca2750ea60d8ab7c48b142b10aba5667
2: b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
3: b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
4: 4c1a19aad90f770956ff5ee00334a2d548b1a350
5: a1444a8a9904666165730168b3ae489447d3cef7
6: b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
7: 5c6327a67ff36f138e0b7bb1d2eafbf8a6e52ebf
8: fed489d2e5f9f85136e5ff53553d5f8b978dbe1a
9: a2fa191f2622bb014702013bfebfca9fe210d9e5
10: 3134641a3e8a1f5f75fa850bb21c3104d6ab863b
11: 0000000000000000000000000000000000000000
12: 0000000000000000000000000000000000000000
13: 0000000000000000000000000000000000000000
14: 71161a5707051fa7d6f584d812240b2e80f61942
15: 0000000000000000000000000000000000000000
16: 0000000000000000000000000000000000000000
17: ffffffffffffffffffffffffffffffffffffffff
18: ffffffffffffffffffffffffffffffffffffffff
19: ffffffffffffffffffffffffffffffffffffffff
20: ffffffffffffffffffffffffffffffffffffffff
21: ffffffffffffffffffffffffffffffffffffffff
22: ffffffffffffffffffffffffffffffffffffffff
23: 0000000000000000000000000000000000000000

439
tests/sign_verify.test Executable file
View File

@ -0,0 +1,439 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# evmctl {,ima_}{sign,verify} tests
#
# Copyright (C) 2020 Vitaly Chikunov <vt@altlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
cd "$(dirname "$0")" || exit 1
PATH=../src:$PATH
source ./functions.sh
_require cmp evmctl getfattr openssl xxd
if cmp -b 2>&1 | grep -q "invalid option"; then
echo "cmp does not support -b (cmp from busybox?) Use cmp from diffutils"
exit "$HARDFAIL"
fi
./gen-keys.sh >/dev/null 2>&1
trap _report_exit_and_cleanup EXIT
WORKDIR=$(mktemp -d)
set -f # disable globbing
# Determine keyid from a cert
_keyid_from_cert() {
local cer=${1%.*}.cer cmd
local tmp
cer=test-${cer#test-}
# shellcheck disable=SC2086
cmd="openssl x509 $OPENSSL_ENGINE \
-in $cer -inform DER -pubkey -noout"
id=$($cmd 2>/dev/null \
| openssl asn1parse \
| grep BIT.STRING \
| tail -n1 \
| cut -d: -f1)
if [ -z "$id" ]; then
echo - "$cmd" >&2
echo "Cannot asn1parse $cer to determine keyid" >&2
exit 1
fi
tmp=$(mktemp)
# shellcheck disable=SC2086
openssl x509 $OPENSSL_ENGINE \
-in "$cer" -inform DER -pubkey -noout 2>/dev/null \
| openssl asn1parse -strparse "$id" -out "$tmp" -noout
# shellcheck disable=SC2002
cat "$tmp" \
| openssl dgst -c -sha1 \
| cut -d' ' -f2 \
| grep -o ":..:..:..:..$" \
| tr -d :
rm -f "$tmp"
}
# Convert test $type into evmctl op prefix
_op() {
if [ "$1" = ima ]; then
echo ima_
fi
}
# Convert test $type into xattr name
_xattr() {
if [ "$1" = ima ]; then
echo user.ima
else
echo user.evm
fi
}
# Check that detached signature matches xattr signature
_test_sigfile() {
local file=$1 attr=$2 file_sig=$3 file_sig2=$4
if [ ! -e "$file_sig" ]; then
color_red
echo "evmctl ima_sign: no detached signature $file_sig"
color_restore
rm "$file"
return "$FAIL"
fi
_extract_xattr "$file" "$attr" "$file_sig2"
if ! cmp -bl "$file_sig" "$file_sig2"; then
color_red
echo "evmctl ima_sign: xattr signature on $file differ from detached $file_sig"
color_restore
rm "$file" "$file_sig" "$file_sig2"
return "$FAIL"
fi
# Leave '$file_sig' for ima_verify --sigfile test.
rm "$file_sig2"
}
# Run single sign command
_evmctl_sign() {
local type=$1 key=$2 alg=$3 file=$4 opts=$5
# Can check --sigfile for ima_sign
[ "$type" = ima ] && opts+=" --sigfile"
# shellcheck disable=SC2086
ADD_TEXT_FOR="$alg ($key)" ADD_DEL=$file \
_evmctl_run "$(_op "$type")sign" $opts \
--hashalgo "$alg" --key "$key" --xattr-user "$file" || return
if [ "$type" = ima ]; then
_test_sigfile "$file" "$(_xattr "$type")" "$file.sig" "$file.sig2"
fi
}
# Run and test {ima_,}sign operation
check_sign() {
# Arguments are passed via global vars:
# TYPE (ima or evm),
# KEY,
# ALG (hash algo),
# PREFIX (signature header prefix in hex),
# OPTS (additional options for evmctl),
# FILE (working file to sign).
local "$@"
local key verifykey
local FILE=${FILE:-$ALG.txt}
# Normalize key filename if it's not a pkcs11 URI
if [ ${KEY:0:7} != pkcs11: ]; then
key=${KEY%.*}.key
key=test-${key#test-}
else
key=${KEY}
fi
# Append suffix to files for negative tests, because we may
# leave only good files for verify tests.
_test_expected_to_fail && FILE+='~'
rm -f $FILE
if ! touch $FILE; then
color_red
echo "Can't create test file: $FILE"
color_restore
return "$HARDFAIL"
fi
if _test_expected_to_pass; then
# Can openssl work with this digest?
cmd="openssl dgst $OPENSSL_ENGINE $OPENSSL_KEYFORM -$ALG $FILE"
echo - "$cmd"
if ! $cmd >/dev/null; then
echo "${CYAN}$ALG ($key) test is skipped (openssl is unable to digest)$NORM"
return "$SKIP"
fi
if [ "${key:0:7}" != pkcs11: ] && [ ! -e "$key" ]; then
echo "${CYAN}$ALG ($key) test is skipped (key file not found)$NORM"
return "$SKIP"
fi
# Can openssl sign with this digest and key?
cmd="openssl dgst $OPENSSL_ENGINE $OPENSSL_KEYFORM -$ALG -sign $key -hex $FILE"
echo - "$cmd"
if ! $cmd >/dev/null; then
echo "${CYAN}$ALG ($key) test is skipped (openssl is unable to sign)$NORM"
return "$SKIP"
fi
fi
# Insert keyid from cert into PREFIX in-place of marker `:K:'
if [[ $PREFIX =~ :K: ]]; then
keyid=$(_keyid_from_cert "$key")
if [ $? -ne 0 ]; then
color_red
echo "Unable to determine keyid for $key"
color_restore
return "$HARDFAIL"
fi
[ "$VERBOSE" -gt 2 ] && echo " Expected keyid: $keyid"
PREFIX=${PREFIX/:K:/$keyid}
fi
# Perform signing by evmctl
_evmctl_sign "$TYPE" "$key" "$ALG" "$FILE" "$OPTS" || return
# First simple pattern match the signature.
ADD_TEXT_FOR=$ALG \
_test_xattr "$FILE" "$(_xattr "$TYPE")" "$PREFIX.*" || return
# This is all we can do for v1 signatures.
[[ "$OPTS" =~ --rsa ]] && return "$OK"
# This is all we can do for evm.
[[ "$TYPE" =~ evm ]] && return "$OK"
# When using the SM2/3 algorithm, the openssl tool uses USERID for verify,
# which is incompatible with calling API directly, so skip it.
[[ "$ALG" == sm3 ]] && return "$OK"
# Extract signature to a file
_extract_xattr "$FILE" "$(_xattr "$TYPE")" "$FILE.sig2" "$PREFIX"
# Verify extracted signature with openssl
if [ "${key:0:7}" != pkcs11: ]; then
verifykey=${key%.*}.pub
else
verifykey=${key}
fi
cmd="openssl dgst $OPENSSL_ENGINE $OPENSSL_KEYFORM -$ALG -verify ${verifykey} \
-signature $FILE.sig2 $FILE"
echo - "$cmd"
if ! $cmd; then
color_red_on_failure
echo "Signature v2 verification with openssl is failed."
color_restore
rm "$FILE.sig2"
return "$FAIL"
fi
rm "$FILE.sig2"
return "$OK"
}
# Test verify operation
check_verify() {
# Arguments are passed via global vars:
# TYPE (ima or evm),
# KEY,
# ALG (hash algo),
# OPTS (additional options for evmctl),
# FILE (filename to verify).
local "$@"
# shellcheck disable=SC2086
if ! openssl dgst $OPENSSL_ENGINE -"$ALG" /dev/null >/dev/null 2>&1; then
echo $CYAN"$ALG ($KEY) test is skipped (openssl does not support $ALG)"$NORM
return $SKIP
fi
# shellcheck disable=SC2086
ADD_TEXT_FOR="$FILE ($KEY)" \
_evmctl_run "$(_op "$TYPE")verify" --key "$KEY" --xattr-user $OPTS "$FILE"
}
# Test runners
# Perform sign and verify ima and evm testing
sign_verify() {
local key=$1 alg=$2 prefix="$3" opts="$4"
local file=$alg.txt
# Set defaults:
# Public key is different for v1 and v2 (where x509 cert is used).
if [[ $opts =~ --rsa ]]; then
KEY=test-$key.pub
else
KEY=test-$key.cer
fi
ALG=$alg
PREFIX=$prefix
OPTS=$opts
FILE=$file
TYPE=ima
if expect_pass check_sign; then
# Normal verify with proper key should pass
expect_pass check_verify
expect_pass check_verify OPTS="--sigfile"
# Multiple files and some don't verify
expect_fail check_verify FILE="/dev/null $file"
rm "$FILE.sig"
fi
TYPE=evm
# Avoid running blkid for evm tests which may require root
# No generation on overlayfs:
# ioctl(3, FS_IOC_GETVERSION, 0x7ffd8e0bd628) = -1 ENOTTY (Inappropriate ioctl for device)
OPTS="$opts --uuid --generation 0"
if expect_pass check_sign; then
# Normal verify with proper key
expect_pass check_verify
# Verify with wrong key
expect_fail check_verify KEY=rsa2048
fi
# Note: Leaving TYPE=evm and file is evm signed
}
# Test --keys
try_different_keys() {
# This run after sign_verify which leaves
# TYPE=evm and file is evm signed
# v2 signing can work with multiple keys in --key option
if [[ ! $OPTS =~ --rsa ]]; then
# Have correct key in the key list
expect_pass check_verify KEY="test-rsa2048.cer,$KEY"
expect_pass check_verify KEY="/dev/null,$KEY,"
fi
# Try key that is not used for signing
expect_fail check_verify KEY=rsa2048
# Try completely wrong key files
expect_fail check_verify KEY=/dev/null
expect_fail check_verify KEY=/dev/zero
}
try_different_sigs() {
# TYPE=evm and file is evm signed
# Test --imasig
if expect_pass check_sign OPTS="$OPTS --imasig"; then
# Verify both evm and ima sigs
expect_pass check_verify
expect_pass check_verify TYPE=ima
fi
# Test --imahash
if expect_pass check_sign OPTS="$OPTS --imahash"; then
expect_pass check_verify
# IMA hash is not verifiable by ima_verify
expect_fail check_verify TYPE=ima
fi
# Test --portable (only supported for V2 signatures)
if expect_pass check_sign OPTS="$OPTS --portable --imahash" PREFIX=0x05; then
if [[ "$OPTS" =~ --rsa ]]; then
expect_fail check_verify
else
expect_pass check_verify
fi
fi
# Test -i (immutable)
expect_pass check_sign OPTS="$OPTS -i" PREFIX=0x0303
# Cannot be verified for now
}
# Single test args: type key hash signature-prefix "evmctl-options"
# sign_verify args: key hash signature-prefix "evmctl-options"
# Only single test can be prefixed with expect_{fail,pass}
# `sign_verify' can not be prefixed with expect_{fail,pass} because
# it runs multiple tests inside. See more tests there.
# signature-prefix can contain `:K:' which will be resolved to keyid (v2 only)
## Test v1 signatures
# Signature v1 only supports sha1 and sha256 so any other should fail
expect_fail \
check_sign TYPE=ima KEY=rsa1024 ALG=md5 PREFIX=0x0301 OPTS=--rsa
sign_verify rsa1024 sha1 0x0301 --rsa
sign_verify rsa1024 sha256 0x0301 --rsa
try_different_keys
try_different_sigs
## Test v2 signatures with RSA PKCS#1
# List of allowed hashes much greater but not all are supported.
sign_verify rsa1024 md5 0x030201:K:0080
sign_verify rsa1024 sha1 0x030202:K:0080
sign_verify rsa1024 sha224 0x030207:K:0080
expect_pass check_sign TYPE=ima KEY=rsa1024 ALG=sha256 PREFIX=0x030204aabbccdd0080 OPTS=--keyid=aabbccdd
expect_pass check_sign TYPE=ima KEY=rsa1024 ALG=sha256 PREFIX=0x030204:K:0080 OPTS=--keyid-from-cert=test-rsa1024.cer
expect_pass check_sign TYPE=ima KEY=rsa1024_skid ALG=sha256 PREFIX=0x030204123456780080
sign_verify rsa1024 sha256 0x030204:K:0080
try_different_keys
try_different_sigs
sign_verify rsa1024 sha384 0x030205:K:0080
sign_verify rsa1024 sha512 0x030206:K:0080
sign_verify rsa1024 rmd160 0x030203:K:0080
# Test v2 signatures with ECDSA
# Signature length is typically 0x34-0x38 bytes long, very rarely 0x33
sign_verify prime192v1 sha1 0x030202:K:003[345678]
sign_verify prime192v1 sha224 0x030207:K:003[345678]
sign_verify prime192v1 sha256 0x030204:K:003[345678]
sign_verify prime192v1 sha384 0x030205:K:003[345678]
sign_verify prime192v1 sha512 0x030206:K:003[345678]
# Signature length is typically 0x44-0x48 bytes long, very rarely 0x43
sign_verify prime256v1 sha1 0x030202:K:004[345678]
sign_verify prime256v1 sha224 0x030207:K:004[345678]
sign_verify prime256v1 sha256 0x030204:K:004[345678]
sign_verify prime256v1 sha384 0x030205:K:004[345678]
sign_verify prime256v1 sha512 0x030206:K:004[345678]
# If openssl 3.0 is installed, test the SM2/3 algorithm combination
if [ -x /opt/openssl3/bin/openssl ]; then
PATH=/opt/openssl3/bin:$PATH LD_LIBRARY_PATH=/opt/openssl3/lib \
sign_verify sm2 sm3 0x030211:K:004[345678]
fi
# Test v2 signatures with EC-RDSA
_enable_gost_engine
sign_verify gost2012_256-A md_gost12_256 0x030212:K:0040
sign_verify gost2012_256-B md_gost12_256 0x030212:K:0040
sign_verify gost2012_256-C md_gost12_256 0x030212:K:0040
sign_verify gost2012_512-A md_gost12_512 0x030213:K:0080
sign_verify gost2012_512-B md_gost12_512 0x030213:K:0080
# Test if signing with wrong key length does not work.
expect_fail \
check_sign TYPE=ima KEY=gost2012_512-B ALG=md_gost12_256 PREFIX=0x0302 OPTS=
expect_fail \
check_sign TYPE=ima KEY=gost2012_256-B ALG=md_gost12_512 PREFIX=0x0302 OPTS=
# Test signing with key described by pkcs11 URI
_softhsm_setup "${WORKDIR}"
if [ -n "${PKCS11_KEYURI}" ]; then
expect_pass check_sign FILE=pkcs11test TYPE=ima KEY=${PKCS11_KEYURI} ALG=sha256 PREFIX=0x030204aabbccdd0100 OPTS=--keyid=aabbccdd
expect_pass check_sign FILE=pkcs11test TYPE=ima KEY=${PKCS11_KEYURI} ALG=sha1 PREFIX=0x030202aabbccdd0100 OPTS=--keyid=aabbccdd
else
# to have a constant number of tests, skip these two tests
__skip() { echo "pkcs11 test is skipped: could not setup softhsm"; return $SKIP; }
expect_pass __skip
expect_pass __skip
fi
_softhsm_teardown "${WORKDIR}"

293
tests/softhsm_setup Executable file
View File

@ -0,0 +1,293 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0 and BSD-3-clause
# This program originates from 'swtpm' project (https://github.com/stefanberger/swtpm/)
if [ -z "$(type -P p11tool)" ]; then
echo "Need p11tool from gnutls"
exit 77
fi
if [ -z "$(type -P softhsm2-util)" ]; then
echo "Need softhsm2-util from softhsm2 package"
exit 77
fi
MAJOR=$(softhsm2-util -v | cut -d '.' -f1)
MINOR=$(softhsm2-util -v | cut -d '.' -f2)
if [ ${MAJOR} -lt 2 ] || [ ${MAJOR} -eq 2 -a ${MINOR} -lt 2 ]; then
echo "Need softhsm v2.2.0 or later"
exit 77
fi
NAME=swtpm-test
PIN=${PIN:-1234}
SO_PIN=${SO_PIN:-1234}
SOFTHSM_SETUP_CONFIGDIR=${SOFTHSM_SETUP_CONFIGDIR:-~/.config/softhsm2}
export SOFTHSM2_CONF=${SOFTHSM_SETUP_CONFIGDIR}/softhsm2.conf
UNAME_S="$(uname -s)"
case "${UNAME_S}" in
Darwin)
msg=$(sudo -v -n)
if [ $? -ne 0 ]; then
echo "Need password-less sudo rights on OS X to change /etc/gnutls/pkcs11.conf"
exit 1
fi
;;
esac
teardown_softhsm() {
local configdir=${SOFTHSM_SETUP_CONFIGDIR}
local configfile=${SOFTHSM2_CONF}
local bakconfigfile=${configfile}.bak
local tokendir=${configdir}/tokens
softhsm2-util --token "${NAME}" --delete-token &>/dev/null
case "${UNAME_S}" in
Darwin*)
if [ -f /etc/gnutls/pkcs11.conf.bak ]; then
sudo rm -f /etc/gnutls/pkcs11.conf
sudo mv /etc/gnutls/pkcs11.conf.bak \
/etc/gnutls/pkcs11.conf &>/dev/null
fi
;;
esac
if [ -f "$bakconfigfile" ]; then
mv "$bakconfigfile" "$configfile"
else
rm -f "$configfile"
fi
if [ -d "$tokendir" ]; then
rm -rf "${tokendir}"
fi
return 0
}
setup_softhsm() {
local msg tokenuri keyuri
local configdir=${SOFTHSM_SETUP_CONFIGDIR}
local configfile=${SOFTHSM2_CONF}
local bakconfigfile=${configfile}.bak
local tokendir=${configdir}/tokens
local rc
case "${UNAME_S}" in
Darwin*)
if [ -f /etc/gnutls/pkcs11.conf.bak ]; then
echo "/etc/gnutls/pkcs11.conf.bak already exists; need to 'teardown' first"
return 1
fi
sudo mv /etc/gnutls/pkcs11.conf \
/etc/gnutls/pkcs11.conf.bak &>/dev/null
if [ $(id -u) -eq 0 ]; then
SONAME="$(sudo -u nobody brew ls --verbose softhsm | \
grep -E "\.so$")"
else
SONAME="$(brew ls --verbose softhsm | \
grep -E "\.so$")"
fi
sudo mkdir -p /etc/gnutls &>/dev/null
sudo bash -c "echo "load=${SONAME}" > /etc/gnutls/pkcs11.conf"
;;
esac
if ! [ -d $configdir ]; then
mkdir -p $configdir
fi
mkdir -p ${tokendir}
if [ -f $configfile ]; then
mv "$configfile" "$bakconfigfile"
fi
if ! [ -f $configfile ]; then
cat <<_EOF_ > $configfile
directories.tokendir = ${tokendir}
objectstore.backend = file
log.level = DEBUG
slots.removable = false
_EOF_
fi
msg=$(p11tool --list-tokens 2>&1 | grep "token=${NAME}" | tail -n1)
if [ $? -ne 0 ]; then
echo "Could not list existing tokens"
echo "$msg"
fi
tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p')
if [ -z "$tokenuri" ]; then
msg=$(softhsm2-util \
--init-token --pin ${PIN} --so-pin ${SO_PIN} \
--free --label ${NAME} 2>&1)
if [ $? -ne 0 ]; then
echo "Could not initialize token"
echo "$msg"
return 2
fi
slot=$(echo "$msg" | \
sed -n 's/.* reassigned to slot \([0-9]*\)$/\1/p')
if [ -z "$slot" ]; then
slot=$(softhsm2-util --show-slots | \
grep -E "^Slot " | head -n1 |
sed -n 's/Slot \([0-9]*\)/\1/p')
if [ -z "$slot" ]; then
echo "Could not parse slot number from output."
echo "$msg"
return 3
fi
fi
msg=$(p11tool --list-tokens 2>&1 | \
grep "token=${NAME}" | tail -n1)
if [ $? -ne 0 ]; then
echo "Could not list existing tokens"
echo "$msg"
fi
tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p')
if [ -z "${tokenuri}" ]; then
echo "Could not get tokenuri!"
return 4
fi
# more recent versions of p11tool have --generate-privkey ...
msg=$(GNUTLS_PIN=$PIN p11tool \
--generate-privkey=rsa --bits 2048 --label mykey --login \
"${tokenuri}" 2>&1)
if [ $? -ne 0 ]; then
# ... older versions have --generate-rsa
msg=$(GNUTLS_PIN=$PIN p11tool \
--generate-rsa --bits 2048 --label mykey --login \
"${tokenuri}" 2>&1)
if [ $? -ne 0 ]; then
echo "Could not create RSA key!"
echo "$msg"
return 5
fi
fi
fi
getkeyuri_softhsm $slot
rc=$?
if [ $rc -ne 0 ]; then
teardown_softhsm
fi
return $rc
}
_getkeyuri_softhsm() {
local msg tokenuri keyuri
msg=$(p11tool --list-tokens 2>&1 | grep "token=${NAME}")
if [ $? -ne 0 ]; then
echo "Could not list existing tokens"
echo "$msg"
return 5
fi
tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p')
if [ -z "$tokenuri" ]; then
echo "Could not get token URL"
echo "$msg"
return 6
fi
msg=$(p11tool --list-all ${tokenuri} 2>&1)
if [ $? -ne 0 ]; then
echo "Could not list object under token $tokenuri"
echo "$msg"
softhsm2-util --show-slots
return 7
fi
keyuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p')
if [ -z "$keyuri" ]; then
echo "Could not get key URL"
echo "$msg"
return 8
fi
echo "$keyuri"
return 0
}
getkeyuri_softhsm() {
local keyuri rc
keyuri=$(_getkeyuri_softhsm)
rc=$?
if [ $rc -ne 0 ]; then
return $rc
fi
echo "keyuri: $keyuri?pin-value=${PIN}" #&module-name=softhsm2"
return 0
}
getpubkey_softhsm() {
local keyuri rc
keyuri=$(_getkeyuri_softhsm)
rc=$?
if [ $rc -ne 0 ]; then
return $rc
fi
GNUTLS_PIN=${PIN} p11tool --export-pubkey "${keyuri}" --login 2>/dev/null
return $?
}
usage() {
cat <<_EOF_
Usage: $0 [command]
Supported commands are:
setup : Setup the user's account for softhsm and create a
token and key with a test configuration
getkeyuri : Get the key's URI; may only be called after setup
getpubkey : Get the public key in PEM format; may only be called after setup
teardown : Remove the temporary softhsm test configuration
_EOF_
}
main() {
local ret
if [ $# -lt 1 ]; then
usage $0
echo -e "Missing command.\n\n"
return 1
fi
case "$1" in
setup)
setup_softhsm
ret=$?
;;
getkeyuri)
getkeyuri_softhsm
ret=$?
;;
getpubkey)
getpubkey_softhsm
ret=$?
;;
teardown)
teardown_softhsm
ret=$?
;;
*)
echo -e "Unsupported command: $1\n\n"
usage $0
ret=1
esac
return $ret
}
main "$@"
exit $?

View File

@ -0,0 +1,3 @@
10 cf41b43c4031672fcc2bd358b309ad33b977424f ima-ng sha256:f1b4c7c9b27e94569f4c2b64051c452bc609c3cb891dd7fae06b758f8bc83d14 boot_aggregate
10 983dcd8e6f7c84a1a5f10e762d1850623966ceab ima-ng sha256:ae06e032a65fed8102aff5f8f31c678dcf2eb25b826f77ecb699faa0411f89e0 /init
10 b6e4d01c73f6e4b698eaf48e7d76a2bae0c02514 ima-ng sha256:4b1764ee112aa8b2a6ae9a3a2f1e272b6601681f610708497673cd49e5bd2f5c /bin/sh

Binary file not shown.