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

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>
This commit is contained in:
Mimi Zohar
2019-07-21 19:19:51 -04:00
parent 340f7eb7dd
commit 31ceff7eb6
2 changed files with 60 additions and 4 deletions

View File

@ -7,6 +7,7 @@ AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_HOST
AC_USE_SYSTEM_EXTENSIONS
# Checks for programs.
AC_PROG_CC
@ -29,6 +30,11 @@ AC_SUBST(KERNEL_HEADERS)
AC_CHECK_HEADER(unistd.h)
AC_CHECK_HEADERS(openssl/conf.h)
AC_CHECK_PROG(TSSPCRREAD, [tsspcrread], yes, no)
if test "x$TSSPCRREAD" = "xyes"; then
AC_DEFINE(HAVE_TSSPCRREAD, 1, [Define to 1 if you have tsspcrread binary installed])],
fi
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.])])
@ -71,4 +77,5 @@ echo
echo "Configuration:"
echo " debug: $pkg_cv_enable_debug"
echo " openssl-conf: $enable_openssl_conf"
echo " tsspcrread: $TSSPCRREAD"
echo

View File

@ -1383,10 +1383,8 @@ static int tpm_pcr_read(int idx, uint8_t *pcr, int len)
if (!fp)
fp = fopen(misc_pcrs, "r");
if (!fp) {
log_err("Unable to open %s or %s\n", pcrs, misc_pcrs);
if (!fp)
return -1;
}
for (;;) {
p = fgets(buf, sizeof(buf), fp);
@ -1402,6 +1400,43 @@ static int tpm_pcr_read(int idx, uint8_t *pcr, int len)
return result;
}
#ifdef HAVE_TSSPCRREAD
static int tpm2_pcr_read(int idx, uint8_t *hwpcr, int len, char **errmsg)
{
FILE *fp;
char pcr[100]; /* may contain an error */
char cmd[50];
int ret;
sprintf(cmd, "tsspcrread -halg sha1 -ha %d -ns 2> /dev/null", idx);
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);
if (!ret)
hex2bin(hwpcr, pcr, SHA_DIGEST_LENGTH);
else
*errmsg = strndup(pcr, strlen(pcr) - 1); /* remove newline */
return ret;
}
#endif
#define TCG_EVENT_NAME_LEN_MAX 255
struct template_entry {
@ -1658,8 +1693,22 @@ static int ima_measurement(const char *file)
log_info("PCRAgg %.2d: ", i);
log_dump(pcr[i], SHA_DIGEST_LENGTH);
if (tpm_pcr_read(i, hwpcr, sizeof(hwpcr)))
if (tpm_pcr_read(i, hwpcr, sizeof(hwpcr))) {
#ifdef HAVE_TSSPCRREAD
char *errmsg = NULL;
err = tpm2_pcr_read(i, hwpcr, sizeof(hwpcr), &errmsg);
if (err) {
log_info("Failed to read PCRs: (%s)\n", errmsg);
free(errmsg);
exit(1);
}
#else
log_info("Failed to read TPM 1.2 PCRs.\n");
exit(1);
#endif
}
log_info("HW PCR-%d: ", i);
log_dump(hwpcr, sizeof(hwpcr));