summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cesar/common/defs/homeplugAV.h5
-rw-r--r--cesar/cp2/inc/context.h4
-rw-r--r--cesar/cp2/mme.h6
-rw-r--r--cesar/cp2/msg/msg.h12
-rw-r--r--cesar/cp2/msg/src/mme.c3
-rw-r--r--cesar/cp2/msg/src/msg.c145
-rw-r--r--cesar/cp2/msg/test/overide/cp2/inc/context.h5
-rw-r--r--cesar/cp2/msg/test/src/cp_cl_interface_stub.c12
-rw-r--r--cesar/cp2/msg/test/src/sta_mgr_stub.c6
-rw-r--r--cesar/cp2/msg/test/src/test-msg.c30
10 files changed, 220 insertions, 8 deletions
diff --git a/cesar/common/defs/homeplugAV.h b/cesar/common/defs/homeplugAV.h
index fec6936bf0..72b220b9ba 100644
--- a/cesar/common/defs/homeplugAV.h
+++ b/cesar/common/defs/homeplugAV.h
@@ -44,4 +44,9 @@
/** Define FMI Size. */
#define HPAV_FMI_SIZE 2
+/** CRC Data. */
+#define HPAV_CRC32_GENERATOR 0x04c11db7
+#define HPAV_CRC32_INIT 0xffffffff
+#define HPAV_CRC32_MAGIC 0x2144df1c
+
#endif /* common_defs_homeplugAV_h */
diff --git a/cesar/cp2/inc/context.h b/cesar/cp2/inc/context.h
index 7f5eabbed8..6d310bf1ab 100644
--- a/cesar/cp2/inc/context.h
+++ b/cesar/cp2/inc/context.h
@@ -13,6 +13,7 @@
* \ingroup cp2
*
*/
+#include "lib/rnd.h"
#include "mac/common/config.h"
#include "interface/interface.h"
@@ -97,6 +98,9 @@ struct cp_t
/** PB Processing layer. */
pbproc_t *pbproc;
+
+ /** Random generator. */
+ lib_rnd_t rand;
};
#endif /* cp2_inc_cp_h */
diff --git a/cesar/cp2/mme.h b/cesar/cp2/mme.h
index 3469ad558d..ac27baed6a 100644
--- a/cesar/cp2/mme.h
+++ b/cesar/cp2/mme.h
@@ -268,6 +268,12 @@ struct cp_mme_tx_t
bitstream_t bitstream;
/** CP context used by the destructor of the MME_tx_t message. */
cp_t *cp;
+ /** Offset of the payload. */
+ uint payload_offset;
+ /** RF Len. */
+ uint rf_len;
+ /** IV or UUID. */
+ cp_key_t iv_uuid;
};
typedef struct cp_mme_tx_t cp_mme_tx_t;
diff --git a/cesar/cp2/msg/msg.h b/cesar/cp2/msg/msg.h
index ed3f30965b..2e1029ddfb 100644
--- a/cesar/cp2/msg/msg.h
+++ b/cesar/cp2/msg/msg.h
@@ -28,6 +28,18 @@
#include "inc/msg_cm.h"
#include "inc/msg_drv.h"
+enum cp_msg_avln_status_t
+{
+ CP_MSG_AVLN_STATUS_UNASSOC_CCO_0,
+ CP_MSG_AVLN_STATUS_UNASSOC_CCO_1,
+ CP_MSG_AVLN_STATUS_UNASSOC_CCO_2,
+ CP_MSG_AVLN_STATUS_UNASSOC_CCO_3,
+ CP_MSG_AVLN_STATUS_ASSOC_NOT_PCO,
+ CP_MSG_AVLN_STATUS_ASSOC_PCO,
+ CP_MSG_AVLN_STATUS_CCO = 0x8,
+ CP_MSG_AVLN_STATUS_NB
+};
+
BEGIN_DECLS
/**
diff --git a/cesar/cp2/msg/src/mme.c b/cesar/cp2/msg/src/mme.c
index 9736d08e45..4a8898aef0 100644
--- a/cesar/cp2/msg/src/mme.c
+++ b/cesar/cp2/msg/src/mme.c
@@ -17,8 +17,9 @@
#include "lib/slab.h"
#include "interface/interface.h"
-#include "cp2/msg/inc/msg.h"
+#include "cp2/cl_interf/cl_interf.h"
+#include "cp2/msg/inc/msg.h"
#include "cp2/inc/context.h"
/**
diff --git a/cesar/cp2/msg/src/msg.c b/cesar/cp2/msg/src/msg.c
index 265a4c17f9..81bcb51914 100644
--- a/cesar/cp2/msg/src/msg.c
+++ b/cesar/cp2/msg/src/msg.c
@@ -14,6 +14,8 @@
#include "common/std.h"
#include "lib/read_word.h"
#include "lib/swap.h"
+#include "lib/crc.h"
+#include "lib/rnd.h"
#include "common/defs/homeplugAV.h"
#include "common/defs/ethernet.h"
@@ -105,6 +107,10 @@ cp_msg_mme_init (cp_t *ctx, cp_mme_peer_t *peer, uint mmtype)
// Get the station own data.
own_data = cp_sta_mgr_get_sta_own_data (ctx);
+ // Compute the payload offset.
+ msg->payload_offset = peer->vlan_tag ? HPAV_MME_HEADER_LEN_WITH_VLAN :
+ HPAV_MME_HEADER;
+
// Initialise the bitstream context and fill the MME header.
bitstream_init (&msg->bitstream, msg->p_mme,
peer->vlan_tag ? HPAV_MME_HEADER_LEN_WITH_VLAN :
@@ -164,11 +170,18 @@ cp_msg_mme_init_encrypted (cp_t *ctx, cp_mme_peer_t *peer,
cp_mme_tx_t *msg;
cp_sta_own_data_t *own_data;
u64 data;
+ uint i;
dbg_assert (ctx);
dbg_assert (peer);
dbg_assert (prun);
+ if (peks == CP_MME_PEKS_SPC_NOT_EMBEDDED)
+ {
+ msg = cp_msg_mme_init (ctx, peer, mmtype);
+ return msg;
+ }
+
// Initialise the message context.
msg = cp_msg_mme_tx_init (ctx);
dbg_assert (msg);
@@ -179,11 +192,13 @@ cp_msg_mme_init_encrypted (cp_t *ctx, cp_mme_peer_t *peer,
msg->peks = peks;
msg->prun = *prun;
+ // Compute the random filler.
+
own_data = cp_sta_mgr_get_sta_own_data (ctx);
+
// Initialise the bitstream context.
- bitstream_init (&msg->bitstream, msg->p_mme,
- peer->vlan_tag ? 2 * HPAV_MME_HEADER_LEN_WITH_VLAN :
- 2 * HPAV_MME_HEADER, BITSTREAM_WRITE);
+ bitstream_init (&msg->bitstream, msg->p_mme, ETH_PACKET_MAX_SIZE,
+ BITSTREAM_WRITE);
// Store the ODA.
bitstream_access (&msg->bitstream, &msg->peer.mac,
@@ -219,6 +234,54 @@ cp_msg_mme_init_encrypted (cp_t *ctx, cp_mme_peer_t *peer,
bitstream_access (&msg->bitstream, &data,
BYTES_SIZE_TO_BITS (HPAV_FMI_SIZE));
+ // PKES.
+ bitstream_access (&msg->bitstream, &msg->peks, 8);
+
+ // AVLN status.
+ if (own_data->is_cco)
+ data = CP_MSG_AVLN_STATUS_CCO;
+ else if (!cp_sta_own_data_get_tei (own_data))
+ data = CP_MSG_AVLN_STATUS_UNASSOC_CCO_0 + CP_CCO_LEVEL;
+ else if (own_data->pco_status && cp_sta_own_data_get_tei(own_data))
+ data = CP_MSG_AVLN_STATUS_ASSOC_PCO;
+ else if (!own_data->pco_status && cp_sta_own_data_get_tei(own_data))
+ data = CP_MSG_AVLN_STATUS_ASSOC_NOT_PCO;
+
+ bitstream_access (&msg->bitstream, &data, 8);
+
+ // PID.
+ bitstream_access (&msg->bitstream, &msg->prun.pid, 8);
+
+ // PRN.
+ bitstream_access (&msg->bitstream, &msg->prun.prn, 16);
+
+ // PMN.
+ bitstream_access (&msg->bitstream, &msg->prun.pmn, 8);
+
+ // IV or UUID.
+ bitstream_access (&msg->bitstream, &msg->iv_uuid.key[0], 32);
+ bitstream_access (&msg->bitstream, &msg->iv_uuid.key[1], 32);
+ bitstream_access (&msg->bitstream, &msg->iv_uuid.key[2], 32);
+ bitstream_access (&msg->bitstream, &msg->iv_uuid.key[3], 32);
+
+ // Length of the MME TO be patch at the end.
+ data = 0;
+ bitstream_access (&msg->bitstream, &data, 16);
+
+ // RFLen
+ msg->rf_len = lib_rnd32 (&ctx->rand) % 0xF;
+ data = 0;
+ for (i = 0; i < msg->rf_len; i++)
+ bitstream_access (&msg->bitstream, &data, 8);
+
+ // Compute the payload offset.
+ // 24 bytes to reach the RF LEN.
+ // + RF Len
+ // + MME header 19 without Vlan tag or 23 with the Vlan tag.
+ msg->payload_offset = 24 + (msg->peer.vlan_tag ?
+ HPAV_MME_HEADER_LEN_WITH_VLAN
+ : HPAV_MME_HEADER) + msg->rf_len;
+
// The payload
// Store the ODA.
bitstream_access (&msg->bitstream, &msg->peer.mac,
@@ -260,7 +323,81 @@ cp_msg_mme_init_encrypted (cp_t *ctx, cp_mme_peer_t *peer,
* message.
*/
void
-cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme);
+cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ /* Ends the MME. See HPAV table 11-253. */
+ if ((mme->peks == CP_MME_PEKS_SPC_NOT_EMBEDDED)
+ && (mme->prun.pid != 0x4))
+ {
+ crc_t crc;
+ uint crc_value;
+ u32 enc_tab[256];
+ uint word;
+
+ crc.width = 32;
+ crc.generator = HPAV_CRC32_GENERATOR;
+ crc.init = HPAV_CRC32_INIT;
+ crc.refin = true;
+ crc.refout = true;
+ crc.xorout = 0xffffffff;
+ crc.reg_init = 0;
+ crc.table.t32 = enc_tab;
+ crc_init(&crc);
+
+ /* Patch the length of the MME in the header.
+ * 22 Bytes in after the head of the encrypted payload to reach the
+ * length field.
+ * + The MME header.
+ * - 1 for the alignment.
+ */
+ 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;
+ *(uint*)(mme->p_mme + (mme->peer.vlan_tag ?
+ HPAV_MME_HEADER_LEN_WITH_VLAN:
+ HPAV_MME_HEADER)
+ + 21) = word;
+
+
+
+ /* Compute the CRC. */
+ crc_value = crc_compute_block_le (&crc,
+ mme->p_mme + mme->payload_offset,
+ mme->length);
+ /* Store the CRC. */
+ bitstream_access (&mme->bitstream, &crc_value, 4);
+
+ /* PID. */
+ bitstream_access (&mme->bitstream, &mme->prun.pid, 8);
+
+ /* PRN. */
+ bitstream_access (&mme->bitstream, &mme->prun.prn, 16);
+
+ /* PMN. */
+ bitstream_access (&mme->bitstream, &mme->prun.pmn, 8);
+
+ /* Padding. crc_value variable used as Padding. */
+ crc_value = 0;
+ bitstream_access (&mme->bitstream, &crc_value, 32);
+ bitstream_access (&mme->bitstream, &crc_value, 32);
+ bitstream_access (&mme->bitstream, &crc_value, 24);
+
+ /* RF Len. */
+ bitstream_access (&mme->bitstream, &mme->rf_len, 8);
+ }
+
+ /* Finalise the bitstream. */
+ bitstream_finalise (&mme->bitstream);
+
+ /* Send the MME. */
+ cp_cl_interf_mme_send (ctx, mme);
+}
/**
diff --git a/cesar/cp2/msg/test/overide/cp2/inc/context.h b/cesar/cp2/msg/test/overide/cp2/inc/context.h
index fc07d7919d..a63d9bd876 100644
--- a/cesar/cp2/msg/test/overide/cp2/inc/context.h
+++ b/cesar/cp2/msg/test/overide/cp2/inc/context.h
@@ -15,7 +15,7 @@
* « long description »
*/
-
+#include "lib/rnd.h"
#include "cp2/msg/inc/context.h"
#include "cl/cl.h"
@@ -29,6 +29,9 @@ struct cp_t
/** Convergence layer context. */
cl_t *cl;
+
+ /** Random generator. */
+ lib_rnd_t rand;
};
#endif /* overide_cp2_inc_context_h */
diff --git a/cesar/cp2/msg/test/src/cp_cl_interface_stub.c b/cesar/cp2/msg/test/src/cp_cl_interface_stub.c
index a3664facb5..bd0625cb21 100644
--- a/cesar/cp2/msg/test/src/cp_cl_interface_stub.c
+++ b/cesar/cp2/msg/test/src/cp_cl_interface_stub.c
@@ -15,6 +15,7 @@
#include "common/std.h"
#include "cp2/cp.h"
+#include "cp2/msg/msg.h"
static u8 buffer[2048] __attribute__((aligned(2048)));
@@ -30,3 +31,14 @@ 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)
+{
+
+}
diff --git a/cesar/cp2/msg/test/src/sta_mgr_stub.c b/cesar/cp2/msg/test/src/sta_mgr_stub.c
index a44a30393b..2202b7bea8 100644
--- a/cesar/cp2/msg/test/src/sta_mgr_stub.c
+++ b/cesar/cp2/msg/test/src/sta_mgr_stub.c
@@ -42,3 +42,9 @@ cp_sta_own_data_get_mac_address (cp_sta_own_data_t *ctx)
{
return 0x123456789ABCull;
}
+
+cp_tei_t
+cp_sta_own_data_get_tei (cp_sta_own_data_t *ctx)
+{
+ return 0xA;
+}
diff --git a/cesar/cp2/msg/test/src/test-msg.c b/cesar/cp2/msg/test/src/test-msg.c
index 2a591b25f7..db6595dc04 100644
--- a/cesar/cp2/msg/test/src/test-msg.c
+++ b/cesar/cp2/msg/test/src/test-msg.c
@@ -13,7 +13,7 @@
* « long description »
*/
#include "common/std.h"
-
+#include "common/defs/ethernet.h"
#include "common/defs/homeplugAV.h"
#include "lib/test.h"
@@ -22,6 +22,8 @@
#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"
@@ -127,9 +129,13 @@ test_case_msg_mme_tx_init_enc (test_t test)
cp_mme_peer_t peer;
cp_secu_protocol_run_t prun;
bitstream_t bitstream;
+ cp_sta_own_data_t *sta;
u64 data;
cp_msg_init (&cp);
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+ sta->is_cco = false;
+ sta->pco_status = false;
test_case_begin (test, "Get a MME TX enc context");
@@ -147,7 +153,7 @@ test_case_msg_mme_tx_init_enc (test_t test)
// Close the MME bitstream.
bitstream_finalise (&mme->bitstream);
- bitstream_init (&bitstream, mme->p_mme, 2*HPAV_MME_HEADER_LEN_WITH_VLAN,
+ bitstream_init (&bitstream, mme->p_mme, ETH_PACKET_MAX_SIZE,
BITSTREAM_READ);
test_begin (test, "Verify")
{
@@ -178,6 +184,26 @@ test_case_msg_mme_tx_init_enc (test_t test)
bitstream_access (&bitstream, &data, 16);
test_fail_if (data != 0, "Wrong FMI");
+ bitstream_access (&bitstream, &data, 8);
+ test_fail_if (data != 2, "Wrong PEKS");
+
+ // AVLN status.
+ bitstream_access (&bitstream, &data, 8);
+ test_fail_if (data != CP_MSG_AVLN_STATUS_ASSOC_NOT_PCO,
+ "Wrong AVLN Status");
+
+ bitstream_access (&bitstream, &data, 8);
+ test_fail_if (data != prun.pid, "Wrong PID");
+
+ bitstream_access (&bitstream, &data, 16);
+ test_fail_if (data != prun.prn, "Wrong PRN");
+
+ bitstream_access (&bitstream, &data, 8);
+ test_fail_if (data != prun.pmn, "Wrong PMN");
+ bitstream_finalise (&bitstream);
+
+ bitstream_init (&bitstream, mme->p_mme + mme->payload_offset,
+ ETH_PACKET_MAX_SIZE, BITSTREAM_READ);
bitstream_access (&bitstream, &data, 48);
test_fail_if (data != peer.mac, "enc: Wrong destination mac address");