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