mirror of
https://github.com/stefanberger/swtpm.git
synced 2026-08-08 12:25:52 +00:00
Extend swtpm_bios with --tpm2 to support a TPM 2
Extend the swtpm_bios tool with a --tpm2 command line parameter to support TPM 2 initialization. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
parent
3008874c91
commit
8fcec541f8
@ -133,7 +133,7 @@
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "swtpm_bios 8"
|
||||
.TH swtpm_bios 8 "2016-04-18" "swtpm" ""
|
||||
.TH swtpm_bios 8 "2016-07-05" "swtpm" ""
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
@ -197,6 +197,9 @@ if port is not given, the default port 6545 is used.
|
||||
.IP "\fB\-\-unixio <path>\fR" 4
|
||||
.IX Item "--unixio <path>"
|
||||
Connect to the given UnixIO path.
|
||||
.IP "\fB\-tpm2\fR" 4
|
||||
.IX Item "-tpm2"
|
||||
The device is a \s-1TPM 2.\s0
|
||||
.IP "\fB\-c\fR" 4
|
||||
.IX Item "-c"
|
||||
Send TPM_Startup(\s-1ST_CLEAR\s0) (default). This instructs the \s-1TPM\s0 to start
|
||||
@ -208,7 +211,7 @@ previously saved state.
|
||||
.IP "\fB\-d\fR" 4
|
||||
.IX Item "-d"
|
||||
Send TPM_Startup(\s-1ST_DEACTIVATED\s0). This instructs the \s-1TPM\s0 to start in
|
||||
deactivated mode.
|
||||
deactivated mode. This option has no effect on a \s-1TPM 2.\s0
|
||||
.IP "\fB\-n\fR" 4
|
||||
.IX Item "-n"
|
||||
Don't send a TPM_Startup command.
|
||||
@ -221,10 +224,12 @@ Make sure that the \s-1TPM\s0 is activated; if the \s-1TPM\s0 requires a reset,
|
||||
will exist and return a return code of 129.
|
||||
.IP "\fB\-cs\fR" 4
|
||||
.IX Item "-cs"
|
||||
Send a TPM_ContinueSelfTest command.
|
||||
Send a TPM_ContinueSelfTest command to a \s-1TPM 1.2\s0 and a TPM2_IncrementalSelfTest
|
||||
command to a \s-1TPM 2.\s0
|
||||
.IP "\fB\-u\fR" 4
|
||||
.IX Item "-u"
|
||||
Give up physical presence.
|
||||
Give up physical presence on a \s-1TPM 1.2.\s0 In case of a \s-1TPM 2\s0 set the platform
|
||||
hierarchy to a random password.
|
||||
.IP "\fB\-v\fR" 4
|
||||
.IX Item "-v"
|
||||
Display version and exit.
|
||||
|
||||
@ -68,6 +68,10 @@ if port is not given, the default port 6545 is used.
|
||||
|
||||
Connect to the given UnixIO path.
|
||||
|
||||
=item B<-tpm2>
|
||||
|
||||
The device is a TPM 2.
|
||||
|
||||
=item B<-c>
|
||||
|
||||
Send TPM_Startup(ST_CLEAR) (default). This instructs the TPM to start
|
||||
@ -81,7 +85,7 @@ previously saved state.
|
||||
=item B<-d>
|
||||
|
||||
Send TPM_Startup(ST_DEACTIVATED). This instructs the TPM to start in
|
||||
deactivated mode.
|
||||
deactivated mode. This option has no effect on a TPM 2.
|
||||
|
||||
=item B<-n>
|
||||
|
||||
@ -98,11 +102,13 @@ will exist and return a return code of 129.
|
||||
|
||||
=item B<-cs>
|
||||
|
||||
Send a TPM_ContinueSelfTest command.
|
||||
Send a TPM_ContinueSelfTest command to a TPM 1.2 and a TPM2_IncrementalSelfTest
|
||||
command to a TPM 2.
|
||||
|
||||
=item B<-u>
|
||||
|
||||
Give up physical presence.
|
||||
Give up physical presence on a TPM 1.2. In case of a TPM 2 set the platform
|
||||
hierarchy to a random password.
|
||||
|
||||
=item B<-v>
|
||||
|
||||
|
||||
@ -383,130 +383,91 @@ static int TPM_ContinueSelfTest(int *tpm_errcode)
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
static void versioninfo(void)
|
||||
static int TPM2_Startup(unsigned short startup_type, int *tpm_errcode)
|
||||
{
|
||||
printf(
|
||||
"TPM emulator BIOS emulator version %d.%d.%d, Copyright (c) 2015 IBM Corp.\n"
|
||||
,SWTPM_VER_MAJOR, SWTPM_VER_MINOR, SWTPM_VER_MICRO);
|
||||
struct tpm2_startup ts = {
|
||||
.hdr = {
|
||||
.tag = htobe16(TPM2_ST_NO_SESSIONS),
|
||||
.length = htobe32(sizeof(ts)),
|
||||
.ordinal = htobe32(TPM2_CC_Startup),
|
||||
},
|
||||
.startup_type = htobe16(startup_type),
|
||||
};
|
||||
|
||||
return talk(&ts, sizeof(ts), tpm_errcode,
|
||||
TPM_DURATION_SHORT, NULL, 0);
|
||||
}
|
||||
|
||||
static void print_usage(const char *prgname)
|
||||
static int TPM2_IncrementalSelfTest(int *tpm_errcode)
|
||||
{
|
||||
versioninfo();
|
||||
printf(
|
||||
"\n"
|
||||
"%s [options]\n"
|
||||
"\n"
|
||||
"Runs TPM_Startup (unless -n), then (unless -o) sets PP, enable, activate \n"
|
||||
"and finally (using -u) gives up physical presence (PP)\n"
|
||||
"\n"
|
||||
"The following options are supported:\n"
|
||||
"\t--tpm-device <device> use the given device; default is /dev/tpm0\n"
|
||||
"\t--tcp [<host>]:[<prt>] connect to TPM on given host and port;\n"
|
||||
"\t default host is 127.0.0.1, default port is %u\n"
|
||||
"\t--unix <path> connect to TPM using UnixIO socket\n"
|
||||
"\t-c startup clear (default)\n"
|
||||
"\t-s startup state\n"
|
||||
"\t-d startup deactivate\n"
|
||||
"\t-n no startup\n"
|
||||
"\t-o startup only\n"
|
||||
"\t-cs run TPM_ContinueSelfTest\n"
|
||||
"\t-ea make sure that the TPM is activated; terminate\n"
|
||||
"\t with exit code 129 if the TPM needs to be reset\n"
|
||||
"\t-u give up physical presence\n"
|
||||
"\t-v display version and exit\n"
|
||||
"\t-h display this help screen and exit\n"
|
||||
, prgname, DEFAULT_TCP_PORT);
|
||||
struct tpm2_incremental_selftest ts = {
|
||||
.hdr = {
|
||||
.tag = htobe16(TPM2_ST_NO_SESSIONS),
|
||||
.length = htobe32(sizeof(ts)),
|
||||
.ordinal = htobe32(TPM2_CC_IncrementalSelfTest),
|
||||
},
|
||||
.to_test = {
|
||||
.num_entries = htobe32(1),
|
||||
.algids = {
|
||||
htobe16(TPM2_ALG_SHA1),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return talk(&ts, sizeof(ts), tpm_errcode,
|
||||
TPM_DURATION_SHORT, NULL, 0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
static int TPM2_HierarchyChangeAuth(int *tpm_errcode)
|
||||
{
|
||||
int ret = 0;
|
||||
int do_more = 1;
|
||||
int ensure_activated = 0;
|
||||
int contselftest = 0;
|
||||
unsigned char startupparm = TPM_ST_CLEAR; /* parameter for TPM_Startup(); */
|
||||
int tpm_errcode = 0;
|
||||
int unassert_pp = 0;
|
||||
int tpm_error = 0;
|
||||
struct tpm2_hierarchy_change_auth thca = {
|
||||
.hdr = {
|
||||
.tag = htobe16(TPM2_ST_SESSIONS),
|
||||
.length = htobe32(sizeof(thca)),
|
||||
.ordinal = htobe32(TPM2_CC_HierarchyChangeAuth),
|
||||
},
|
||||
.authhandle = htobe32(TPM2_RH_PLATFORM),
|
||||
.authblock_size = htobe32(sizeof(thca.authblock)),
|
||||
.authblock = {
|
||||
.handle = htobe32(TPM2_RS_PW),
|
||||
.nonce_size = htobe16(0),
|
||||
.cont = 1,
|
||||
.password_size = htobe16(0),
|
||||
},
|
||||
.newauth = {
|
||||
.size = htobe16(sizeof(thca.newauth.buffer)),
|
||||
},
|
||||
};
|
||||
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
ssize_t n = read(fd, &thca.newauth.buffer,
|
||||
sizeof(thca.newauth.buffer));
|
||||
close(fd);
|
||||
if (n != sizeof(thca.newauth.buffer)) {
|
||||
printf("Read of bytes from /dev/urandom failed");
|
||||
if (n < 0)
|
||||
printf(": %s", strerror(errno));
|
||||
printf("\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printf("Could not open /dev/urandom: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return talk(&thca, sizeof(thca), tpm_errcode,
|
||||
TPM_DURATION_SHORT, NULL, 0);
|
||||
}
|
||||
|
||||
static int tpm12_bios(int do_more, int contselftest, unsigned char startupparm,
|
||||
int unassert_pp, int ensure_activated)
|
||||
{
|
||||
int ret = 0;
|
||||
int tpm_errcode;
|
||||
int tpm_error = 0;
|
||||
unsigned short physical_presence;
|
||||
struct tpm_get_capability_permflags_res perm_flags;
|
||||
static struct option long_options[] = {
|
||||
{"tpm-device", required_argument, NULL, 'D'},
|
||||
{"tcp", required_argument, NULL, 'T'},
|
||||
{"unix", required_argument, NULL, 'U'},
|
||||
{"c", no_argument, NULL, 'c'},
|
||||
{"d", no_argument, NULL, 'd'},
|
||||
{"h", no_argument, NULL, 'h'},
|
||||
{"v", no_argument, NULL, 'v'},
|
||||
{"n", no_argument, NULL, 'n'},
|
||||
{"s", no_argument, NULL, 's'},
|
||||
{"o", no_argument, NULL, 'o'},
|
||||
{"cs", no_argument, NULL, 'C'},
|
||||
{"ea", no_argument, NULL, 'E'},
|
||||
{"u", no_argument, NULL, 'u'},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
int opt, option_index = 0;
|
||||
|
||||
while ((opt = getopt_long_only(argc, argv, "", long_options,
|
||||
&option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'D':
|
||||
tpm_device = strdup(optarg);
|
||||
if (!tpm_device) {
|
||||
fprintf(stderr, "Out of memory.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
if (parse_tcp_optarg(optarg, &tcp_hostname, &tcp_port) < 0) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
unix_path = strdup(optarg);
|
||||
if (!unix_path) {
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
startupparm = TPM_ST_CLEAR;
|
||||
do_more = 1;
|
||||
break;
|
||||
case 'd':
|
||||
startupparm = TPM_ST_DEACTIVATED;
|
||||
do_more = 0;
|
||||
break;
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
return EXIT_SUCCESS;
|
||||
case 'n':
|
||||
startupparm = 0xff;
|
||||
do_more = 1;
|
||||
break;
|
||||
case 's':
|
||||
startupparm = TPM_ST_STATE;
|
||||
do_more = 1;
|
||||
break;
|
||||
case 'o':
|
||||
do_more = 0;
|
||||
break;
|
||||
case 'C':
|
||||
contselftest = 1;
|
||||
break;
|
||||
case 'E':
|
||||
ensure_activated = 1;
|
||||
break;
|
||||
case 'u':
|
||||
unassert_pp = 1;
|
||||
break;
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (0xff != startupparm) {
|
||||
@ -617,3 +578,191 @@ int main(int argc, char *argv[])
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tpm2_bios(int do_more, int contselftest, unsigned char startupparm,
|
||||
int set_password)
|
||||
{
|
||||
int ret = 0;
|
||||
int tpm_errcode;
|
||||
int tpm_error = 0;
|
||||
|
||||
if (ret == 0) {
|
||||
if (0xff != startupparm) {
|
||||
ret = TPM2_Startup(startupparm, &tpm_errcode);
|
||||
if (tpm_errcode != 0) {
|
||||
tpm_error = 1;
|
||||
printf("TPM2_Startup returned error code "
|
||||
"0x%08x\n", tpm_errcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret == 0) && contselftest) {
|
||||
ret = TPM2_IncrementalSelfTest(&tpm_errcode);
|
||||
if (tpm_errcode != 0) {
|
||||
tpm_error = 1;
|
||||
printf("TPM2_ImcrementalSelfTest returned error "
|
||||
"code 0x%08x\n", tpm_errcode);
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret == 0) && set_password) {
|
||||
ret = TPM2_HierarchyChangeAuth(&tpm_errcode);
|
||||
if (tpm_errcode != 0) {
|
||||
tpm_error = 1;
|
||||
printf("TPM2_HierarchyChangeAuth returned error "
|
||||
"code 0x%08x\n", tpm_errcode);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret && tpm_error)
|
||||
ret = 0x80;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void versioninfo(void)
|
||||
{
|
||||
printf(
|
||||
"TPM emulator BIOS emulator version %d.%d.%d, Copyright (c) 2015 IBM Corp.\n"
|
||||
,SWTPM_VER_MAJOR, SWTPM_VER_MINOR, SWTPM_VER_MICRO);
|
||||
}
|
||||
|
||||
static void print_usage(const char *prgname)
|
||||
{
|
||||
versioninfo();
|
||||
printf(
|
||||
"\n"
|
||||
"%s [options]\n"
|
||||
"\n"
|
||||
"Runs TPM_Startup (unless -n), then (unless -o) sets PP, enable, activate \n"
|
||||
"and finally (using -u) gives up physical presence (PP)\n"
|
||||
"\n"
|
||||
"The following options are supported:\n"
|
||||
"\t--tpm-device <device> use the given device; default is /dev/tpm0\n"
|
||||
"\t--tcp [<host>]:[<prt>] connect to TPM on given host and port;\n"
|
||||
"\t default host is 127.0.0.1, default port is %u\n"
|
||||
"\t--unix <path> connect to TPM using UnixIO socket\n"
|
||||
"\t--tpm2 initialize a TPM2\n"
|
||||
"\t-c startup clear (default)\n"
|
||||
"\t-s startup state\n"
|
||||
"\t-d startup deactivate (no effect on TPM2)\n"
|
||||
"\t-n no startup\n"
|
||||
"\t-o startup only\n"
|
||||
"\t-cs run TPM_ContinueSelfTest on TPM1.2\n"
|
||||
"\t run TPM2_IncrementalSelfTest on TPM2\n"
|
||||
"\t-ea make sure that the TPM 1.2 is activated;\n"
|
||||
"\t terminate with exit code 129 if the TPM\n"
|
||||
"\t needs to be reset\n"
|
||||
"\t-u give up physical presence\n"
|
||||
"\t on TPM 2 set the platform hierachy to a\n"
|
||||
"\t random password\n"
|
||||
"\t-v display version and exit\n"
|
||||
"\t-h display this help screen and exit\n"
|
||||
, prgname, DEFAULT_TCP_PORT);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
int do_more = 1;
|
||||
int ensure_activated = 0;
|
||||
int contselftest = 0;
|
||||
unsigned char startupparm = 0x1; /* parameter for TPM_Startup(); */
|
||||
unsigned char startupparm_tpm2 = 0x00;
|
||||
int unassert_pp = 0;
|
||||
int tpm2 = 0;
|
||||
static struct option long_options[] = {
|
||||
{"tpm-device", required_argument, NULL, 'D'},
|
||||
{"tcp", required_argument, NULL, 'T'},
|
||||
{"unix", required_argument, NULL, 'U'},
|
||||
{"c", no_argument, NULL, 'c'},
|
||||
{"d", no_argument, NULL, 'd'},
|
||||
{"h", no_argument, NULL, 'h'},
|
||||
{"v", no_argument, NULL, 'v'},
|
||||
{"n", no_argument, NULL, 'n'},
|
||||
{"s", no_argument, NULL, 's'},
|
||||
{"o", no_argument, NULL, 'o'},
|
||||
{"cs", no_argument, NULL, 'C'},
|
||||
{"ea", no_argument, NULL, 'E'},
|
||||
{"u", no_argument, NULL, 'u'},
|
||||
{"tpm2", no_argument, NULL, '2'},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
int opt, option_index = 0;
|
||||
|
||||
while ((opt = getopt_long_only(argc, argv, "", long_options,
|
||||
&option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'D':
|
||||
tpm_device = strdup(optarg);
|
||||
if (!tpm_device) {
|
||||
fprintf(stderr, "Out of memory.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
if (parse_tcp_optarg(optarg, &tcp_hostname, &tcp_port) < 0) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
unix_path = strdup(optarg);
|
||||
if (!unix_path) {
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
startupparm = TPM_ST_CLEAR;
|
||||
startupparm_tpm2 = TPM2_SU_CLEAR;
|
||||
do_more = 1;
|
||||
break;
|
||||
case 'd':
|
||||
startupparm = TPM_ST_DEACTIVATED;
|
||||
startupparm_tpm2 = 0xff;
|
||||
do_more = 0;
|
||||
break;
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
return EXIT_SUCCESS;
|
||||
case 'n':
|
||||
startupparm = 0xff;
|
||||
startupparm_tpm2 = 0xff;
|
||||
do_more = 1;
|
||||
break;
|
||||
case 's':
|
||||
startupparm = TPM_ST_STATE;
|
||||
startupparm_tpm2 = TPM2_SU_STATE;
|
||||
do_more = 1;
|
||||
break;
|
||||
case 'o':
|
||||
do_more = 0;
|
||||
break;
|
||||
case 'C':
|
||||
contselftest = 1;
|
||||
break;
|
||||
case 'E':
|
||||
ensure_activated = 1;
|
||||
break;
|
||||
case 'u':
|
||||
unassert_pp = 1;
|
||||
break;
|
||||
case '2':
|
||||
tpm2 = 1;
|
||||
break;
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (tpm2) {
|
||||
ret = tpm2_bios(do_more, contselftest, startupparm_tpm2,
|
||||
unassert_pp);
|
||||
} else {
|
||||
ret = tpm12_bios(do_more, contselftest, startupparm,
|
||||
unassert_pp, ensure_activated);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -117,4 +117,59 @@ struct tpm_get_capability_permflags_res {
|
||||
uint8_t flags[20];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* constants for TPM 2 */
|
||||
|
||||
#define TPM2_ST_NO_SESSIONS 0x8001
|
||||
#define TPM2_ST_SESSIONS 0x8002
|
||||
|
||||
#define TPM2_CC_HierarchyChangeAuth 0x00000129
|
||||
#define TPM2_CC_IncrementalSelfTest 0x00000142
|
||||
#define TPM2_CC_Startup 0x00000144
|
||||
|
||||
#define TPM2_SU_CLEAR 0x0000
|
||||
#define TPM2_SU_STATE 0x0001
|
||||
|
||||
#define TPM2_ALG_SHA1 0x0004
|
||||
|
||||
#define TPM2_RS_PW 0x40000009
|
||||
#define TPM2_RH_PLATFORM 0x4000000c
|
||||
|
||||
/* data structures for TPM 2 */
|
||||
|
||||
struct tpm2_startup {
|
||||
struct tpm_header hdr;
|
||||
uint16_t startup_type;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tpm2l_alg_1_entry {
|
||||
uint32_t num_entries;
|
||||
uint16_t algids[1];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tpm2_incremental_selftest {
|
||||
struct tpm_header hdr;
|
||||
struct tpm2l_alg_1_entry to_test;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tpm2_authblock {
|
||||
uint32_t handle;
|
||||
uint16_t nonce_size;
|
||||
uint8_t cont;
|
||||
uint16_t password_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tpm2b_20 {
|
||||
uint16_t size;
|
||||
uint8_t buffer[20];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tpm2_hierarchy_change_auth {
|
||||
struct tpm_header hdr;
|
||||
uint32_t authhandle;
|
||||
uint32_t authblock_size;
|
||||
struct tpm2_authblock authblock;
|
||||
struct tpm2b_20 newauth;
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* _SWTPM_BIOS_H */
|
||||
|
||||
@ -45,7 +45,9 @@ TESTS += \
|
||||
test_tpm2_savestate \
|
||||
test_tpm2_setbuffersize \
|
||||
test_tpm2_wrongorder \
|
||||
test_tpm2_probe
|
||||
test_tpm2_probe \
|
||||
\
|
||||
test_tpm2_swtpm_bios
|
||||
|
||||
if WITH_SWTPM_SETUP
|
||||
TESTS += \
|
||||
@ -108,6 +110,7 @@ EXTRA_DIST=$(TESTS) \
|
||||
_test_tpm2_probe \
|
||||
_test_tpm2_savestate \
|
||||
_test_tpm2_setbuffersize \
|
||||
_test_tpm2_swtpm_bios \
|
||||
_test_tpm2_wrongorder \
|
||||
_test_volatilestate \
|
||||
_test_wrongorder
|
||||
|
||||
168
tests/_test_tpm2_swtpm_bios
Executable file
168
tests/_test_tpm2_swtpm_bios
Executable file
@ -0,0 +1,168 @@
|
||||
#!/bin/bash
|
||||
|
||||
# For the license, see the LICENSE file in the root directory.
|
||||
#set -x
|
||||
|
||||
DIR=$(dirname "$0")
|
||||
ROOT=${DIR}/..
|
||||
VTPM_NAME="vtpm-test-tpm2-swtpm-bios"
|
||||
SWTPM_DEV_NAME="/dev/${VTPM_NAME}"
|
||||
TPM_PATH=$(mktemp -d)
|
||||
STATE_FILE=$TPM_PATH/tpm2-00.permall
|
||||
VOLATILE_STATE_FILE=$TPM_PATH/tpm-00.volatilestate
|
||||
PID_FILE=$TPM_PATH/${SWTPM}.pid
|
||||
SWTPM_INTERFACE=${SWTPM_INTERFACE:-cuse}
|
||||
SWTPM_CMD_UNIX_PATH=${TPM_PATH}/unix-cmd.sock
|
||||
SWTPM_CTRL_UNIX_PATH=${TPM_PATH}/unix-ctrl.sock
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
pid=${SWTPM_PID}
|
||||
if [ -n "$pid" ]; then
|
||||
kill -9 $pid
|
||||
fi
|
||||
rm -rf $TPM_PATH
|
||||
}
|
||||
|
||||
trap "cleanup" EXIT
|
||||
|
||||
[ "${SWTPM_INTERFACE}" == "cuse" ] && source ${DIR}/test_cuse
|
||||
source ${DIR}/common
|
||||
|
||||
rm -f $STATE_FILE $VOLATILE_STATE_FILE 2>/dev/null
|
||||
|
||||
run_swtpm ${SWTPM_INTERFACE} --tpm2 --tpmstate dir=$TPM_PATH --pid file=$PID_FILE
|
||||
|
||||
ps aux | grep $SWTPM | grep -v grep
|
||||
|
||||
kill -0 ${SWTPM_PID}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: ${SWTPM_INTERFACE} TPM did not start."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -r $PID_FILE ]; then
|
||||
echo "Error: ${SWTPM_INTERFACE} TPM did not write pidfile."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PIDF="$(cat $PID_FILE)"
|
||||
if [ "$PIDF" != "${SWTPM_PID}" ]; then
|
||||
echo "Error: ${SWTPM_INTERFACE} TPM wrote pid $PIDF, but found ${SWTPM_PID}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Init the TPM
|
||||
run_swtpm_ioctl ${SWTPM_INTERFACE} -i
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Could not initialize the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 0.5
|
||||
|
||||
kill -0 ${SWTPM_PID} 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: ${SWTPM_INTERFACE} TPM not running anymore after INIT."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# must work
|
||||
res=$(run_swtpm_bios ${SWTPM_INTERFACE} --tpm2 -o 2>&1)
|
||||
if [ $? -ne 0 ] || [ -n "$res" ]; then
|
||||
echo "Error: Could not startup the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# must work
|
||||
res=$(run_swtpm_bios ${SWTPM_INTERFACE} --tpm2 -n -cs 2>&1)
|
||||
if [ $? -ne 0 ] || [ -n "$res" ]; then
|
||||
echo "Error: Could not self-test the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# must work
|
||||
res=$(run_swtpm_bios ${SWTPM_INTERFACE} --tpm2 -n -u 2>&1)
|
||||
if [ $? -ne 0 ] || [ -n "$res" ]; then
|
||||
echo "Error: Could not give up physical presence on the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# will NOT work -- we get error output in $res
|
||||
res=$(run_swtpm_bios ${SWTPM_INTERFACE} --tpm2 -n -u 2>&1)
|
||||
ret=$?
|
||||
if [ $ret -eq 0 ] || [ -z "$res" ]; then
|
||||
echo "Error: Could give up physical presence on the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $ret -ne 128 ]; then
|
||||
echo "Error: Wrong return code from swtpm_bios. Should be 128, had $ret."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# will NOT work (wrong device) -- we get error output in $res
|
||||
if [ "${SWTPM_INTERFACE}" == "cuse" ]; then
|
||||
res=$($SWTPM_BIOS --tpm-device /dev/${VTPM_NAME}123--tpm2 -n -u 2>&1)
|
||||
ret=$?
|
||||
if [ $ret -eq 0 ] || [ -z "$res" ]; then
|
||||
echo "Error: Could give up physical presence on wrong device."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $ret -ne 255 ]; then
|
||||
echo "Error: Wrong return code from swtpm_bios. Should be 255, had $ret."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# RESET TPM
|
||||
|
||||
run_swtpm_ioctl ${SWTPM_INTERFACE} -i
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Could not initialize the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# must work
|
||||
res=$(run_swtpm_bios ${SWTPM_INTERFACE} --tpm2 -cs -u 2>&1)
|
||||
if [ $? -ne 0 ] || [ -n "$res" ]; then
|
||||
echo "Error: Could not startup the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# will NOT work -- we get error output in $res
|
||||
res=$(run_swtpm_bios ${SWTPM_INTERFACE} --tpm2 -n -u 2>&1)
|
||||
ret=$?
|
||||
if [ $ret -eq 0 ] || [ -z "$res" ]; then
|
||||
echo "Error: Could give up physical presence on the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $ret -ne 128 ]; then
|
||||
echo "Error: Wrong return code from swtpm_bios. Should be 128, had $ret."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
run_swtpm_ioctl ${SWTPM_INTERFACE} -s
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Could not shut down the ${SWTPM_INTERFACE} TPM."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 0.5
|
||||
|
||||
kill -0 ${SWTPM_PID} 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Error: ${SWTPM_INTERFACE} TPM should not be running anymore."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e $STATE_FILE ]; then
|
||||
echo "Error: TPM state file $STATE_FILE does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "OK"
|
||||
|
||||
exit 0
|
||||
37
tests/test_tpm2_swtpm_bios
Executable file
37
tests/test_tpm2_swtpm_bios
Executable file
@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
export SWTPM_IOCTL_BUFFERSIZE=100
|
||||
export SWTPM_INTERFACE=cuse
|
||||
bash _test_tpm2_swtpm_bios
|
||||
ret=$?
|
||||
[ $ret -ne 0 ] && [ $ret -ne 77 ] && exit $ret
|
||||
|
||||
export SWTPM_IOCTL_BUFFERSIZE=4096
|
||||
export SWTPM_INTERFACE=cuse
|
||||
bash _test_tpm2_swtpm_bios
|
||||
ret=$?
|
||||
[ $ret -ne 0 ] && [ $ret -ne 77 ] && exit $ret
|
||||
|
||||
export SWTPM_INTERFACE=socket+socket
|
||||
export SWTPM_SERVER_NAME=localhost
|
||||
export SWTPM_SERVER_PORT=65520
|
||||
export SWTPM_CTRL_PORT=65521
|
||||
bash _test_tpm2_swtpm_bios
|
||||
ret=$?
|
||||
[ $ret -ne 0 ] && [ $ret -ne 77 ] && exit $ret
|
||||
|
||||
export SWTPM_INTERFACE=socket+unix
|
||||
export SWTPM_SERVER_NAME=localhost
|
||||
export SWTPM_SERVER_PORT=65520
|
||||
bash _test_tpm2_swtpm_bios
|
||||
ret=$?
|
||||
[ $ret -ne 0 ] && [ $ret -ne 77 ] && exit $ret
|
||||
|
||||
export SWTPM_INTERFACE=unix+unix
|
||||
bash _test_tpm2_swtpm_bios
|
||||
ret=$?
|
||||
[ $ret -ne 0 ] && [ $ret -ne 77 ] && exit $ret
|
||||
|
||||
exit 0
|
||||
Loading…
Reference in New Issue
Block a user