From 9c943b3e4c407737712c8ef0d61091758b076446 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Thu, 23 Apr 2020 13:18:07 -0400 Subject: [PATCH 1/4] swtpm_setup: Report supported RSA key sizes useful for EK key creation Extend the --print-capabilities option to also report supported RSA key sizes. Only the TPM 2 may support anything else than 2048 bit RSA keys, so we only consult 'swtpm socket --tpm2 --print-capabilities' and grep for 2048 and 3072 key sizes and report them. If nothing is found, nothing is reported, as before, and 2048 bit RSA keys should be assumed. 'swtpm_setup --tpm2 --print-capabilities' may now show the following: { "type": "swtpm_setup", "features": [ "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", "tpm2-rsa-keysize-2048", "tpm2-rsa-keysize-3072" ] } Also adjust a test case to use a regular expression for matching against an expected string that may nor may not have rsa-keysize verbs. Signed-off-by: Stefan Berger --- man/man8/swtpm_setup.8 | 16 ++++++--- man/man8/swtpm_setup.pod | 13 +++++-- src/swtpm_setup/swtpm_setup.sh.in | 53 +++++++++++++++++++++++++++-- tests/_test_print_capabilities | 2 +- tests/_test_tpm2_print_capabilities | 2 +- 5 files changed, 73 insertions(+), 13 deletions(-) diff --git a/man/man8/swtpm_setup.8 b/man/man8/swtpm_setup.8 index f8f1365e..709dfb94 100644 --- a/man/man8/swtpm_setup.8 +++ b/man/man8/swtpm_setup.8 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "swtpm_setup 8" -.TH swtpm_setup 8 "2020-05-01" "swtpm" "" +.TH swtpm_setup 8 "2020-05-04" "swtpm" "" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -279,16 +279,18 @@ needed by \s-1TCSD\s0 for key related functions. This option is only useful with \s-1TPM 1.2\s0 and in if ownership is taken. .IP "\fB\-\-print\-capabilities\fR (since v0.2)" 4 .IX Item "--print-capabilities (since v0.2)" -Print capabilities that were added to swtpm_setup after version 0.1. The output -contains the following: +Print capabilities that were added to swtpm_setup after version 0.1. +The output may contain the following: .Sp -.Vb 8 +.Vb 10 \& { \& "type": "swtpm_setup", \& "features": [ \& "cmdarg\-keyfile\-fd", \& "cmdarg\-pwdfile\-fd", -\& "no\-tpm12\-tools" +\& "no\-tpm12\-tools", +\& "tpm2\-rsa\-keysize\-2048", +\& "tpm2\-rsa\-keysize\-3072" \& ] \& } .Ve @@ -306,6 +308,10 @@ The \fI\-\-pwdfile\-fd\fR option is supported. \&\s-1TPM 1.2\s0 tools cannot be found in the \s-1PATH.\s0 This means that no certificates can be created since they cannot be written into the \s-1NVRAM\s0 and the \s-1NVRAM\s0 cannot be locked. Among the \s-1TPM 1.2\s0 setup parameters only \fI\-\-createek\fR can be passed. +.IP "\fBtpm2\-rsa\-keysize\-2048, ...\fR" 4 +.IX Item "tpm2-rsa-keysize-2048, ..." +The shown \s-1RSA\s0 key sizes are supported for a \s-1TPM 2\s0's \s-1EK\s0 key. If none of the +tpm2\-rsa\-keysize verbs is shown then only \s-1RSA 2048\s0 bit keys are supported. .RE .RS 4 .RE diff --git a/man/man8/swtpm_setup.pod b/man/man8/swtpm_setup.pod index de1e0cbb..7f459520 100644 --- a/man/man8/swtpm_setup.pod +++ b/man/man8/swtpm_setup.pod @@ -175,15 +175,17 @@ This option is only useful with TPM 1.2 and in if ownership is taken. =item B<--print-capabilities> (since v0.2) -Print capabilities that were added to swtpm_setup after version 0.1. The output -contains the following: +Print capabilities that were added to swtpm_setup after version 0.1. +The output may contain the following: { "type": "swtpm_setup", "features": [ "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", - "no-tpm12-tools" + "no-tpm12-tools", + "tpm2-rsa-keysize-2048", + "tpm2-rsa-keysize-3072" ] } @@ -205,6 +207,11 @@ TPM 1.2 tools cannot be found in the PATH. This means that no certificates can be created since they cannot be written into the NVRAM and the NVRAM cannot be locked. Among the TPM 1.2 setup parameters only I<--createek> can be passed. +=item B + +The shown RSA key sizes are supported for a TPM 2's EK key. If none of the +tpm2-rsa-keysize verbs is shown then only RSA 2048 bit keys are supported. + =back =item B<--help, -h> diff --git a/src/swtpm_setup/swtpm_setup.sh.in b/src/swtpm_setup/swtpm_setup.sh.in index 0fe7ca20..207c979a 100755 --- a/src/swtpm_setup/swtpm_setup.sh.in +++ b/src/swtpm_setup/swtpm_setup.sh.in @@ -1990,9 +1990,46 @@ TPM emulator setup tool version @SWTPM_VER_MAJOR@.@SWTPM_VER_MINOR@.@SWTPM_VER_M EOF } +# Get the support RSA key sizes +# @return This function echos something like the following +# - "1024\n2048\n3072\n" +# - "" (empty string, indicating only 2048 bit RSA keys are supported) +get_rsa_keysizes() { + local flags="$1" + + if [ $((flags & SETUP_TPM2_F)) -ne 0 ]; then + $SWTPM --tpm2 --print-capabilities | + sed -n 's/rsa\-keysize\-[^"]*"/\n&/gp' | + sed -n 's/rsa\-keysize\-\([^"]*\)".*/\1/gp' + fi +} + +# Get supported RSA key sizes useful for creating the EK key; only 2048 +# and 3072 bits are checked and reported +# @return This function echos something like the following +# - "tpm2-rsa-keysize-2048", "tpm2-rsa-keyssize-3072" +# - "" (empty string, indicating only 2048 bit RSA keys are supported) +get_rsakeysize_caps() { + local flags="$1" + + local keysizes keysize result="" + + for keysize in $(get_rsa_keysizes "$flags"); do + if [ $keysize -ge 2048 ]; then + if [ -n "$result" ]; then + result+=", " + fi + result+=\""tpm2-rsa-keysize-${keysize}\"" + fi + done + + echo "$result" + return 0 +} + print_capabilities() { - local param="" + local output param="" if [ -z "$(type -P tcsd)" ] || \ [ -z "$(type -P tpm_nvinfo)" ] || \ @@ -2000,6 +2037,11 @@ print_capabilities() param=', "no-tpm12-tools"' fi + output="$(get_rsakeysize_caps "$((SETUP_TPM2_F))")" + if [ -n "$output" ]; then + param+=", ${output}" + fi + echo '{ "type": "swtpm_setup",' \ '"features": [ "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd"'${param}' ]'\ '}' @@ -2123,7 +2165,7 @@ main() local tpm_state_path="" local config_file="$DEFAULT_CONFIG_FILE" local vmid="" tmp - local ret + local ret printcapabilities=0 local keyfile pwdfile cipher="aes-128-cbc" local keyfile_fd pwdfile_fd local got_ownerpass=0 got_srkpass=0 @@ -2167,13 +2209,18 @@ main() --pcr-banks) shift; pcr_banks="${pcr_banks},$1";; --tcsd-system-ps-file) shift; tcsd_system_ps_file="$1";; --version) versioninfo "$0"; exit 0;; - --print-capabilities) print_capabilities; exit 0;; + --print-capabilities) printcapabilities=1;; --help|-h|-?) usage "$0"; exit 0;; *) logerr "Unknown option $1"; usage "$0"; exit 1;; esac shift done + if [ $printcapabilities -ne 0 ]; then + print_capabilities "$flags" + exit 0 + fi + [ $got_ownerpass -eq 0 ] && flags=$((flags | SETUP_OWNERPASS_ZEROS_F)) [ $got_srkpass -eq 0 ] && flags=$((flags | SETUP_SRKPASS_ZEROS_F)) diff --git a/tests/_test_print_capabilities b/tests/_test_print_capabilities index 2c12822c..5f7a4485 100755 --- a/tests/_test_print_capabilities +++ b/tests/_test_print_capabilities @@ -41,7 +41,7 @@ if [ $? -ne 0 ]; then fi # The are some variable parameters at the end, use regex -exp='\{ "type": "swtpm_setup", "features": \[ "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd"(, "no-tpm12-tools")? \] \}' +exp='\{ "type": "swtpm_setup", "features": \[ "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd"(, "no-tpm12-tools")?(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")? \] \}' if ! [[ ${msg} =~ ${exp} ]]; then echo "Unexpected response from ${SWTPM_SETUP} to --print-capabilities:" echo "Actual : ${msg}" diff --git a/tests/_test_tpm2_print_capabilities b/tests/_test_tpm2_print_capabilities index 39b6988b..8f6ee406 100755 --- a/tests/_test_tpm2_print_capabilities +++ b/tests/_test_tpm2_print_capabilities @@ -42,7 +42,7 @@ if [ $? -ne 0 ]; then fi # The are some variable parameters at the end, use regex -exp='\{ "type": "swtpm_setup", "features": \[ "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd"(, "no-tpm12-tools")? \] \}' +exp='\{ "type": "swtpm_setup", "features": \[ "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd"(, "no-tpm12-tools")?(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")? \] \}' if ! [[ ${msg} =~ ${exp} ]]; then echo "Unexpected response from ${SWTPM_SETUP} to --print-capabilities:" echo "Actual : ${msg}" From 7af93fdd099ffab22e03f659efc713a9859f5aa5 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Thu, 23 Apr 2020 11:28:57 -0400 Subject: [PATCH 2/4] swtpm_setup: Add support for RSA 3072 bit EK keys Extend the creation of the EK key to support also 3072 bits RSA keys. Signed-off-by: Stefan Berger --- man/man8/swtpm_setup.8 | 6 + man/man8/swtpm_setup.pod | 7 ++ src/swtpm_setup/swtpm_setup.c | 1 + src/swtpm_setup/swtpm_setup.sh.in | 191 +++++++++++++++++++++--------- 4 files changed, 151 insertions(+), 54 deletions(-) diff --git a/man/man8/swtpm_setup.8 b/man/man8/swtpm_setup.8 index 709dfb94..cb891b2e 100644 --- a/man/man8/swtpm_setup.8 +++ b/man/man8/swtpm_setup.8 @@ -277,6 +277,12 @@ A file to copy \s-1TCSD\s0's system_ps_file to. The system_ps_file contains the needed by \s-1TCSD\s0 for key related functions. .Sp This option is only useful with \s-1TPM 1.2\s0 and in if ownership is taken. +.IP "\fBrsa-keysize (since v0.4)" 4 +.IX Item "rsa-keysize (since v0.4)" +This option allows to pass the size of a \s-1TPM 2 RSA EK\s0 key, such as 2048 +or 3072. The supported keysizes for a \s-1TPM 2\s0 can be queried for using +the \fI\-\-print\-capabilities\fR option. The default size is 2048 bits for +both \s-1TPM 1.2\s0 and \s-1TPM 2.\s0 .IP "\fB\-\-print\-capabilities\fR (since v0.2)" 4 .IX Item "--print-capabilities (since v0.2)" Print capabilities that were added to swtpm_setup after version 0.1. diff --git a/man/man8/swtpm_setup.pod b/man/man8/swtpm_setup.pod index 7f459520..b5a954dc 100644 --- a/man/man8/swtpm_setup.pod +++ b/man/man8/swtpm_setup.pod @@ -173,6 +173,13 @@ needed by TCSD for key related functions. This option is only useful with TPM 1.2 and in if ownership is taken. +=item B> (since v0.4) + +This option allows to pass the size of a TPM 2 RSA EK key, such as 2048 +or 3072. The supported keysizes for a TPM 2 can be queried for using +the I<--print-capabilities> option. The default size is 2048 bits for +both TPM 1.2 and TPM 2. + =item B<--print-capabilities> (since v0.2) Print capabilities that were added to swtpm_setup after version 0.1. diff --git a/src/swtpm_setup/swtpm_setup.c b/src/swtpm_setup/swtpm_setup.c index 111a51dc..1ff9fc5d 100644 --- a/src/swtpm_setup/swtpm_setup.c +++ b/src/swtpm_setup/swtpm_setup.c @@ -74,6 +74,7 @@ const char *one_arg_params[] = { "--swtpm_ioctl", "--pcr-banks", "--tcsd-system-ps-file", + "--rsa-keysize", NULL }; diff --git a/src/swtpm_setup/swtpm_setup.sh.in b/src/swtpm_setup/swtpm_setup.sh.in index 207c979a..ced991a0 100755 --- a/src/swtpm_setup/swtpm_setup.sh.in +++ b/src/swtpm_setup/swtpm_setup.sh.in @@ -5,7 +5,7 @@ # # Authors: Stefan Berger # -# (c) Copyright IBM Corporation 2011,2014,2015. +# (c) Copyright IBM Corporation 2011,2014-2020 # # All rights reserved. # @@ -129,6 +129,7 @@ TPM2_NV_INDEX_ECC_SECP384R1_HI_EKCert=$((0x01c00016)) TPM2_NV_INDEX_ECC_SECP384R1_HI_EKTemplate=$((0x01c00017)) TPM2_EK_RSA_HANDLE=$((0x81010001)) +TPM2_EK_RSA3072_HANDLE=$((0x8101001c)) TPM2_EK_ECC_SECP384R1_HANDLE=$((0x81010016)) TPM2_SPK_HANDLE=$((0x81000001)) @@ -140,10 +141,16 @@ TPMLIB_INFO_TPMATTRIBUTES=2 NB16='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' NB32=${NB16}${NB16} -NB256=${NB32}${NB32}${NB32}${NB32}${NB32}${NB32}${NB32}${NB32} -# Nonce used for EK creation; 2 bytes length + nonce -NONCE_RSA='\x01\x00'${NB256} -NONCE_RSA_SIZE=256 +NB128=${NB32}${NB32}${NB32}${NB32} +NB256=${NB128}${NB128} +# Nonce used for EK creation for RSA 2048 keys; 2 bytes length + nonce +NONCE_RSA2048='\x01\x00'${NB256} +NONCE_RSA2048_SIZE=256 + +# Nonce used for EK creation for RSA 3072 keys; 2 bytes length + nonce +NB384=${NB256}${NB128} +NONCE_RSA3072='\x01\x80'${NB384} +NONCE_RSA3072_SIZE=384 NONCE_ECC_384='\x00\x30'${NB32}${NB16} NONCE_ECC_384_SIZE=48 @@ -151,6 +158,8 @@ NONCE_ECC_384_SIZE=48 NONCE_EMPTY='\x00\x00' NONCE_EMPTY_SIZE=0 +DEFAULT_RSA_KEYSIZE=2048 + trap "cleanup" SIGTERM EXIT logit() @@ -925,81 +934,104 @@ init_tpm() # # @param1: flags # @param2: filename for template +# @param3: RSA key size in bits tpm2_createprimary_ek_rsa() { local flags="$1" local templatefile="$2" - - local symkeydata keyflags totlen publen off min_exp authpolicy + local rsa_keysize="$3" + + local symkeydata keyflags totlen publen off min_exp authpolicy nonce_size + local addlen + + case "$rsa_keysize" in + 2048) nonce_size=$NONCE_RSA2048_SIZE + # authPolicy from: Ek Credential Profile; Spec v 2.1; rev12; p.37 + authpolicy='\\x83\\x71\\x97\\x67\\x44\\x84\\xb3\\xf8\\x1a\\x90\\xcc\\x8d' + authpolicy+='\\x46\\xa5\\xd7\\x24\\xfd\\x52\\xd7\\x6e\\x06\\x52\\x0b\\x64' + authpolicy+='\\xf2\\xa1\\xda\\x1b\\x33\\x14\\x69\\xaa' + addlen=0 + keyflags=0 + ;; + 3072) nonce_size=$NONCE_RSA3072_SIZE + # authPolicy from: Ek Credential Profile; Spec v 2.3; rev2; p.47 + authpolicy='\\xB2\\x6E\\x7D\\x28\\xD1\\x1A\\x50\\xBC\\x53\\xD8\\x82\\xBC' + authpolicy+='\\xF5\\xFD\\x3A\\x1A\\x07\\x41\\x48\\xBB\\x35\\xD3\\xB4\\xE4' + authpolicy+='\\xCB\\x1C\\x0A\\xD9\\xBD\\xE4\\x19\\xCA\\xCB\\x47\\xBA\\x09' + authpolicy+='\\x69\\x96\\x46\\x15\\x0F\\x9F\\xC0\\x00\\xF3\\xF8\\x0E\\x12' + addlen=16 + # keyflags: userWithAuth + keyflags=$((0x40)) + ;; + esac if [ $((flags & SETUP_ALLOW_SIGNING_F)) -ne 0 ] && \ [ $((flags & SETUP_DECRYPTION_F)) -ne 0 ]; then # keyflags: fixedTPM, fixedParent, sensitiveDatOrigin, # adminWithPolicy, sign, decrypt - keyflags=$((0x000600b2)) + keyflags=$((keyflags | 0x000600b2)) # symmetric: TPM_ALG_NULL symkeydata='\\x00\\x10' - publen=$((0x36 + NONCE_RSA_SIZE)) - totlen=$((0x5f + NONCE_RSA_SIZE)) + publen=$((0x36 + nonce_size + addlen)) + totlen=$((0x5f + nonce_size + addlen)) min_exp=1506 # offset of length indicator for key - off=216 + off=$((216 + addlen * 3)) elif [ $((flags & SETUP_ALLOW_SIGNING_F)) -ne 0 ]; then # keyflags: fixedTPM, fixedParent, sensitiveDatOrigin, # adminWithPolicy, sign - keyflags=$((0x000400b2)) + keyflags=$((keyflags | 0x000400b2)) # symmetric: TPM_ALG_NULL symkeydata='\\x00\\x10' - publen=$((0x36 + NONCE_RSA_SIZE)) - totlen=$((0x5f + NONCE_RSA_SIZE)) + publen=$((0x36 + nonce_size + addlen)) + totlen=$((0x5f + nonce_size + addlen)) min_exp=1506 # offset of length indicator for key - off=216 + off=$((216 + addlen * 3)) else # keyflags: fixedTPM, fixedParent, sensitiveDatOrigin, # adminWithPolicy, restricted, decrypt - keyflags=$((0x000300b2)) - # symmetric: TPM_ALG_AES, 128bit, TPM_ALG_CFB - symkeydata='\\x00\\x06\\x00\\x80\\x00\\x43' - publen=$((0x3a + NONCE_RSA_SIZE)) - totlen=$((0x63 + NONCE_RSA_SIZE)) + keyflags=$((keyflags | 0x000300b2)) + # symmetric: TPM_ALG_AES, 128bit or 256bit, TPM_ALG_CFB + symkeydata='\\x00\\x06@SYMKEYLEN-2@\\x00\\x43' + publen=$((0x3a + nonce_size + addlen)) + totlen=$((0x63 + nonce_size + addlen)) min_exp=1518 # offset of length indicator for key - off=228 + off=$((228 + addlen * 3)) fi - # authPolicy from: Ek Credential Profile; Spec v 2.1; rev12; p.37 - authpolicy='\\x83\\x71\\x97\\x67\\x44\\x84\\xb3\\xf8\\x1a\\x90\\xcc\\x8d' - authpolicy+='\\x46\\xa5\\xd7\\x24\\xfd\\x52\\xd7\\x6e\\x06\\x52\\x0b\\x64' - authpolicy+='\\xf2\\xa1\\xda\\x1b\\x33\\x14\\x69\\xaa' - - # Check the TCG EK Credential Profile doc for TPM 2 for - # parameters used here - # TPM_RH_ENDORSEMENT tpm2_createprimary_rsa_params '\\x40\\x00\\x00\\x0b' "${keyflags}" \ "${symkeydata}" "${publen}" "${totlen}" "${min_exp}" "${off}" \ - "${authpolicy}" "${templatefile}" + "${authpolicy}" "${templatefile}" "${rsa_keysize}" return $? } # Create a storage primary key # # @param1: flags +# @param2: RSA key size in bits tpm2_createprimary_spk_rsa() { local flags="$1" + local rsa_keysize="$2" - local symkeydata keyflags totlen publen off min_exp + local symkeydata keyflags totlen publen off min_exp nonce_size + + case "$rsa_keysize" in + 2048) nonce_size=$NONCE_RSA2048_SIZE;; + 3072) nonce_size=$NONCE_RSA3072_SIZE;; + esac # keyflags: fixedTPM, fixedParent, sensitiveDataOrigin, # userWithAuth, noDA, restricted, decrypt keyflags=$((0x00030472)) # keyflags=$((0x000300b2)) # symmetric: TPM_ALG_NULL - symkeydata='\\x00\\x06\\x00\\x80\\x00\\x43' - publen=$((0x1a + NONCE_RSA_SIZE)) - totlen=$((0x43 + NONCE_RSA_SIZE)) + symkeydata='\\x00\\x06@SYMKEYLEN-2@\\x00\\x43' + publen=$((0x1a + nonce_size)) + totlen=$((0x43 + nonce_size)) min_exp=1470 # offset of length indicator for key off=132 @@ -1007,7 +1039,7 @@ tpm2_createprimary_spk_rsa() # TPM_RH_OWNER tpm2_createprimary_rsa_params '\\x40\\x00\\x00\\x01' "${keyflags}" \ "${symkeydata}" "${publen}" "${totlen}" "${min_exp}" "${off}" "" \ - "" + "" "${rsa_keysize}" return $? } @@ -1022,10 +1054,25 @@ function tpm2_createprimary_rsa_params() local off="$7" local authpolicy="$8" local templatefile="$9" + local rsa_keysize="${10}" - local req rsp res temp + local req rsp res temp nonce_rsa modulus_len_str key_strlen hashalg + local symkeylen local authpolicylen=$((${#authpolicy} / 5)) + case "$rsa_keysize" in + 2048) nonce_rsa=${NONCE_RSA2048} + modulus_len_str=" 01 00" + hashalg=11 + symkeylen=128 + ;; + 3072) nonce_rsa=${NONCE_RSA3072} + modulus_len_str=" 01 80" + hashalg=12 + symkeylen=256 + ;; + esac + req='\x80\x02@TOTLEN-4@\x00\x00\x01\x31' req+='@KEYHANDLE-4@' # size of buffer @@ -1036,7 +1083,7 @@ function tpm2_createprimary_rsa_params() # Size of TPM2B_PUBLIC req+='@PUBLEN-2@' # TPM_ALG_RSA, TPM_ALG_SHA256 - temp='\x00\x01\x00\x0b' + temp='\x00\x01@HASHALG-2@' # fixedTPM, fixedParent, sensitiveDatOrigin, adminWithPolicy # restricted, decrypt temp+='@KEYFLAGS-4@' @@ -1044,18 +1091,21 @@ function tpm2_createprimary_rsa_params() temp+='@AUTHPOLICYLEN-2@' temp+='@AUTHPOLICY@' temp+='@SYMKEYDATA@' - # scheme: TPM_ALG_NULL, keyBits: 2048bits - temp+='\x00\x10\x08\x00' + # scheme: TPM_ALG_NULL, keyBits: 2048bits or 3072bits + temp+='\x00\x10@RSAKEYSIZE-2@' # exponent temp+='\x00\x00\x00\x00' # TPM2B_DATA - temp+=${NONCE_RSA} + temp+=${nonce_rsa} temp=$(echo $temp | \ sed -e "s/@KEYFLAGS-4@/$(_format "$keyflags" 4)/" \ -e "s/@SYMKEYDATA@/$symkeydata/" \ -e "s/@AUTHPOLICY@/$authpolicy/" \ - -e "s/@AUTHPOLICYLEN-2@/$(_format "$authpolicylen" 2)/") + -e "s/@AUTHPOLICYLEN-2@/$(_format "$authpolicylen" 2)/" \ + -e "s/@RSAKEYSIZE-2@/$(_format "$rsa_keysize" 2)/" \ + -e "s/@SYMKEYLEN-2@/$(_format "$symkeylen" 2)/" \ + -e "s/@HASHALG-2@/$(_format "$hashalg" 2)/") req+=${temp} # TPML_PCR_SELECTION @@ -1076,16 +1126,18 @@ function tpm2_createprimary_rsa_params() fi # Check the RSA modulus length indicator - if [ "${rsp:$off:6}" != " 01 00" ]; then + if [ "${rsp:$off:6}" != "${modulus_len_str}" ]; then logerr "Getting modulus from wrong offset." return 1 fi off=$((off + 6)) + key_strlen=$((rsa_keysize / 8 * 3)) # output: handle,ek res="$(echo "0x${rsp:30:12}" | sed -n 's/ //pg')," - res+="$(echo "${rsp:$off:768}" | sed -n 's/ //pg')" + res+="$(echo "${rsp:$off:$key_strlen}" | sed -n 's/ //pg')" + echo "$res" if [ -n "${templatefile}" ]; then @@ -1328,18 +1380,20 @@ tpm2_evictcontrol() # @param1: flags # @param2: non-evict handle, if any # @param3: filename for EK template +# @param4: RSA key size in bits tpm2_create_ek() { local flags="$1" local nehandle="$2" local ektemplatefile="$3" + local rsa_keysize="$4" local res handle if [ $((flags & SETUP_TPM2_ECC_F)) -ne 0 ]; then res=$(tpm2_createprimary_ek_ecc_nist_p384 "$flags" "${ektemplatefile}") else - res=$(tpm2_createprimary_ek_rsa "$flags" "${ektemplatefile}") + res=$(tpm2_createprimary_ek_rsa "$flags" "${ektemplatefile}" "${rsa_keysize}") fi [ $? -ne 0 ] && return 1 @@ -1364,12 +1418,14 @@ tpm2_create_ek() # @param2: configuration file # @param3: certificates directory # @param4: VM identifier +# @param5: RSA key size in bits tpm2_create_ek_and_cert() { local flags="$1" local config_file="$2" local certs_dir="$3" local vmid="$4" + local rsa_keysize="$5" local PLATFORM_CERT_FILE="$certsdir/platform.cert" local EK_CERT_FILE="$certsdir/ek.cert" @@ -1388,12 +1444,16 @@ tpm2_create_ek_and_cert() keytype="ECC" tpm2_ek_handle=$TPM2_EK_ECC_SECP384R1_HANDLE else - keytype="RSA" - tpm2_ek_handle=$TPM2_EK_RSA_HANDLE + keytype="RSA $rsa_keysize" + case "$rsa_keysize" in + 2048) tpm2_ek_handle=$TPM2_EK_RSA_HANDLE;; + 3072) tpm2_ek_handle=$TPM2_EK_RSA3072_HANDLE;; + esac fi if [ $((flags & SETUP_CREATE_EK_F)) -ne 0 ]; then - ek=$(tpm2_create_ek "$flags" "${tpm2_ek_handle}" "${EK_TEMP_FILE}") + ek=$(tpm2_create_ek "$flags" "${tpm2_ek_handle}" \ + "${EK_TEMP_FILE}" "${rsa_keysize}") if [ $? -ne 0 ]; then logerr "tpm2_create_ek failed" return 1 @@ -1515,21 +1575,23 @@ tpm2_create_ek_and_cert() # @param2: configuration file # @param3: certificates directory # @param4: VM identifier +# @param5: RSA key size in bits tpm2_create_eks_and_certs() { local flags="$1" local config_file="$2" local certs_dir="$3" local vmid="$4" + local rsa_keysize="$5" # 1st key will be RSA flags=$((flags & ~SETUP_TPM2_ECC_F)) - tpm2_create_ek_and_cert "$flags" "$config_file" "$certsdir" "$vmid" + tpm2_create_ek_and_cert "$flags" "$config_file" "$certsdir" "$vmid" "$rsa_keysize" [ $? -ne 0 ] && return 1 # 2nd key will be an ECC; no more platform cert flags=$(((flags & ~SETUP_PLATFORM_CERT_F) | SETUP_TPM2_ECC_F)) - tpm2_create_ek_and_cert "$flags" "$config_file" "$certsdir" "$vmid" + tpm2_create_ek_and_cert "$flags" "$config_file" "$certsdir" "$vmid" "$rsa_keysize" return $? } @@ -1537,17 +1599,19 @@ tpm2_create_eks_and_certs() # # @param1: flags # @param2: non-evict handle, if any +# @param3: RSA key size in bits tpm2_create_spk() { local flags="$1" local nehandle="$2" + local rsa_keysize="$3" local res handle if [ $((flags & SETUP_TPM2_ECC_F)) -ne 0 ]; then res=$(tpm2_createprimary_spk_ecc_nist_p384 "$flags") else - res=$(tpm2_createprimary_spk_rsa "$flags") + res=$(tpm2_createprimary_spk_rsa "$flags" "$rsa_keysize") fi [ $? -ne 0 ] && return 1 @@ -1881,6 +1945,7 @@ function tpm2_shutdown # @param6: The ID of the VM # @param7: The set of PCR banks to activate # @param8: The --key option parameter to start swtpm with +# @param9: The RSA key size in bits init_tpm2() { local flags="$1" @@ -1891,6 +1956,7 @@ init_tpm2() local vmid="$6" local pcr_banks="$7" local swtpm_keyopt="$8" + local rsa_keysize="$9" # where external app writes certs into local certsdir="$tpm2_state_path" @@ -1913,7 +1979,7 @@ init_tpm2() fi if [ $((flags & SETUP_CREATE_SPK_F)) -ne 0 ]; then - pk=$(tpm2_create_spk "$flags" "${TPM2_SPK_HANDLE}") + pk=$(tpm2_create_spk "$flags" "${TPM2_SPK_HANDLE}" "${rsa_keysize}") if [ $? -ne 0 ]; then logerr "tpm2_create_spk failed: $pk" return 1 @@ -1922,7 +1988,7 @@ init_tpm2() "handle $(printf "0x%08x" ${TPM2_SPK_HANDLE})." fi - tpm2_create_eks_and_certs "$flags" "$config_file" "$certsdir" "$vmid" + tpm2_create_eks_and_certs "$flags" "$config_file" "$certsdir" "$vmid" "$rsa_keysize" [ $? -ne 0 ] && return 1 if [ "$pcr_banks" != "-" ]; then @@ -2150,6 +2216,11 @@ The following options are supported: like 'sha1,sha256'. '-' to skip and leave all banks active. Default: $DEFAULT_PCR_BANKS +--rsa-keysize + : The RSA key size of the EK key; 3072 bits may be supported + if libtpms supports it. + Default: $DEFAULT_RSA_KEYSIZE + --tcsd-system-ps-file : File to copy TCSD's system_ps_file to; only for TPM 1.2 @@ -2170,7 +2241,7 @@ main() local keyfile_fd pwdfile_fd local got_ownerpass=0 got_srkpass=0 local pcr_banks="" swtpm_keyopt="" - local tcsd_system_ps_file="" + local tcsd_system_ps_file="" rsa_keysize=$DEFAULT_RSA_KEYSIZE while [ $# -ne 0 ]; do case "$1" in @@ -2207,6 +2278,7 @@ main() --allow-signing) flags=$((flags | SETUP_ALLOW_SIGNING_F));; --decryption) flags=$((flags | SETUP_DECRYPTION_F));; --pcr-banks) shift; pcr_banks="${pcr_banks},$1";; + --rsa-keysize) shift; rsa_keysize="$1";; --tcsd-system-ps-file) shift; tcsd_system_ps_file="$1";; --version) versioninfo "$0"; exit 0;; --print-capabilities) printcapabilities=1;; @@ -2400,6 +2472,17 @@ main() fi fi + case "${rsa_keysize}" in + 2048) ;; + 3072) tmp="$(get_rsakeysize_caps "$flags")" + if [ -z "$(echo "$tmp" | grep ${rsa_keysize})" ]; then + logerr "${rsa_keysize} bit RSA keys are not supported by libtpms" + exit 1 + fi + ;; + *) logerr "Unsupported RSA key size ${rsa_keysize}"; exit 1;; + esac + logit "Starting vTPM manufacturing as $(id -n -u):$(id -n -g) @ $(date +%c)" if [ $((flags & SETUP_TPM2_F)) -eq 0 ]; then @@ -2410,7 +2493,7 @@ main() SWTPM="$SWTPM --tpm2" init_tpm2 $flags "$config_file" "$tpm_state_path" \ "$ownerpass" "$srkpass" "$vmid" "$pcr_banks" \ - "$swtpm_keyopt" + "$swtpm_keyopt" "$rsa_keysize" fi ret=$? if [ $ret -eq 0 ]; then From d5cdc94f592a2698875bd96ce599fb66d229bf7f Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Thu, 23 Apr 2020 15:01:14 -0400 Subject: [PATCH 3/4] tests: Extend swtpm_setup test cases to also test with RSA 3072 bit keys Extend a few test cases to also test with RSA 3072 bit keys if they are supported. Signed-off-by: Stefan Berger --- tests/test_tpm2_parameters | 18 ++++++ tests/test_tpm2_swtpm_setup_create_cert | 76 ++++++++++++++----------- 2 files changed, 62 insertions(+), 32 deletions(-) diff --git a/tests/test_tpm2_parameters b/tests/test_tpm2_parameters index cd62d9dc..ad56fd4f 100755 --- a/tests/test_tpm2_parameters +++ b/tests/test_tpm2_parameters @@ -32,6 +32,20 @@ PARAMETERS=( "--ecc --createek --allow-signing --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --pwdfile-fd 101 --cipher aes-256-cbc" ) +# Tests for 3072 bit RSA keys to be appended to above array if RSA 3072 keys are supported +PARAMETERS_3072=( + "--createek --rsa-keysize 3072" + "--createek --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --rsa-keysize 3072" + "--createek --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --keyfile ${TESTDIR}/data/keyfile.txt --rsa-keysize 3072" + "--createek --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --pwdfile ${TESTDIR}/data/pwdfile.txt --rsa-keysize 3072" + "--createek --allow-signing --rsa-keysize 3072" + "--createek --allow-signing --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --rsa-keysize 3072" + "--createek --allow-signing --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --keyfile ${TESTDIR}/data/keyfile.txt --rsa-keysize 3072" + "--createek --allow-signing --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --pwdfile ${TESTDIR}/data/pwdfile.txt --rsa-keysize 3072" + "--createek --allow-signing --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --keyfile ${TESTDIR}/data/keyfile256bit.txt --cipher aes-256-cbc --rsa-keysize 3072" + "--createek --allow-signing --create-ek-cert --create-platform-cert --config ${TESTDIR}/swtpm_setup.conf --vmid test --display --pwdfile ${TESTDIR}/data/pwdfile.txt --cipher aes-256-cbc --rsa-keysize 3072" +) + # Open read-only file descriptors referenced in test cases exec 100<${TESTDIR}/data/keyfile256bit.txt exec 101<${TESTDIR}/data/pwdfile.txt @@ -70,6 +84,10 @@ if [ $? -ne 0 ]; then exit 1 fi +if [ -n "$($TPMAUTHORING --tpm2 --print-capabilities | grep tpm2-rsa-keysize-3072 )" ]; then + PARAMETERS+=( "${PARAMETERS_3072[@]}" ) +fi + # swtpm_setup.conf points to the local create_certs.sh # For create_certs.sh to be found (with out full path) # add this directory to the PATH diff --git a/tests/test_tpm2_swtpm_setup_create_cert b/tests/test_tpm2_swtpm_setup_create_cert index f9ec1432..0437ac38 100755 --- a/tests/test_tpm2_swtpm_setup_create_cert +++ b/tests/test_tpm2_swtpm_setup_create_cert @@ -61,43 +61,55 @@ _EOF_ # We need to adapt the PATH so the correct swtpm_cert is picked export PATH=${TOPBUILD}/src/swtpm_cert:${PATH} -# we need to create at least one cert: --create-ek-cert -$SWTPM_SETUP \ - --tpm2 \ - --allow-signing \ - --tpm-state "${workdir}" \ - --create-ek-cert \ - --create-platform-cert \ - --config "${workdir}/swtpm_setup.conf" \ - --logfile "${workdir}/logfile" \ - --tpm "${SWTPM} socket ${SWTPM_TEST_SECCOMP_OPT}" \ - --swtpm_ioctl "${SWTPM_IOCTL}" - -if [ $? -ne 0 ]; then - echo "Error: Could not run $SWTPM_SETUP." - echo "Logfile output:" - cat "${workdir}/logfile" - exit 1 +keysizes="2048" +if [ -n "$($SWTPM_SETUP --tpm2 --print-capabilities | + grep tpm2-rsa-keysize-3072 )" ]; then + keysizes+=" 3072" fi -if [ ! -r "${SIGNINGKEY}" ]; then - echo "Error: Signingkey file ${SIGNINGKEY} was not created." - exit 1 -fi - -if [ ! -r "${ISSUERCERT}" ]; then - echo "Error: Issuer cert file ${ISSUERCERT} was not created." - exit 1 -fi - -if [ ! -r "${CERTSERIAL}" ]; then - echo "Error: Cert serial number file ${CERTSERIAL} was not created." - exit 1 -fi +for keysize in $(echo $keysizes); do + echo "Testing with RSA keysize $keysize" + # we need to create at least one cert: --create-ek-cert + $SWTPM_SETUP \ + --tpm2 \ + --allow-signing \ + --tpm-state "${workdir}" \ + --create-ek-cert \ + --create-platform-cert \ + --config "${workdir}/swtpm_setup.conf" \ + --logfile "${workdir}/logfile" \ + --tpm "${SWTPM} socket ${SWTPM_TEST_SECCOMP_OPT}" \ + --swtpm_ioctl "${SWTPM_IOCTL}" \ + --rsa-keysize ${keysize} \ + --overwrite + + if [ $? -ne 0 ]; then + echo "Error: Could not run $SWTPM_SETUP." + echo "Logfile output:" + cat "${workdir}/logfile" + exit 1 + fi + + if [ ! -r "${SIGNINGKEY}" ]; then + echo "Error: Signingkey file ${SIGNINGKEY} was not created." + exit 1 + fi + + if [ ! -r "${ISSUERCERT}" ]; then + echo "Error: Issuer cert file ${ISSUERCERT} was not created." + exit 1 + fi + + if [ ! -r "${CERTSERIAL}" ]; then + echo "Error: Cert serial number file ${CERTSERIAL} was not created." + exit 1 + fi + + rm -rf ${SIGNINGKEY} ${ISSUERCERT} ${CERTSERIAL} +done echo "Test 1: OK" -rm -rf ${SIGNINGKEY} ${ISSUERCERT} ${CERTSERIAL} # we need to create at least one cert: --create-ek-cert $SWTPM_SETUP \ From d46624f68a943d9e7f7f78885a21422efe0a97d7 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Wed, 29 Apr 2020 15:14:36 -0400 Subject: [PATCH 4/4] swtpm_setup: Allow to create largest possible EK By passing '--rsa-keysize max' allow to create the largest possible RSA EK key. Signed-off-by: Stefan Berger --- man/man8/swtpm_setup.8 | 3 ++- man/man8/swtpm_setup.pod | 3 ++- src/swtpm_setup/swtpm_setup.sh.in | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/man/man8/swtpm_setup.8 b/man/man8/swtpm_setup.8 index cb891b2e..ca797c8e 100644 --- a/man/man8/swtpm_setup.8 +++ b/man/man8/swtpm_setup.8 @@ -282,7 +282,8 @@ This option is only useful with \s-1TPM 1.2\s0 and in if ownership is taken. This option allows to pass the size of a \s-1TPM 2 RSA EK\s0 key, such as 2048 or 3072. The supported keysizes for a \s-1TPM 2\s0 can be queried for using the \fI\-\-print\-capabilities\fR option. The default size is 2048 bits for -both \s-1TPM 1.2\s0 and \s-1TPM 2.\s0 +both \s-1TPM 1.2\s0 and \s-1TPM 2.\s0 If 'max' is passed, the largest possible key +size is used. .IP "\fB\-\-print\-capabilities\fR (since v0.2)" 4 .IX Item "--print-capabilities (since v0.2)" Print capabilities that were added to swtpm_setup after version 0.1. diff --git a/man/man8/swtpm_setup.pod b/man/man8/swtpm_setup.pod index b5a954dc..30ca2886 100644 --- a/man/man8/swtpm_setup.pod +++ b/man/man8/swtpm_setup.pod @@ -178,7 +178,8 @@ This option is only useful with TPM 1.2 and in if ownership is taken. This option allows to pass the size of a TPM 2 RSA EK key, such as 2048 or 3072. The supported keysizes for a TPM 2 can be queried for using the I<--print-capabilities> option. The default size is 2048 bits for -both TPM 1.2 and TPM 2. +both TPM 1.2 and TPM 2. If 'max' is passed, the largest possible key +size is used. =item B<--print-capabilities> (since v0.2) diff --git a/src/swtpm_setup/swtpm_setup.sh.in b/src/swtpm_setup/swtpm_setup.sh.in index ced991a0..d8d62d05 100755 --- a/src/swtpm_setup/swtpm_setup.sh.in +++ b/src/swtpm_setup/swtpm_setup.sh.in @@ -2472,6 +2472,14 @@ main() fi fi + # Determine maximum possible RSA keysize that we will then use + if [ "$rsa_keysize" = "max" ]; then + rsa_keysize=$(get_rsa_keysizes "$flags" | sed '$!d') + if [ -z "$rsa_keysize" ]; then + rsa_keysize=2048 + fi + fi + case "${rsa_keysize}" in 2048) ;; 3072) tmp="$(get_rsakeysize_caps "$flags")"