summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cesar/cp/av/sta/action/src/assoc.c45
-rw-r--r--cesar/cp/av/sta/mgr/src/sta_own_data.c42
-rw-r--r--cesar/cp/av/sta/mgr/sta_own_data.h31
3 files changed, 118 insertions, 0 deletions
diff --git a/cesar/cp/av/sta/action/src/assoc.c b/cesar/cp/av/sta/action/src/assoc.c
index 0430363398..547aaf959f 100644
--- a/cesar/cp/av/sta/action/src/assoc.c
+++ b/cesar/cp/av/sta/action/src/assoc.c
@@ -23,6 +23,7 @@
#include "cp/secu/defs.h"
#include "cp/beacon/beacon.h"
#include "bsu/bsu.h"
+#include "cp/av/sta/mgr/sta_own_data.h"
#define RETRY_TIMEOUT_MS 1000
#define RENEW_MARGIN_MS (5 * 60 * 1000)
@@ -650,6 +651,50 @@ cp_av_sta_action_assoc__started__cm_set_key_req_pid_2 (
{
dbg_assert (ctx);
dbg_assert (mme);
+ cp_msg_cm_set_key_req_t req;
+
+ if (cp_msg_cm_set_key_req_receive (ctx, mme, &req))
+ {
+ if ((req.key_type == CP_MSG_KEY_NMK)
+ && (mme->peks == CP_MME_PEKS_DAK)
+ && (cp_secu_protocol_check
+ (NULL, &mme->prun,
+ CP_SECU_PROTOCOL_RUN_CHECK_RESULT_NEW)))
+ {
+ cp_secu_protocol_run_t prun = mme->prun;
+ cp_msg_cm_set_key_cnf_t cnf = {
+ CP_MSG_CM_SET_KEY_CNF_RESULT_SUCCESS,
+ CP_CCO_LEVEL };
+
+ cp_secu_protocol_next (&prun, &ctx->rnd, true);
+
+ /* Send response. */
+ cp_msg_cm_set_key_cnf_send (
+ ctx, &mme->peer, CP_MME_PEKS_DAK,
+ &prun, &cnf);
+
+ if (cp_av_sta_own_data_set_nmk_and_nid (
+ ctx, req.new_key, req.nid))
+ {
+ /* On change, update the fsm. In other words,
+ * no leave if nid and nmk are the same. */
+ cp_fsm_trigger_new_event (ctx, bare, to_leave);
+ }
+ }
+ else
+ {
+ /* Send failure response. */
+ cp_msg_cm_set_key_cnf_t cnf = {
+ CP_MSG_CM_SET_KEY_CNF_RESULT_FAILURE,
+ CP_CCO_LEVEL };
+ cp_secu_protocol_run_t prun = mme->prun;
+ prun.my_nonce = lib_rnd32 (&ctx->rnd);
+ cp_secu_protocol_next (&prun, &ctx->rnd, true);
+ cp_msg_cm_set_key_cnf_send (
+ ctx, &mme->peer, mme->peks,
+ &prun, &cnf);
+ }
+ }
}
void
diff --git a/cesar/cp/av/sta/mgr/src/sta_own_data.c b/cesar/cp/av/sta/mgr/src/sta_own_data.c
index 91d7795a1e..373d696797 100644
--- a/cesar/cp/av/sta/mgr/src/sta_own_data.c
+++ b/cesar/cp/av/sta/mgr/src/sta_own_data.c
@@ -21,6 +21,7 @@
#include "hal/gpio/gpio.h"
/* Public interfaces. */
+#include "cp/av/sta/mgr/sta_own_data.h"
#include "cp/sta/mgr/sta_own_data.h"
#include "cp/msg/msg.h"
@@ -95,3 +96,44 @@ cp_av_sta_own_data_set_nmk (cp_t *ctx, const cp_key_t nmk,
return false;
}
+
+bool
+cp_av_sta_own_data_set_nmk_and_nid (
+ cp_t *ctx, const cp_key_t new_nmk,
+ const cp_nid_t new_nid)
+{
+ dbg_assert (ctx);
+ bool update_nid = false;
+ bool update_nmk = false;
+
+ cp_nid_t current_nid = cp_sta_own_data_get_nid (ctx);
+
+ if (current_nid != new_nid)
+ {
+ cp_sta_own_data_set_nid (ctx, new_nid);
+ update_nid = true;
+ }
+
+ if (cp_av_sta_own_data_is_nmk_different (ctx, new_nmk))
+ {
+ ctx->sta_mgr.sta_own_data.nmk = new_nmk;
+ update_nmk = true;
+ }
+
+ if (update_nid || update_nmk)
+ {
+ /* Report new computed values to HLE. */
+ cp_mme_peer_t peer = CP_MME_PEER (
+ cp_sta_own_data_get_mac_address (ctx),
+ MAC_TEI_FOREIGN);
+ cp_security_level_t sl = 0;
+
+ cp_msg_drv_sta_set_key_ind_send (
+ ctx, &peer, new_nmk,
+ CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_NID,
+ new_nid, sl);
+ return true;
+ }
+
+ return false;
+}
diff --git a/cesar/cp/av/sta/mgr/sta_own_data.h b/cesar/cp/av/sta/mgr/sta_own_data.h
new file mode 100644
index 0000000000..b24cb8cab8
--- /dev/null
+++ b/cesar/cp/av/sta/mgr/sta_own_data.h
@@ -0,0 +1,31 @@
+#ifndef cp_av_sta_mgr_sta_own_data_h
+#define cp_av_sta_mgr_sta_own_data_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2013 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/av/sta/mgr/sta_own_data.h
+ * \brief Station own data (AV).
+ * \ingroup cp_av_sta_data
+ */
+#include "cp/cp.h"
+
+/**
+ * Set the station NMK and NID.
+ * \param ctx the module context.
+ * \param nmk The NMK to set.
+ * \param nid The NID to set.
+ * \return true if the nmk or nid were changed.
+ */
+bool
+cp_av_sta_own_data_set_nmk_and_nid (
+ cp_t *ctx,
+ const cp_key_t nmk,
+ const cp_nid_t new_nid);
+
+
+#endif /* cp_av_sta_mgr_sta_own_data_h */