libtpmtss: Implemented TSS2 quote() method
This commit is contained in:
@@ -7,6 +7,9 @@ libimcv.plugins.imc-attestation.aik_cert =
|
|||||||
libimcv.plugins.imc-attestation.aik_pubkey =
|
libimcv.plugins.imc-attestation.aik_pubkey =
|
||||||
AIK public key file.
|
AIK public key file.
|
||||||
|
|
||||||
|
libimcv.plugins.imc-attestation.aik_handle =
|
||||||
|
AIK object handle.
|
||||||
|
|
||||||
libimcv.plugins.imc-attestation.mandatory_dh_groups = yes
|
libimcv.plugins.imc-attestation.mandatory_dh_groups = yes
|
||||||
Enforce mandatory Diffie-Hellman groups.
|
Enforce mandatory Diffie-Hellman groups.
|
||||||
|
|
||||||
|
|||||||
+139
-23
@@ -393,18 +393,16 @@ METHOD(tpm_tss_t, get_public, chunk_t,
|
|||||||
return aik_pubkey;
|
return aik_pubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tpm_tss_t, read_pcr, bool,
|
/**
|
||||||
private_tpm_tss_tss2_t *this, uint32_t pcr_num, chunk_t *pcr_value,
|
* Configure a PCR Selection assuming a maximum of 24 registers
|
||||||
hash_algorithm_t alg)
|
*/
|
||||||
|
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;
|
TPM_ALG_ID alg_id;
|
||||||
|
uint32_t pcr;
|
||||||
|
|
||||||
uint32_t pcr_update_counter, rval;
|
/* check if hash algorithm is supported by TPM */
|
||||||
uint8_t *pcr_value_ptr;
|
|
||||||
size_t pcr_value_len;
|
|
||||||
|
|
||||||
alg_id = hash_alg_to_tpm_alg_id(alg);
|
alg_id = hash_alg_to_tpm_alg_id(alg);
|
||||||
if (!is_supported_alg(this, alg_id))
|
if (!is_supported_alg(this, alg_id))
|
||||||
{
|
{
|
||||||
@@ -413,6 +411,36 @@ METHOD(tpm_tss_t, read_pcr, bool,
|
|||||||
return FALSE;
|
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)
|
if (pcr_num >= PLATFORM_PCR)
|
||||||
{
|
{
|
||||||
DBG1(DBG_PTS, "%s maximum number of supported PCR is %d",
|
DBG1(DBG_PTS, "%s maximum number of supported PCR is %d",
|
||||||
@@ -420,23 +448,17 @@ METHOD(tpm_tss_t, read_pcr, bool,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the PCR Selection structure */
|
if (!init_pcr_selection(this, (1 << pcr_num), alg, &pcr_selection))
|
||||||
pcr_sel_in.count = 1;
|
{
|
||||||
pcr_sel_in.pcrSelections[0].hash = alg_id;
|
return FALSE;
|
||||||
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);
|
|
||||||
|
|
||||||
/* initialize the PCR Digest structure */
|
/* initialize the PCR Digest structure */
|
||||||
memset(&pcr_values, 0, sizeof(TPML_DIGEST));
|
memset(&pcr_values, 0, sizeof(TPML_DIGEST));
|
||||||
|
|
||||||
/* read the PCR value */
|
/* read the PCR value */
|
||||||
rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_sel_in,
|
rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection,
|
||||||
&pcr_update_counter, &pcr_sel_out, &pcr_values, 0);
|
&pcr_update_counter, &pcr_selection, &pcr_values, 0);
|
||||||
if (rval != TPM_RC_SUCCESS)
|
if (rval != TPM_RC_SUCCESS)
|
||||||
{
|
{
|
||||||
DBG1(DBG_PTS, "%s PCR bank could not be read: 0x%60x",
|
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,
|
hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t mode, chunk_t *pcr_comp,
|
||||||
chunk_t *quote_sig)
|
chunk_t *quote_sig)
|
||||||
{
|
{
|
||||||
/* TODO */
|
chunk_t quote_info;
|
||||||
return FALSE;
|
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,
|
METHOD(tpm_tss_t, destroy, void,
|
||||||
|
|||||||
Reference in New Issue
Block a user