summaryrefslogtreecommitdiff
path: root/cesar/cp2/msg
diff options
context:
space:
mode:
authorlaranjeiro2008-06-27 14:31:20 +0000
committerlaranjeiro2008-06-27 14:31:20 +0000
commit0f0cda2c1b7f697f114353254392ad82fcc4c306 (patch)
tree7b66928a63b266d55076c1a770d93f8ef25fac4f /cesar/cp2/msg
parentb7868b19ee39c159cb34aca2fb91d20e550ba9f9 (diff)
cp2/msg: Tested the CM_SET_KEY.REQ, CM_SET_KEY.CNF, CM_GET_KEY.REQ and CM_GET_KEY.CNF
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@2467 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/cp2/msg')
-rw-r--r--cesar/cp2/msg/inc/cm_get_key.h2
-rw-r--r--cesar/cp2/msg/src/msg.c42
-rw-r--r--cesar/cp2/msg/src/msg_cm.c252
-rw-r--r--cesar/cp2/msg/test/Makefile5
-rw-r--r--cesar/cp2/msg/test/src/msg_cm.c321
5 files changed, 506 insertions, 116 deletions
diff --git a/cesar/cp2/msg/inc/cm_get_key.h b/cesar/cp2/msg/inc/cm_get_key.h
index a1f74adbcc..59ffcc4d51 100644
--- a/cesar/cp2/msg/inc/cm_get_key.h
+++ b/cesar/cp2/msg/inc/cm_get_key.h
@@ -26,7 +26,7 @@ enum cp_msg_cm_get_key_cnf_result_t
struct cp_msg_cm_get_key_req_t
{
/** Request type: direct or relayed. */
- bool relayed;
+ uint relayed;
/** Requested key type. */
enum cp_msg_key_type_t key_type;
/** NID. */
diff --git a/cesar/cp2/msg/src/msg.c b/cesar/cp2/msg/src/msg.c
index d4cc0825d4..ccdf5ec58e 100644
--- a/cesar/cp2/msg/src/msg.c
+++ b/cesar/cp2/msg/src/msg.c
@@ -32,6 +32,22 @@
#include <stdio.h>
+/** Padd the MME to reach the minimal length. */
+static void
+cp_msg_mme_pad (cp_t *ctx, cp_mme_tx_t *msg)
+{
+ uint data;
+
+ dbg_assert (ctx);
+ dbg_assert (msg);
+
+ data = 0;
+ while (bitstream_bytes_processed (&msg->bitstream) < ETH_PACKET_MIN_SIZE)
+ {
+ bitstream_access (&msg->bitstream, &data, 8);
+ }
+}
+
/**
* Initialise the MSG module.
* \param ctx control plane context
@@ -455,12 +471,14 @@ cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme)
* + The MME header.
* - 1 for the alignment.
*/
+ mme->length = (bitstream_bytes_processed (&mme->bitstream)
+ - mme->payload_offset);
word = *((uint *) (mme->p_mme + (mme->peer.vlan_tag ?
HPAV_MME_HEADER_LEN_WITH_VLAN:
HPAV_MME_HEADER)
+ 21));
word &= 0xFF0000FF;
- word |= mme->length << 8;
+ word |= mme->length << 8;
*((uint*)(mme->p_mme + (mme->peer.vlan_tag ?
HPAV_MME_HEADER_LEN_WITH_VLAN:
HPAV_MME_HEADER)
@@ -488,7 +506,8 @@ cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme)
bitstream_access (&mme->bitstream, &mme->prun.pmn, 8);
/* Padding. crc_value variable used as Padding. */
- padding_len = (mme->length + mme->rf_len) / 16;
+ padding_len = 16 - ((mme->length + mme->rf_len
+ + CP_MSG_ENCRYPTED_DATA_FOOTER_SIZE) % 16);
word = 0;
for ( i = 0; i < padding_len; i++)
@@ -498,12 +517,11 @@ cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme)
bitstream_access (&mme->bitstream, &mme->rf_len, 8);
/* Finalise the bitstream. */
+ cp_msg_mme_pad (ctx, mme);
bitstream_finalise (&mme->bitstream);
/* AES encryption. */
- enc_length = (mme->peer.vlan_tag ? HPAV_MME_HEADER_LEN_WITH_VLAN :
- HPAV_MME_HEADER)
- + mme->length
+ enc_length = mme->length
+ mme->rf_len
+ CP_MSG_ENCRYPTED_DATA_FOOTER_SIZE
+ padding_len;
@@ -517,6 +535,7 @@ cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme)
else
{
/* Finalise the bitstream. */
+ cp_msg_mme_pad (ctx, mme);
bitstream_finalise (&mme->bitstream);
}
@@ -597,11 +616,11 @@ cp_msg_mme_read_header_enc (cp_t *ctx, cp_mme_rx_t *mme)
uint payload_offset;
uint rf_len;
- mac_t oda;
- mac_t osa;
- uint vlan_tag;
- uint mtype;
- uint mmv;
+ mac_t oda = 0;
+ mac_t osa = 0;
+ uint vlan_tag = 0;
+ uint mtype = 0;
+ uint mmv = 0;
aes_context aes;
cp_sta_own_data_t *owndata;
@@ -645,8 +664,7 @@ cp_msg_mme_read_header_enc (cp_t *ctx, cp_mme_rx_t *mme)
+ (mme->peer.vlan_tag ? HPAV_MME_HEADER_LEN_WITH_VLAN :
HPAV_MME_HEADER);
- enc_length = full_length - payload_offset +
- (16 - ((full_length - payload_offset) % 16));
+ enc_length = full_length - payload_offset;
aes_set_key (&aes, (u8 *) &mme->iv_uuid);
aes_cbc_decrypt (&aes, (u8*) &mme->iv_uuid,
diff --git a/cesar/cp2/msg/src/msg_cm.c b/cesar/cp2/msg/src/msg_cm.c
index 5b7164378a..a5d6cb9ea8 100644
--- a/cesar/cp2/msg/src/msg_cm.c
+++ b/cesar/cp2/msg/src/msg_cm.c
@@ -44,6 +44,36 @@ cp_msg_cm_unassociated_sta_ind_receive (cp_t *ctx, cp_mme_rx_t *mme,
cp_nid_t *nid, u8 *cco_cap);
/**
+ * Access to the data in the buffer.
+ * \param stream the stream to access the buffer.
+ * \param prun the protocol run.
+ * \param data the data.
+ */
+static void
+cp_msg_cm_set_key_req_access (bitstream_t *stream,
+ cp_secu_protocol_run_t *prun,
+ cp_msg_cm_set_key_req_t *data)
+{
+ uint i;
+
+ dbg_assert (stream);
+ dbg_assert (prun);
+ dbg_assert (data);
+
+ bitstream_access (stream, &data->key_type, 8);
+ bitstream_access (stream, &prun->my_nonce, 32);
+ bitstream_access (stream, &prun->your_nonce, 32);
+ bitstream_access (stream, &prun->pid, 8);
+ bitstream_access (stream, &prun->prn, 16);
+ bitstream_access (stream, &prun->pmn, 8);
+ bitstream_write (stream, CP_CCO_LEVEL, 8);
+ bitstream_access (stream, &data->nid, 56);
+ bitstream_access (stream, &data->new_eks, 8);
+ for (i = 0; i < 4; i ++)
+ bitstream_access (stream, &data->new_key.key[i], 32);
+}
+
+/**
* Send a CM_SET_KEY.REQ.
* \param ctx control plane context
* \param peer peer information
@@ -58,7 +88,6 @@ cp_msg_cm_set_key_req_send (cp_t *ctx, cp_mme_peer_t *peer,
const cp_msg_cm_set_key_req_t *data)
{
cp_mme_tx_t *msg;
- uint unused;
dbg_assert (peer);
dbg_assert (prun);
@@ -68,16 +97,9 @@ cp_msg_cm_set_key_req_send (cp_t *ctx, cp_mme_peer_t *peer,
prun);
dbg_check (msg);
- /* TODO : Relay == 0 for this time, It shall be updated once we manage
- * the relayed MME. */
- unused = 0;
- bitstream_access (&msg->bitstream, &unused /* Direct. */, 8);
- bitstream_access (&msg->bitstream, (u8 *) &data->key_type, 8);
- bitstream_access (&msg->bitstream, (cp_nid_t *) &data->nid, 56);
- bitstream_access (&msg->bitstream, (uint *) &prun->my_nonce, 32);
- bitstream_access (&msg->bitstream, (u8 *) &prun->pid, 8);
- bitstream_access (&msg->bitstream, (u16*) &prun->prn, 16);
- bitstream_access (&msg->bitstream, (u8 *) &prun->pmn, 8);
+ cp_msg_cm_set_key_req_access (&msg->bitstream,
+ (cp_secu_protocol_run_t *) prun,
+ (cp_msg_cm_set_key_req_t *) data);
/* request type is HASH Key. */
/* if (data->key_type == CP_MSG_KEY_HASH_KEY)
@@ -101,19 +123,13 @@ bool
cp_msg_cm_set_key_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
cp_msg_cm_set_key_req_t *data)
{
- uint unused;
cp_net_t *net;
dbg_assert (ctx);
dbg_assert (mme);
dbg_assert (data);
- bitstream_access (&mme->bitstream, &unused /* Direct. */, 8);
- bitstream_access (&mme->bitstream, (u8*) &data->key_type, 8);
- bitstream_access (&mme->bitstream, (cp_nid_t*) &data->nid, 56);
- bitstream_access (&mme->bitstream, (uint*) &mme->prun.your_nonce, 32);
- bitstream_access (&mme->bitstream, (u8*) &mme->prun.pid, 8);
- bitstream_access (&mme->bitstream, (u16*) &mme->prun.prn, 16);
- bitstream_access (&mme->bitstream, (u8*) &mme->prun.pmn, 8);
+ cp_msg_cm_set_key_req_access (&mme->bitstream, &mme->prun, data);
+ XCH(mme->prun.my_nonce, mme->prun.your_nonce);
/* Verify some data. */
net = cp_sta_mgr_get_our_avln (ctx);
@@ -127,6 +143,30 @@ cp_msg_cm_set_key_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
}
/**
+ * CM_SET_KEY.CNF access.
+ * \param stream the bitstream context.
+ * \param prun the protocol run context.
+ * \param data the structure to use to read or write the data.
+ */
+static void
+cp_msg_cm_set_key_cnf_access (bitstream_t *stream,
+ cp_secu_protocol_run_t *prun,
+ cp_msg_cm_set_key_cnf_t *data)
+{
+ dbg_assert (stream);
+ dbg_assert (prun);
+ dbg_assert (data);
+
+ bitstream_access (stream, &data->result, 8);
+ bitstream_access (stream, &prun->my_nonce, 32);
+ bitstream_access (stream, &prun->your_nonce, 32);
+ bitstream_access (stream, &prun->pid, 8);
+ bitstream_access (stream, &prun->prn, 16);
+ bitstream_access (stream, &prun->pmn, 8);
+ bitstream_access (stream, &data->cco_cap, 8);
+}
+
+/**
* Send a CM_SET_KEY.CNF.
* \param ctx control plane context
* \param peer peer information
@@ -152,13 +192,9 @@ cp_msg_cm_set_key_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
msg = cp_msg_mme_init (ctx, peer, CM_SET_KEY_CNF);
dbg_check (msg);
- bitstream_access (&msg->bitstream, (u8*) &data->result, 8);
- bitstream_access (&msg->bitstream, (uint*) &prun->my_nonce, 32);
- bitstream_access (&msg->bitstream, (uint*) &prun->your_nonce, 32);
- bitstream_access (&msg->bitstream, (u8*) &prun->pid, 8);
- bitstream_access (&msg->bitstream, (u16*) &prun->prn, 16);
- bitstream_access (&msg->bitstream, (u8*) &prun->pmn, 8);
- bitstream_access (&msg->bitstream, (u8*) &data->cco_cap, 8);
+ cp_msg_cm_set_key_cnf_access (&msg->bitstream,
+ (cp_secu_protocol_run_t *) prun,
+ (cp_msg_cm_set_key_cnf_t *) data);
cp_msg_mme_send (ctx, msg);
}
@@ -180,13 +216,10 @@ cp_msg_cm_set_key_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
dbg_assert (mme);
dbg_assert (data);
- bitstream_access (&mme->bitstream, &data->result, 8);
- bitstream_access (&mme->bitstream, &mme->prun.your_nonce, 32);
- bitstream_access (&mme->bitstream, &mme->prun.my_nonce, 32);
- bitstream_access (&mme->bitstream, &mme->prun.pid, 8);
- bitstream_access (&mme->bitstream, &mme->prun.prn, 16);
- bitstream_access (&mme->bitstream, &mme->prun.pmn, 8);
- bitstream_access (&mme->bitstream, &data->cco_cap, 8);
+ cp_msg_cm_set_key_cnf_access (&mme->bitstream,
+ &mme->prun,
+ data);
+ XCH (mme->prun.my_nonce, mme->prun.your_nonce);
/* Verify data. */
if ((data->result > CP_MSG_CM_SET_KEY_CNF_RESULT_NB)
@@ -196,6 +229,37 @@ cp_msg_cm_set_key_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
}
/**
+ * CM_GET_KEY.REQ Access.
+ * \param stream the bitstream context.
+ * \param prun the protocol run context.
+ * \param data the structure to use to read or write the data.
+ */
+static void
+cp_msg_cm_get_key_req_access (bitstream_t *stream,
+ cp_secu_protocol_run_t *prun,
+ cp_msg_cm_get_key_req_t *data)
+{
+ uint i;
+ dbg_assert (stream);
+ dbg_assert (prun);
+ dbg_assert (data);
+
+ bitstream_access (stream, &data->relayed, 8);
+ bitstream_access (stream, &data->key_type, 8);
+ bitstream_access (stream, &data->nid, 56);
+ bitstream_access (stream, &prun->my_nonce, 8);
+ bitstream_access (stream, &prun->pid, 8);
+ bitstream_access (stream, &prun->prn, 16);
+ bitstream_access (stream, &prun->pmn, 8);
+
+ if (data->key_type == CP_MSG_KEY_HASH_KEY)
+ {
+ for (i = 0; i < CP_HASH_KEY_SIZE; i++);
+ bitstream_access (stream, &data->hash_key[i], 8);
+ }
+}
+
+/**
* Send a CM_GET_KEY.REQ.
* \param ctx control plane context
* \param peer peer information
@@ -210,7 +274,6 @@ cp_msg_cm_get_key_req_send (cp_t *ctx, cp_mme_peer_t *peer,
const cp_msg_cm_get_key_req_t *data)
{
cp_mme_tx_t *mme;
- uint usefull;
dbg_assert (ctx);
dbg_assert (peer);
dbg_assert (prun);
@@ -223,20 +286,10 @@ cp_msg_cm_get_key_req_send (cp_t *ctx, cp_mme_peer_t *peer,
prun);
dbg_check (mme);
- usefull = data->relayed;
- bitstream_access (&mme->bitstream, (uint*) &usefull, 8);
- bitstream_access (&mme->bitstream, (u8*) &data->key_type, 8);
- bitstream_access (&mme->bitstream, (cp_nid_t*) &data->nid, 56);
- bitstream_access (&mme->bitstream, (u8*) &prun->my_nonce, 8);
- bitstream_access (&mme->bitstream, (u8*) &prun->pid, 8);
- bitstream_access (&mme->bitstream, (u16*) &prun->prn, 16);
- bitstream_access (&mme->bitstream, (u8*) &prun->pmn, 8);
+ cp_msg_cm_get_key_req_access (&mme->bitstream,
+ (cp_secu_protocol_run_t *) prun,
+ (cp_msg_cm_get_key_req_t *) data);
- if (data->key_type == CP_MSG_KEY_HASH_KEY)
- {
- for (usefull = 0; usefull < CP_HASH_KEY_SIZE; usefull++);
- bitstream_access (&mme->bitstream, (u8*) &data->hash_key[usefull], 8);
- }
cp_msg_mme_send (ctx, mme);
}
@@ -254,24 +307,14 @@ bool
cp_msg_cm_get_key_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
cp_msg_cm_get_key_req_t *data)
{
- uint usefull;
cp_net_t *net;
dbg_assert (mme);
dbg_assert (data);
- bitstream_access (&mme->bitstream, (uint*) &usefull, 8);
- bitstream_access (&mme->bitstream, (u8*) &data->key_type, 8);
- bitstream_access (&mme->bitstream, (cp_nid_t*) &data->nid, 56);
- bitstream_access (&mme->bitstream, (u8*) &mme->prun.your_nonce, 8);
- bitstream_access (&mme->bitstream, (u8*) &mme->prun.pid, 8);
- bitstream_access (&mme->bitstream, (u16*) &mme->prun.prn, 16);
- bitstream_access (&mme->bitstream, (u8*) &mme->prun.pmn, 8);
-
- if (data->key_type == CP_MSG_KEY_HASH_KEY)
- {
- for (usefull = 0; usefull < CP_HASH_KEY_SIZE; usefull++);
- bitstream_access (&mme->bitstream, &data->hash_key[usefull], 8);
- }
+ cp_msg_cm_get_key_req_access (&mme->bitstream,
+ &mme->prun,
+ data);
+ XCH (mme->prun.my_nonce, mme->prun.your_nonce);
/* Verify */
net = cp_sta_mgr_get_our_avln (ctx);
@@ -284,6 +327,45 @@ cp_msg_cm_get_key_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
}
/**
+ * CM_GET_KEY_CNF_access.
+ * \param stream the bitstream context.
+ * \param prun the protocol run context.
+ * \param data the structure to use to read or write the data.
+ */
+static void
+cp_msg_cm_get_key_cnf_access (bitstream_t *stream,
+ cp_secu_protocol_run_t *prun,
+ cp_msg_cm_get_key_cnf_t *data)
+{
+ uint i;
+
+ dbg_assert (stream);
+ dbg_assert (prun);
+ dbg_assert (data);
+
+ bitstream_access (stream, &data->result, 8);
+ bitstream_access (stream, &data->key_type, 8);
+ bitstream_access (stream, &prun->my_nonce, 32);
+ bitstream_access (stream, &prun->your_nonce, 32);
+ bitstream_access (stream, &data->nid, 56);
+ bitstream_access (stream, &data->eks, 8);
+ bitstream_access (stream, &prun->pid, 8);
+ bitstream_access (stream, &prun->prn, 16);
+ bitstream_access (stream, &prun->pmn, 8);
+
+ if (data->key_type == CP_MSG_KEY_HASH_KEY)
+ {
+ for ( i = 0; i < CP_HASH_KEY_SIZE; i++)
+ bitstream_access (stream, &data->hash_key[i], 8);
+ }
+ else if (data->key_type != CP_MSG_KEY_NONCE_ONLY)
+ {
+ for ( i = 0; i < sizeof (cp_key_t); i++)
+ bitstream_access (stream, &data->hash_key[i], 8);
+ }
+}
+
+/**
* Send a CM_GET_KEY.CNF.
* \param ctx control plane context
* \param peer peer information
@@ -298,7 +380,6 @@ cp_msg_cm_get_key_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
const cp_msg_cm_get_key_cnf_t *data)
{
cp_mme_tx_t *msg;
- uint i;
dbg_assert (ctx);
dbg_assert (peer);
@@ -310,26 +391,10 @@ cp_msg_cm_get_key_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
msg = cp_msg_mme_init_encrypted (ctx, peer, CM_GET_KEY_CNF, peks, prun);
dbg_check (msg);
- bitstream_access (&msg->bitstream, (u8*) &data->result, 8);
- bitstream_access (&msg->bitstream, (u8*) &data->key_type, 8);
- bitstream_access (&msg->bitstream, (uint*) &prun->my_nonce, 32);
- bitstream_access (&msg->bitstream, (uint*) &prun->your_nonce, 32);
- bitstream_access (&msg->bitstream, (cp_nid_t*) &data->nid, 56);
- bitstream_access (&msg->bitstream, (u8*) &data->eks, 8);
- bitstream_access (&msg->bitstream, (u8*) &prun->pid, 8);
- bitstream_access (&msg->bitstream, (u16*) &prun->prn, 16);
- bitstream_access (&msg->bitstream, (u8*) &prun->pmn, 8);
+ cp_msg_cm_get_key_cnf_access (&msg->bitstream,
+ (cp_secu_protocol_run_t *) prun,
+ (cp_msg_cm_get_key_cnf_t *) data);
- if (data->key_type == CP_MSG_KEY_HASH_KEY)
- {
- for ( i = 0; i < CP_HASH_KEY_SIZE; i++)
- bitstream_access (&msg->bitstream, (u8*) &data->hash_key[i], 8);
- }
- else if (data->key_type != CP_MSG_KEY_NONCE_ONLY)
- {
- for ( i = 0; i < sizeof (cp_key_t); i++)
- bitstream_access (&msg->bitstream, (u8*) &data->hash_key[i], 8);
- }
cp_msg_mme_send (ctx, msg);
}
@@ -347,33 +412,16 @@ bool
cp_msg_cm_get_key_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
cp_msg_cm_get_key_cnf_t *data)
{
- uint i;
cp_net_t *net;
dbg_assert (ctx);
dbg_assert (mme);
dbg_assert (data);
- bitstream_access (&mme->bitstream, &data->result, 8);
- bitstream_access (&mme->bitstream, &data->key_type, 8);
- bitstream_access (&mme->bitstream, &mme->prun.my_nonce, 32);
- bitstream_access (&mme->bitstream, &mme->prun.your_nonce, 32);
- bitstream_access (&mme->bitstream, &data->nid, 56);
- bitstream_access (&mme->bitstream, &data->eks, 8);
- bitstream_access (&mme->bitstream, &mme->prun.pid, 8);
- bitstream_access (&mme->bitstream, &mme->prun.prn, 16);
- bitstream_access (&mme->bitstream, &mme->prun.pmn, 8);
-
- if (data->key_type == CP_MSG_KEY_HASH_KEY)
- {
- for ( i = 0; i < CP_HASH_KEY_SIZE; i++)
- bitstream_access (&mme->bitstream, &data->hash_key[i], 8);
- }
- else if (data->key_type != CP_MSG_KEY_NONCE_ONLY)
- {
- for ( i = 0; i < sizeof (cp_key_t); i++)
- bitstream_access (&mme->bitstream, &data->hash_key[i], 8);
- }
+ cp_msg_cm_get_key_cnf_access (&mme->bitstream,
+ &mme->prun,
+ data);
+ XCH (mme->prun.my_nonce, mme->prun.your_nonce);
/* Verify data. */
net = cp_sta_mgr_get_our_avln (ctx);
diff --git a/cesar/cp2/msg/test/Makefile b/cesar/cp2/msg/test/Makefile
index 030006e978..34083f11a4 100644
--- a/cesar/cp2/msg/test/Makefile
+++ b/cesar/cp2/msg/test/Makefile
@@ -2,7 +2,7 @@ BASE = ../../..
INCLUDES = cp2/msg/test/overide/
-HOST_PROGRAMS = test-msg-read-header test-msg test-msg-cc
+HOST_PROGRAMS = test-msg-read-header test-msg test-msg-cc test-msg-cm
test-msg-read-header_SOURCES = test-msg-read-header.c interface_stub.c \
cp_cl_interface_stub.c cl_stub.c
@@ -15,4 +15,7 @@ test-msg_MODULES = lib cp2/msg cp2/secu cp2/sta/mgr
test-msg-cc_SOURCES = msg_cc.c interface_stub.c cl_stub.c
test-msg-cc_MODULES = lib cp2/msg cp2/sta/mgr cp2/secu
+test-msg-cm_SOURCES = msg_cm.c interface_stub.c cl_stub.c
+test-msg-cm_MODULES = lib cp2/msg cp2/sta/mgr cp2/secu
+
include $(BASE)/common/make/top.mk
diff --git a/cesar/cp2/msg/test/src/msg_cm.c b/cesar/cp2/msg/test/src/msg_cm.c
new file mode 100644
index 0000000000..4842c44804
--- /dev/null
+++ b/cesar/cp2/msg/test/src/msg_cm.c
@@ -0,0 +1,321 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp2/msg/test/src/msg_cm.c
+ * \brief Test the MSG_CM Family functions.
+ * \ingroup cp2_msg
+ *
+ */
+#include "common/std.h"
+
+#include "common/defs/ethernet.h"
+#include "common/defs/homeplugAV.h"
+
+#include "lib/test.h"
+#include "lib/swap.h"
+#include "lib/bitstream.h"
+
+#include "cp2/cp.h"
+#include "cp2/msg/msg.h"
+#include "cp2/sta/mgr/sta_mgr.h"
+#include "cp2/sta/mgr/sta_own_data.h"
+
+#include "cp2/inc/context.h"
+#include "cp2/msg/inc/msg.h"
+
+struct mme_header_t
+{
+ mac_t oda;
+ mac_t osa;
+ uint vlan;
+ uint mtype;
+ uint mmv;
+ uint mmtype;
+ uint fmi_inf;
+ uint fmi_mi;
+ uint fmi_ssn;
+};
+typedef struct mme_header_t mme_header_t;
+
+static u8 buffer[2048] __attribute__((aligned(2048)));
+static uint buffer_len;
+cp_t cp;
+mac_config_t mac_config;
+bitstream_t stream;
+mme_header_t header;
+mac_t own_mac_addr = 0x123456789ABCull;
+
+mme_header_t expected;
+test_t test;
+
+void
+test_case_cm_set_key (void)
+{
+ cp_mme_peer_t peer;
+ cp_nid_t nid;
+ cp_secu_protocol_run_t prun;
+ cp_msg_cm_set_key_req_t key_req;
+ cp_msg_cm_set_key_cnf_t key_cnf;
+ cp_mme_rx_t *msg;
+ uint fmi;
+ cp_sta_own_data_t *own_data;
+
+ test_case_begin (test, "CM_SET_KEY.REQ");
+
+ peer.mac = 0x23456789ABCDull;
+ peer.vlan_tag = 0x0;
+ peer.tei = 0xA;
+ peer.all_sta = false;
+
+ nid = 0x123456789ABCDEull;
+
+ prun.pid = 2;
+ prun.pmn = 2;
+ prun.prn = 2;
+ prun.my_nonce = 0x12;
+ prun.your_nonce = 0x13;
+
+ key_req.key_type = CP_MSG_KEY_DAK;
+ key_req.cco_cap = CP_CCO_LEVEL;
+ key_req.new_eks = 2;
+ key_req.new_key.key[0] = 0;
+ key_req.new_key.key[1] = 1;
+ key_req.new_key.key[2] = 2;
+ key_req.new_key.key[3] = 3;
+ key_req.nid = nid;
+
+ cp_msg_cm_set_key_req_send (&cp, &peer, 2, &prun, &key_req);
+
+ // Read the MME.
+ own_data = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_mac_address (own_data, peer.mac, &cp);
+
+ msg = cp_msg_mme_read_header (&cp, (u8*)buffer, buffer_len, 0xa, &fmi);
+ cp_msg_mme_read_header_enc (&cp, msg);
+
+ cp_msg_cm_set_key_req_receive (&cp, msg, &key_req);
+ test_begin (test, "Verify")
+ {
+ test_fail_if (key_req.key_type != CP_MSG_KEY_DAK, "Wrong key type");
+ test_fail_if (key_req.cco_cap != CP_CCO_LEVEL, "Wrong CCo level");
+ test_fail_if (key_req.nid != nid, "Wrong NID");
+ test_fail_if (msg->prun.pid != prun.pid, "Wrong PID");
+ test_fail_if (msg->prun.prn != prun.prn, "Wrong PRN");
+ test_fail_if (msg->prun.pmn != prun.pmn, "Wrong PMN");
+ test_fail_if (msg->prun.your_nonce != prun.my_nonce , "Wrong nonce");
+ }
+ test_end;
+
+ slab_release (msg);
+
+ test_case_begin (test, "CM_SET_KEY.CNF");
+
+ cp_sta_own_data_set_mac_address (own_data, own_mac_addr, &cp);
+ peer.mac = 0x23456789ABCDull;
+ peer.vlan_tag = 0x0;
+ peer.tei = 0xA;
+ peer.all_sta = false;
+
+ nid = 0x123456789ABCDEull;
+
+ prun.pid = 2;
+ prun.pmn = 2;
+ prun.prn = 2;
+ prun.my_nonce = 0x12;
+ prun.your_nonce = 0x13;
+
+ key_cnf.result = CP_MSG_CM_SET_KEY_CNF_RESULT_SUCCESS;
+ key_cnf.cco_cap = CP_CCO_LEVEL;
+
+ cp_msg_cm_set_key_cnf_send (&cp, &peer, 2, &prun, &key_cnf);
+
+ // Read the MME.
+ cp_sta_own_data_set_mac_address (own_data, peer.mac, &cp);
+
+ msg = cp_msg_mme_read_header (&cp, (u8*)buffer, buffer_len, 0xa, &fmi);
+
+ cp_msg_cm_set_key_cnf_receive (&cp, msg, &key_cnf);
+ test_begin (test, "Verify")
+ {
+ test_fail_if (key_cnf.result != CP_MSG_CM_SET_KEY_CNF_RESULT_SUCCESS,
+ "Wrong result type");
+ test_fail_if (key_cnf.cco_cap != CP_CCO_LEVEL, "Wrong CCo level");
+ test_fail_if (msg->prun.pid != prun.pid, "Wrong PID");
+ test_fail_if (msg->prun.prn != prun.prn, "Wrong PRN");
+ test_fail_if (msg->prun.pmn != prun.pmn, "Wrong PMN");
+ test_fail_if (msg->prun.your_nonce != prun.my_nonce , "Wrong nonce");
+ }
+ test_end;
+
+ slab_release (msg);
+}
+
+void
+test_case_cm_get_key (void)
+{
+ cp_mme_peer_t peer;
+ cp_nid_t nid;
+ cp_secu_protocol_run_t prun;
+ cp_mme_rx_t *msg;
+ uint fmi;
+ cp_sta_own_data_t *own_data;
+ cp_msg_cm_get_key_req_t data;
+ cp_msg_cm_get_key_cnf_t cnf;
+
+ test_case_begin (test, "CM_SET_GET_KEY.REQ");
+
+ peer.mac = 0x23456789ABCDull;
+ peer.vlan_tag = 0x0;
+ peer.tei = 0xA;
+ peer.all_sta = false;
+
+ nid = 0x123456789ABCDEull;
+
+ prun.pid = 2;
+ prun.pmn = 2;
+ prun.prn = 2;
+ prun.my_nonce = 0x12;
+ prun.your_nonce = 0x13;
+
+ data.relayed = false;
+ data.key_type = CP_MSG_KEY_DAK;
+ data.nid = nid;
+
+ cp_msg_cm_get_key_req_send (&cp, &peer, 2, &prun, &data);
+
+ // Read the MME.
+ own_data = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_mac_address (own_data, peer.mac, &cp);
+
+ msg = cp_msg_mme_read_header (&cp, (u8*)buffer, buffer_len, 0xa, &fmi);
+ cp_msg_mme_read_header_enc (&cp, msg);
+
+ cp_msg_cm_get_key_req_receive (&cp, msg, &data);
+ test_begin (test, "Verify")
+ {
+ test_fail_if (data.relayed != false, "Wrong relayed data");
+ test_fail_if (data.key_type != CP_MSG_KEY_DAK, "Wrong key type");
+ test_fail_if (data.nid != nid, "Wrong NID");
+ test_fail_if (msg->prun.pid != prun.pid, "Wrong PID");
+ test_fail_if (msg->prun.prn != prun.prn, "Wrong PRN");
+ test_fail_if (msg->prun.pmn != prun.pmn, "Wrong PMN");
+ test_fail_if (msg->prun.your_nonce != prun.my_nonce , "Wrong nonce");
+ }
+ test_end;
+
+ slab_release (msg);
+
+ test_case_begin (test, "CM_SET_GET_KEY.CNF");
+
+ peer.mac = 0x23456789ABCDull;
+ peer.vlan_tag = 0x0;
+ peer.tei = 0xA;
+ peer.all_sta = false;
+
+ nid = 0x123456789ABCDEull;
+
+ prun.pid = 2;
+ prun.pmn = 2;
+ prun.prn = 2;
+ prun.my_nonce = 0x12;
+ prun.your_nonce = 0x13;
+
+ cnf.result = CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED;
+ cnf.key_type = CP_MSG_KEY_DAK;
+ cnf.nid = nid;
+ cnf.eks = 2;
+ cnf.key.key[0] = 0;
+ cnf.key.key[1] = 1;
+ cnf.key.key[2] = 2;
+ cnf.key.key[3] = 3;
+
+ cp_msg_cm_get_key_cnf_send (&cp, &peer, 2, &prun, &cnf);
+
+ // Read the MME.
+ own_data = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_mac_address (own_data, peer.mac, &cp);
+
+ msg = cp_msg_mme_read_header (&cp, (u8*)buffer, buffer_len, 0xa, &fmi);
+ cp_msg_mme_read_header_enc (&cp, msg);
+
+ cp_msg_cm_get_key_cnf_receive (&cp, msg, &cnf);
+ test_begin (test, "Verify")
+ {
+ test_fail_if (cnf.result != CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED,
+ "Wrong result data");
+ test_fail_if (cnf.key_type != CP_MSG_KEY_DAK, "Wrong key type");
+ test_fail_if (cnf.nid != nid, "Wrong NID");
+ test_fail_if (cnf.eks != 2, "Wrong EKS");
+ test_fail_if (cnf.key.key[0] != 0, "Wrong Key 0");
+ test_fail_if (cnf.key.key[1] != 1, "Wrong Key 1");
+ test_fail_if (cnf.key.key[2] != 2, "Wrong Key 2");
+ test_fail_if (cnf.key.key[3] != 3, "Wrong Key 3");
+ test_fail_if (msg->prun.pid != prun.pid, "Wrong PID");
+ test_fail_if (msg->prun.prn != prun.prn, "Wrong PRN");
+ test_fail_if (msg->prun.pmn != prun.pmn, "Wrong PMN");
+ test_fail_if (msg->prun.your_nonce != prun.my_nonce , "Wrong nonce");
+ }
+ test_end;
+
+ slab_release (msg);
+}
+
+int
+main (void)
+{
+ cp_sta_own_data_t *own_data;
+
+ cp.mac_config = &mac_config;
+ test_init (test, 0, NULL);
+
+ own_data = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_tei (own_data, 0xA, &cp);
+ cp_sta_own_data_set_mac_address (own_data, own_mac_addr, &cp);
+ cp_sta_mgr_update_our_avln_nid (&cp, 0x123456789ABCDEFull);
+ cp_sta_mgr_update_our_avln_snid (&cp, 0x2);
+
+ lib_rnd_init (&cp.rnd, 0x12345678);
+
+ test_case_cm_set_key ();
+ test_case_cm_get_key ();
+
+ test_case_begin (test, "Memory allocation");
+ test_begin (test, "memory leaks")
+ {
+ test_fail_if (blk_check_memory () != true, "Memory leaks");
+ }
+ test_end;
+
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
+
+u8 *
+cp_cl_interf_get_buffer_tx (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return buffer;
+}
+
+void
+cp_cl_interf_add_buffer_tx (cp_t *ctx, u8 * buffer)
+{
+}
+
+/**
+ * Send a MME over the PWL or the HLE.
+ * \param ctx the module context.
+ * \param mme The MME to send.
+ *
+ */
+void
+cp_cl_interf_mme_send (cp_t *ctx, cp_mme_tx_t * mme)
+{
+ buffer_len = mme->length;
+ mme->p_mme = NULL;
+}