1
0
mirror of https://git.code.sf.net/p/linux-ima/ima-evm-utils synced 2025-04-28 22:53:37 +02:00
Petr Vorel 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

192 lines
5.2 KiB
C

/*
* 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, int idx, 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[idx / 8] = (1 << (idx % 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;
}