From: Mimi Zohar <zohar@linux.ibm.com>
To: Ken Goldman <kgoldman@us.ibm.com>,
Linux Integrity <linux-integrity@vger.kernel.org>
Subject: Re: [PATCH v2 3/5] ima-evm-utils: Change tpm2_pcr_read() to use C code
Date: Tue, 10 Nov 2020 11:04:58 -0500 [thread overview]
Message-ID: <d19bc808b3eeb40f47e010e0b23c26d2c807c538.camel@linux.ibm.com> (raw)
In-Reply-To: <20201012234416.20995-4-kgoldman@us.ibm.com>
Hi Ken,
On Mon, 2020-10-12 at 19:44 -0400, Ken Goldman wrote:
> Replace the call out to the command line tools with C functions.
>
> The algorithm_string_to_algid() function supports only the digest
> algorithms in use. The table has place holders for other agorithms as
> they are needed and the C strings are defined.
>
> The table can also be used for an algrithm 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>
The code seems to be working properly, but needs to be cleaned up.
There are simple formatting changes and some style changes.
Simple formatting changes:
- Tabs should be 8 characters.
- Remove blank spaces before code.
- 80 characater maximum line length.
- Leave a blank line between variable definitions and code.
- Long comments should start with "/*" and end with "*/" on separate
lines:
/*
* multiple line comments
* continued
*/
- When defining function variables, please use the format:
term:
<definition>
Style changes:
- There are valid reasons for having a common function exit (e.g.
freeing memory), otherwise the function should exit early. The "if (rc
== 0)" tests cause the code to unnecessarily be indented. Instead the
test could be inverted "if (!rc)" followed by a "goto out".
- Please do not use camel or Hungarian variable naming conventions.
The variable definition can reference the spec name.
thanks,
Mimi
> ---
> src/Makefile.am | 1 +
> src/pcr_tsspcrread.c | 156 +++++++++++++++++++++++++++++++++----------
> 2 files changed, 123 insertions(+), 34 deletions(-)
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index d6c779f..bf18caf 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -26,6 +26,7 @@ if USE_PCRTSS
> evmctl_SOURCES += pcr_tss.c
> else
> evmctl_SOURCES += pcr_tsspcrread.c
> +evmctl_LDADD += -libmtss
> endif
>
> AM_CPPFLAGS = -I$(top_srcdir) -include config.h
> diff --git a/src/pcr_tsspcrread.c b/src/pcr_tsspcrread.c
> index 118c7d2..eae68b7 100644
> --- a/src/pcr_tsspcrread.c
> +++ b/src/pcr_tsspcrread.c
> @@ -50,6 +50,10 @@
> #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];
> @@ -68,44 +72,128 @@ int tpm2_pcr_supported(void)
> return 1;
> }
>
> -int tpm2_pcr_read(const char *algo_name, uint32_t pcrHandle, 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 %d -ns 2> /dev/null",
> - path, algo_name, pcrHandle);
> - 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;
> - }
> +/* Table mapping C strings to TCG algorithm identifiers */
> +
> +typedef struct tdAlgorithm_Map {
> + const char *algorithm_string;
> + TPMI_ALG_HASH algid;
> +} Algorithm_Map;
>
> - 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;
> +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;
> +}
>
> - /* get the popen "cmd" return code */
> - ret = pclose(fp);
> +/* tpm2_pcr_read() reads the PCR
>
> - /* Treat an unallocated bank as an error */
> - if (!ret && (strlen(pcr) < SHA_DIGEST_LENGTH))
> - ret = -1;
> + algo_name is the PCR digest algorithm (the PCR bank) as a C string
> + pcrHandle is the PCR number to read
> + hwpcr is a buffer for the PCR output in binary
> + len is the allocated size of hwpcr and should match the digest algorithm
> +*/
>
> - if (!ret)
> - hex2bin(hwpcr, pcr, len);
> - else
> - *errmsg = strndup(pcr, strlen(pcr) - 1); /* remove newline */
> +int tpm2_pcr_read(const char *algo_name, uint32_t pcrHandle, uint8_t *hwpcr,
> + int len, char **errmsg)
> +{
> + int ret = 0; /* function return code */
> + TPM_RC rc = 0; /* TCG return code */
> + PCR_Read_In pcrReadIn; /* command input */
> + PCR_Read_Out pcrReadOut; /* response output */
> + TSS_CONTEXT *tssContext = NULL;
> + TPMI_ALG_HASH alg_id; /* PCR algorithm */
>
> - return ret;
> + if (rc == 0) { /* map algorithm string to TCG value */
> + 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;
> + }
> + }
> + if (rc == 0) {
> + rc = TSS_Create(&tssContext);
> + }
> + /* call TSS to execute the command */
> + if (rc == 0) {
> + pcrReadIn.pcrSelectionIn.count = 1;
> + pcrReadIn.pcrSelectionIn.pcrSelections[0].hash = alg_id;
> + pcrReadIn.pcrSelectionIn.pcrSelections[0].sizeofSelect = 3;
> + pcrReadIn.pcrSelectionIn.pcrSelections[0].pcrSelect[0] = 0;
> + pcrReadIn.pcrSelectionIn.pcrSelections[0].pcrSelect[1] = 0;
> + pcrReadIn.pcrSelectionIn.pcrSelections[0].pcrSelect[2] = 0;
> + pcrReadIn.pcrSelectionIn.pcrSelections[0].pcrSelect[pcrHandle / 8] =
> + 1 << (pcrHandle % 8);
> + rc = TSS_Execute(tssContext,
> + (RESPONSE_PARAMETERS *)&pcrReadOut,
> + (COMMAND_PARAMETERS *)&pcrReadIn,
> + NULL,
> + TPM_CC_PCR_Read,
> + TPM_RH_NULL, NULL, 0);
> + }
> + if (rc == 0) {
> + /* nothing read, bank missing */
> + if (pcrReadOut.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;
> + }
> + /* len parameter did not match the digest algorithm */
> + else if (pcrReadOut.pcrValues.digests[0].t.size != len) {
> + ret = asprintf(errmsg,
> + "tpm2_pcr_read: expected length %d actual %u for %s",
> + len, pcrReadOut.pcrValues.digests[0].t.size, algo_name);
> + if (ret == -1) { /* the contents of errmsg is undefined */
> + *errmsg = NULL;
> + }
> + rc = 1;
> + }
> + else {
> + memcpy(hwpcr,
> + pcrReadOut.pcrValues.digests[0].t.buffer,
> + pcrReadOut.pcrValues.digests[0].t.size);
> + }
> + }
> + {
> + TPM_RC rc1 = TSS_Delete(tssContext);
> + if (rc == 0) {
> + rc = rc1;
> + }
> + }
> + /* map TCG return code to function return code */
> + if (rc == 0) {
> + return 0;
> + }
> + else {
> + return -1;
> + }
> }
> +
next prev parent reply other threads:[~2020-11-10 16:05 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-12 23:44 [PATCH v2 0/5] Updates to use IBM TSS C API rather than command line tools Ken Goldman
2020-10-12 23:44 ` [PATCH v2 1/5] ima-evm-utils: Change env variable TPM_SERVER_TYPE for tpm_server Ken Goldman
2020-10-14 22:04 ` Mimi Zohar
2020-10-14 22:17 ` Ken Goldman
2020-10-14 22:28 ` Mimi Zohar
2020-10-15 12:54 ` Ken Goldman
2020-10-15 13:36 ` Mimi Zohar
2020-10-15 13:04 ` Ken Goldman
2020-10-12 23:44 ` [PATCH v2 2/5] ima-evm-utils: Change PCR iterater from int to uint32_t Ken Goldman
2020-10-12 23:44 ` [PATCH v2 3/5] ima-evm-utils: Change tpm2_pcr_read() to use C code Ken Goldman
2020-11-10 16:04 ` Mimi Zohar [this message]
2020-10-12 23:44 ` [PATCH v2 4/5] ima-evm-utils: Correct spelling errors Ken Goldman
2020-10-12 23:44 ` [PATCH v2 5/5] ima-evm-utils: Expand the INSTALL instructions Ken Goldman
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=d19bc808b3eeb40f47e010e0b23c26d2c807c538.camel@linux.ibm.com \
--to=zohar@linux.ibm.com \
--cc=kgoldman@us.ibm.com \
--cc=linux-integrity@vger.kernel.org \
/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