From bd98690a4aeb38147c0c4a2df54bfe3b84fd681f Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Tue, 26 May 2015 07:30:38 -0400 Subject: [PATCH] Add ioctl to get configuration flags about keys in use Add an ioctl that lets an application retrieve which keys are in use by the TPM, i.e., file encryption or migration key Signed-off-by: Stefan Berger --- include/swtpm/tpm_ioctl.h | 19 +++++++++++++++++++ man/man8/swtpm_ioctl.8 | 6 +++++- man/man8/swtpm_ioctl.pod | 5 +++++ src/swtpm/cuse_tpm.c | 20 +++++++++++++++++++- src/swtpm/swtpm_nvfile.c | 10 ++++++++++ src/swtpm/swtpm_nvfile.h | 3 +++ src/swtpm_ioctl/tpm_ioctl.c | 17 +++++++++++++++++ tests/test_encrypted_state | 12 +++++++++++- tests/test_migration_key | 11 +++++++++++ 9 files changed, 100 insertions(+), 3 deletions(-) diff --git a/include/swtpm/tpm_ioctl.h b/include/swtpm/tpm_ioctl.h index d36e702e..3f9e0d00 100644 --- a/include/swtpm/tpm_ioctl.h +++ b/include/swtpm/tpm_ioctl.h @@ -137,6 +137,22 @@ struct ptm_setstate { } u; }; +/* + * Data structure to get runtime configuration information + * such as which keys are applied. + */ +struct ptm_getconfig { + union { + struct { + ptmres_t tpm_result; + uint32_t flags; + } resp; + } u; +}; + +#define CONFIG_FLAG_FILE_KEY 0x1 +#define CONFIG_FLAG_MIGRATION_KEY 0x2 + typedef uint64_t ptmcap_t; typedef struct ptmest ptmest_t; @@ -146,6 +162,7 @@ typedef struct ptmhdata ptmhdata_t; typedef struct ptminit ptminit_t; typedef struct ptm_getstate ptm_getstate_t; typedef struct ptm_setstate ptm_setstate_t; +typedef struct ptm_getconfig ptm_getconfig_t; /* capability flags returned by PTM_GET_CAPABILITY */ #define PTM_CAP_INIT (1) @@ -159,6 +176,7 @@ typedef struct ptm_setstate ptm_setstate_t; #define PTM_CAP_GET_STATEBLOB (1<<8) #define PTM_CAP_SET_STATEBLOB (1<<9) #define PTM_CAP_STOP (1<<10) +#define PTM_CAP_GET_CONFIG (1<<11) enum { PTM_GET_CAPABILITY = _IOR('P', 0, ptmcap_t), @@ -175,4 +193,5 @@ enum { PTM_GET_STATEBLOB = _IOWR('P', 11, ptm_getstate_t), PTM_SET_STATEBLOB = _IOWR('P', 12, ptm_setstate_t), PTM_STOP = _IOR('P', 13, ptmres_t), + PTM_GET_CONFIG = _IOR('P', 14, ptm_getconfig_t), }; diff --git a/man/man8/swtpm_ioctl.8 b/man/man8/swtpm_ioctl.8 index 0fa191c5..0e9a108c 100644 --- a/man/man8/swtpm_ioctl.8 +++ b/man/man8/swtpm_ioctl.8 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "swtpm_ioctl 8" -.TH swtpm_ioctl 8 "2015-03-16" "swtpm" "" +.TH swtpm_ioctl 8 "2015-05-26" "swtpm" "" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -211,6 +211,10 @@ names are permanent, volatile, and savestate. Note that this command can only be executed on a \s-1TPM\s0 that is shut down. To then start the \s-1TPM\s0 with the uploaded state, the \fI\-i\fR command must be issued. +.IP "\fB\-g\fR" 4 +.IX Item "-g" +Get configuration flags that for example indicate which keys (file encryption +or migration key) are in use by the \s-1CUSE TPM.\s0 .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fBswtpm_cuse\fR diff --git a/man/man8/swtpm_ioctl.pod b/man/man8/swtpm_ioctl.pod index df2834be..58b31aef 100644 --- a/man/man8/swtpm_ioctl.pod +++ b/man/man8/swtpm_ioctl.pod @@ -89,6 +89,11 @@ Note that this command can only be executed on a TPM that is shut down. To then start the TPM with the uploaded state, the I<-i> command must be issued. +=item B<-g> + +Get configuration flags that for example indicate which keys (file encryption +or migration key) are in use by the CUSE TPM. + =back =head1 SEE ALSO diff --git a/src/swtpm/cuse_tpm.c b/src/swtpm/cuse_tpm.c index c9198da8..694006b4 100644 --- a/src/swtpm/cuse_tpm.c +++ b/src/swtpm/cuse_tpm.c @@ -548,6 +548,7 @@ static void ptm_ioctl(fuse_req_t req, int cmd, void *arg, case PTM_GET_CAPABILITY: case PTM_SET_LOCALITY: case PTM_CANCEL_TPM_CMD: + case PTM_GET_CONFIG: /* no need to wait */ break; case PTM_INIT: @@ -584,7 +585,8 @@ static void ptm_ioctl(fuse_req_t req, int cmd, void *arg, | PTM_CAP_RESET_TPMESTABLISHED | PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB - | PTM_CAP_STOP; + | PTM_CAP_STOP + | PTM_CAP_GET_CONFIG; fuse_reply_ioctl(req, 0, &ptm_caps, sizeof(ptm_caps)); } break; @@ -875,6 +877,22 @@ static void ptm_ioctl(fuse_req_t req, int cmd, void *arg, } break; + case PTM_GET_CONFIG: + if (out_bufsz != sizeof(ptm_getconfig_t)) { + struct iovec iov = { arg, sizeof(uint32_t) }; + fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0); + } else { + ptm_getconfig_t pgs; + pgs.u.resp.tpm_result = 0; + pgs.u.resp.flags = 0; + if (SWTPM_NVRAM_Has_FileKey()) + pgs.u.resp.flags |= CONFIG_FLAG_FILE_KEY; + if (SWTPM_NVRAM_Has_MigrationKey()) + pgs.u.resp.flags |= CONFIG_FLAG_MIGRATION_KEY; + fuse_reply_ioctl(req, 0, &pgs, sizeof(pgs)); + } + break; + default: fuse_reply_err(req, EINVAL); } diff --git a/src/swtpm/swtpm_nvfile.c b/src/swtpm/swtpm_nvfile.c index 0ba2dd45..7e16379a 100644 --- a/src/swtpm/swtpm_nvfile.c +++ b/src/swtpm/swtpm_nvfile.c @@ -531,6 +531,11 @@ SWTPM_NVRAM_KeyParamCheck(uint32_t keylen, return rc; } +TPM_BOOL SWTPM_NVRAM_Has_FileKey(void) +{ + return filekey.symkey.valid; +} + TPM_RESULT SWTPM_NVRAM_Set_FileKey(const unsigned char *key, uint32_t keylen, enum encryption_mode encmode) { @@ -547,6 +552,11 @@ TPM_RESULT SWTPM_NVRAM_Set_FileKey(const unsigned char *key, uint32_t keylen, return rc; } +TPM_BOOL SWTPM_NVRAM_Has_MigrationKey(void) +{ + return migrationkey.symkey.valid; +} + TPM_RESULT SWTPM_NVRAM_Set_MigrationKey(const unsigned char *key, uint32_t keylen, enum encryption_mode encmode) diff --git a/src/swtpm/swtpm_nvfile.h b/src/swtpm/swtpm_nvfile.h index 8b19e9ab..404a2112 100644 --- a/src/swtpm/swtpm_nvfile.h +++ b/src/swtpm/swtpm_nvfile.h @@ -91,5 +91,8 @@ TPM_RESULT SWTPM_NVRAM_SetStateBlob(unsigned char *data, uint32_t tpm_number, const char *name); +TPM_BOOL SWTPM_NVRAM_Has_FileKey(void); +TPM_BOOL SWTPM_NVRAM_Has_MigrationKey(void); + #endif /* _SWTPM_NVFILE_H */ diff --git a/src/swtpm_ioctl/tpm_ioctl.c b/src/swtpm_ioctl/tpm_ioctl.c index 93e0bfb4..0ba1345b 100644 --- a/src/swtpm_ioctl/tpm_ioctl.c +++ b/src/swtpm_ioctl/tpm_ioctl.c @@ -350,6 +350,7 @@ static void usage(const char *prgname) " type may be one of volatile, permanent, or savestate\n" "--load : load the TPM state blob of given type from a file;\n" " type may be one of volatile, permanent, or savestate\n" +"-g : get configuration flags indicating which keys are in use\n" "\n" ,prgname); } @@ -364,6 +365,7 @@ int main(int argc, char *argv[]) ptmcap_t cap; ptmres_t res; ptminit_t init; + ptm_getconfig_t cfg; if (argc < 2) { fprintf(stderr, "Error: Missing command.\n\n"); @@ -552,6 +554,21 @@ int main(int argc, char *argv[]) if (do_load_state_blob(fd, argv[2], argv[3])) return 1; + } else if (!strcmp(argv[1], "-g")) { + n = ioctl(fd, PTM_GET_CONFIG, &cfg); + if (n < 0) { + fprintf(stderr, + "Could not execute ioctl PTM_GET_CONFIG: " + "%s\n", strerror(errno)); + return 1; + } + if (cfg.u.resp.tpm_result != 0) { + fprintf(stderr, + "TPM result from PTM_GET_CONFIG: 0x%x\n", + cfg.u.resp.tpm_result); + return 1; + } + printf("ptm configuration flags: 0x%x\n",cfg.u.resp.flags); } else { usage(argv[0]); return 1; diff --git a/tests/test_encrypted_state b/tests/test_encrypted_state index 700f2fd4..80b0f42f 100755 --- a/tests/test_encrypted_state +++ b/tests/test_encrypted_state @@ -111,7 +111,17 @@ if [ ! -r $VOLATILE_STATE_FILE ]; then exit 1 fi -sleep 5 +tmp=$($CUSE_TPM_IOCTL -g /dev/$VTPM_NAME | cut -d":" -f2) +if [ $? -ne 0 ]; then + echo "Error: Could not get the configration flags of the CUSE TPM." + exit 1 +fi + +if [ "$tmp" != " 0x1" ]; then + echo "Error: Unexpected configuration flags: $tmp; expected 0x1." + exit 1 +fi + # Shut the TPM down exec 100>&- $CUSE_TPM_IOCTL -s /dev/$VTPM_NAME diff --git a/tests/test_migration_key b/tests/test_migration_key index 03b4460e..e16bd555 100755 --- a/tests/test_migration_key +++ b/tests/test_migration_key @@ -136,6 +136,17 @@ if [ "$hash" != "$exphash" ]; then exit 1 fi +tmp=$($CUSE_TPM_IOCTL -g /dev/$VTPM_NAME | cut -d":" -f2) +if [ $? -ne 0 ]; then + echo "Error: Could not get the configration flags of the CUSE TPM." + exit 1 +fi + +if [ "$tmp" != " 0x2" ]; then + echo "Error: Unexpected configuration flags: $tmp; expected 0x2." + exit 1 +fi + # Shut the TPM down exec 100>&- $CUSE_TPM_IOCTL -s /dev/$VTPM_NAME