* High Entropy Random Data
* used in calculation of shared secret for the assessment session
*/
-static chunk_t responder_nonce;
+static char *responder_nonce = NULL;
/**
* see section 3.7.1 of TCG TNC IF-IMC Specification 1.2
TNC_Version max_version,
TNC_Version *actual_version)
{
+ rng_t *rng;
+
if (imc_attestation)
{
DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
libpts_init();
+ /* create a responder nonce */
+ responder_nonce = (char*)malloc(NONCE_LEN);
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (rng)
+ {
+ rng->get_bytes(rng, NONCE_LEN, responder_nonce);
+ rng->destroy(rng);
+ }
+
if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
{
DBG1(DBG_IMC, "no common IF-IMC version");
tcg_pts_attr_dh_nonce_params_req_t *attr_cast;
u_int8_t min_nonce_len;
pts_dh_group_t offered_dh_groups, selected_dh_group;
- rng_t *rng;
chunk_t responder_pub_val;
- char buf[NONCE_LEN];
-
+
attr_cast = (tcg_pts_attr_dh_nonce_params_req_t*)attr;
min_nonce_len = attr_cast->get_min_nonce_len(attr_cast);
if (NONCE_LEN < min_nonce_len || NONCE_LEN <= 16)
attr_list->insert_last(attr_list, attr);
break;
}
-
+
offered_dh_groups = attr_cast->get_dh_groups(attr_cast);
if ((supported_dh_groups & PTS_DH_GROUP_IKE20) &&
return TNC_RESULT_FATAL;
}
responder_pub_val = pts->get_my_pub_val(pts);
-
- /* create a responder nonce */
- rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- if (rng)
- {
- rng->get_bytes(rng, sizeof(buf), buf);
- rng->destroy(rng);
- }
- responder_nonce = chunk_create(buf, sizeof(buf));
-
+
attr = tcg_pts_attr_dh_nonce_params_resp_create(NONCE_LEN,
selected_dh_group, supported_algorithms,
- responder_nonce, responder_pub_val);
+ chunk_create(responder_nonce, NONCE_LEN),
+ responder_pub_val);
attr_list->insert_last(attr_list, attr);
break;
}
tcg_pts_attr_dh_nonce_finish_t *attr_cast;
u_int8_t nonce_len;
pts_meas_algorithms_t selected_algorithm;
- chunk_t initiator_nonce, initiator_pub_val;
+ chunk_t initiator_nonce, initiator_pub_val, responder_non;
attr_cast = (tcg_pts_attr_dh_nonce_finish_t*)attr;
nonce_len = attr_cast->get_nonce_len(attr_cast);
selected_algorithm = attr_cast->get_hash_algo(attr_cast);
initiator_pub_val = attr_cast->get_initiator_pub_val(attr_cast);
initiator_nonce = attr_cast->get_initiator_nonce(attr_cast);
+ responder_non = chunk_create(responder_nonce, NONCE_LEN);
DBG3(DBG_IMC, "Initiator nonce: %B", &initiator_nonce);
- DBG3(DBG_IMC, "Responder nonce: %B", &responder_nonce);
+ DBG3(DBG_IMC, "Responder nonce: %B", &responder_non);
+
pts->set_other_pub_val(pts, initiator_pub_val);
if (!pts->calculate_secret(pts, initiator_nonce,
- responder_nonce, selected_algorithm))
+ responder_non, selected_algorithm))
{
return TNC_RESULT_FATAL;
}
-
+
break;
}
case TCG_PTS_MEAS_ALGO:
u_int8_t family;
pts_qualifier_t qualifier;
pts_funct_comp_name_t name;
-
+
attr_info = attr->get_value(attr);
attr_cast = (tcg_pts_attr_req_funct_comp_evid_t*)attr;
negotiated_caps = pts->get_proto_caps(pts);
"sub component measurement deeper than 1. "
"Measuring top level component only.");
}
-
+
comp_name_vendor_id = attr_cast->get_comp_funct_name_vendor_id(attr_cast);
if (comp_name_vendor_id != PEN_TCG)
{
"only functional component namings by TCG ");
break;
}
-
+
family = attr_cast->get_family(attr_cast);
if (family)
{
{
/* TODO: Implement what todo with received qualifier */
}
-
+
name = attr_cast->get_comp_funct_name(attr_cast);
switch (name)
{
break;
}
}
-
+
break;
}
case TCG_PTS_GEN_ATTEST_EVID:
{
pts_simple_evid_final_flag_t flags;
/* TODO: TPM quote operation over included PCR's */
-
+
/* Send Simple Evidence Final attribute */
flags = PTS_SIMPLE_EVID_FINAL_FLAG_NO;
attr = tcg_pts_attr_simple_evid_final_create(flags, 0,
is_directory ? "directory" : "file",
pathname);
metadata = pts->get_metadata(pts, pathname, is_directory);
-
+
if (!metadata)
{
/* TODO handle error codes from measurements */
attr = tcg_pts_attr_unix_file_meta_create(metadata);
attr->set_noskip_flag(attr, TRUE);
attr_list->insert_last(attr_list, attr);
-
+
break;
}
case TCG_PTS_REQ_FILE_MEAS:
delimiter = attr_cast->get_delimiter(attr_cast);
pathname = attr_cast->get_pathname(attr_cast);
valid_path = pts->is_path_valid(pts, pathname, &pts_error);
-
+
if (valid_path && pts_error)
{
attr_info = attr->get_value(attr);
return TNC_RESULT_NOT_INITIALIZED;
}
- free(responder_nonce.ptr);
+ free(responder_nonce);
libpts_deinit();
imc_attestation->destroy(imc_attestation);
* High Entropy Random Data
* used in calculation of shared secret for the assessment session
*/
-static chunk_t initiator_nonce;
+static char *initiator_nonce = NULL;
/**
* PTS file measurement database
TNC_Version *actual_version)
{
char *hash_alg, *dh_group, *uri, *cadir;
+ rng_t *rng;
if (imv_attestation)
{
}
libpts_init();
+
+ /* Create a initiator nonce */
+ initiator_nonce = (char*)malloc(NONCE_LEN);
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (rng)
+ {
+ rng->get_bytes(rng, NONCE_LEN, initiator_nonce);
+ rng->destroy(rng);
+ }
if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1)
{
return result;
}
attestation_state = (imv_attestation_state_t*)state;
-
+
/* TODO: Get some configurations */
-
+
return TNC_RESULT_SUCCESS;
default:
return imv_attestation->change_state(imv_attestation, connection_id,
imv_attestation_state_t *attestation_state;
imv_attestation_handshake_state_t handshake_state;
TNC_Result result;
-
+
if (!imv_attestation->get_state(imv_attestation, connection_id, &state))
{
return TNC_RESULT_FATAL;
attestation_state = (imv_attestation_state_t*)state;
handshake_state = attestation_state->get_handshake_state(attestation_state);
pts = attestation_state->get_pts(attestation_state);
-
+
msg = pa_tnc_msg_create();
-
- switch_state:
+
+ /* Jump to Measurement state if IMC has no TPM */
+ if (handshake_state == IMV_ATTESTATION_STATE_TPM_INIT &&
+ !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T))
+ {
+ handshake_state = IMV_ATTESTATION_STATE_MEAS;
+ DBG3(DBG_IMV, "TPM is not available on IMC side, ",
+ "jumping to measurement phase");
+ }
+
/* Switch on the attribute type IMV has received */
switch (handshake_state)
{
attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
attr->set_noskip_flag(attr, TRUE);
msg->add_attribute(msg, attr);
-
+
/* Send Measurement Algorithms attribute */
attr = tcg_pts_attr_meas_algo_create(supported_algorithms, FALSE);
attr->set_noskip_flag(attr, TRUE);
}
case IMV_ATTESTATION_STATE_TPM_INIT:
{
- /* Jump to Measurement state if IMC has no TPM */
- if(!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T))
- {
- handshake_state = IMV_ATTESTATION_STATE_MEAS;
- DBG3(DBG_IMV, "TPM is not available on IMC side, ",
- "jumping to measurement phase");
- goto switch_state;
- }
-
if (!dh_nonce_req_sent)
{
/* Send DH nonce parameters request attribute */
selected_algorithm = pts->get_meas_algorithm(pts);
initiator_pub_val = pts->get_my_pub_val(pts);
attr = tcg_pts_attr_dh_nonce_finish_create(NONCE_LEN,
- selected_algorithm, initiator_nonce,
+ selected_algorithm,
+ chunk_create(initiator_nonce, NONCE_LEN),
initiator_pub_val);
attr->set_noskip_flag(attr, TRUE);
msg->add_attribute(msg, attr);
}
case IMV_ATTESTATION_STATE_MEAS:
{
-
+
enumerator_t *enumerator;
u_int32_t delimiter = SOLIDUS_UTF;
char *platform_info, *pathname;
u_int32_t sub_comp_depth;
pts_qualifier_t qualifier;
pts_funct_comp_name_t name;
-
+
attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_END);
qualifier.sub_component = FALSE;
qualifier.type = PTS_FUNC_COMP_TYPE_ALL;
name = PTS_FUNC_COMP_NAME_BIOS;
-
+
/* Send Request Functional Component Evidence attribute */
attr = tcg_pts_attr_req_funct_comp_evid_create(flags, sub_comp_depth,
PEN_TCG, qualifier, name);
attr = tcg_pts_attr_gen_attest_evid_create();
attr->set_noskip_flag(attr, TRUE);
msg->add_attribute(msg, attr);
-
+
break;
}
default:
handshake_state);
return TNC_RESULT_FATAL;
}
-
+
msg->build(msg);
result = imv_attestation->send_message(imv_attestation, connection_id,
msg->get_encoding(msg));
msg->destroy(msg);
-
+
return result;
}
attr_cast = (ietf_attr_product_info_t*)attr;
platform_info = attr_cast->get_info(attr_cast, NULL, NULL);
- pts->set_platform_info(pts, platform_info);
+ pts->set_platform_info(pts, platform_info);
}
}
else if (attr->get_vendor_id(attr) == PEN_TCG)
{
tcg_pts_attr_proto_caps_t *attr_cast;
pts_proto_caps_flag_t flags;
-
+
attr_cast = (tcg_pts_attr_proto_caps_t*)attr;
flags = attr_cast->get_flags(attr_cast);
pts->set_proto_caps(pts, flags);
{
tcg_pts_attr_meas_algo_t *attr_cast;
pts_meas_algorithms_t selected_algorithm;
-
+
attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
selected_algorithm = attr_cast->get_algorithms(attr_cast);
pts->set_meas_algorithm(pts, selected_algorithm);
u_int8_t nonce_len;
pts_dh_group_t dh_group;
pts_meas_algorithms_t offered_algorithms, selected_algorithm;
- chunk_t responder_nonce;
- chunk_t responder_pub_val;
- rng_t *rng;
- char buf[NONCE_LEN];
+ chunk_t responder_nonce, initiator_non, responder_pub_val;
attr_cast = (tcg_pts_attr_dh_nonce_params_resp_t*)attr;
-
+
nonce_len = attr_cast->get_nonce_len(attr_cast);
if (nonce_len < 0 || nonce_len <= 16)
{
attr_list->insert_last(attr_list, attr);
break;
}
-
+
dh_group = attr_cast->get_dh_group(attr_cast);
-
+
offered_algorithms = attr_cast->get_hash_algo_set(attr_cast);
if ((supported_algorithms & PTS_MEAS_ALGO_SHA384) &&
(offered_algorithms & PTS_MEAS_ALGO_SHA384))
selected_algorithm = pts->get_meas_algorithm(pts);
responder_nonce = attr_cast->get_responder_nonce(attr_cast);
responder_pub_val = attr_cast->get_responder_pub_val(attr_cast);
-
+ initiator_non = chunk_create(initiator_nonce, NONCE_LEN);
+
/* Calculate secret assessment value */
if (!pts->create_dh(pts, dh_group))
{
return TNC_RESULT_FATAL;
}
pts->set_other_pub_val(pts, responder_pub_val);
-
- /* Create a initiator nonce */
- rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- if (rng)
- {
- rng->get_bytes(rng, sizeof(buf), buf);
- rng->destroy(rng);
- }
- initiator_nonce = chunk_create(buf, sizeof(buf));
-
- DBG3(DBG_IMV, "Initiator nonce: %B", &initiator_nonce);
+
+ DBG3(DBG_IMV, "Initiator nonce: %B", &initiator_non);
DBG3(DBG_IMV, "Responder nonce: %B", &responder_nonce);
- if (!pts->calculate_secret(pts, initiator_nonce,
- responder_nonce, selected_algorithm))
+ if (!pts->calculate_secret(pts, initiator_non,
+ responder_nonce, selected_algorithm))
{
return TNC_RESULT_FATAL;
}
{
tcg_pts_attr_tpm_version_info_t *attr_cast;
chunk_t tpm_version_info;
-
+
attr_cast = (tcg_pts_attr_tpm_version_info_t*)attr;
tpm_version_info = attr_cast->get_tpm_version_info(attr_cast);
pts->set_tpm_version_info(pts, tpm_version_info);
pts->set_aik(pts, aik);
break;
}
-
+
/* PTS-based Attestation Evidence */
case TCG_PTS_SIMPLE_COMP_EVID:
{
/** TODO: Implement saving the PCR number, Hash Algo = communicated one,
* PCR transform (truncate SHA256, SHA384), PCR before and after values
- */
+ */
break;
}
-
+
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
- */
+ */
break;
}
-
+
case TCG_PTS_FILE_MEAS:
{
tcg_pts_attr_file_meas_t *attr_cast;
if (!attestation_state->check_off_request(attestation_state,
request_id, &file_id, &is_dir))
{
- DBG1(DBG_IMV, " no entry found for this request");
+ DBG1(DBG_IMV, " no entry found for this request");
break;
}
/* check hashes from database against measurements */
- e_hash = pts_db->create_hash_enumerator(pts_db,
+ e_hash = pts_db->create_hash_enumerator(pts_db,
platform_info, algo, file_id, is_dir);
if (!measurements->verify(measurements, e_hash, is_dir))
{
DBG1(DBG_IMV, " owner id: %d", entry->owner_id);
DBG1(DBG_IMV, " group id: %d", entry->group_id);
}
-
+
e->destroy(e);
-
+
break;
}
-
+
/* TODO: Not implemented yet */
case TCG_PTS_INTEG_MEAS_LOG:
/* Attributes using XML */
}
enumerator->destroy(enumerator);
pa_tnc_msg->destroy(pa_tnc_msg);
-
+
if (fatal_error)
{
pa_tnc_msg->build(pa_tnc_msg);
result = imv_attestation->send_message(imv_attestation, connection_id,
pa_tnc_msg->get_encoding(pa_tnc_msg));
+
pa_tnc_msg->destroy(pa_tnc_msg);
attr_list->destroy(attr_list);
+
return result;
}
+ DESTROY_IF(attr_list);
if (attestation_state->get_handshake_state(attestation_state) &
IMV_ATTESTATION_STATE_END)
return imv_attestation->provide_recommendation(imv_attestation,
connection_id);
}
-
+
return send_message(connection_id);
}
}
DESTROY_IF(pts_db);
DESTROY_IF(pts_credmgr);
- free(initiator_nonce.ptr);
+ free(initiator_nonce);
libpts_deinit();
return TNC_RESULT_NOT_INITIALIZED;
}
return imv_attestation->bind_functions(imv_attestation, bind_function);
-}
+}
\ No newline at end of file