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