Commit be6c1529 authored by Reinhard Pfau's avatar Reinhard Pfau Committed by Andy Fleming

tpm: add AUTH1 cmds for LoadKey2 and GetPubKey

Extend the tpm library with support for single authorized (AUTH1) commands
as specified in the TCG Main Specification 1.2. (The internally used helper
functions are implemented in a way that they could also be used for double
authorized commands if someone needs it.)

Provide enums with the return codes from the TCG Main specification.

For now only a single OIAP session is supported.

OIAP authorized version of the commands TPM_LoadKey2 and TPM_GetPubKey are
provided. Both features are available using the 'tpm' command, too.

Authorized commands are enabled with CONFIG_TPM_AUTH_SESSIONS. (Note that
this also requires CONFIG_SHA1 to be enabled.)
Signed-off-by: 's avatarReinhard Pfau <reinhard.pfau@gdsys.cc>
Signed-off-by: 's avatarDirk Eibach <dirk.eibach@gdsys.cc>
Acked-by: 's avatarChe-Liang Chiou <clchiou@chromium.org>
Signed-off-by: 's avatarAndy Fleming <afleming@freescale.com>
parent baa8841d
......@@ -1247,6 +1247,20 @@ The following options need to be configured:
to. Contemporary x86 systems usually map it at
0xfed40000.
CONFIG_CMD_TPM
Add tpm monitor functions.
Requires CONFIG_TPM. If CONFIG_TPM_AUTH_SESSIONS is set, also
provides monitor access to authorized functions.
CONFIG_TPM
Define this to enable the TPM support library which provides
functional interfaces to some TPM commands.
Requires support for a TPM device.
CONFIG_TPM_AUTH_SESSIONS
Define this to enable authorized functions in the TPM library.
Requires CONFIG_TPM and CONFIG_SHA1.
- USB Support:
At the moment only the UHCI host controller is
supported (PIP405, MIP405, MPC5200); define
......
......@@ -27,6 +27,13 @@
#include <asm/unaligned.h>
#include <linux/string.h>
/* Useful constants */
enum {
DIGEST_LENGTH = 20,
/* max lengths, valid for RSA keys <= 2048 bits */
TPM_PUBKEY_MAX_LENGTH = 288,
};
/**
* Print a byte string in hexdecimal format, 16-bytes per line.
*
......@@ -546,6 +553,72 @@ static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
return convert_return_code(err);
}
#ifdef CONFIG_TPM_AUTH_SESSIONS
static int do_tpm_oiap(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
uint32_t auth_handle, err;
err = tpm_oiap(&auth_handle);
return convert_return_code(err);
}
static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
uint32_t parent_handle, key_len, key_handle, err;
uint8_t usage_auth[DIGEST_LENGTH];
void *key;
if (argc < 5)
return CMD_RET_USAGE;
parent_handle = simple_strtoul(argv[1], NULL, 0);
key = (void *)simple_strtoul(argv[2], NULL, 0);
key_len = simple_strtoul(argv[3], NULL, 0);
if (strlen(argv[4]) != 2 * DIGEST_LENGTH)
return CMD_RET_FAILURE;
parse_byte_string(argv[4], usage_auth, NULL);
err = tpm_load_key2_oiap(parent_handle, key, key_len, usage_auth,
&key_handle);
if (!err)
printf("Key handle is 0x%x\n", key_handle);
return convert_return_code(err);
}
static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
uint32_t key_handle, err;
uint8_t usage_auth[DIGEST_LENGTH];
uint8_t pub_key_buffer[TPM_PUBKEY_MAX_LENGTH];
size_t pub_key_len = sizeof(pub_key_buffer);
if (argc < 3)
return CMD_RET_USAGE;
key_handle = simple_strtoul(argv[1], NULL, 0);
if (strlen(argv[2]) != 2 * DIGEST_LENGTH)
return CMD_RET_FAILURE;
parse_byte_string(argv[2], usage_auth, NULL);
err = tpm_get_pub_key_oiap(key_handle, usage_auth,
pub_key_buffer, &pub_key_len);
if (!err) {
printf("dump of received pub key structure:\n");
print_byte_string(pub_key_buffer, pub_key_len);
}
return convert_return_code(err);
}
TPM_COMMAND_NO_ARG(tpm_end_oiap)
#endif /* CONFIG_TPM_AUTH_SESSIONS */
#define MAKE_TPM_CMD_ENTRY(cmd) \
U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
......@@ -590,6 +663,16 @@ static cmd_tbl_t tpm_commands[] = {
do_tpm_nv_read, "", ""),
U_BOOT_CMD_MKENT(nv_write, 0, 1,
do_tpm_nv_write, "", ""),
#ifdef CONFIG_TPM_AUTH_SESSIONS
U_BOOT_CMD_MKENT(oiap, 0, 1,
do_tpm_oiap, "", ""),
U_BOOT_CMD_MKENT(end_oiap, 0, 1,
do_tpm_end_oiap, "", ""),
U_BOOT_CMD_MKENT(load_key2_oiap, 0, 1,
do_tpm_load_key2_oiap, "", ""),
U_BOOT_CMD_MKENT(get_pub_key_oiap, 0, 1,
do_tpm_get_pub_key_oiap, "", ""),
#endif /* CONFIG_TPM_AUTH_SESSIONS */
};
static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
......@@ -638,6 +721,16 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
" get_capability cap_area sub_cap addr count\n"
" - Read <count> bytes of TPM capability indexed by <cap_area> and\n"
" <sub_cap> to memory address <addr>.\n"
#ifdef CONFIG_TPM_AUTH_SESSIONS
"Storage functions\n"
" loadkey2_oiap parent_handle key_addr key_len usage_auth\n"
" - loads a key data from memory address <key_addr>, <key_len> bytes\n"
" into TPM using the parent key <parent_handle> with authorization\n"
" <usage_auth> (20 bytes hex string).\n"
" get_pub_key_oiap key_handle usage_auth\n"
" - get the public key portion of a loaded key <key_handle> using\n"
" authorization <usage auth> (20 bytes hex string)\n"
#endif /* CONFIG_TPM_AUTH_SESSIONS */
"Endorsement Key Handling Commands:\n"
" read_pubek addr count\n"
" - Read <count> bytes of the public endorsement key to memory\n"
......@@ -648,6 +741,13 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
" <digest_hex_string>\n"
" pcr_read index addr count\n"
" - Read <count> bytes from PCR <index> to memory address <addr>.\n"
#ifdef CONFIG_TPM_AUTH_SESSIONS
"Authorization Sessions\n"
" oiap\n"
" - setup an OIAP session\n"
" end_oiap\n"
" - terminates an active OIAP session\n"
#endif /* CONFIG_TPM_AUTH_SESSIONS */
"Non-volatile Storage Commands:\n"
" nv_define_space index permission size\n"
" - Establish a space at index <index> with <permission> of <size> bytes.\n"
......
/*
* Copyright (c) 2013 The Chromium OS Authors.
* Coypright (c) 2013 Guntermann & Drunck GmbH
*
* See file CREDITS for list of people who contributed to this
* project.
......@@ -53,6 +54,120 @@ enum tpm_nv_index {
TPM_NV_INDEX_DIR = 0x10000001,
};
/**
* TPM return codes as defined in the TCG Main specification
* (TPM Main Part 2 Structures; Specification version 1.2)
*/
enum tpm_return_code {
TPM_BASE = 0x00000000,
TPM_NON_FATAL = 0x00000800,
TPM_SUCCESS = TPM_BASE,
/* TPM-defined fatal error codes */
TPM_AUTHFAIL = TPM_BASE + 1,
TPM_BADINDEX = TPM_BASE + 2,
TPM_BAD_PARAMETER = TPM_BASE + 3,
TPM_AUDITFAILURE = TPM_BASE + 4,
TPM_CLEAR_DISABLED = TPM_BASE + 5,
TPM_DEACTIVATED = TPM_BASE + 6,
TPM_DISABLED = TPM_BASE + 7,
TPM_DISABLED_CMD = TPM_BASE + 8,
TPM_FAIL = TPM_BASE + 9,
TPM_BAD_ORDINAL = TPM_BASE + 10,
TPM_INSTALL_DISABLED = TPM_BASE + 11,
TPM_INVALID_KEYHANDLE = TPM_BASE + 12,
TPM_KEYNOTFOUND = TPM_BASE + 13,
TPM_INAPPROPRIATE_ENC = TPM_BASE + 14,
TPM_MIGRATE_FAIL = TPM_BASE + 15,
TPM_INVALID_PCR_INFO = TPM_BASE + 16,
TPM_NOSPACE = TPM_BASE + 17,
TPM_NOSRK = TPM_BASE + 18,
TPM_NOTSEALED_BLOB = TPM_BASE + 19,
TPM_OWNER_SET = TPM_BASE + 20,
TPM_RESOURCES = TPM_BASE + 21,
TPM_SHORTRANDOM = TPM_BASE + 22,
TPM_SIZE = TPM_BASE + 23,
TPM_WRONGPCRVAL = TPM_BASE + 24,
TPM_BAD_PARAM_SIZE = TPM_BASE + 25,
TPM_SHA_THREAD = TPM_BASE + 26,
TPM_SHA_ERROR = TPM_BASE + 27,
TPM_FAILEDSELFTEST = TPM_BASE + 28,
TPM_AUTH2FAIL = TPM_BASE + 29,
TPM_BADTAG = TPM_BASE + 30,
TPM_IOERROR = TPM_BASE + 31,
TPM_ENCRYPT_ERROR = TPM_BASE + 32,
TPM_DECRYPT_ERROR = TPM_BASE + 33,
TPM_INVALID_AUTHHANDLE = TPM_BASE + 34,
TPM_NO_ENDORSEMENT = TPM_BASE + 35,
TPM_INVALID_KEYUSAGE = TPM_BASE + 36,
TPM_WRONG_ENTITYTYPE = TPM_BASE + 37,
TPM_INVALID_POSTINIT = TPM_BASE + 38,
TPM_INAPPROPRIATE_SIG = TPM_BASE + 39,
TPM_BAD_KEY_PROPERTY = TPM_BASE + 40,
TPM_BAD_MIGRATION = TPM_BASE + 41,
TPM_BAD_SCHEME = TPM_BASE + 42,
TPM_BAD_DATASIZE = TPM_BASE + 43,
TPM_BAD_MODE = TPM_BASE + 44,
TPM_BAD_PRESENCE = TPM_BASE + 45,
TPM_BAD_VERSION = TPM_BASE + 46,
TPM_NO_WRAP_TRANSPORT = TPM_BASE + 47,
TPM_AUDITFAIL_UNSUCCESSFUL = TPM_BASE + 48,
TPM_AUDITFAIL_SUCCESSFUL = TPM_BASE + 49,
TPM_NOTRESETABLE = TPM_BASE + 50,
TPM_NOTLOCAL = TPM_BASE + 51,
TPM_BAD_TYPE = TPM_BASE + 52,
TPM_INVALID_RESOURCE = TPM_BASE + 53,
TPM_NOTFIPS = TPM_BASE + 54,
TPM_INVALID_FAMILY = TPM_BASE + 55,
TPM_NO_NV_PERMISSION = TPM_BASE + 56,
TPM_REQUIRES_SIGN = TPM_BASE + 57,
TPM_KEY_NOTSUPPORTED = TPM_BASE + 58,
TPM_AUTH_CONFLICT = TPM_BASE + 59,
TPM_AREA_LOCKED = TPM_BASE + 60,
TPM_BAD_LOCALITY = TPM_BASE + 61,
TPM_READ_ONLY = TPM_BASE + 62,
TPM_PER_NOWRITE = TPM_BASE + 63,
TPM_FAMILY_COUNT = TPM_BASE + 64,
TPM_WRITE_LOCKED = TPM_BASE + 65,
TPM_BAD_ATTRIBUTES = TPM_BASE + 66,
TPM_INVALID_STRUCTURE = TPM_BASE + 67,
TPM_KEY_OWNER_CONTROL = TPM_BASE + 68,
TPM_BAD_COUNTER = TPM_BASE + 69,
TPM_NOT_FULLWRITE = TPM_BASE + 70,
TPM_CONTEXT_GAP = TPM_BASE + 71,
TPM_MAXNVWRITES = TPM_BASE + 72,
TPM_NOOPERATOR = TPM_BASE + 73,
TPM_RESOURCEMISSING = TPM_BASE + 74,
TPM_DELEGATE_LOCK = TPM_BASE + 75,
TPM_DELEGATE_FAMILY = TPM_BASE + 76,
TPM_DELEGATE_ADMIN = TPM_BASE + 77,
TPM_TRANSPORT_NOTEXCLUSIVE = TPM_BASE + 78,
TPM_OWNER_CONTROL = TPM_BASE + 79,
TPM_DAA_RESOURCES = TPM_BASE + 80,
TPM_DAA_INPUT_DATA0 = TPM_BASE + 81,
TPM_DAA_INPUT_DATA1 = TPM_BASE + 82,
TPM_DAA_ISSUER_SETTINGS = TPM_BASE + 83,
TPM_DAA_TPM_SETTINGS = TPM_BASE + 84,
TPM_DAA_STAGE = TPM_BASE + 85,
TPM_DAA_ISSUER_VALIDITY = TPM_BASE + 86,
TPM_DAA_WRONG_W = TPM_BASE + 87,
TPM_BAD_HANDLE = TPM_BASE + 88,
TPM_BAD_DELEGATE = TPM_BASE + 89,
TPM_BADCONTEXT = TPM_BASE + 90,
TPM_TOOMANYCONTEXTS = TPM_BASE + 91,
TPM_MA_TICKET_SIGNATURE = TPM_BASE + 92,
TPM_MA_DESTINATION = TPM_BASE + 93,
TPM_MA_SOURCE = TPM_BASE + 94,
TPM_MA_AUTHORITY = TPM_BASE + 95,
TPM_PERMANENTEK = TPM_BASE + 97,
TPM_BAD_SIGNATURE = TPM_BASE + 98,
TPM_NOCONTEXTSPACE = TPM_BASE + 99,
/* TPM-defined non-fatal errors */
TPM_RETRY = TPM_BASE + TPM_NON_FATAL,
TPM_NEEDS_SELFTEST = TPM_BASE + TPM_NON_FATAL + 1,
TPM_DOING_SELFTEST = TPM_BASE + TPM_NON_FATAL + 2,
TPM_DEFEND_LOCK_RUNNING = TPM_BASE + TPM_NON_FATAL + 3,
};
/**
* Initialize TPM device. It must be called before any TPM commands.
*
......@@ -201,4 +316,63 @@ uint32_t tpm_physical_set_deactivated(uint8_t state);
uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
void *cap, size_t count);
/**
* Issue a TPM_FlushSpecific command for a AUTH ressource.
*
* @param auth_handle handle of the auth session
* @return return code of the operation
*/
uint32_t tpm_terminate_auth_session(uint32_t auth_handle);
/**
* Issue a TPM_OIAP command to setup an object independant authorization
* session.
* Information about the session is stored internally.
* If there was already an OIAP session active it is terminated and a new
* session is set up.
*
* @param auth_handle pointer to the (new) auth handle or NULL.
* @return return code of the operation
*/
uint32_t tpm_oiap(uint32_t *auth_handle);
/**
* Ends an active OIAP session.
*
* @return return code of the operation
*/
uint32_t tpm_end_oiap(void);
/**
* Issue a TPM_LoadKey2 (Auth1) command using an OIAP session for authenticating
* the usage of the parent key.
*
* @param parent_handle handle of the parent key.
* @param key pointer to the key structure (TPM_KEY or TPM_KEY12).
* @param key_length size of the key structure
* @param parent_key_usage_auth usage auth for the parent key
* @param key_handle pointer to the key handle
* @return return code of the operation
*/
uint32_t tpm_load_key2_oiap(uint32_t parent_handle,
const void *key, size_t key_length,
const void *parent_key_usage_auth,
uint32_t *key_handle);
/**
* Issue a TPM_GetPubKey (Auth1) command using an OIAP session for
* authenticating the usage of the key.
*
* @param key_handle handle of the key
* @param usage_auth usage auth for the key
* @param pubkey pointer to the pub key buffer; may be NULL if the pubkey
* should not be stored.
* @param pubkey_len pointer to the pub key buffer len. On entry: the size of
* the provided pubkey buffer. On successful exit: the size
* of the stored TPM_PUBKEY structure (iff pubkey != NULL).
* @return return code of the operation
*/
uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth,
void *pubkey, size_t *pubkey_len);
#endif /* __TPM_H */
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment