summaryrefslogtreecommitdiff
path: root/cesar/cp/beacon/src/beacon.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cp/beacon/src/beacon.c')
-rw-r--r--cesar/cp/beacon/src/beacon.c109
1 files changed, 77 insertions, 32 deletions
diff --git a/cesar/cp/beacon/src/beacon.c b/cesar/cp/beacon/src/beacon.c
index f1385de89a..086253b8e1 100644
--- a/cesar/cp/beacon/src/beacon.c
+++ b/cesar/cp/beacon/src/beacon.c
@@ -570,12 +570,15 @@ cp_beacon_process_bmi_eks (cp_t *ctx, const bsu_beacon_t *beacon)
if (beacon->bmis.eks.present)
{
- if ((beacon->bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK)
- && (ctx->mac_config->nek[bsu_nek_index_next (ctx->bsu)].eks
- != beacon->bmis.eks.new_eks))
+ if ((beacon->bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK))
{
- /* We don't have the new NEK. We need to ask for it. */
- cp_fsm_post_new_event (ctx, bare, nek_request);
+ if ((ctx->mac_config->nek_mgr.next_nek == NULL)
+ || (ctx->mac_config->nek_mgr.next_nek->eks
+ != beacon->bmis.eks.new_eks))
+ {
+ /* We don't have the new NEK. We need to ask for it. */
+ cp_fsm_post_new_event (ctx, bare, nek_request);
+ }
}
ctx->beacon.eks.kccd = beacon->bmis.eks.kccd;
@@ -588,12 +591,13 @@ cp_beacon_process_bmi_eks (cp_t *ctx, const bsu_beacon_t *beacon)
{
if (ctx->beacon.eks.kbc == BSU_BEACON_EKS_KBC_NEK)
{
- if (ctx->mac_config->nek[
- bsu_nek_index_current (ctx->bsu)].eks == MAC_EKS_CLEAR)
- /* Countdown elapsed and no NEK is available */
+ mac_nek_t *nek = bsu_nek_get_current (ctx->bsu);
+ if (nek->eks != ctx->beacon.eks.new_eks)
+ {
+ /* The countdown elapsed and we are not using the new NEK.
+ */
cp_fsm_trigger_new_event (ctx, bare, to_leave);
-
- ctx->beacon.eks.kbc = BSU_BEACON_EKS_KBC_NB;
+ }
}
}
ctx->beacon.eks.kccd = 0;
@@ -708,7 +712,6 @@ cp_beacon_process_beacon_central (
beacon->bmis.handover.hcd;
ctx->beacon.hoip.cco = beacon->bmis.handover.tei;
}
-
cp_beacon_process_bmi_eks (ctx, beacon);
/** Update the schedules. */
@@ -905,25 +908,78 @@ cp_beacon_beacon_not_received (cp_t *ctx)
}
/**
- * Set the nek in the beacon module.
- * \param ctx the CP context.
- * \param eks the eks tu use.
- * \param nek the nek key.
- * \param now indicate if the nek shall be use right now.
+ * Store a NEK.
+ * \param nek_mgr the NEK management structure.
+ * \param eks The eks of the NEK to store.
+ * \param nek_enc The encryption part of the NEK to store.
+ * \param nek_dec The decryption part of the NEK to store.
+ * \return A pointer to the stored NEK, or NULL if the storage failed.
*/
+PRIVATE mac_nek_t *
+cp_beacon_store_nek (mac_nek_mgr_t *nek_mgr, u8 eks, const u32 *nek_enc,
+ const u32 *nek_dec)
+{
+ /* Find a free slot. i.e. A slot that is neither in use, nor containing the
+ * next key. */
+ /* arch_dsr_lock() is not necessary for the search, because even if this
+ * function is interrupted, a free slot will remain free, because only the
+ * cp fills slots, and this function is called by the cp, and the cp doesn't
+ * interrupt the cp.
+ * */
+ mac_nek_t *nek = NULL;
+ uint i;
+ for (i = 0; i < MAC_NEK_STORE_NB; i++)
+ {
+ if ((nek_mgr->store[i].in_use == false)
+ && (&nek_mgr->store[i] != nek_mgr->next_nek))
+ {
+ nek = &nek_mgr->store[i];
+ break;
+ }
+ }
+
+ if (nek == NULL)
+ return NULL;
+
+ /* Put the key in the free slot. */
+ nek->eks = eks;
+ for (i = 0; i < COUNT (nek->nek_enc); i++)
+ {
+ nek->nek_enc[i] = nek_enc[i];
+ nek->nek_dec[i] = nek_dec[i];
+ }
+
+ /* Ensure the storage of the NEK is over, before returning.
+ * Probably not necessary before returning from a function, but seems safer
+ * in case this is inlined, for example (?) */
+ arch_reorder_barrier ();
+
+ return nek;
+}
+
void
-cp_beacon_change_nek (cp_t *ctx, uint eks, cp_key_t nek, bool now)
+cp_beacon_change_nek (cp_t *ctx, uint eks, cp_key_t nek_enc, bool now)
{
- cp_key_t rnek;
- uint i,index;
+ cp_key_t nek_dec;
dbg_assert (ctx);
dbg_assert (ctx->mac_config);
+ cp_secu_pbb_dec_gen (nek_enc, &nek_dec);
+
+ mac_nek_t *nek = cp_beacon_store_nek (&ctx->mac_config->nek_mgr, eks,
+ nek_enc.key, nek_dec.key);
+
+ /* Failing to store the NEK should not happen (See MAC_NEK_STORE_NB). */
+ dbg_assert (nek);
+
if (now)
- index = bsu_nek_index_current (ctx->bsu);
+ {
+ bsu_nek_use (ctx->bsu, nek);
+ }
else
{
- index = bsu_nek_index_next (ctx->bsu);
+ bsu_nek_set_next (ctx->bsu, nek);
+
if (cp_sta_own_data_get_cco_status (ctx))
{
/* Initiate key change countdown. */
@@ -932,17 +988,6 @@ cp_beacon_change_nek (cp_t *ctx, uint eks, cp_key_t nek, bool now)
ctx->beacon.eks.new_eks = eks;
}
}
-
- cp_secu_pbb_dec_gen (nek, &rnek);
- ctx->mac_config->nek[index].eks = MAC_EKS_CLEAR;
- arch_reorder_barrier ();
- for (i = 0; i < COUNT(nek.key); i++)
- {
- ctx->mac_config->nek[index].nek_enc[i] = nek.key[i];
- ctx->mac_config->nek[index].nek_dec[i] = rnek.key[i];
- }
- arch_reorder_barrier ();
- ctx->mac_config->nek[index].eks = eks;
}
/**