Blame src/pcr_tsspcrread.c

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_tsspcrread.c
Packit Service 087331
 *	 PCR reading implementation based on IBM TSS2
Packit Service 087331
 */
Packit Service 087331
Packit Service 087331
#include <errno.h>
Packit Service 087331
#include <limits.h>
Packit Service 087331
#include <stdio.h>
Packit Service 087331
#include <string.h>
Packit Service 087331
#include <stdint.h>
Packit Service 087331
Packit Service 087331
#include <openssl/sha.h>
Packit Service 087331
Packit Service 087331
#define USE_FPRINTF
Packit Service 087331
#include "utils.h"
Packit Service 087331
#include "imaevm.h"
Packit Service 087331
Packit Service 087331
#define CMD "tsspcrread"
Packit Service 087331
Packit Service 087331
static char path[PATH_MAX];
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", CMD);
Packit Service 087331
Packit Service 087331
	if (get_cmd_path(CMD, path, sizeof(path))) {
Packit Service 087331
		log_debug("Couldn't find '%s' in $PATH", CMD);
Packit Service 087331
		return 0;
Packit Service 087331
	}
Packit Service 087331
Packit Service 087331
	log_debug("Found '%s' in $PATH", CMD);
Packit Service 087331
	return 1;
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
	FILE *fp;
Packit Service 087331
	char pcr[100];	/* may contain an error */
Packit Service 087331
	char cmd[PATH_MAX + 50];
Packit Service 087331
	int ret;
Packit Service 087331
Packit Service 087331
	sprintf(cmd, "%s -halg %s -ha %d -ns 2> /dev/null",
Packit Service 087331
		path, algo_name, idx);
Packit Service 087331
	fp = popen(cmd, "r");
Packit Service 087331
	if (!fp) {
Packit Service 087331
		ret = asprintf(errmsg, "popen failed: %s", strerror(errno));
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 (fgets(pcr, sizeof(pcr), fp) == NULL) {
Packit Service 087331
		ret = asprintf(errmsg, "tsspcrread failed: %s",
Packit Service 087331
			       strerror(errno));
Packit Service 087331
		if (ret == -1)	/* the contents of errmsg is undefined */
Packit Service 087331
			*errmsg = NULL;
Packit Service 087331
		ret = pclose(fp);
Packit Service 087331
		return -1;
Packit Service 087331
	}
Packit Service 087331
Packit Service 087331
	/* get the popen "cmd" return code */
Packit Service 087331
	ret = pclose(fp);
Packit Service 087331
Packit Service 087331
	/* Treat an unallocated bank as an error */
Packit Service 087331
	if (!ret && (strlen(pcr) < SHA_DIGEST_LENGTH))
Packit Service 087331
		ret = -1;
Packit Service 087331
Packit Service 087331
	if (!ret)
Packit Service 087331
		hex2bin(hwpcr, pcr, len);
Packit Service 087331
	else
Packit Service 087331
		*errmsg = strndup(pcr, strlen(pcr) - 1); /* remove newline */
Packit Service 087331
Packit Service 087331
	return ret;
Packit Service 087331
}