both TPM 1.2 and TPM 2. If 'max' is passed, the largest possible key
size is used.
+=item B<--reconfigure> (since v0.7)
+
+This option allows the reconfiguration of the active PCR banks of a
+TPM 2 using the I<--pcr-banks> option.
+
=item B<--print-capabilities> (since v0.2)
Print capabilities that were added to swtpm_setup after version 0.1.
"cmdarg-pwdfile-fd",
"cmdarg-write-ek-cert-files",
"cmdarg-create-config-files",
+ "cmdarg-reconfigure-pcr-banks",
"tpm2-rsa-keysize-2048",
"tpm2-rsa-keysize-3072",
"tpm12-not-need-root",
The I<--create-config-files> option is supported.
+=item B<cmdarg-reconfigure-pcr-banks> (since v0.7)
+
+The I<--reconfigure> option is supported and allows the reconfiguration of
+the active PCR banks.
+
=item B<tpm2-rsa-keysize-2048, ...> (since v0.4)
The shown RSA key sizes are supported for a TPM 2's EK key. If none of the
#define SETUP_DISPLAY_RESULTS_F (1 << 13)
#define SETUP_DECRYPTION_F (1 << 14)
#define SETUP_WRITE_EK_CERT_FILES_F (1 << 15)
+#define SETUP_RECONFIGURE_F (1 << 16)
/* default configuration file */
#define SWTPM_SETUP_CONF "swtpm_setup.conf"
goto error;
}
- if ((flags & SETUP_CREATE_SPK_F)) {
- ret = swtpm2->ops->create_spk(swtpm, !!(flags & SETUP_TPM2_ECC_F), rsa_keysize);
+ if (!(flags & SETUP_RECONFIGURE_F)) {
+ if ((flags & SETUP_CREATE_SPK_F)) {
+ ret = swtpm2->ops->create_spk(swtpm, !!(flags & SETUP_TPM2_ECC_F), rsa_keysize);
+ if (ret != 0)
+ goto destroy;
+ }
+
+ ret = tpm2_create_eks_and_certs(flags, config_file, certsdir, vmid, rsa_keysize, swtpm2,
+ user_certsdir);
if (ret != 0)
goto destroy;
}
- ret = tpm2_create_eks_and_certs(flags, config_file, certsdir, vmid, rsa_keysize, swtpm2,
- user_certsdir);
- if (ret != 0)
- goto destroy;
-
ret = tpm2_activate_pcr_banks(swtpm2, pcr_banks);
if (ret != 0)
goto destroy;
" root: allow to create files under root's home directory\n"
" skip-if-exist: if any file exists exit without error\n"
"\n"
+ "--reconfigure : Reconfigure an existing swtpm by reusing existing state.\n"
+ " The active PCR banks can be changed but no new keys will\n"
+ " be created.\n"
+ "\n"
"--version : Display version and exit\n"
"\n"
"--help,-h : Display this help screen\n\n",
printf("{ \"type\": \"swtpm_setup\", "
"\"features\": [ %s%s\"cmdarg-keyfile-fd\", \"cmdarg-pwdfile-fd\", \"tpm12-not-need-root\""
", \"cmdarg-write-ek-cert-files\", \"cmdarg-create-config-files\""
+ ", \"cmdarg-reconfigure-pcr-banks\""
"%s ], "
"\"version\": \"" VERSION "\" "
"}\n",
{"tcsd-system-ps-file", required_argument, NULL, 'F'},
{"version", no_argument, NULL, '1'},
{"print-capabilities", no_argument, NULL, 'y'},
+ {"reconfigure", no_argument, NULL, 'R'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
case 'y': /* --print-capabilities */
printcapabilities = TRUE;
break;
+ case 'R': /* --reconfigure */
+ flags |= SETUP_RECONFIGURE_F;
+ break;
case '?':
case 'h': /* --help */
usage(argv[0], config_file);
logerr(gl_LOGFILE, "--create-spk requires --tpm2.\n");
goto error;
}
+ if (flags & SETUP_RECONFIGURE_F) {
+ logerr(gl_LOGFILE, "--reconfigure requires --tpm2.\n");
+ goto error;
+ }
}
- ret = check_state_overwrite(swtpm_prg_l, flags, tpm_state_path);
- if (ret == 1) {
- goto error;
- } else if (ret == 2) {
- ret = 0;
- goto out;
- }
+ if (!(flags & SETUP_RECONFIGURE_F)) {
+ ret = check_state_overwrite(swtpm_prg_l, flags, tpm_state_path);
+ if (ret == 1) {
+ goto error;
+ } else if (ret == 2) {
+ ret = 0;
+ goto out;
+ }
- ret = backend_ops->delete_state(backend_state);
- if (ret != 0)
- goto error;
+ ret = backend_ops->delete_state(backend_state);
+ if (ret != 0)
+ goto error;
+ }
if (access(config_file, R_OK) != 0) {
logerr(gl_LOGFILE, "User %s cannot read config file %s.\n",
goto error;
}
+ if (flags & SETUP_RECONFIGURE_F) {
+ if (flags & (SETUP_CREATE_EK_F | SETUP_EK_CERT_F | SETUP_PLATFORM_CERT_F)) {
+ logerr(gl_LOGFILE, "Reconfiguration is not supported with creation of EK or certificates\n");
+ goto error;
+ }
+ }
+
now = time(NULL);
tm = localtime(&now);
if (strftime(tmpbuffer, sizeof(tmpbuffer), "%a %d %h %Y %I:%M:%S %p %Z", tm) == 0) {
goto error;
}
curr_grp = getgrgid(getgid());
- logit(gl_LOGFILE, "Starting vTPM manufacturing as %s:%s @ %s\n",
+ logit(gl_LOGFILE, "Starting vTPM %s as %s:%s @ %s\n",
+ flags & SETUP_RECONFIGURE_F ? "reconfiguration" : "manufacturing",
curr_user ? curr_user->pw_name : "<unknown>",
curr_grp ? curr_grp->gr_name : "<unknown>",
tmpbuffer);
fi
# The are some variable parameters at the end, use regex
-exp='\{ "type": "swtpm_setup", "features": \[ "tpm-1.2",( "tpm-2.0",)? "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", "tpm12-not-need-root", "cmdarg-write-ek-cert-files", "cmdarg-create-config-files"(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")? \], "version": "[^"]*" \}'
+exp='\{ "type": "swtpm_setup", "features": \[ "tpm-1.2",( "tpm-2.0",)? "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", "tpm12-not-need-root", "cmdarg-write-ek-cert-files", "cmdarg-create-config-files", "cmdarg-reconfigure-pcr-banks"(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")? \], "version": "[^"]*" \}'
if ! [[ ${msg} =~ ${exp} ]]; then
echo "Unexpected response from ${SWTPM_SETUP} to --print-capabilities:"
echo "Actual : ${msg}"
fi
# The are some variable parameters at the end, use regex
-exp='\{ "type": "swtpm_setup", "features": \[( "tpm-1.2",)? "tpm-2.0", "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", "tpm12-not-need-root", "cmdarg-write-ek-cert-files", "cmdarg-create-config-files"(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")? \], "version": "[^"]*" \}'
+exp='\{ "type": "swtpm_setup", "features": \[( "tpm-1.2",)? "tpm-2.0", "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", "tpm12-not-need-root", "cmdarg-write-ek-cert-files", "cmdarg-create-config-files", "cmdarg-reconfigure-pcr-banks"(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")? \], "version": "[^"]*" \}'
if ! [[ ${msg} =~ ${exp} ]]; then
echo "Unexpected response from ${SWTPM_SETUP} to --print-capabilities:"
echo "Actual : ${msg}"
echo "Test 1: OK"
+function swtpm_setup_reconfigure() {
+ local workdir="$1"
+ local pwdfile="$2"
+
+ # Reconfigure the active PCR banks a few times; the size of the state
+ # file must not change but its content (hash) must change every time
+ # since activating the PCR banks changes a few bits in the permanent
+ # state, also when the state is not encrypted.
+ local PERMALL_FILE="${workdir}/tpm2-00.permall"
+ local permall_size=$(get_filesize "${PERMALL_FILE}")
+
+ for pcrbanks in "sha1" "sha1,sha256" "sha1,sha256,sha384,sha512"; do
+ # hash must change between before and after
+ permall_hash=$(get_sha1_file "${PERMALL_FILE}")
+
+ $SWTPM_SETUP \
+ --tpm2 \
+ --tpm-state "${workdir}" \
+ --config "${workdir}/swtpm_setup.conf" \
+ --logfile "${workdir}/logfile" \
+ --tpm "${SWTPM_EXE} socket ${SWTPM_TEST_SECCOMP_OPT}" \
+ --pcr-banks "${pcrbanks}" \
+ --reconfigure \
+ ${pwdfile:+--pwdfile "${pwdfile}"}
+ if [ $? -ne 0 ]; then
+ echo "Error: Could not run $SWTPM_SETUP --reconfigure."
+ echo "Logfile output:"
+ cat "${workdir}/logfile"
+ exit 1
+ fi
+
+ local newhash=$(get_sha1_file "${PERMALL_FILE}")
+ if [ "${newhash}" = "${permall_hash}" ]; then
+ echo "Error: The hash of the permanent state did not change."
+ exit 1
+ fi
+
+ local newsize=$(get_filesize "${PERMALL_FILE}")
+ if [ "${newsize}" != "${permall_size}" ]; then
+ echo "Error: The size of the permanent state file changed."
+ echo "Actual : ${tmp}"
+ echo "Expected: ${permall_size}"
+ fi
+ echo "Filesize: ${newsize}; hash: ${newhash}; pwdfile: ${pwdfile}"
+ done
+}
-# we need to create at least one cert: --create-ek-cert
-$SWTPM_SETUP \
- --tpm2 \
- --ecc \
- --tpm-state "${workdir}" \
- --create-ek-cert \
- --config "${workdir}/swtpm_setup.conf" \
- --logfile "${workdir}/logfile" \
- --tpm "${SWTPM_EXE} socket ${SWTPM_TEST_SECCOMP_OPT}" \
- --overwrite \
- --write-ek-cert-files "${workdir}"
-
-if [ $? -ne 0 ]; then
- echo "Error: Could not run $SWTPM_SETUP."
- echo "Logfile output:"
- cat "${workdir}/logfile"
- exit 1
-fi
+# Create with certificates with and without encryption enabled and reconfigure
+# the PCR banks
+PWDFILE="${workdir}/pwd"
+echo -n "password" > "${PWDFILE}"
+rm -f "${workdir}/logfile"
-if [ ! -r "${SIGNINGKEY}" ]; then
- echo "Error: Signingkey file ${SIGNINGKEY} was not created."
- exit 1
-fi
+for pwdfile in "" "${PWDFILE}"; do
+ $SWTPM_SETUP \
+ --tpm2 \
+ --ecc \
+ --tpm-state "${workdir}" \
+ --create-ek-cert \
+ --create-platform-cert \
+ --config "${workdir}/swtpm_setup.conf" \
+ --logfile "${workdir}/logfile" \
+ --tpm "${SWTPM_EXE} socket ${SWTPM_TEST_SECCOMP_OPT}" \
+ --overwrite \
+ --write-ek-cert-files "${workdir}" \
+ ${pwdfile:+--pwdfile "${pwdfile}"}
-if [ ! -r "${ISSUERCERT}" ]; then
- echo "Error: Issuer cert file ${ISSUERCERT} was not created."
- exit 1
-fi
+ if [ $? -ne 0 ]; then
+ echo "Error: Could not run $SWTPM_SETUP."
+ echo "Logfile output:"
+ cat "${workdir}/logfile"
+ exit 1
+ fi
-if [ ! -r "${CERTSERIAL}" ]; then
- echo "Error: Cert serial number file ${CERTSERIAL} was not created."
- exit 1
-fi
+ if [ ! -r "${SIGNINGKEY}" ]; then
+ echo "Error: Signingkey file ${SIGNINGKEY} was not created."
+ exit 1
+ fi
-certfile="${workdir}/ek-secp384r1.crt"
-if [ ! -f "${certfile}" ]; then
- echo "Error: EK file '${certfile}' was not written."
- ls -l "${workdir}"
- exit 1
-fi
+ if [ ! -r "${ISSUERCERT}" ]; then
+ echo "Error: Issuer cert file ${ISSUERCERT} was not created."
+ exit 1
+ fi
-if [ -z "$($CERTTOOL --inder --infile "${certfile}" -i | grep "384 bits")" ]; then
- echo "Error: EK file '${certfile}' is not an ECC 384 bit key."
- $CERTTOOL --inder --infile "${certfile}" -i
- exit 1
-fi
+ if [ ! -r "${CERTSERIAL}" ]; then
+ echo "Error: Cert serial number file ${CERTSERIAL} was not created."
+ exit 1
+ fi
+
+ certfile="${workdir}/ek-secp384r1.crt"
+ if [ ! -f "${certfile}" ]; then
+ echo "Error: EK file '${certfile}' was not written."
+ ls -l "${workdir}"
+ exit 1
+ fi
+
+ if [ -z "$($CERTTOOL --inder --infile "${certfile}" -i | grep "384 bits")" ]; then
+ echo "Error: EK file '${certfile}' is not an ECC 384 bit key."
+ $CERTTOOL --inder --infile "${certfile}" -i
+ exit 1
+ fi
+
+ swtpm_setup_reconfigure "${workdir}" "${pwdfile}"
+done
echo "Test 2: OK"