/*---------------------------------------------------------------------------*/ void akes_broadcast_hello(void) { uint8_t *payload; if(is_awaiting_helloacks) { PRINTF("akes: Still waiting for HELLOACKs\n"); return; } if(leaky_bucket_is_full(&hello_bucket)) { PRINTF("akes: HELLO bucket is full\n"); return; } leaky_bucket_pour(&hello_bucket); payload = adaptivesec_prepare_command(AKES_HELLO_IDENTIFIER, &linkaddr_null); adaptivesec_add_security_header(NULL); anti_replay_suppress_counter(); /* write payload */ akes_nbr_copy_challenge(payload, hello_challenge); payload += AKES_NBR_CHALLENGE_LEN; packetbuf_set_datalen(1 /* command frame identifier */ + AKES_NBR_CHALLENGE_LEN); /* challenge */ PRINTF("akes: broadcasting HELLO\n"); ADAPTIVESEC_STRATEGY.send(on_hello_sent, NULL); }
/*---------------------------------------------------------------------------*/ void adaptivesec_add_security_header(struct anti_replay_info *receiver_info) { if(!anti_replay_set_counter(receiver_info)) { watchdog_reboot(); } #if ANTI_REPLAY_WITH_SUPPRESSION anti_replay_suppress_counter(); #else /* ANTI_REPLAY_WITH_SUPPRESSION */ packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, adaptivesec_get_sec_lvl()); #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ }
/*---------------------------------------------------------------------------*/ static void prepare_update_command(uint8_t cmd_id, struct akes_nbr_entry *entry, enum akes_nbr_status status) { uint8_t *payload; uint8_t payload_len; payload = adaptivesec_prepare_command(cmd_id, akes_nbr_get_addr(entry)); adaptivesec_add_security_header(entry->refs[status]); anti_replay_suppress_counter(); if(status) { /* avoids that csma.c confuses frames for tentative and permanent neighbors */ packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, 0xff00 + packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)); } #if ANTI_REPLAY_WITH_SUPPRESSION packetbuf_set_attr(PACKETBUF_ATTR_NEIGHBOR_INDEX, akes_nbr_index_of(entry->refs[status])); #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ switch(cmd_id) { case AKES_HELLOACK_IDENTIFIER: case AKES_HELLOACK_P_IDENTIFIER: case AKES_ACK_IDENTIFIER: packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_RETRANSMISSIONS_OF_HELLOACKS_AND_ACKS + 1); break; default: break; } /* write payload */ if(status) { akes_nbr_copy_challenge(payload, entry->tentative->challenge); payload += AKES_NBR_CHALLENGE_LEN; } #if AKES_NBR_WITH_INDICES payload[0] = akes_nbr_index_of(entry->refs[status]); payload++; #endif /* AKES_NBR_WITH_INDICES */ #if ANTI_REPLAY_WITH_SUPPRESSION { frame802154_frame_counter_t reordered_counter; anti_replay_write_counter(payload); payload += 4; reordered_counter.u32 = LLSEC802154_HTONL(anti_replay_my_broadcast_counter); memcpy(payload, reordered_counter.u8, 4); payload += 4; } #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ payload_len = payload - ((uint8_t *)packetbuf_hdrptr()); #if AKES_NBR_WITH_GROUP_KEYS switch(cmd_id) { case AKES_HELLOACK_IDENTIFIER: case AKES_HELLOACK_P_IDENTIFIER: case AKES_ACK_IDENTIFIER: akes_nbr_copy_key(payload, adaptivesec_group_key); packetbuf_set_attr(PACKETBUF_ATTR_UNENCRYPTED_BYTES, payload_len); payload_len += AES_128_KEY_LENGTH; break; } #endif /* AKES_NBR_WITH_GROUP_KEYS */ packetbuf_set_datalen(payload_len); }