From: Ken Goldman <kgoldman@us.ibm.com>
To: zohar@linux.ibm.com, maroon@lists.linux.ibm.com,
linux-integrity@vger.kernel.org
Cc: kgold@linux.ibm.com, Ken Goldman <kgoldman@us.ibm.com>
Subject: [PATCH v5 ima-evm-utils 3/3] Create alternative tpm2_pcr_read() that uses IBM TSS
Date: Tue, 3 Aug 2021 16:40:08 -0400 [thread overview]
Message-ID: <20210803204008.29612-4-kgoldman@us.ibm.com> (raw)
In-Reply-To: <20210803204008.29612-1-kgoldman@us.ibm.com>
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>
Please review the configure.ac change.
---
configure.ac | 8 ++
src/Makefile.am | 15 +++-
src/pcr_ibmtss.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 213 insertions(+), 2 deletions(-)
create mode 100644 src/pcr_ibmtss.c
diff --git a/configure.ac b/configure.ac
index e1ed100..4f6fe7c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,10 +30,17 @@ 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, [have_ibmtss=true],
+ [have_ibmtss=false],
+ [[#define TPM_POSIX]])
+AM_CONDITIONAL([USE_IBMTSS], $have_ibmtss)
+
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.])])
@@ -79,5 +86,6 @@ echo " debug: $pkg_cv_enable_debug"
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: $have_ibmtss"
echo " doc: $have_doc"
echo
diff --git a/src/Makefile.am b/src/Makefile.am
index d6c779f..f89d971 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,10 +22,21 @@ evmctl_CPPFLAGS = $(AM_CPPFLAGS) $(LIBCRYPTO_CFLAGS)
evmctl_LDFLAGS = $(LDFLAGS_READLINE)
evmctl_LDADD = $(LIBCRYPTO_LIBS) -lkeyutils libimaevm.la
+# USE_PCRTSS uses the Intel TSS
if USE_PCRTSS
-evmctl_SOURCES += pcr_tss.c
+ 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
+ evmctl_SOURCES += pcr_tsspcrread.c
+
+endif
endif
AM_CPPFLAGS = -I$(top_srcdir) -include config.h
diff --git a/src/pcr_ibmtss.c b/src/pcr_ibmtss.c
new file mode 100644
index 0000000..551f9c4
--- /dev/null
+++ b/src/pcr_ibmtss.c
@@ -0,0 +1,192 @@
+/*
+ * ima-evm-utils - IMA/EVM support utilities
+ *
+ * Copyright (C) 2021 IBM
+ *
+ * Authors:
+ * Ken Goldman <kgoldman@us.ibm.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 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() reads 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:
+ rc1 = TSS_Delete(tss_context);
+ if (rc == 0)
+ rc = rc1;
+ /* map TCG return code to function return code */
+ if (rc == 0)
+ return 0;
+ else
+ return -1;
+}
+
--
2.25.1
next prev parent reply other threads:[~2021-08-03 20:40 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-03 20:40 [PATCH v5 ima-evm-utils 0/3] Add alternative calls to IBM TSS library Ken Goldman
2021-08-03 20:40 ` [PATCH v5 ima-evm-utils 1/3] Expand the INSTALL instructions Ken Goldman
2021-08-03 20:40 ` [PATCH v5 ima-evm-utils 2/3] Change PCR iterator from int to uint32_t Ken Goldman
2021-08-03 20:40 ` Ken Goldman [this message]
2021-08-11 10:57 ` [PATCH v5 ima-evm-utils 3/3] Create alternative tpm2_pcr_read() that uses IBM TSS Mimi Zohar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210803204008.29612-4-kgoldman@us.ibm.com \
--to=kgoldman@us.ibm.com \
--cc=kgold@linux.ibm.com \
--cc=linux-integrity@vger.kernel.org \
--cc=maroon@lists.linux.ibm.com \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox