From: Andreas Steffen Date: Thu, 16 Jun 2016 15:40:10 +0000 (+0200) Subject: libtpmtss: Implemented TSS2 quote() method X-Git-Tag: 5.5.0dr1~1^2~4 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=57e80492eb0aab84ba33abf2e872e2761f884674;p=thirdparty%2Fstrongswan.git libtpmtss: Implemented TSS2 quote() method --- diff --git a/conf/plugins/imc-attestation.opt b/conf/plugins/imc-attestation.opt index c2dbe42263..925ac4eaf7 100644 --- a/conf/plugins/imc-attestation.opt +++ b/conf/plugins/imc-attestation.opt @@ -7,6 +7,9 @@ libimcv.plugins.imc-attestation.aik_cert = libimcv.plugins.imc-attestation.aik_pubkey = AIK public key file. +libimcv.plugins.imc-attestation.aik_handle = + AIK object handle. + libimcv.plugins.imc-attestation.mandatory_dh_groups = yes Enforce mandatory Diffie-Hellman groups. diff --git a/src/libtpmtss/tpm_tss_tss2.c b/src/libtpmtss/tpm_tss_tss2.c index 5d8658b3e7..81d659cdbe 100644 --- a/src/libtpmtss/tpm_tss_tss2.c +++ b/src/libtpmtss/tpm_tss_tss2.c @@ -393,18 +393,16 @@ METHOD(tpm_tss_t, get_public, chunk_t, return aik_pubkey; } -METHOD(tpm_tss_t, read_pcr, bool, - private_tpm_tss_tss2_t *this, uint32_t pcr_num, chunk_t *pcr_value, - hash_algorithm_t alg) +/** + * Configure a PCR Selection assuming a maximum of 24 registers + */ +static bool init_pcr_selection(private_tpm_tss_tss2_t *this, uint32_t pcrs, + hash_algorithm_t alg, TPML_PCR_SELECTION *pcr_sel) { - TPML_PCR_SELECTION pcr_sel_in, pcr_sel_out; - TPML_DIGEST pcr_values; TPM_ALG_ID alg_id; + uint32_t pcr; - uint32_t pcr_update_counter, rval; - uint8_t *pcr_value_ptr; - size_t pcr_value_len; - + /* check if hash algorithm is supported by TPM */ alg_id = hash_alg_to_tpm_alg_id(alg); if (!is_supported_alg(this, alg_id)) { @@ -413,6 +411,36 @@ METHOD(tpm_tss_t, read_pcr, bool, return FALSE; } + /* initialize the PCR Selection structure,*/ + pcr_sel->count = 1; + pcr_sel->pcrSelections[0].hash = alg_id; + pcr_sel->pcrSelections[0].sizeofSelect = 3; + pcr_sel->pcrSelections[0].pcrSelect[0] = 0; + pcr_sel->pcrSelections[0].pcrSelect[1] = 0; + pcr_sel->pcrSelections[0].pcrSelect[2] = 0; + + /* set the selected PCRs */ + for (pcr = 0; pcr < PLATFORM_PCR; pcr++) + { + if (pcrs & (1 << pcr)) + { + pcr_sel->pcrSelections[0].pcrSelect[pcr / 8] |= ( 1 << (pcr % 8) ); + } + } + return TRUE; +} + +METHOD(tpm_tss_t, read_pcr, bool, + private_tpm_tss_tss2_t *this, uint32_t pcr_num, chunk_t *pcr_value, + hash_algorithm_t alg) +{ + TPML_PCR_SELECTION pcr_selection; + TPML_DIGEST pcr_values; + + uint32_t pcr_update_counter, rval; + uint8_t *pcr_value_ptr; + size_t pcr_value_len; + if (pcr_num >= PLATFORM_PCR) { DBG1(DBG_PTS, "%s maximum number of supported PCR is %d", @@ -420,23 +448,17 @@ METHOD(tpm_tss_t, read_pcr, bool, return FALSE; } - /* initialize the PCR Selection structure */ - pcr_sel_in.count = 1; - pcr_sel_in.pcrSelections[0].hash = alg_id; - pcr_sel_in.pcrSelections[0].sizeofSelect = 3; - pcr_sel_in.pcrSelections[0].pcrSelect[0] = 0; - pcr_sel_in.pcrSelections[0].pcrSelect[1] = 0; - pcr_sel_in.pcrSelections[0].pcrSelect[2] = 0; - - /* set the desired PCR */ - pcr_sel_in.pcrSelections[0].pcrSelect[pcr_num / 8] = 1 << (pcr_num % 8); + if (!init_pcr_selection(this, (1 << pcr_num), alg, &pcr_selection)) + { + return FALSE; + } /* initialize the PCR Digest structure */ memset(&pcr_values, 0, sizeof(TPML_DIGEST)); /* read the PCR value */ - rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_sel_in, - &pcr_update_counter, &pcr_sel_out, &pcr_values, 0); + rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection, + &pcr_update_counter, &pcr_selection, &pcr_values, 0); if (rval != TPM_RC_SUCCESS) { DBG1(DBG_PTS, "%s PCR bank could not be read: 0x%60x", @@ -464,8 +486,102 @@ METHOD(tpm_tss_t, quote, bool, hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t mode, chunk_t *pcr_comp, chunk_t *quote_sig) { - /* TODO */ - return FALSE; + chunk_t quote_info; + uint32_t rval; + + TPM2B_DATA qualifying_data; + TPML_PCR_SELECTION pcr_selection; + TPMS_ATTEST *attest; + TPM2B_ATTEST quoted = { { sizeof(TPM2B_ATTEST)-2, } }; + TPM2B_DIGEST digest; + TPMT_SIGNATURE sig; + TPMT_SIG_SCHEME scheme; + TPMS_AUTH_COMMAND session_data_cmd; + TPMS_AUTH_RESPONSE session_data_rsp; + TSS2_SYS_CMD_AUTHS sessions_data_cmd; + TSS2_SYS_RSP_AUTHS sessions_data_rsp; + TPMS_AUTH_COMMAND *session_data_cmd_array[1]; + TPMS_AUTH_RESPONSE *session_data_rsp_array[1]; + + session_data_cmd_array[0] = &session_data_cmd; + session_data_rsp_array[0] = &session_data_rsp; + + sessions_data_cmd.cmdAuths = &session_data_cmd_array[0]; + sessions_data_rsp.rspAuths = &session_data_rsp_array[0]; + + sessions_data_cmd.cmdAuthsCount = 1; + sessions_data_rsp.rspAuthsCount = 1; + + session_data_cmd.sessionHandle = TPM_RS_PW; + session_data_cmd.hmac.t.size = 0; + session_data_cmd.nonce.t.size = 0; + + *( (uint8_t *)((void *)&session_data_cmd.sessionAttributes ) ) = 0; + + qualifying_data.t.size = data.len; + memcpy(qualifying_data.t.buffer, data.ptr, data.len); + + scheme.scheme = TPM_ALG_NULL; + memset(&sig, 0x00, sizeof(sig)); + + if (mode == TPM_QUOTE || mode == TPM_QUOTE2_VERSION_INFO) + { + DBG1(DBG_PTS, "%s TPM Quote mode not supported", LABEL); + return FALSE; + } + + if (!init_pcr_selection(this, pcr_sel, alg, &pcr_selection)) + { + return FALSE; + } + + rval = Tss2_Sys_Quote(this->sys_context, aik_handle, &sessions_data_cmd, + &qualifying_data, &scheme, &pcr_selection, "ed, + &sig, &sessions_data_rsp); + if (rval != TPM_RC_SUCCESS) + { + DBG1(DBG_PTS,"%s Tss2_Sys_Quote failed: 0x%06x", LABEL, rval); + return FALSE; + } + + attest = (TPMS_ATTEST *)quoted.t.attestationData; + digest = attest->attested.quote.pcrDigest; + *pcr_comp = chunk_clone(chunk_create(digest.t.buffer, digest.t.size)); + DBG2(DBG_PTS, "Hash of PCR Composite: %#B", pcr_comp); + + quote_info = chunk_create(quoted.t.attestationData, quoted.t.size); + DBG2(DBG_PTS, "TPM Quote Info: %B","e_info); + + /* extract signature */ + switch (sig.sigAlg) + { + case TPM_ALG_RSASSA: + case TPM_ALG_RSAPSS: + *quote_sig = chunk_clone( + chunk_create( + sig.signature.rsassa.sig.t.buffer, + sig.signature.rsassa.sig.t.size)); + break; + case TPM_ALG_ECDSA: + case TPM_ALG_ECDAA: + case TPM_ALG_SM2: + case TPM_ALG_ECSCHNORR: + *quote_sig = chunk_cat("cc", + chunk_create( + sig.signature.ecdsa.signatureR.t.buffer, + sig.signature.ecdsa.signatureR.t.size), + chunk_create( + sig.signature.ecdsa.signatureS.t.buffer, + sig.signature.ecdsa.signatureS.t.size)); + break; + default: + DBG1(DBG_PTS, "%s unsupported %N signature algorithm", + LABEL, tpm_alg_id_names, sig.sigAlg); + return FALSE; + }; + DBG2(DBG_PTS, "TPM Quote Signature: %B", quote_sig); + + return TRUE; } METHOD(tpm_tss_t, destroy, void,