/*---------------------------------------------------------------------------*/ static int on_frame_created(void) { uint8_t sec_lvl; enum akes_nbr_status status; struct akes_nbr_entry *entry; uint8_t *dataptr; uint8_t datalen; sec_lvl = adaptivesec_get_sec_lvl(); if(sec_lvl && !packetbuf_holds_broadcast()) { status = akes_get_receiver_status(); entry = akes_nbr_get_receiver_entry(); if(!entry || !entry->refs[status]) { return 0; } dataptr = packetbuf_dataptr(); datalen = packetbuf_datalen(); adaptivesec_aead(entry->refs[status]->pairwise_key, sec_lvl & (1 << 2), dataptr + datalen, 1); packetbuf_set_datalen(datalen + ADAPTIVESEC_UNICAST_MIC_LEN); } return 1; }
/*---------------------------------------------------------------------------*/ 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 */ }
/*---------------------------------------------------------------------------*/ int adaptivesec_verify(uint8_t *key) { int shall_decrypt; uint8_t generated_mic[MAX(ADAPTIVESEC_UNICAST_MIC_LEN, ADAPTIVESEC_BROADCAST_MIC_LEN)]; shall_decrypt = adaptivesec_get_sec_lvl() & (1 << 2); packetbuf_set_datalen(packetbuf_datalen() - adaptivesec_mic_len()); adaptivesec_aead(key, shall_decrypt, generated_mic, 0); return memcmp(generated_mic, ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), adaptivesec_mic_len()); }
/*---------------------------------------------------------------------------*/ static void send_broadcast(mac_callback_t sent, void *ptr) { struct queuebuf *qb; #if ANTI_REPLAY_WITH_SUPPRESSION uint16_t frame_counter_bytes_0_1; uint16_t frame_counter_bytes_2_3; uint8_t seqno; frame_counter_bytes_0_1 = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1); frame_counter_bytes_2_3 = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3); seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); adaptivesec_add_security_header(NULL); #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ qb = queuebuf_new_from_packetbuf(); if(!qb || (NETSTACK_FRAMER.create() < 0)) { PRINTF("coresec-strategy: Did not send broadcast\n"); if(qb) { queuebuf_free(qb); } sent(ptr, MAC_TX_ERR, 0); return; } prepare_announce(); #if ANTI_REPLAY_WITH_SUPPRESSION packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame_counter_bytes_0_1); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame_counter_bytes_2_3); packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, seqno); #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ adaptivesec_send_command_frame(); watchdog_periodic(); queuebuf_to_packetbuf(qb); queuebuf_free(qb); #if WITH_BROADCAST_ENCRYPTION { uint8_t ignore[ADAPTIVESEC_BROADCAST_MIC_LEN]; if(adaptivesec_get_sec_lvl() & (1 << 2)) { adaptivesec_aead(adaptivesec_group_key, 1, ignore, 1); } } #endif /* WITH_BROADCAST_ENCRYPTION */ NETSTACK_MAC.send(sent, ptr); }
/*---------------------------------------------------------------------------*/ 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; } }