summaryrefslogtreecommitdiff
path: root/cesar/cp
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cp')
-rw-r--r--cesar/cp/fsm/src/fsm/cp.fsm40
-rw-r--r--cesar/cp/sta/action/assoc.h115
-rw-r--r--cesar/cp/sta/action/doc/assoc.sdl8
-rw-r--r--cesar/cp/sta/action/inc/context.h12
-rw-r--r--cesar/cp/sta/action/src/assoc.c245
-rw-r--r--cesar/cp/sta/action/test/utest/inc/scenario_defs.h8
-rw-r--r--cesar/cp/sta/action/test/utest/src/msg_stub.c11
7 files changed, 400 insertions, 39 deletions
diff --git a/cesar/cp/fsm/src/fsm/cp.fsm b/cesar/cp/fsm/src/fsm/cp.fsm
index e022b6bd12..9f10bf95bb 100644
--- a/cesar/cp/fsm/src/fsm/cp.fsm
+++ b/cesar/cp/fsm/src/fsm/cp.fsm
@@ -9,6 +9,11 @@ States:
LEAVING
LEAVE_WAIT [enter=cp_sta_action_assoc__leave_wait__enter]
+ SC_WAIT_ASSOC_CONF [enter=cp_sta_action_assoc__start_retry_timer leave=cp_sta_action_assoc__stop_retry_timer]
+ SC_ASSOCIATED [enter=cp_sta_action_assoc__start_retry_timer leave=cp_sta_action_assoc__stop_retry_timer]
+ SC_TEK_EXCHANGED
+ SC_NMK_EXCHANGED
+
*STOPPED
STARTED
STOPPING
@@ -25,6 +30,7 @@ States:
Events:
to_assoc
+ to_sc_assoc
to_leave
assoc_timeout
renew
@@ -83,10 +89,14 @@ Events:
CM_SET_KEY_CNF
CM_SET_KEY_REQ_PID1
CM_SET_KEY_CNF_PID1
+ CM_SET_KEY_REQ_PID3
+ CM_SET_KEY_CNF_PID3
CM_GET_KEY_REQ
CM_GET_KEY_CNF
CM_GET_KEY_REQ_PID0
CM_GET_KEY_CNF_PID0
+ CM_GET_KEY_REQ_PID3
+ CM_GET_KEY_CNF_PID3
CM_SC_JOIN_REQ
CM_SC_JOIN_CNF
CM_CHAN_EST_IND
@@ -106,6 +116,8 @@ Events:
UNASSOCIATED:
to_assoc -> WAIT_ASSOC_CONF [cp_sta_action_assoc__unassociated__to_assoc]
send CC_ASSOC.REQ
+ to_sc_assoc -> SC_WAIT_ASSOC_CONF [cp_sta_action_assoc__unassociated__to_assoc]
+ send CC_ASSOC.REQ
WAIT_ASSOC_CONF:
CC_ASSOC_CNF: ok -> ASSOCIATED [cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf]
@@ -117,6 +129,16 @@ WAIT_ASSOC_CONF:
assoc_timeout: no retry -> UNASSOCIATED
to_leave -> UNASSOCIATED [NULL]
+SC_WAIT_ASSOC_CONF:
+ CC_ASSOC_CNF: ok -> SC_ASSOCIATED [cp_sta_action_assoc__sc_wait_assoc_cnf__cc_assoc_cnf]
+ send CM_GET_KEY.REQ
+ CC_ASSOC_CNF: nok -> UNASSOCIATED
+ CC_ASSOC_CNF: unrelated -> .
+ assoc_timeout: retry -> . [cp_sta_action_assoc__sc_wait_assoc_cnf__timeout]
+ send CC_ASSOC.REQ
+ assoc_timeout: no retry -> UNASSOCIATED
+ to_leave -> UNASSOCIATED [NULL]
+
ASSOCIATED:
CM_GET_KEY_CNF_PID0: ok -> AUTHENTICATED [cp_sta_action_assoc__associated__cm_get_key_cnf_pid_0]
CM_GET_KEY_CNF_PID0: nok -> UNASSOCIATED
@@ -124,6 +146,24 @@ ASSOCIATED:
assoc_timeout -> UNASSOCIATED [cp_sta_action_assoc__associated__timeout]
to_leave -> UNASSOCIATED [cp_sta_action_assoc__associated__to_leave]
+SC_ASSOCIATED:
+ CM_GET_KEY_REQ_PID3: ok -> SC_TEK_EXCHANGED [cp_sta_action_assoc__sc_associated__cm_get_key_req_pid_3]
+ send CM_GET_KEY_CNF_PID3
+ CM_GET_KEY_REQ_PID3: unrelated -> .
+ assoc_timeout -> UNASSOCIATED
+
+SC_TEK_EXCHANGED:
+ CM_SET_KEY_REQ_PID3: ok -> SC_NMK_EXCHANGED [cp_sta_action_assoc__sc_tek_exchanged__cm_set_key_req_pid_3]
+ send CM_SET_KEY_CNF_PID3 and CM_GET_KEY_CNF_PID0
+ CM_SET_KEY_REQ_PID3: unrelated -> .
+ assoc_timeout -> UNASSOCIATED
+
+SC_NMK_EXCHANGED:
+ CM_GET_KEY_CNF_PID3: ok -> AUTHENTICATED [cp_sta_action_assoc__sc_nmk_exchanged__cm_get_key_cnf_pid_0]
+ CM_GET_KEY_CNF_PID3: unrelated -> .
+ CM_GET_KEY_CNF_PID3: nok -> UNASSOCIATED
+ assoc_timeout -> UNASSOCIATED
+
AUTHENTICATED:
renew -> . [cp_sta_action_assoc__authenticated__renew]
send CC_ASSOC.REQ for renewal
diff --git a/cesar/cp/sta/action/assoc.h b/cesar/cp/sta/action/assoc.h
index 4981108c96..097641ea40 100644
--- a/cesar/cp/sta/action/assoc.h
+++ b/cesar/cp/sta/action/assoc.h
@@ -152,6 +152,19 @@ void
cp_sta_action_assoc_start (cp_t *ctx, cp_net_t *cco_net, cp_sta_t *cco);
/**
+ * Start an Simple Connect association procedure.
+ * \param ctx control plane context
+ * \param cco_net AVLN of the CCo to associate with
+ * \param cco CCo to associate with
+ * \param sc_peer the peer with which we are doing the SC procedure.
+ *
+ * Trigger TO_SC_ASSOC event.
+ */
+void
+cp_sta_action_sc_assoc_start (cp_t *ctx, cp_net_t *cco_net, cp_sta_t *cco,
+ cp_sta_t *sc_peer);
+
+/**
* Request to leave the current AVLN.
* \param ctx control plane context
*
@@ -170,16 +183,20 @@ void
cp_sta_action_assoc__unassociated__enter (cp_t *ctx);
/**
- * Handle UNASSOCIATED => TO_ASSOC event.
+ * Handle UNASSOCIATED => (TO_ASSOC or TO_SC_ASSOC) events.
* \param ctx control plane context
*
* Send a CC_ASSOC.REQ to the CCo.
+ * \note the transition is the same if we are in the SC procedure or not
+ * because the CC_ASSOC.REQ is sent to the CCo (in the SC procedure, the peer
+ * STA will act as the CCo).
*/
void
cp_sta_action_assoc__unassociated__to_assoc (cp_t *ctx);
/**
- * Handle entering WAIT_ASSOC_CNF, ASSOCIATED.
+ * Handle entering WAIT_ASSOC_CONF, SC_WAIT_ASSOC_CONF, ASSOCIATED and
+ * SC_ASSOCIATED
* \param ctx control plane context
*
* Start retry timer.
@@ -188,7 +205,8 @@ void
cp_sta_action_assoc__start_retry_timer (cp_t *ctx);
/**
- * Handle leaving WAIT_ASSOC_CNF, ASSOCIATED.
+ * Handle leaving WAIT_ASSOC_CONF, SC_WAIT_ASSOC_CONF, ASSOCIATED and
+ * SC_ASSOCIATED.
* \param ctx control plane context
*
* Stop retry timer.
@@ -197,14 +215,17 @@ void
cp_sta_action_assoc__stop_retry_timer (cp_t *ctx);
/**
- * Handle WAIT_ASSOC_CNF => CC_ASSOC.CNF.
+ * Common handle (WAIT_ASSOC_CONF or SC_WAIT_ASSOC_CONF) => CC_ASSOC.CNF.
* \param ctx control plane context
* \param mme received MME handle
+ * \param sc true if we are in simple connect procedure.
+ * \
*
- * If the CCo accepted our association, update association information, send
- * the CM_GET_KEY.REQ, and go to ASSOCIATED state. If the CCo refused, go
- * back to UNASSOCIATED state and update the CCo information to remember the
- * failure.
+ * If the CCo accepted our association and update association information.
+ * If we are not in SC procedure, send the CM_GET_KEY.REQ and go to the
+ * ASSOCIATED state. If we are in SC, do nothing and go to SC_ASSOCIATED.
+ * If the CCo refused, go back to UNASSOCIATED state and update the CCo
+ * information to remember the failure.
*
* Update:
* - our TEI.
@@ -214,24 +235,59 @@ cp_sta_action_assoc__stop_retry_timer (cp_t *ctx);
* - CCo failure info.
*/
void
+cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf__common (cp_t *ctx,
+ cp_mme_rx_t *mme,
+ bool sc);
+
+/**
+ * Handle WAIT_ASSOC_CONF => CC_ASSOC.CNF.
+ * \param ctx control plane context
+ * \param mme received MME handle
+ */
+void
cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf (cp_t *ctx,
cp_mme_rx_t *mme);
/**
- * Handle WAIT_ASSOC_CNF => TIMEOUT.
+ * Handle SC_WAIT_ASSOC_CONF => CC_ASSOC.CNF.
* \param ctx control plane context
+ * \param mme received MME handle
+ */
+void
+cp_sta_action_assoc__sc_wait_assoc_cnf__cc_assoc_cnf (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+/**
+ * Common handle for {SC_,}WAIT_ASSOC_CONF => TIMEOUT.
+ * \param ctx control plane context.
+ * \param sc true if we are in simple connect procedure.
*
* If retry count is not zero, resend the CC_ASSOC.REQ.
*
* If retry count is zero, go back to UNASSOCIATED state.
*/
void
+cp_sta_action_assoc__wait_assoc_cnf__timeout_common (cp_t *ctx, bool sc);
+
+/**
+ * Handle WAIT_ASSOC_CONF => TIMEOUT.
+ * \param ctx control plane context.
+ */
+void
cp_sta_action_assoc__wait_assoc_cnf__timeout (cp_t *ctx);
/**
- * Handle ASSOCIATED => CM_GET_KEY.CNF (PID=0).
+ * Handle SC_WAIT_ASSOC_CONF => TIMEOUT.
+ * \param ctx control plane context.
+ */
+void
+cp_sta_action_assoc__sc_wait_assoc_cnf__timeout (cp_t *ctx);
+
+/**
+ * Common handle for ASSOCIATED or SC_NMK_EXCHANGED => CM_GET_KEY.CNF (PID=0).
* \param ctx control plane context
* \param mme received MME handle
+ * \param sc true if we are in simple connect procedure.
*
* If this is a success, go to AUTHENTICATED state, trigger JOINED event and
* update station status.
@@ -244,6 +300,26 @@ cp_sta_action_assoc__wait_assoc_cnf__timeout (cp_t *ctx);
* - NEK.
* - CCo failure info.
*/
+
+void
+cp_sta_action_assoc__cm_get_key_cnf_pid_0__common (cp_t *ctx, cp_mme_rx_t
+ *mme, bool sc);
+
+/**
+ * Handle SC_NMK_EXCHANGED => CM_GET_KYE.CNF (PID=0)
+ * \param ctx control plane context.
+ * \param mme received MME to handle.
+ */
+void
+cp_sta_action_assoc__sc_nmk_exchanged__cm_get_key_cnf_pid_0 (cp_t *ctx,
+ cp_mme_rx_t *
+ mme);
+
+/**
+ * Handle ASSOCIATED => CM_GET_KEY.CNF (PID=0).
+ * \param ctx control plane context
+ * \param mme received MME handle
+ */
void
cp_sta_action_assoc__associated__cm_get_key_cnf_pid_0 (cp_t *ctx,
cp_mme_rx_t *mme);
@@ -270,6 +346,25 @@ void
cp_sta_action_assoc__associated__to_leave (cp_t *ctx);
/**
+ * Handle SC_ASSOCIATED => CM_GET_KEY.REQ (PID=3).
+ * \param ctx control plane context.
+ * \param mme received MME to handle.
+ */
+void
+cp_sta_action_assoc__sc_associated__cm_get_key_req_pid_3 (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+/**
+ * Handle SC_TEK_EXCHANGED => CM_SET_KEY.REQ (PID=3).
+ * \param ctx control plane context.
+ * \param mme received MME to handle.
+ */
+void
+cp_sta_action_assoc__sc_tek_exchanged__cm_set_key_req_pid_3 (cp_t *ctx,
+ cp_mme_rx_t *
+ mme);
+
+/**
* Handle leaving AUTHENTICATED.
* \param ctx control plane context
*
diff --git a/cesar/cp/sta/action/doc/assoc.sdl b/cesar/cp/sta/action/doc/assoc.sdl
index accfb43567..729444046d 100644
--- a/cesar/cp/sta/action/doc/assoc.sdl
+++ b/cesar/cp/sta/action/doc/assoc.sdl
@@ -36,9 +36,9 @@
<ws:retry?> -n-> (unassociated)
(wait assoc cnf sc) -to leave-> (unassociated)
-(associated sc) -CM_GET_KEY.REQ-> <as:ok?> -y-> (tek exchanged sc)
- <as:ok?> -n-> (unassociated)
- <as:ok?> -unrelated-> (associated sc)
+(associated sc) -CM_GET_KEY.REQ PID=3-> <as:ok?> -y-> (tek exchanged sc)
+ <as:ok?> -n-> (unassociated)
+ <as:ok?> -unrelated-> (associated sc)
(associated sc) -timeout-> (unassociated)
(associated sc) -to leave-> (unassociated)
@@ -48,7 +48,7 @@
(tek exchanged sc) -timeout-> (unassociated)
(tek exchanged sc) -to leave-> (unassociated)
-(nmk exchanged sc) -CM_GET_KEY.REQ PID=3-> <ns:ok> -y-> (authenticated)
+(nmk exchanged sc) -CM_GET_KEY.CNF PID=3-> <ns:ok> -y-> (authenticated)
<ns:ok> -n-> (unassociated)
<ns:ok> -unrelated-> (nmk exchanged sc)
(nmk exchanged sc) -timeout-> (unassociated)
diff --git a/cesar/cp/sta/action/inc/context.h b/cesar/cp/sta/action/inc/context.h
index 9d6cf1f795..5f377df10e 100644
--- a/cesar/cp/sta/action/inc/context.h
+++ b/cesar/cp/sta/action/inc/context.h
@@ -16,6 +16,16 @@
#include "cp/sta/mgr/net.h"
#include "cp/sta/core/core.h"
+/** STA action/sc_assoc sub-context. */
+struct cp_sta_action_sc_assoc_t
+{
+ /** Peer with which we are doing the SC procedure. In some cases, it can
+ * be the same as assoc.peer */
+ cp_mme_peer_t peer;
+ /** TEK generated. */
+ cp_key_t tek;
+};
+
/** STA action/assoc sub-context. */
struct cp_sta_action_assoc_t
{
@@ -33,6 +43,8 @@ struct cp_sta_action_assoc_t
cp_sta_core_timed_event_def_t lease_timer;
/** Number of lost central beacons since the last beacon reception. */
uint beacon_loss;
+ /** Simple Connect data. */
+ struct cp_sta_action_sc_assoc_t sc;
};
/** STA action/poweron sub-context. */
diff --git a/cesar/cp/sta/action/src/assoc.c b/cesar/cp/sta/action/src/assoc.c
index 702db26cc4..c9813849d9 100644
--- a/cesar/cp/sta/action/src/assoc.c
+++ b/cesar/cp/sta/action/src/assoc.c
@@ -33,22 +33,35 @@ cp_sta_action_assoc_init (cp_t *ctx)
}
void
-cp_sta_action_assoc_start (cp_t *ctx, cp_net_t *cco_net, cp_sta_t *cco)
+cp_sta_action_sc_assoc_start (cp_t *ctx, cp_net_t *cco_net, cp_sta_t *cco,
+ cp_sta_t *sc_peer)
{
+ /* Check parameters. */
dbg_assert (ctx);
dbg_assert (cco_net);
dbg_assert (cco);
+ dbg_assert (sc_peer);
+
/* Remember CCo to associate with. */
dbg_assert (cp_sta_own_data_get_nid (ctx)
== cp_net_get_nid (ctx, cco_net));
ctx->sta_action.assoc.cco_net = cco_net;
cp_sta_get_peer (cco, &ctx->sta_action.assoc.peer);
+ /* Copy SC peer information. */
+ cp_sta_get_peer (sc_peer, &ctx->sta_action.assoc.sc.peer);
ctx->sta_action.assoc.retry = 3;
/* Trigger to_assoc event. */
cp_fsm_trigger_new_event (ctx, bare, to_assoc);
}
void
+cp_sta_action_assoc_start (cp_t *ctx, cp_net_t *cco_net, cp_sta_t *cco)
+{
+ /* SC peer is the CCo. */
+ cp_sta_action_sc_assoc_start (ctx, cco_net, cco, cco);
+}
+
+void
cp_sta_action_assoc_leave (cp_t *ctx)
{
dbg_assert (ctx);
@@ -99,8 +112,9 @@ cp_sta_action_assoc__unassociated__to_assoc (cp_t *ctx)
}
void
-cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf (cp_t *ctx,
- cp_mme_rx_t *mme)
+cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf__common (cp_t *ctx,
+ cp_mme_rx_t *mme,
+ bool sc)
{
cp_msg_cc_assoc_cnf_t cnf;
dbg_assert (ctx);
@@ -112,12 +126,18 @@ cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf (cp_t *ctx,
|| cnf.nid != cp_sta_own_data_get_nid (ctx))
{
/* Unrelated message, drop. */
- cp_fsm_branch (ctx, WAIT_ASSOC_CONF, CC_ASSOC_CNF, unrelated);
+ if (!sc)
+ cp_fsm_branch (ctx, WAIT_ASSOC_CONF, CC_ASSOC_CNF, unrelated);
+ else
+ cp_fsm_branch (ctx, SC_WAIT_ASSOC_CONF, CC_ASSOC_CNF, unrelated);
}
else if (cnf.result != CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS)
{
/* Failure indication. */
- cp_fsm_branch (ctx, WAIT_ASSOC_CONF, CC_ASSOC_CNF, nok);
+ if (!sc)
+ cp_fsm_branch (ctx, WAIT_ASSOC_CONF, CC_ASSOC_CNF, nok);
+ else
+ cp_fsm_branch (ctx, SC_WAIT_ASSOC_CONF, CC_ASSOC_CNF, nok);
}
else
{
@@ -148,22 +168,49 @@ cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf (cp_t *ctx,
ctx->sta_action.assoc.peer.tei = mme->peer.tei;
slab_release (cco);
}
- /* Send get key request. */
- cp_msg_cm_get_key_req_t get_key = {
- .relayed = false, .key_type = CP_MSG_KEY_NEK,
- .nid = cp_sta_own_data_get_nid (ctx) };
- cp_secu_protocol_run_new (&ctx->sta_action.assoc.prun, 0,
- lib_rnd32 (&ctx->rnd),
- lib_rnd32 (&ctx->rnd));
- cp_msg_cm_get_key_req_send (ctx, &mme->peer, CP_MME_PEKS_NMK,
- &ctx->sta_action.assoc.prun, &get_key);
- /* Change state. */
- cp_fsm_branch (ctx, WAIT_ASSOC_CONF, CC_ASSOC_CNF, ok);
+ /* Not in SC procedure. */
+ if (!sc)
+ {
+ /* Send get key request. */
+ cp_msg_cm_get_key_req_t get_key = {
+ .relayed = false, .key_type = CP_MSG_KEY_NEK,
+ .nid = cp_sta_own_data_get_nid (ctx) };
+ cp_secu_protocol_run_new (&ctx->sta_action.assoc.prun, 0,
+ lib_rnd32 (&ctx->rnd),
+ lib_rnd32 (&ctx->rnd));
+ cp_msg_cm_get_key_req_send (ctx, &mme->peer, CP_MME_PEKS_NMK,
+ &ctx->sta_action.assoc.prun, &get_key);
+ /* Change state. */
+ cp_fsm_branch (ctx, WAIT_ASSOC_CONF, CC_ASSOC_CNF, ok);
+ }
+ else
+ {
+ /* In SC procedure. */
+ /* Nothing to send. */
+ /* Change state. */
+ cp_fsm_branch (ctx, SC_WAIT_ASSOC_CONF, CC_ASSOC_CNF, ok);
+ }
}
}
void
-cp_sta_action_assoc__wait_assoc_cnf__timeout (cp_t *ctx)
+cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf__common (ctx, mme,
+ false);
+}
+
+void
+cp_sta_action_assoc__sc_wait_assoc_cnf__cc_assoc_cnf (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ cp_sta_action_assoc__wait_assoc_cnf__cc_assoc_cnf__common (ctx, mme,
+ true);
+}
+
+void
+cp_sta_action_assoc__wait_assoc_cnf__timeout_common (cp_t *ctx, bool sc)
{
dbg_assert (ctx);
ctx->sta_action.assoc.retry--;
@@ -172,19 +219,38 @@ cp_sta_action_assoc__wait_assoc_cnf__timeout (cp_t *ctx)
/* Restart timer. */
cp_sta_action_assoc__start_retry_timer (ctx);
/* Resend association request. */
+
cp_sta_action_assoc__unassociated__to_assoc (ctx);
- cp_fsm_branch (ctx, WAIT_ASSOC_CONF, assoc_timeout, retry);
+ if (!sc)
+ cp_fsm_branch (ctx, WAIT_ASSOC_CONF, assoc_timeout, retry);
+ else
+ cp_fsm_branch (ctx, SC_WAIT_ASSOC_CONF, assoc_timeout, retry);
}
else
{
/* Give up. */
- cp_fsm_branch (ctx, WAIT_ASSOC_CONF, assoc_timeout, no_retry);
+ if (!sc)
+ cp_fsm_branch (ctx, WAIT_ASSOC_CONF, assoc_timeout, no_retry);
+ else
+ cp_fsm_branch (ctx, SC_WAIT_ASSOC_CONF, assoc_timeout, no_retry);
}
}
void
-cp_sta_action_assoc__associated__cm_get_key_cnf_pid_0 (cp_t *ctx,
- cp_mme_rx_t *mme)
+cp_sta_action_assoc__wait_assoc_cnf__timeout (cp_t *ctx)
+{
+ cp_sta_action_assoc__wait_assoc_cnf__timeout_common (ctx, false);
+}
+
+void
+cp_sta_action_assoc__sc_wait_assoc_cnf__timeout (cp_t *ctx)
+{
+ cp_sta_action_assoc__wait_assoc_cnf__timeout_common (ctx, true);
+}
+
+void
+cp_sta_action_assoc__cm_get_key_cnf_pid_0__common (cp_t *ctx, cp_mme_rx_t
+ *mme, bool sc)
{
dbg_assert (ctx);
dbg_assert (mme);
@@ -198,12 +264,18 @@ cp_sta_action_assoc__associated__cm_get_key_cnf_pid_0 (cp_t *ctx,
|| cnf.key_type != CP_MSG_KEY_NEK)
{
/* Unrelated message, drop. */
- cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF_PID0, unrelated);
+ if (!sc)
+ cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF_PID0, unrelated);
+ else
+ cp_fsm_branch (ctx, SC_NMK_EXCHANGED, CM_GET_KEY_CNF_PID3, unrelated);
}
else if (cnf.result != CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED)
{
/* Failure indication. */
- cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF_PID0, nok);
+ if (!sc)
+ cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF_PID0, nok);
+ else
+ cp_fsm_branch (ctx, SC_NMK_EXCHANGED, CM_GET_KEY_CNF_PID3, nok);
}
else
{
@@ -214,11 +286,29 @@ cp_sta_action_assoc__associated__cm_get_key_cnf_pid_0 (cp_t *ctx,
cp_fsm_trigger_new_event (ctx, bare, joined);
/* Reset beacon loss counter. */
ctx->sta_action.assoc.beacon_loss = 0;
- cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF_PID0, ok);
+ if (!sc)
+ cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF_PID0, ok);
+ else
+ cp_fsm_branch (ctx, SC_NMK_EXCHANGED, CM_GET_KEY_CNF_PID3, ok);
}
}
void
+cp_sta_action_assoc__sc_nmk_exchanged__cm_get_key_cnf_pid_0 (cp_t *ctx,
+ cp_mme_rx_t *
+ mme)
+{
+ cp_sta_action_assoc__cm_get_key_cnf_pid_0__common (ctx, mme, true);
+}
+
+void
+cp_sta_action_assoc__associated__cm_get_key_cnf_pid_0 (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ cp_sta_action_assoc__cm_get_key_cnf_pid_0__common (ctx, mme, false);
+}
+
+void
cp_sta_action_assoc__associated__timeout (cp_t *ctx)
{
dbg_assert (ctx);
@@ -237,6 +327,112 @@ cp_sta_action_assoc__associated__to_leave (cp_t *ctx)
}
void
+cp_sta_action_assoc__sc_associated__cm_get_key_req_pid_3 (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ /* Check parameters. */
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ cp_msg_cm_get_key_req_t req;
+ /* Check response (note, the MME should be sent by the STA with which are
+ * doing the SC (it can be different from the CCo); */
+ if (!cp_mme_peer_cmp (&mme->peer, &ctx->sta_action.assoc.sc.peer)
+ || !cp_msg_cm_get_key_req_receive (ctx, mme, &req)
+ || (cp_secu_protocol_check (NULL, &mme->prun)
+ != CP_SECU_PROTOCOL_RUN_CHECK_RESULT_NEW)
+ || (req.nid != cp_sta_own_data_get_nid (ctx))
+ || (req.key_type != CP_MSG_KEY_HASH_KEY)
+ || (mme->encrypt != false)
+ || (mme->peks != CP_MME_PEKS_NONE)
+ )
+ {
+ /* Unrelated message, drop it. */
+ cp_fsm_branch (ctx, SC_ASSOCIATED, CM_GET_KEY_REQ_PID3, unrelated);
+ }
+ else
+ {
+ /* Message is valid, reply. */
+ /* Copy security protocol run for authentication. */
+ ctx->sta_action.assoc.prun = mme->prun;
+ /* Prepare message. */
+ cp_msg_cm_get_key_cnf_t cnf;
+ cnf.result = CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED;
+ cnf.key_type = CP_MSG_KEY_HASH_KEY;
+ cnf.nid = cp_sta_own_data_get_nid (ctx);
+ cnf.eks = CP_MME_PEKS_TEK_MIN;
+ cp_secu_aes_generate_key (lib_rnd32 (&ctx->rnd), cnf.hash_key);
+ /* Generate TEK with hash key from CM_HET_KEY REQ and CNF. */
+ cp_secu_tek_gen ((u32 *)req.hash_key, (u32 *)cnf.hash_key,
+ &ctx->sta_action.assoc.sc.tek);
+ /* Set it for encryption/decryption of cm_encrypted payload. */
+ // TODO
+ /* Send CM_GET_KEY.CNF. */
+ cp_secu_protocol_next (&ctx->sta_action.assoc.prun, true);
+ cp_msg_cm_get_key_cnf_send (ctx, &ctx->sta_action.assoc.sc.peer,
+ CP_MME_PEKS_TEK_MIN,
+ &ctx->sta_action.assoc.prun,
+ &cnf);
+ cp_fsm_branch (ctx, SC_ASSOCIATED, CM_GET_KEY_REQ_PID3, ok);
+ }
+}
+
+void
+cp_sta_action_assoc__sc_tek_exchanged__cm_set_key_req_pid_3 (cp_t *ctx,
+ cp_mme_rx_t
+ *mme)
+{
+ /* Check parameters. */
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ cp_msg_cm_set_key_req_t req;
+ /* Check response (note, the MME should be sent by the STA with which are
+ * doing the SC (it can be different from the CCo); */
+ if (!cp_mme_peer_cmp (&mme->peer, &ctx->sta_action.assoc.sc.peer)
+ || !cp_msg_cm_set_key_req_receive (ctx, mme, &req)
+ || (cp_secu_protocol_check (&ctx->sta_action.assoc.prun, &mme->prun)
+ != CP_SECU_PROTOCOL_RUN_CHECK_RESULT_NEXT)
+ || (req.nid != cp_sta_own_data_get_nid (ctx))
+ || (req.key_type != CP_MSG_KEY_NMK)
+ || (mme->encrypt != true)
+ )
+ {
+ /* Unrelated message, drop it. */
+ cp_fsm_branch (ctx, SC_TEK_EXCHANGED, CM_SET_KEY_REQ_PID3, unrelated);
+ }
+ else
+ {
+ /* Message is valid. */
+ /* TODO: Set the NMK -> req.new_key */
+
+ /* Copy security protocol run for authentication. */
+ ctx->sta_action.assoc.prun = mme->prun;
+ /* Prepare message for reply. */
+ cp_msg_cm_set_key_cnf_t cnf;
+ cnf.result = CP_MSG_CM_SET_KEY_CNF_RESULT_SUCCESS;
+ cnf.cco_cap = CP_CCO_LEVEL;
+ /* Send CM_SET_KEY.CNF. */
+ cp_secu_protocol_next (&ctx->sta_action.assoc.prun, true);
+ cp_msg_cm_set_key_cnf_send (ctx, &ctx->sta_action.assoc.sc.peer,
+ CP_MME_PEKS_NMK,
+ &ctx->sta_action.assoc.prun,
+ &cnf);
+ /* Start authentication. */
+ cp_msg_cm_get_key_req_t get_key = {
+ .relayed = false, .key_type = CP_MSG_KEY_NEK,
+ .nid = cp_sta_own_data_get_nid (ctx) };
+ cp_secu_protocol_run_new (&ctx->sta_action.assoc.prun, 0,
+ lib_rnd32 (&ctx->rnd),
+ lib_rnd32 (&ctx->rnd));
+ cp_msg_cm_get_key_req_send (ctx, &ctx->sta_action.assoc.peer,
+ CP_MME_PEKS_NMK,
+ &ctx->sta_action.assoc.prun, &get_key);
+ cp_fsm_branch (ctx, SC_TEK_EXCHANGED, CM_SET_KEY_REQ_PID3, ok);
+ }
+}
+
+void
cp_sta_action_assoc__authenticated__leave (cp_t *ctx)
{
dbg_assert (ctx);
@@ -462,4 +658,3 @@ cp_sta_action_assoc__leave_wait__timeout (cp_t *ctx)
{
dbg_assert (ctx);
}
-
diff --git a/cesar/cp/sta/action/test/utest/inc/scenario_defs.h b/cesar/cp/sta/action/test/utest/inc/scenario_defs.h
index e01f9b4b31..3ae55a142a 100644
--- a/cesar/cp/sta/action/test/utest/inc/scenario_defs.h
+++ b/cesar/cp/sta/action/test/utest/inc/scenario_defs.h
@@ -257,6 +257,8 @@ __0 (update_bridge_table)
cp_msg_cm_set_key_cnf_send, \
cp_msg_cm_get_key_req_send, \
cp_msg_cm_get_key_cnf_receive, \
+ cp_msg_cm_get_key_cnf_send, \
+ cp_msg_cm_get_key_req_receive, \
cp_msg_cm_hfid_req_receive, \
cp_msg_cm_hfid_cnf_send, \
cp_msg_cm_mme_error_ind_receive, \
@@ -403,6 +405,12 @@ __mrk (cp_msg_cm_get_key_cnf_receive,
enum cp_msg_cm_get_key_cnf_result_t result,
enum cp_msg_key_type_t key_type, cp_nid_t nid, u8 eks, u8 *hash_key,
cp_key_t *key)
+__mrk (cp_msg_cm_get_key_req_receive,
+ bool relayed,
+ enum cp_msg_key_type_t key_type, cp_nid_t nid, u8 *hash_key)
+__msk (cp_msg_cm_get_key_cnf_send,
+ enum cp_msg_cm_get_key_cnf_result_t result,
+ enum cp_msg_key_type_t key_type, cp_nid_t nid, u8 eks, u8 *hash_key)
__mr (cp_msg_cm_hfid_req_receive, enum cp_msg_cm_hfid_req_reqtype_t req_type,
cp_nid_t nid, char *hfid)
__ms (cp_msg_cm_hfid_cnf_send, enum cp_msg_cm_hfid_cnf_restype_t restype,
diff --git a/cesar/cp/sta/action/test/utest/src/msg_stub.c b/cesar/cp/sta/action/test/utest/src/msg_stub.c
index af7b959ca9..8abf14e89d 100644
--- a/cesar/cp/sta/action/test/utest/src/msg_stub.c
+++ b/cesar/cp/sta/action/test/utest/src/msg_stub.c
@@ -300,11 +300,22 @@ __mrk (cp_msg_cm_set_key_req_receive, cp_msg_cm_set_key_req_t,
__msk (cp_msg_cm_set_key_cnf_send, cp_msg_cm_set_key_cnf_t,
(enum cp_msg_cm_set_key_cnf_result_t, result, assign),
(u8, cco_cap, assign))
+__msk (cp_msg_cm_get_key_cnf_send, cp_msg_cm_get_key_cnf_t,
+ (enum cp_msg_cm_get_key_cnf_result_t, result, assign),
+ (enum cp_msg_key_type_t, key_type, assign),
+ (cp_nid_t, nid, assign),
+ (u8, eks, assign),
+ (u8 *, hash_key, hash_key))
__msk (cp_msg_cm_get_key_req_send, cp_msg_cm_get_key_req_t,
(bool, relayed, assign),
(enum cp_msg_key_type_t, key_type, assign),
(cp_nid_t, nid, assign),
(u8 *, hash_key, hash_key))
+__mrk (cp_msg_cm_get_key_req_receive, cp_msg_cm_get_key_req_t,
+ (bool, relayed, assign),
+ (enum cp_msg_key_type_t, key_type, assign),
+ (cp_nid_t, nid, assign),
+ (u8 *, hash_key, hash_key))
__mrk (cp_msg_cm_get_key_cnf_receive, cp_msg_cm_get_key_cnf_t,
(enum cp_msg_cm_get_key_cnf_result_t, result, assign),
(enum cp_msg_key_type_t, key_type, assign),