diff options
author | Sansar Choinyambuu <schoinya@hsr.ch> | 2011-10-07 15:15:56 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2011-11-28 14:34:21 +0100 |
commit | 924f3bf59e3ada87a2ca927a0e662ff76ee7b4fe (patch) | |
tree | 3cb69fa7e0316f71276fad432172f426ca430618 | |
parent | e1aebc940aad17183928265c874c719ce5b46653 (diff) | |
download | strongswan-924f3bf59e3ada87a2ca927a0e662ff76ee7b4fe.tar.bz2 strongswan-924f3bf59e3ada87a2ca927a0e662ff76ee7b4fe.tar.xz |
Improved implementation of Read PCR/ Extend PCR/ Quote_TPM functions
Implemented creating/handling of Simple Evidence Final attribute (incomplete)
-rw-r--r-- | src/libimcv/plugins/imc_attestation/imc_attestation.c | 64 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_attestation/imv_attestation.c | 26 | ||||
-rw-r--r-- | src/libpts/pts/pts.c | 28 | ||||
-rw-r--r-- | src/libpts/pts/pts.h | 11 |
4 files changed, 101 insertions, 28 deletions
diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation.c b/src/libimcv/plugins/imc_attestation/imc_attestation.c index 1e0f3606f..0ed43e8ed 100644 --- a/src/libimcv/plugins/imc_attestation/imc_attestation.c +++ b/src/libimcv/plugins/imc_attestation/imc_attestation.c @@ -409,7 +409,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, selected_dh_group = pts->get_dh_group(pts); if (!pts->create_dh(pts, selected_dh_group)) { - return TNC_RESULT_FATAL; + goto err; } pts->get_my_pub_val(pts, &responder_pub_val); @@ -450,7 +450,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, if (!pts->calculate_secret(pts, initiator_nonce, responder_non, selected_algorithm)) { - return TNC_RESULT_FATAL; + goto err; } break; @@ -672,13 +672,13 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, { DBG1(DBG_IMC, " hasher %N not available", hash_algorithm_names, hash_alg); - return TNC_RESULT_FATAL; + goto err; } if (!pts->hash_file(pts, hasher, "/etc/tnc_config", hash_output)) { hasher->destroy(hasher); - return TNC_RESULT_FATAL; + goto err; } measurement_time_t = time(NULL); @@ -698,9 +698,13 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, time_now->tm_sec) < 0) { DBG1(DBG_IMC, "Couldn not format local time to UTC"); - return TNC_RESULT_FATAL; + hasher->destroy(hasher); + goto err; } params.measurement_time = chunk_create(utc_time, 20); + params.measurement_time = chunk_clone(params.measurement_time); + free(utc_time); + } params.measurement = chunk_create(hash_output, hasher->get_hash_size(hasher)); @@ -710,13 +714,14 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, if (!pts->read_pcr(pts, EXTEND_PCR, ¶ms.pcr_before)) { DBG1(DBG_IMC, "Error occured while reading PCR: %d", EXTEND_PCR); - return TNC_RESULT_FATAL; + goto err; } + if (!pts->extend_pcr(pts, EXTEND_PCR, params.measurement, ¶ms.pcr_after)) { DBG1(DBG_IMC, "Error occured while extending PCR: %d", EXTEND_PCR); - return TNC_RESULT_FATAL; + goto err; } /* Buffer Simple Component Evidence attribute */ @@ -744,22 +749,47 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, { enumerator_t *e; pts_simple_evid_final_flag_t flags; - + chunk_t pcr_composite, quote_signature; + linked_list_t *pcrs; + /* Send buffered Simple Component Evidences */ + pcrs = linked_list_create(); + e = evidences->create_enumerator(evidences); while (e->enumerate(e, &attr)) { + tcg_pts_attr_simple_comp_evid_t *attr_cast; + u_int32_t extended_pcr; + + attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr; + extended_pcr = attr_cast->get_extended_pcr(attr_cast); + + /* Add extended PCR number to PCR list to quote */ + /* Duplicated PCR numbers have no influence */ + pcrs->insert_last(pcrs, &extended_pcr); + /* Send Simple Compoenent Evidence */ attr_list->insert_last(attr_list, attr); } - /* TODO: TPM quote operation over included PCR's */ + /* Quote */ + if (!pts->quote_tpm(pts, pcrs, &pcr_composite, "e_signature)) + { + DBG1(DBG_IMC, "Error occured while TPM quote operation"); + DESTROY_IF(e); + DESTROY_IF(pcrs); + DESTROY_IF(evidences); + goto err; + } + /* Send Simple Evidence Final attribute */ - flags = PTS_SIMPLE_EVID_FINAL_FLAG_NO; + flags = PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO; + attr = tcg_pts_attr_simple_evid_final_create(flags, 0, - chunk_empty, chunk_empty, chunk_empty); + pcr_composite, quote_signature, chunk_empty); attr_list->insert_last(attr_list, attr); - e->destroy(e); + DESTROY_IF(e); + DESTROY_IF(pcrs); DESTROY_IF(evidences); break; @@ -806,7 +836,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, if (!metadata) { /* TODO handle error codes from measurements */ - return TNC_RESULT_FATAL; + goto err; } attr = tcg_pts_attr_unix_file_meta_create(metadata); attr->set_noskip_flag(attr, TRUE); @@ -862,7 +892,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, if (!measurements) { /* TODO handle error codes from measurements */ - return TNC_RESULT_FATAL; + goto err; } attr = tcg_pts_attr_file_meas_create(measurements); attr->set_noskip_flag(attr, TRUE); @@ -918,9 +948,13 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, pa_tnc_msg->get_encoding(pa_tnc_msg)); pa_tnc_msg->destroy(pa_tnc_msg); } - attr_list->destroy(attr_list); + DESTROY_IF(attr_list); return result; + + err: + DESTROY_IF(attr_list); + return TNC_RESULT_FATAL; } /** diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation.c b/src/libimcv/plugins/imv_attestation/imv_attestation.c index bdf37abba..719f849c8 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation.c @@ -750,9 +750,31 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, case TCG_PTS_SIMPLE_EVID_FINAL: { - /** TODO: Implement construct Quote structure over saved values from - * TCG_PTS_SIMPLE_COMP_EVID and compare with received one + tcg_pts_attr_simple_evid_final_t *attr_cast; + pts_simple_evid_final_flag_t flags; + chunk_t pcr_comp = chunk_empty; + chunk_t tpm_quote_sign = chunk_empty; + chunk_t evid_sign = chunk_empty; + + /** TODO: Ignoring Composite Hash Algorithm field + * No flag defined which indicates the precense of it */ + attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr; + flags = attr_cast->get_flags(attr_cast); + + if ((flags >> 6) & PTS_SIMPLE_EVID_FINAL_FLAG_NO) + { + pcr_comp = attr_cast->get_pcr_comp(attr_cast); + tpm_quote_sign = attr_cast->get_tpm_quote_sign(attr_cast); + + /** TODO: Construct PCR Composite */ + } + if (flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID) + { + /** TODO: What to do with Evidence Signature */ + evid_sign = attr_cast->get_evid_sign(attr_cast); + } + break; } diff --git a/src/libpts/pts/pts.c b/src/libpts/pts/pts.c index 14271f63f..d66130839 100644 --- a/src/libpts/pts/pts.c +++ b/src/libpts/pts/pts.c @@ -650,6 +650,7 @@ METHOD(pts_t, read_pcr, bool, { goto err; } + pcr_value = chunk_alloc(PCR_LEN); result = Tspi_TPM_PcrRead(hTPM, pcr_num, &pcr_length, &pcr_value.ptr); if (result != TSS_SUCCESS) { @@ -659,11 +660,13 @@ METHOD(pts_t, read_pcr, bool, *output = pcr_value; *output = chunk_clone(*output); + chunk_clear(&pcr_value); Tspi_Context_Close(hContext); DBG3(DBG_PTS, "PCR %d value:%B", pcr_num, output); return TRUE; err: + chunk_clear(&pcr_value); DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result); Tspi_Context_Close(hContext); return FALSE; @@ -694,7 +697,10 @@ METHOD(pts_t, extend_pcr, bool, { goto err; } - result = Tspi_TPM_PcrExtend(hTPM, pcr_num, 20, input.ptr, NULL, &pcr_length, &pcr_value.ptr); + + pcr_value = chunk_alloc(PCR_LEN); + result = Tspi_TPM_PcrExtend(hTPM, pcr_num, PCR_LEN, input.ptr, + NULL, &pcr_length, &pcr_value.ptr); if (result != TSS_SUCCESS) { goto err; @@ -703,20 +709,21 @@ METHOD(pts_t, extend_pcr, bool, *output = pcr_value; *output = chunk_clone(*output); + chunk_clear(&pcr_value); Tspi_Context_Close(hContext); DBG3(DBG_PTS, "PCR %d extended with: %B", pcr_num, &input); DBG3(DBG_PTS, "PCR %d value after extend: %B", pcr_num, output); - return TRUE; err: + chunk_clear(&pcr_value); DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result); Tspi_Context_Close(hContext); return FALSE; } METHOD(pts_t, quote_tpm, bool, - private_pts_t *this, u_int32_t *pcrs, u_int32_t num_of_pcrs, + private_pts_t *this, linked_list_t *pcrs, chunk_t *pcr_composite, chunk_t *quote_signature) { TSS_HCONTEXT hContext; @@ -729,10 +736,11 @@ METHOD(pts_t, quote_tpm, bool, TSS_HPCRS hPcrComposite; TSS_VALIDATION valData; TPM_QUOTE_INFO *quoteInfo; - u_int32_t i; + u_int32_t i, pcr; TSS_RESULT result; chunk_t aik_key_encoding; chunk_t pcr_composite_without_nonce; + enumerator_t *enumerator; result = Tspi_Context_Create(&hContext); if (result != TSS_SUCCESS) @@ -774,7 +782,7 @@ METHOD(pts_t, quote_tpm, bool, /* Create from AIK public key a HKEY object to sign Quote operation output*/ if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY) { - if (!this->aik->get_encoding(this->aik, CERT_ASN1_DER, &aik_key_encoding)) + if (!this->aik->get_encoding(this->aik, CERT_PEM, &aik_key_encoding)) { DBG1(DBG_PTS, "encoding AIK certificate for quote operation failed"); goto err1; @@ -789,7 +797,7 @@ METHOD(pts_t, quote_tpm, bool, DBG1(DBG_PTS, "unable to retrieve public key from AIK certificate"); goto err1; } - if (!key->get_encoding(key, PUBKEY_ASN1_DER, &aik_key_encoding)) + if (!key->get_encoding(key, PUBKEY_PEM, &aik_key_encoding)) { DBG1(DBG_PTS, "encoding AIK Public Key for quote operation failed"); goto err1; @@ -816,9 +824,9 @@ METHOD(pts_t, quote_tpm, bool, } /* Select PCR's */ - for (i = 0; i < num_of_pcrs; i++) + enumerator = pcrs->create_enumerator(pcrs); + while (enumerator->enumerate(enumerator, &pcr)) { - u_int32_t pcr = pcrs[i]; if (pcr < 0 || pcr >= MAX_NUM_PCR ) { DBG1(DBG_PTS, "Invalid PCR number: %d", pcr); @@ -830,6 +838,7 @@ METHOD(pts_t, quote_tpm, bool, goto err3; } } + enumerator->destroy(enumerator); /* Set the Validation Data */ valData.ulExternalDataLength = this->secret.len; @@ -872,6 +881,9 @@ METHOD(pts_t, quote_tpm, bool, memcpy(pcr_composite_without_nonce.ptr, valData.rgbData, valData.ulDataLength - ASSESSMENT_SECRET_LEN); *pcr_composite = pcr_composite_without_nonce; + *pcr_composite = chunk_clone(*pcr_composite); + free(pcr_composite_without_nonce.ptr); + *quote_signature = chunk_from_thing(valData.rgbValidationData); *quote_signature = chunk_clone(*quote_signature); diff --git a/src/libpts/pts/pts.h b/src/libpts/pts/pts.h index efc7271cc..d0c03ee1d 100644 --- a/src/libpts/pts/pts.h +++ b/src/libpts/pts/pts.h @@ -31,6 +31,7 @@ typedef struct pts_t pts_t; #include "pts_dh_group.h" #include <library.h> +#include <utils/linked_list.h> /** * UTF-8 encoding of the character used to delimiter the filename @@ -54,6 +55,11 @@ typedef struct pts_t pts_t; #define MAX_NUM_PCR 24 /** + * Number of bytes can be savedin a PCR of TPM, TPM Spec 1.2 + */ +#define PCR_LEN 20 + +/** * Class implementing the TCG Platform Trust System (PTS) * */ @@ -249,14 +255,13 @@ struct pts_t { * Quote over PCR's * Expects owner and SRK secret to be WELL_KNOWN_SECRET and no password set for AIK * - * @param pcrs Set of PCR's to make quotation over - * @param num_of_pcr Number of PCR's + * @param pcrs List of PCR's to make quotation over * @param pcr_composite Chunk to save pcr composite structure * @param quote_signature Chunk to save quote operation output * without external data (anti-replay protection) * @return FALSE in case of TSS error, TRUE otherwise */ - bool (*quote_tpm)(pts_t *this, u_int32_t *pcrs, u_int32_t num_of_pcrs, + bool (*quote_tpm)(pts_t *this, linked_list_t *pcrs, chunk_t *pcr_composite, chunk_t *quote_signature); /** |