*/
static pts_meas_algorithms_t supported_algorithms = 0;
+/**
+ * Supported PTS Diffie Hellman Groups
+ */
+static pts_dh_group_t supported_dh_groups = 0;
+
/**
* see section 3.7.1 of TCG TNC IF-IMC Specification 1.2
*/
{
return TNC_RESULT_FATAL;
}
+ if (!pts_probe_dh_groups(&supported_dh_groups))
+ {
+ return TNC_RESULT_FATAL;
+ }
imc_attestation = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE,
imc_id, actual_version);
if (!imc_attestation)
attr_list->insert_last(attr_list, attr);
break;
}
+ case TCG_PTS_DH_NONCE_PARAMS_REQ:
+ {
+ 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;
+
+ attr_cast = (tcg_pts_attr_dh_nonce_params_req_t*)attr;
+ min_nonce_len = attr_cast->get_min_nonce_len(attr_cast);
+ offered_dh_groups = attr_cast->get_dh_groups(attr_cast);
+
+ if ((supported_dh_groups & PTS_DH_GROUP_IKE20) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE20))
+ {
+ pts->set_dh_group(pts, PTS_DH_GROUP_IKE20);
+ }
+ else if ((supported_dh_groups & PTS_DH_GROUP_IKE19) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE19))
+ {
+ pts->set_dh_group(pts, PTS_DH_GROUP_IKE19);
+ }
+ else if ((supported_dh_groups & PTS_DH_GROUP_IKE14) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE14))
+ {
+ pts->set_dh_group(pts, PTS_DH_GROUP_IKE14);
+ }
+ else if ((supported_dh_groups & PTS_DH_GROUP_IKE5) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE5))
+ {
+ pts->set_dh_group(pts, PTS_DH_GROUP_IKE5);
+ }
+ else if ((supported_dh_groups & PTS_DH_GROUP_IKE2) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE2))
+ {
+ pts->set_dh_group(pts, PTS_DH_GROUP_IKE2);
+ }
+ else
+ {
+ attr_info = attr->get_value(attr);
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ TCG_PTS_DH_GRPS_NOT_SUPPORTED, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+
+ /* Send DH Nonce Parameters Response attribute */
+ selected_dh_group = pts->get_dh_group(pts);
+ /* TODO: Implement */
+
+ break;
+ }
+ case TCG_PTS_DH_NONCE_FINISH:
+ {
+ /* TODO: Implement */
+ break;
+ }
case TCG_PTS_MEAS_ALGO:
{
tcg_pts_attr_meas_algo_t *attr_cast;
- pts_meas_algorithms_t selected_algorithm;
-
+ pts_meas_algorithms_t offered_algorithms, selected_algorithm;
+
attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
- selected_algorithm = attr_cast->get_algorithms(attr_cast);
+ offered_algorithms = attr_cast->get_algorithms(attr_cast);
if ((supported_algorithms & PTS_MEAS_ALGO_SHA384) &&
- (selected_algorithm & PTS_MEAS_ALGO_SHA384))
+ (offered_algorithms & PTS_MEAS_ALGO_SHA384))
{
pts->set_meas_algorithm(pts, PTS_MEAS_ALGO_SHA384);
}
else if ((supported_algorithms & PTS_MEAS_ALGO_SHA256) &&
- (selected_algorithm & PTS_MEAS_ALGO_SHA256))
+ (offered_algorithms & PTS_MEAS_ALGO_SHA256))
{
pts->set_meas_algorithm(pts, PTS_MEAS_ALGO_SHA256);
}
else if ((supported_algorithms & PTS_MEAS_ALGO_SHA1) &&
- (selected_algorithm & PTS_MEAS_ALGO_SHA1))
+ (offered_algorithms & PTS_MEAS_ALGO_SHA1))
{
pts->set_meas_algorithm(pts, PTS_MEAS_ALGO_SHA1);
}
break;
}
/* TODO: Not implemented yet */
- case TCG_PTS_DH_NONCE_PARAMS_REQ:
- case TCG_PTS_DH_NONCE_FINISH:
case TCG_PTS_REQ_INTEG_MEAS_LOG:
/* Attributes using XML */
case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META:
#include <pen/pen.h>
#include <debug.h>
#include <credentials/credential_manager.h>
+#include <utils/linked_list.h>
/* IMV definitions */
*/
static pts_meas_algorithms_t supported_algorithms = 0;
+/**
+ * Supported PTS Diffie Hellman Groups
+ */
+static pts_dh_group_t supported_dh_groups = 0;
+
/**
* PTS file measurement database
*/
TNC_Version max_version,
TNC_Version *actual_version)
{
- char *hash_alg, *uri, *cadir;
+ char *hash_alg, *dh_group, *uri, *cadir;
if (imv_attestation)
{
{
return TNC_RESULT_FATAL;
}
+ if (!pts_probe_dh_groups(&supported_dh_groups))
+ {
+ return TNC_RESULT_FATAL;
+ }
imv_attestation = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE,
imv_id, actual_version);
if (!imv_attestation)
supported_algorithms &= ~PTS_MEAS_ALGO_SHA256;
}
+ /**
+ * Specify supported PTS Diffie Hellman Groups
+ *
+ * ike2: PTS_DH_GROUP_IKE2
+ * ike5: PTS_DH_GROUP_IKE2 | PTS_DH_GROUP_IKE5
+ * ike14: PTS_DH_GROUP_IKE2 | PTS_DH_GROUP_IKE5 | PTS_DH_GROUP_IKE14
+ * ike19: PTS_DH_GROUP_IKE2 | PTS_DH_GROUP_IKE5 | PTS_DH_GROUP_IKE14 | PTS_DH_GROUP_IKE19
+ * ike20: PTS_DH_GROUP_IKE2 | PTS_DH_GROUP_IKE5 | PTS_DH_GROUP_IKE14 | PTS_DH_GROUP_IKE19 | PTS_DH_GROUP_IKE20
+ *
+ * we expect the PTS-IMC to select the strongest supported group
+ */
+ dh_group = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imv-attestation.dh_group", "ike19");
+ if (!pts_update_supported_dh_groups(dh_group, &supported_dh_groups))
+ {
+ return TNC_RESULT_FATAL;
+ }
+
/* create a PTS credential manager */
pts_credmgr = credential_manager_create();
msg->add_attribute(msg, attr);
attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_DH_NONCE);
+ break;
+ }
+ case IMV_ATTESTATION_STATE_DH_NONCE:
+ {
+ bool request_sent = FALSE;
+
+ /* Jump to Measurement state if IMC has no TPM */
+ if(!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T))
+ {
+ attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_MEAS);
+ }
+ else if (!request_sent)
+ {
+ /* Send DH nonce parameters request attribute */
+ attr = tcg_pts_attr_dh_nonce_params_req_create(0, supported_dh_groups);
+ attr->set_noskip_flag(attr, TRUE);
+ msg->add_attribute(msg, attr);
+ request_sent = TRUE;
+ }
+ else if (request_sent)
+ {
+ /* Send DH nonce finish attribute */
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_MEAS);
+ }
+
break;
+
}
case IMV_ATTESTATION_STATE_MEAS:
IMV_ATTESTATION_STATE_COMP_EVID);
/* Does the PTS-IMC have TPM support? */
- if (pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T)
{
/* Send Get TPM Version attribute */
attr = tcg_pts_attr_get_tpm_version_info_create();
break;
}
- case IMV_ATTESTATION_STATE_IML:
- DBG1(DBG_IMV, "Attestation IMV has nothing to send: \"%s\"",
- handshake_state);
- return TNC_RESULT_FATAL;
default:
DBG1(DBG_IMV, "Attestation IMV is in unknown state: \"%s\"",
handshake_state);
pts->set_proto_caps(pts, flags);
break;
}
+ case TCG_PTS_DH_NONCE_PARAMS_RESP:
+ {
+ /* TODO: Implement */
+ break;
+ }
case TCG_PTS_MEAS_ALGO_SELECTION:
{
tcg_pts_attr_meas_algo_t *attr_cast;
}
/* TODO: Not implemented yet */
- case TCG_PTS_DH_NONCE_PARAMS_RESP:
case TCG_PTS_INTEG_MEAS_LOG:
/* Attributes using XML */
case TCG_PTS_TEMPL_REF_MANI_SET_META:
*/
enum imv_attestation_handshake_state_t {
IMV_ATTESTATION_STATE_INIT,
+ IMV_ATTESTATION_STATE_DH_NONCE,
IMV_ATTESTATION_STATE_MEAS,
IMV_ATTESTATION_STATE_COMP_EVID,
- IMV_ATTESTATION_STATE_IML,
IMV_ATTESTATION_STATE_END,
};
pts/pts_file_meas.h pts/pts_file_meas.c \
pts/pts_file_meta.h pts/pts_file_meta.c \
pts/pts_meas_algo.h pts/pts_meas_algo.c \
+ pts/pts_dh_group.h pts/pts_dh_group.c \
tcg/tcg_attr.h tcg/tcg_attr.c \
tcg/tcg_pts_attr_proto_caps.h tcg/tcg_pts_attr_proto_caps.c \
tcg/tcg_pts_attr_dh_nonce_params_req.h tcg/tcg_pts_attr_dh_nonce_params_req.c \
*/
pts_meas_algorithms_t algorithm;
+ /**
+ * PTS Diffie Hellman Group
+ */
+ pts_dh_group_t dh_group;
+
+ /**
+ * Contains a Diffie Hellman Nonce
+ */
+ chunk_t dh_nonce;
+
+ /**
+ * Contains a Diffie Hellman Public Value
+ */
+ chunk_t dh_public_value;
+
/**
* Platform and OS Info
*/
}
}
+METHOD(pts_t, get_dh_group, pts_dh_group_t,
+ private_pts_t *this)
+{
+ return this->dh_group;
+}
+
+METHOD(pts_t, set_dh_group, void,
+ private_pts_t *this, pts_dh_group_t group)
+{
+ diffie_hellman_group_t dh_group;
+
+ dh_group = pts_dh_group_to_strongswan_dh_group(group);
+ DBG2(DBG_PTS, "selected PTS Diffie Hellman Group is %N",
+ diffie_hellman_group_names, dh_group);
+ if (dh_group != MODP_NONE)
+ {
+ this->dh_group = dh_group;
+ }
+}
+
/**
* Print TPM 1.2 Version Info
*/
private_pts_t *this)
{
DESTROY_IF(this->aik);
+ free(this->dh_nonce.ptr);
+ free(this->dh_public_value.ptr);
free(this->platform_info);
free(this->tpm_version_info.ptr);
free(this);
.set_proto_caps = _set_proto_caps,
.get_meas_algorithm = _get_meas_algorithm,
.set_meas_algorithm = _set_meas_algorithm,
+ .get_dh_group = _get_dh_group,
+ .set_dh_group = _set_dh_group,
.get_platform_info = _get_platform_info,
.set_platform_info = _set_platform_info,
.get_tpm_version_info = _get_tpm_version_info,
},
.proto_caps = PTS_PROTO_CAPS_V,
.algorithm = PTS_MEAS_ALGO_SHA256,
+ .dh_group = PTS_DH_GROUP_IKE19,
);
if (is_imc)
#include "pts_meas_algo.h"
#include "pts_file_meas.h"
#include "pts_file_meta.h"
+#include "pts_dh_group.h"
#include <library.h>
*/
void (*set_meas_algorithm)(pts_t *this, pts_meas_algorithms_t algorithm);
+ /**
+ * Get PTS Diffie Hellman Group
+ *
+ * @return DH Group
+ */
+ pts_dh_group_t (*get_dh_group)(pts_t *this);
+
+ /**
+ * Set PTS Diffie Hellman Group
+ *
+ * @param dh_group DH Group
+ */
+ void (*set_dh_group)(pts_t *this, pts_dh_group_t dh_group);
+
/**
* Get Platform and OS Info
*
--- /dev/null
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "pts_dh_group.h"
+
+#include <debug.h>
+
+/**
+ * Described in header.
+ */
+bool pts_probe_dh_groups(pts_dh_group_t *groups)
+{
+ enumerator_t *enumerator;
+ diffie_hellman_group_t dh_group;
+ const char *plugin_name;
+ char format1[] = " %s PTS Diffie Hellman Group %N[%s] available";
+ char format2[] = " %s PTS Diffie Hellman Group %N[%s] not available";
+
+ *groups = 0;
+
+ enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &dh_group, &plugin_name))
+ {
+ DBG2(DBG_PTS, format1, "Following ", diffie_hellman_group_names, dh_group,
+ plugin_name);
+
+ if (dh_group == MODP_1024_BIT)
+ {
+ *groups |= PTS_DH_GROUP_IKE2;
+ DBG2(DBG_PTS, format1, "optional", diffie_hellman_group_names, dh_group,
+ plugin_name);
+ }
+ else if (dh_group == MODP_1536_BIT)
+ {
+ *groups |= PTS_DH_GROUP_IKE5;
+ DBG2(DBG_PTS, format1, "optional", diffie_hellman_group_names, dh_group,
+ plugin_name);
+ }
+ else if (dh_group == MODP_2048_BIT)
+ {
+ *groups |= PTS_DH_GROUP_IKE14;
+ DBG2(DBG_PTS, format1, "optional", diffie_hellman_group_names, dh_group,
+ plugin_name);
+ }
+ else if (dh_group == ECP_256_BIT)
+ {
+ *groups |= PTS_DH_GROUP_IKE19;
+ DBG2(DBG_PTS, format1, "mandatory", diffie_hellman_group_names, dh_group,
+ plugin_name);
+ }
+ else if (dh_group == ECP_384_BIT)
+ {
+ *groups |= PTS_DH_GROUP_IKE20;
+ DBG2(DBG_PTS, format1, "optional", diffie_hellman_group_names, dh_group,
+ plugin_name);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (*groups & PTS_DH_GROUP_IKE19)
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBG1(DBG_PTS, format2, "mandatory", diffie_hellman_group_names, ECP_256_BIT, plugin_name);
+ }
+
+ /* TODO: return FALSE : Elliptic Curves are not available */
+ return TRUE;
+
+}
+
+/**
+ * Described in header.
+ */
+bool pts_update_supported_dh_groups(char *dh_group, pts_dh_group_t *groups)
+{
+ if (strcaseeq(dh_group, "ike20"))
+ {
+ /* nothing to update, all groups are supported */
+ return TRUE;
+ }
+ else if (strcaseeq(dh_group, "ike19"))
+ {
+ /* remove DH Group 20 */
+ *groups = ~PTS_DH_GROUP_IKE20;
+ return TRUE;
+ }
+ else if (strcaseeq(dh_group, "ike14"))
+ {
+ /* remove DH Group 19 and 20 */
+ *groups = ~PTS_DH_GROUP_IKE20 | ~PTS_DH_GROUP_IKE19;
+ return TRUE;
+ }
+ else if (strcaseeq(dh_group, "ike5"))
+ {
+ /* remove DH Group 14, 19 and 20 */
+ *groups = ~PTS_DH_GROUP_IKE20 | ~PTS_DH_GROUP_IKE19
+ | ~PTS_DH_GROUP_IKE14;
+ return TRUE;
+ }
+ else if (strcaseeq(dh_group, "ike2"))
+ {
+ /* remove DH Group 5, 14, 19 and 20 */
+ *groups = ~PTS_DH_GROUP_IKE20 | ~PTS_DH_GROUP_IKE19 |
+ ~PTS_DH_GROUP_IKE14 | ~PTS_DH_GROUP_IKE5;
+ return TRUE;
+ }
+
+ DBG1(DBG_PTS, "Unknown DH Group: %s configured");
+ return FALSE;
+}
+
+/**
+ * Described in header.
+ */
+diffie_hellman_group_t pts_dh_group_to_strongswan_dh_group(pts_dh_group_t dh_group)
+{
+ switch (dh_group)
+ {
+ case PTS_DH_GROUP_IKE2:
+ return MODP_1024_BIT;
+ case PTS_DH_GROUP_IKE5:
+ return MODP_1536_BIT;
+ case PTS_DH_GROUP_IKE14:
+ return MODP_2048_BIT;
+ case PTS_DH_GROUP_IKE19:
+ return ECP_256_BIT;
+ case PTS_DH_GROUP_IKE20:
+ return ECP_384_BIT;
+ default:
+ return MODP_NONE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup pts_dh_group pts_dh_group
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_DH_GROUP_H_
+#define PTS_DH_GROUP_H_
+
+#include <library.h>
+#include <crypto/diffie_hellman.h>
+
+typedef enum pts_dh_group_t pts_dh_group_t;
+
+/**
+ * PTS Diffie Hellman Group Values
+ */
+enum pts_dh_group_t {
+ /** IKE Group 2 */
+ PTS_DH_GROUP_IKE2 = (1<<15),
+ /** IKE Group 5 */
+ PTS_DH_GROUP_IKE5 = (1<<14),
+ /** IKE Group 14 */
+ PTS_DH_GROUP_IKE14 = (1<<13),
+ /** IKE Group 19 */
+ PTS_DH_GROUP_IKE19 = (1<<12),
+ /** IKE Group 20 */
+ PTS_DH_GROUP_IKE20 = (1<<11),
+};
+
+/**
+ * Diffie-Hellman Group Values
+ * see section 3.8.6 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |1|2|3|4|5|R|R|R|R|R|R|R|R|R|R|R|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+/**
+ * Probe available PTS measurement algorithms
+ *
+ * @param groups set of available groups
+ * @return TRUE if mandatory group PTS_DH_GROUP_IKE19 is available
+ */
+bool pts_probe_dh_groups(pts_dh_group_t *groups);
+
+/**
+ * Update supported Diffie Hellman Groups according to configuration
+ *
+ * @param dh_group configured Diffie Hellman Group
+ * @param groups set of available groups
+ */
+bool pts_update_supported_dh_groups(char *dh_group, pts_dh_group_t *groups);
+
+/**
+ * Convert pts_dh_group_t to diffie_hellman_group_t
+ *
+ * @param dh_group PTS Diffie Hellman Group type
+ * @return libstrongswan diffie hellman group type
+ */
+diffie_hellman_group_t pts_dh_group_to_strongswan_dh_group(pts_dh_group_t dh_group);
+
+#endif /** PTS_DH_GROUP_H_ @}*/
case TCG_PTS_PROTO_CAPS:
return tcg_pts_attr_proto_caps_create_from_data(value, FALSE);
case TCG_PTS_DH_NONCE_PARAMS_REQ:
- return tcg_pts_attr_dh_nonce_params_req_create(value);
+ return tcg_pts_attr_dh_nonce_params_req_create_from_data(value);
case TCG_PTS_DH_NONCE_PARAMS_RESP:
- return tcg_pts_attr_dh_nonce_params_resp_create(value);
+ return tcg_pts_attr_dh_nonce_params_resp_create_from_data(value);
case TCG_PTS_DH_NONCE_FINISH:
- return tcg_pts_attr_dh_nonce_finish_create(value);
+ return tcg_pts_attr_dh_nonce_finish_create_from_data(value);
case TCG_PTS_MEAS_ALGO:
return tcg_pts_attr_meas_algo_create_from_data(value, FALSE);
case TCG_PTS_MEAS_ALGO_SELECTION:
bio_writer_t *writer;
writer = bio_writer_create(PTS_DH_NONCE_PARAMS_REQ_SIZE);
- writer->write_uint8(writer, PTS_DH_NONCE_PARAMS_REQ_RESERVED);
- writer->write_uint8(writer, this->min_nonce_len);
- writer->write_uint8(writer, this->dh_groups);
+ writer->write_uint8 (writer, PTS_DH_NONCE_PARAMS_REQ_RESERVED);
+ writer->write_uint8 (writer, this->min_nonce_len);
+ writer->write_uint16(writer, this->dh_groups);
this->value = chunk_clone(writer->get_buf(writer));
writer->destroy(writer);
#define TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_
typedef struct tcg_pts_attr_dh_nonce_params_req_t tcg_pts_attr_dh_nonce_params_req_t;
-typedef enum pts_dh_group_t pts_dh_group_t;
#include "tcg_attr.h"
#include "pa_tnc/pa_tnc_attr.h"
-
-/**
- * PTS Diffie Hellman Group Values
- */
-enum pts_dh_group_t {
- /** IKE Group 2 */
- PTS_DH_GROUP_IKE2 = (1<<15),
- /** IKE Group 5 */
- PTS_DH_GROUP_IKE5 = (1<<14),
- /** IKE Group 14 */
- PTS_DH_GROUP_IKE14 = (1<<13),
- /** IKE Group 19, Elliptic curves using NIST 256 bit prime modules */
- PTS_DH_GROUP_IKE19 = (1<<12),
- /** IKE Group 20, Elliptic curves using NIST 384 bit prime modules */
- PTS_DH_GROUP_IKE20 = (1<<11),
-};
+#include "pts/pts_dh_group.h"
/**
* Class implementing the TCG PTS DH Nonce Parameters Request Attribute
#include "tcg_attr.h"
#include "pa_tnc/pa_tnc_attr.h"
-#include "tcg_pts_attr_dh_nonce_params_req.h"
+#include "pts/pts_dh_group.h"
#include "pts/pts_meas_algo.h"
/**