/*---------------------------------------------------------------------------*/ static void process_update_command(struct akes_nbr *nbr, uint8_t *data, int cmd_id) { switch(cmd_id) { case AKES_ACK_IDENTIFIER: akes_nbr_free_tentative_metadata(nbr); nbr->sent_authentic_hello = 1; break; case AKES_HELLOACK_IDENTIFIER: nbr->sent_authentic_hello = 0; break; } anti_replay_was_replayed(&nbr->anti_replay_info); #if ANTI_REPLAY_WITH_SUPPRESSION nbr->last_was_broadcast = 1; #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ akes_nbr_prolong(nbr); #if AKES_NBR_WITH_INDICES nbr->foreign_index = data[0]; data++; #endif /* AKES_NBR_WITH_INDICES */ #if ANTI_REPLAY_WITH_SUPPRESSION { frame802154_frame_counter_t disordered_counter; data += 4; memcpy(disordered_counter.u8, data, 4); nbr->anti_replay_info.his_broadcast_counter.u32 = LLSEC802154_HTONL(disordered_counter.u32); data += 4; } #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ #if AKES_NBR_WITH_GROUP_KEYS switch(cmd_id) { case AKES_HELLOACK_IDENTIFIER: case AKES_ACK_IDENTIFIER: akes_nbr_copy_key(nbr->group_key, data); break; } #endif /* AKES_NBR_WITH_GROUP_KEYS */ }
/*---------------------------------------------------------------------------*/ static void input(void) { struct akes_nbr_entry *entry; #if LLSEC802154_USES_AUX_HEADER && POTR_ENABLED packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, adaptivesec_get_sec_lvl()); #endif /* LLSEC802154_USES_AUX_HEADER && POTR_ENABLED */ switch(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE)) { case FRAME802154_CMDFRAME: cmd_broker_publish(); break; case FRAME802154_DATAFRAME: entry = akes_nbr_get_sender_entry(); if(!entry || !entry->permanent) { PRINTF("adaptivesec: Ignored incoming frame\n"); return; } #if SECRDC_WITH_SECURE_PHASE_LOCK if(packetbuf_holds_broadcast() && ADAPTIVESEC_STRATEGY.verify(entry->permanent)) { return; } #else /* SECRDC_WITH_SECURE_PHASE_LOCK */ #if ANTI_REPLAY_WITH_SUPPRESSION && !POTR_ENABLED anti_replay_restore_counter(&entry->permanent->anti_replay_info); #endif /* ANTI_REPLAY_WITH_SUPPRESSION && !POTR_ENABLED */ if(ADAPTIVESEC_STRATEGY.verify(entry->permanent) != ADAPTIVESEC_VERIFY_SUCCESS) { return; } #endif /* SECRDC_WITH_SECURE_PHASE_LOCK */ akes_nbr_prolong(entry->permanent); NETSTACK_NETWORK.input(); break; } }
/*---------------------------------------------------------------------------*/ static enum cmd_broker_result on_hello(uint8_t *payload) { struct akes_nbr_entry *entry; clock_time_t waiting_period; PRINTF("akes: Received HELLO\n"); akes_nbr_delete_expired_tentatives(); entry = akes_nbr_get_sender_entry(); if(entry && entry->permanent) { #if ANTI_REPLAY_WITH_SUPPRESSION anti_replay_restore_counter(&entry->permanent->anti_replay_info); #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ switch(ADAPTIVESEC_STRATEGY.verify(entry->permanent)) { case ADAPTIVESEC_VERIFY_SUCCESS: akes_nbr_prolong(entry->permanent); akes_trickle_on_fresh_authentic_hello(entry->permanent); return CMD_BROKER_CONSUMED; case ADAPTIVESEC_VERIFY_INAUTHENTIC: PRINTF("akes: Starting new session with permanent neighbor\n"); break; case ADAPTIVESEC_VERIFY_REPLAYED: PRINTF("akes: Replayed HELLO\n"); return CMD_BROKER_ERROR; } } if(leaky_bucket_is_full(&helloack_bucket)) { PRINTF("akes: Bucket is full\n"); return CMD_BROKER_ERROR; } if(entry && entry->tentative) { PRINTF("akes: Received HELLO from tentative neighbor\n"); return CMD_BROKER_ERROR; } /* Create tentative neighbor */ entry = akes_nbr_new(AKES_NBR_TENTATIVE); if(!entry) { PRINTF("akes: HELLO flood?\n"); return CMD_BROKER_ERROR; } leaky_bucket_pour(&helloack_bucket); akes_nbr_copy_challenge(entry->tentative->challenge, payload); waiting_period = adaptivesec_random_clock_time(MIN_HELLOACK_DELAY, MAX_HELLOACK_DELAY); entry->tentative->expiration_time = clock_seconds() + (waiting_period / CLOCK_SECOND) + AKES_ACK_DELAY; ctimer_set(&entry->tentative->meta->wait_timer, waiting_period, send_helloack, entry); #if !AKES_NBR_WITH_PAIRWISE_KEYS entry->tentative->meta->has_wait_timer = 1; #endif /* !AKES_NBR_WITH_PAIRWISE_KEYS */ PRINTF("akes: Will send HELLOACK in %lus\n", waiting_period / CLOCK_SECOND); return CMD_BROKER_CONSUMED; }