Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759559AbYHHSzg (ORCPT ); Fri, 8 Aug 2008 14:55:36 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754988AbYHHSzY (ORCPT ); Fri, 8 Aug 2008 14:55:24 -0400 Received: from e2.ny.us.ibm.com ([32.97.182.142]:37586 "EHLO e2.ny.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754463AbYHHSzW (ORCPT ); Fri, 8 Aug 2008 14:55:22 -0400 Subject: [PATCH 1/4] integrity: TPM internel kernel interface From: Mimi Zohar To: linux-kernel@vger.kernel.org Cc: linux-security-module@vger.kernel.org, Al Viro , Stephen Smalley , James Morris , Randy Dunlap , safford@watson.ibm.com, serue@linux.vnet.ibm.com, sailer@watson.ibm.com, zohar@us.ibm.com References: <20080808184349.999902616@linux.vnet.ibm.com> Content-Type: text/plain Date: Fri, 08 Aug 2008 14:55:18 -0400 Message-Id: <1218221718.4444.11.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.22.3.1 (2.22.3.1-1.fc9) Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8024 Lines: 273 Resubmitting integrity-tpm-internal-kernel-interface.patch, which was previously Signed-off-by Kylene Hall. Updated per feedback. Adds the following support: - make internal kernel interface to transmit TPM commands global - adds reading a pcr value - adds extending a pcr value - adds lookup the tpm_chip for given chip number and type Signed-off-by: Debora Velarde Reviewed-by: James Morris Index: security-testing-2.6/drivers/char/tpm/tpm.c =================================================================== --- security-testing-2.6.orig/drivers/char/tpm/tpm.c +++ security-testing-2.6/drivers/char/tpm/tpm.c @@ -1,11 +1,12 @@ /* - * Copyright (C) 2004 IBM Corporation + * Copyright (C) 2004,2007,2008 IBM Corporation * * Authors: * Leendert van Doorn * Dave Safford * Reiner Sailer * Kylene Hall + * Debora Velarde * * Maintained by: * @@ -28,6 +29,13 @@ #include #include +#include +#include +#include +#include +#include +#include +#include #include "tpm.h" enum tpm_const { @@ -50,6 +58,8 @@ enum tpm_duration { static LIST_HEAD(tpm_chip_list); static DEFINE_SPINLOCK(driver_lock); static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES); +#define TPM_CHIP_NUM_MASK 0x0000ffff +#define TPM_CHIP_TYPE_SHIFT 16 /* * Array with one entry per ordinal defining the maximum amount @@ -366,8 +376,7 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_durat /* * Internal kernel interface to transmit TPM commands */ -static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, - size_t bufsiz) +ssize_t tpm_transmit(struct tpm_chip *chip, char *buf, size_t bufsiz) { ssize_t rc; u32 count, ordinal; @@ -425,6 +434,7 @@ out: mutex_unlock(&chip->tpm_mutex); return rc; } +EXPORT_SYMBOL_GPL(tpm_transmit); #define TPM_DIGEST_SIZE 20 #define TPM_ERROR_SIZE 10 @@ -710,6 +720,7 @@ ssize_t tpm_show_temp_deactivated(struct } EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated); +#define READ_PCR_RESULT_SIZE 30 static const u8 pcrread[] = { 0, 193, /* TPM_TAG_RQU_COMMAND */ 0, 0, 0, 14, /* length */ @@ -765,6 +776,102 @@ out: } EXPORT_SYMBOL_GPL(tpm_show_pcrs); +/* + * tpm_chip_lookup - return tpm_chip for given chip number and type + */ +static struct tpm_chip *tpm_chip_lookup(int chip_num, int chip_typ) +{ + struct tpm_chip *pos; + + spin_lock(&driver_lock); + list_for_each_entry(pos, &tpm_chip_list, list) { + if ((chip_num == TPM_ANY_NUM || pos->dev_num == chip_num) + && (chip_typ == TPM_ANY_TYPE)) { + spin_unlock(&driver_lock); + return pos; + } + } + + spin_unlock(&driver_lock); + return NULL; +} + +/** + * tpm_pcr_read - read a pcr value + * @chip_id: tpm chip identifier + * Upper 2 bytes: ANY, HW_ONLY or SW_ONLY + * Lower 2 bytes: tpm idx # or AN& + * @pcr_idx: pcr idx to retrieve + * @res_buf: TPM_PCR value + * size of res_buf is 20 bytes (or NULL if you don't care) + */ +int tpm_pcr_read(u32 chip_id, int pcr_idx, u8 *res_buf) +{ + u8 data[READ_PCR_RESULT_SIZE]; + int rc; + __be32 index; + int chip_num = chip_id & TPM_CHIP_NUM_MASK; + struct tpm_chip *chip; + + chip = tpm_chip_lookup(chip_num, chip_id >> TPM_CHIP_TYPE_SHIFT); + if (chip == NULL) + return -ENODEV; + BUILD_BUG_ON(sizeof(pcrread) > READ_PCR_RESULT_SIZE); + memcpy(data, pcrread, sizeof(pcrread)); + index = cpu_to_be32(pcr_idx); + memcpy(data + 10, &index, 4); + rc = tpm_transmit(chip, data, sizeof(data)); + if (rc > 0) + rc = get_unaligned_be32((__be32 *) (data + 6)); + + if (rc == 0 && res_buf) + memcpy(res_buf, data + 10, TPM_DIGEST_SIZE); + + return rc; + +} +EXPORT_SYMBOL_GPL(tpm_pcr_read); + +#define EXTEND_PCR_SIZE 34 +static const u8 pcrextend[] = { + 0, 193, /* TPM_TAG_RQU_COMMAND */ + 0, 0, 0, 34, /* length */ + 0, 0, 0, 20, /* TPM_ORD_Extend */ + 0, 0, 0, 0 /* PCR index */ +}; + +/** + * tpm_pcr_extend - extend pcr value with hash + * @chip_id: tpm chip identifier + * Upper 2 bytes: ANY, HW_ONLY or SW_ONLY + * Lower 2 bytes: tpm idx # or AN& + * @pcr_idx: pcr idx to extend + * @hash: hash value used to extend pcr value + */ +int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8 *hash) +{ + u8 data[EXTEND_PCR_SIZE]; + int rc; + __be32 index; + int chip_num = chip_id & TPM_CHIP_NUM_MASK; + struct tpm_chip *chip; + + chip = tpm_chip_lookup(chip_num, chip_id >> TPM_CHIP_TYPE_SHIFT); + if (chip == NULL) + return -ENODEV; + + BUILD_BUG_ON(sizeof(pcrextend) > EXTEND_PCR_SIZE); + memcpy(data, pcrextend, sizeof(pcrextend)); + index = cpu_to_be32(pcr_idx); + memcpy(data + 10, &index, 4); + memcpy(data + 14, hash, TPM_DIGEST_SIZE); + rc = tpm_transmit(chip, data, sizeof(data)); + if (rc > 0) + rc = get_unaligned_be32((__be32 *) (data + 6)); + return rc; +} +EXPORT_SYMBOL_GPL(tpm_pcr_extend); + #define READ_PUBEK_RESULT_SIZE 314 static const u8 readpubek[] = { 0, 193, /* TPM_TAG_RQU_COMMAND */ Index: security-testing-2.6/drivers/char/tpm/tpm.h =================================================================== --- security-testing-2.6.orig/drivers/char/tpm/tpm.h +++ security-testing-2.6/drivers/char/tpm/tpm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 IBM Corporation + * Copyright (C) 2004, 2007 IBM Corporation * * Authors: * Leendert van Doorn @@ -26,6 +26,7 @@ #include #include #include +#include enum tpm_timeout { TPM_TIMEOUT = 5, /* msecs */ @@ -128,6 +129,7 @@ extern void tpm_get_timeouts(struct tpm_ extern void tpm_gen_interrupt(struct tpm_chip *); extern void tpm_continue_selftest(struct tpm_chip *); extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); +ssize_t tpm_transmit(struct tpm_chip *chip, char *buf, size_t bufsiz); extern struct tpm_chip* tpm_register_hardware(struct device *, const struct tpm_vendor_specific *); extern int tpm_open(struct inode *, struct file *); Index: security-testing-2.6/include/linux/tpm.h =================================================================== --- /dev/null +++ security-testing-2.6/include/linux/tpm.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2004,2007 IBM Corporation + * + * Authors: + * Leendert van Doorn + * Dave Safford + * Reiner Sailer + * Kylene Hall + * Debora Velarde + * + * Maintained by: + * + * Device driver for TCG/TCPA TPM (trusted platform module). + * Specifications at www.trustedcomputinggroup.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + */ +#ifndef __LINUX_TPM_H__ +#define __LINUX_TPM_H__ + +#define PCI_DEVICE_ID_AMD_8111_LPC 0x7468 + +/* + * Chip type is one of these values in the upper two bytes of chip_id + */ +enum tpm_chip_type { + TPM_HW_TYPE = 0x0, + TPM_SW_TYPE = 0x1, + TPM_ANY_TYPE = 0xFFFF, +}; + +/* + * Chip num is this value or a valid tpm idx in lower two bytes of chip_id + */ +enum tpm_chip_num { + TPM_ANY_NUM = 0xFFFF, +}; + + +#if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) + +extern int tpm_pcr_read(u32 chip_id, int pcr_idx, u8 *res_buf); +extern int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8 *hash); +#endif +#endif -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/